diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-16 00:09:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-16 00:09:26 +0000 |
commit | 6c0eafbb1395d426a72a74538e0b2a95e8344ca6 (patch) | |
tree | 2a5f80b80fc76086a2602b812c2a182d00f961b7 /Build/source/libs/t1lib | |
parent | 70f7efeb5c9965a63a4143ad1c1f473585dc364c (diff) |
libs 1
git-svn-id: svn://tug.org/texlive/trunk@1483 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/t1lib')
44 files changed, 23060 insertions, 0 deletions
diff --git a/Build/source/libs/t1lib/Makefile.in b/Build/source/libs/t1lib/Makefile.in new file mode 100644 index 00000000000..c7539856acc --- /dev/null +++ b/Build/source/libs/t1lib/Makefile.in @@ -0,0 +1,27 @@ +kpse_include ../../texk/make/common.mk +kpse_include ../../texk/make/programs.mk +kpse_include ../../texk/make/library.mk +kpse_include ../../texk/make/paths.mk + +prog_cflags = @X_CFLAGS@ -DT1LIB_IDENT=\"@T1LIB_IDENTIFIER@\" -DGLOBAL_CONFIG_DIR=\"@T1LIB_DATA_DIR@\" + +OBJS = parseAFM.o t1aaset.o t1afmtool.o t1base.o t1delete.o t1enc.o \ + t1env.o t1finfo.o t1load.o t1outline.o t1set.o t1subset.o t1trans.o + +libt1.a: $(OBJS) + rm -f $@ + $(AR) $(ARFLAGS) $@ $(OBJS) + $(RANLIB) $@ + +all: libt1.a +uninstall: + +kpse_include ../../texk/make/clean.mk + +clean:: + rm -f libt1.a + +distclean:: + rm -f sysconf.h + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/Build/source/libs/t1lib/configure b/Build/source/libs/t1lib/configure new file mode 100755 index 00000000000..c12aae93f5d --- /dev/null +++ b/Build/source/libs/t1lib/configure @@ -0,0 +1,3533 @@ +#! /bin/sh + +# From configure.in configure.in 1.00 + + + + + + + + + + + + + + + + + + + + + +# Find a program when cross-compiling, or use a default when not. +# $1 = variable which records the outcome +# $2 = program to look for when cross-compiling +# $3 = program to use when not cross-compiling + + +# Set BUILD$1 to $2 when cross-compiling, to $($1) if not. +# Example: KPSE_CROSS_BUILD_VAR([CC], [cc]) sets 'BUILDCC' to 'cc' +# if cross-compiling, and to '$(CC)' if not. + + + + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-x use the X Window System" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --without-mktexmf-default do not run mktexmf if MF source missing" +ac_help="$ac_help + --without-mktexpk-default do not run mktexpk if PK font missing" +ac_help="$ac_help + --without-mktextfm-default do not run mktextfm if TFM file missing" +ac_help="$ac_help + --without-mkocp-default do not run mkocp if OCP file missing" +ac_help="$ac_help + --without-mkofm-default do not run mkofm if OFM file missing" +ac_help="$ac_help + --with-mktexfmt-default run mktexfmt if format file missing" +ac_help="$ac_help + --with-mktextex-default run mktextex if TeX source missing" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +ac_config_files= +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_envvar| sed 's/[_a-zA-Z0-9]//g'`"; then + { echo "configure: error: invalid variable name: $ac_envvar" 1>&2; exit 1; } + fi + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=t1base.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../config $srcdir/../../config; do + if test -f $ac_dir/install-sh; then + case $ac_dir in + /*|[A-z]:/*) ac_aux_dir=$ac_dir;; + *) ac_aux_dir=`pwd`/$ac_dir;; + esac + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + case $ac_dir in + /*|[A-z]:/*) ac_aux_dir=$ac_dir;; + *) ac_aux_dir=`pwd`/$ac_dir;; + esac + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../config $srcdir/../../config" 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + + + + + + + + + +T1LIB_LT_CURRENT=5 +T1LIB_LT_REVISION=2 +T1LIB_LT_AGE=0 +T1LIB_IDENTIFIER="5.0.2" + +T1LIB_VERSION=5 +T1LIB_REVISION=0 +T1LIB_PATCHLEVEL=2 +T1LIB_VERSIONSTRING=\""5.0.2"\" + +T1LIB_DATA_DIR="${datadir}/t1lib" + + + + + + + + + + + + + + + + + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:655: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:684: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:715: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:767: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:800: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 811 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:816: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:842: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:847: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:856: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:875: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:907: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 922 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:928: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 939 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 956 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:962: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# If we find X, set shell vars x_includes and x_libraries to the +# paths, otherwise set no_x=yes. +# Uses ac_ vars as temps to allow command line to override cache and checks. +# --without-x overrides everything else, but does not touch the cache. +echo $ac_n "checking for X""... $ac_c" 1>&6 +echo "configure:991: checking for X" >&5 + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + : +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else +if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=NO ac_x_libraries=NO +rm -fr conftestdir +if mkdir conftestdir; then + cd conftestdir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case "$ac_im_incroot" in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; + esac + case "$ac_im_usrlibdir" in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; + esac + fi + cd .. + rm -fr conftestdir +fi + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +cat > conftest.$ac_ext <<EOF +#line 1053 "configure" +#include "confdefs.h" +#include <$x_direct_test_include> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1058: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + # Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done +fi +rm -f conftest* +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + test -z "$x_direct_test_arguments" && x_direct_test_arguments=1 + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1128 "configure" +#include "confdefs.h" +#include <${x_direct_test_include}> +int main() { +${x_direct_test_function}(${x_direct_test_arguments}) +; return 0; } +EOF +if { (eval echo configure:1135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ + /usr/X11/lib \ + /usr/X11R6/lib \ + /usr/X11R5/lib \ + /usr/X11R4/lib \ + \ + /usr/lib/X11 \ + /usr/lib/X11R6 \ + /usr/lib/X11R5 \ + /usr/lib/X11R4 \ + \ + /usr/local/X11/lib \ + /usr/local/X11R6/lib \ + /usr/local/X11R5/lib \ + /usr/local/X11R4/lib \ + \ + /usr/local/lib/X11 \ + /usr/local/lib/X11R6 \ + /usr/local/lib/X11R5 \ + /usr/local/lib/X11R4 \ + \ + /usr/X386/lib \ + /usr/x386/lib \ + /usr/XFree86/lib/X11 \ + \ + /usr/lib \ + /usr/local/lib \ + /usr/unsupported/lib \ + /usr/athena/lib \ + /usr/local/x11r5/lib \ + /usr/lpp/Xamples/lib \ + /lib/usr/lib/X11 \ + \ + /usr/openwin/lib \ + /usr/openwin/share/lib \ + ; \ +do + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest* +fi # $ac_x_libraries = NO + +if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$ac_t""$have_x" 1>&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + cat >> confdefs.h <<\EOF +#define X_DISPLAY_MISSING 1 +EOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case "`(uname -sr) 2>/dev/null`" in + "SunOS 5"*) + echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 +echo "configure:1241: checking whether -R must be followed by a space" >&5 + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" + cat > conftest.$ac_ext <<EOF +#line 1244 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:1251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_nospace=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_nospace=no +fi +rm -f conftest* + if test $ac_R_nospace = yes; then + echo "$ac_t""no" 1>&6 + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat > conftest.$ac_ext <<EOF +#line 1267 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:1274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_space=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_space=no +fi +rm -f conftest* + if test $ac_R_space = yes; then + echo "$ac_t""yes" 1>&6 + X_LIBS="$X_LIBS -R $x_libraries" + else + echo "$ac_t""neither works" 1>&6 + fi + fi + LIBS="$ac_xsave_LIBS" + ;; + OSF1*|IRIX*) + # OSF1 refers to Dec-Unix. -rpath is required in du 4.0 - at least + # -rpath is required in irix 5.x and 6.x - at least + # (Is -rpath really needed in IRIX? OJM) + X_LIBS="$X_LIBS -Wl,-rpath,$x_libraries" + ;; + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And karl@cs.umb.edu says + # the Alpha needs dnet_stub (dnet does not exist). + echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 +echo "configure:1313: checking for dnet_ntoa in -ldnet" >&5 +ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1321 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dnet_ntoa(); + +int main() { +dnet_ntoa() +; return 0; } +EOF +if { (eval echo configure:1332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 +echo "configure:1354: checking for dnet_ntoa in -ldnet_stub" >&5 +ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet_stub $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1362 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dnet_ntoa(); + +int main() { +dnet_ntoa() +; return 0; } +EOF +if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to dickey@clark.net. + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:1402: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1407 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_gethostbyname = no; then + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:1451: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1459 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { +gethostbyname() +; return 0; } +EOF +if { (eval echo configure:1470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says simon@lia.di.epfl.ch: it contains + # gethostby* variants that don't use the nameserver (or something). + # -lsocket must be given before -lnsl if both are needed. + # We assume that if connect needs -lnsl, so does gethostbyname. + echo $ac_n "checking for connect""... $ac_c" 1>&6 +echo "configure:1500: checking for connect" >&5 +if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1505 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +connect(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_connect=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_connect=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_connect = no; then + echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 +echo "configure:1549: checking for connect in -lsocket" >&5 +ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1557 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect(); + +int main() { +connect() +; return 0; } +EOF +if { (eval echo configure:1568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. + echo $ac_n "checking for remove""... $ac_c" 1>&6 +echo "configure:1592: checking for remove" >&5 +if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1597 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char remove(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_remove) || defined (__stub___remove) +choke me +#else +remove(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_remove=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_remove=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_remove = no; then + echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 +echo "configure:1641: checking for remove in -lposix" >&5 +ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lposix $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1649 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove(); + +int main() { +remove() +; return 0; } +EOF +if { (eval echo configure:1660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + echo $ac_n "checking for shmat""... $ac_c" 1>&6 +echo "configure:1684: checking for shmat" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1689 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shmat(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shmat) || defined (__stub___shmat) +choke me +#else +shmat(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shmat=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shmat=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_shmat = no; then + echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 +echo "configure:1733: checking for shmat in -lipc" >&5 +ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lipc $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1741 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat(); + +int main() { +shmat() +; return 0; } +EOF +if { (eval echo configure:1752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS="$LDFLAGS" + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. + echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 +echo "configure:1785: checking for IceConnectionNumber in -lICE" >&5 +ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1793 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char IceConnectionNumber(); + +int main() { +IceConnectionNumber() +; return 0; } +EOF +if { (eval echo configure:1804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +else + echo "$ac_t""no" 1>&6 +fi + + LDFLAGS="$ac_save_LDFLAGS" + +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1840: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + # Hack for MSDOS and descendants. + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test $ac_x $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1897: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + if test -z "$COMSPEC"; then ac_x=-f; else ac_x=-x; fi + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test $ac_x $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:1928: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + if test "x$USE_MAINTAINER_MODE" = xyes; then + MAINT= + else + MAINT='#M#' + fi + + + +echo $ac_n "checking for loader (symbol LD)""... $ac_c" 1>&6 +echo "configure:1947: checking for loader (symbol LD)" >&5 +if eval "test \"`echo '$''{'cf_cv_subst_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +test -z "$LD" && LD=ld +cf_cv_subst_LD=$LD +fi + +LD=${cf_cv_subst_LD} +echo "$ac_t""$LD" 1>&6 + + +echo $ac_n "checking for archiver (symbol AR)""... $ac_c" 1>&6 +echo "configure:1961: checking for archiver (symbol AR)" >&5 +if eval "test \"`echo '$''{'cf_cv_subst_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +test -z "$AR" && AR=ar +cf_cv_subst_AR=$AR +fi + +AR=${cf_cv_subst_AR} +echo "$ac_t""$AR" 1>&6 + + +echo $ac_n "checking for archiver options (symbol ARFLAGS)""... $ac_c" 1>&6 +echo "configure:1975: checking for archiver options (symbol ARFLAGS)" >&5 +if eval "test \"`echo '$''{'cf_cv_subst_ARFLAGS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +test -z "$ARFLAGS" && ARFLAGS=rc +cf_cv_subst_ARFLAGS=$ARFLAGS +fi + +ARFLAGS=${cf_cv_subst_ARFLAGS} +echo "$ac_t""$ARFLAGS" 1>&6 + + + +# Check whether --with-mktexmf-default or --without-mktexmf-default was given. +if test "${with_mktexmf_default+set}" = set; then + withval="$with_mktexmf_default" + : +else + with_mktexmf_default=yes +fi + +# Check whether --with-mktexpk-default or --without-mktexpk-default was given. +if test "${with_mktexpk_default+set}" = set; then + withval="$with_mktexpk_default" + : +else + with_mktexpk_default=yes +fi + +# Check whether --with-mktextfm-default or --without-mktextfm-default was given. +if test "${with_mktextfm_default+set}" = set; then + withval="$with_mktextfm_default" + : +else + with_mktextfm_default=yes +fi + +# Check whether --with-mkocp-default or --without-mkocp-default was given. +if test "${with_mkocp_default+set}" = set; then + withval="$with_mkocp_default" + : +else + with_mkocp_default=yes +fi + +# Check whether --with-mkofm-default or --without-mkofm-default was given. +if test "${with_mkofm_default+set}" = set; then + withval="$with_mkofm_default" + : +else + with_mkofm_default=yes +fi + +# Check whether --with-mktexfmt-default or --without-mktexfmt-default was given. +if test "${with_mktexfmt_default+set}" = set; then + withval="$with_mktexfmt_default" + : +fi + +# Check whether --with-mktextex-default or --without-mktextex-default was given. +if test "${with_mktextex_default+set}" = set; then + withval="$with_mktextex_default" + with_mktextex_default=yes +else + with_mktextex_default=no +fi + + +echo $ac_n "checking where the main texmf tree is located""... $ac_c" 1>&6 +echo "configure:2045: checking where the main texmf tree is located" >&5 +texmfmain= +if test "x$datadir" != 'x${prefix}/share'; then + # First case, datadir is defined... + eval p=\"$datadir\" + # Unconditionally set the directory, but... + texmfmain=`echo "$p/texmf" | sed 's,//*,/,g'` + # ... do complain if it wasn't found. + if test -d "$texmfmain"; then + echo "$ac_t"""$texmfmain"" 1>&6 + else + echo "$ac_t""not found" 1>&6 + echo "configure: warning: No texmf tree found at $texmfmain. + ***************************************************************** + * Error: The main texmf tree was not found. * + * If you do not have the files, you should be able to them from * + * the same place you got these sources from, or from one of the * + * CTAN hosts. * + ***************************************************************** + Winging it." 1>&2 + fi +else + # Second case, datadir is default... + if test "x$prefix" = "xNONE"; then + p="$ac_default_prefix" + else + eval p=\"$prefix\" + fi + for e in share/texmf lib/texmf texmf; do + if test -d "$p/$e"; then + texmfmain='${prefix}'/"$e" + break + fi + done + if test -z "$texmfmain" && test "x$prefix" = "xNONE"; then + # Still no texmfmain found, no prefix set, perhaps kpsewhich is + # installed and can help us out. + texmfmain=`kpsewhich --expand-path='$TEXMFMAIN'` 2>/dev/null + fi + texmfmain=`echo "$texmfmain" | sed 's,//*,/,g'` + if test -n "$texmfmain"; then + echo "$ac_t"""$texmfmain"" 1>&6 + else + eval texmfmain="$datadir/texmf" + echo "$ac_t""not found" 1>&6 + echo "configure: warning: The main texmf tree was not found at $texmfmain. + ***************************************************************** + * Error: The main texmf tree was not found. * + * Use the --datadir option to specify its parent directory. * + * If you do not have the files, you should be able to them from * + * the same place you got these sources from, or from one of the * + * CTAN hosts. * + ***************************************************************** + Winging it by pretending $texmfmain is correct." 1>&2 + fi +fi + + + +echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 +echo "configure:2105: checking whether char is unsigned" >&5 +if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$GCC" = yes; then + # GCC predefines this symbol on systems where it applies. +cat > conftest.$ac_ext <<EOF +#line 2112 "configure" +#include "confdefs.h" +#ifdef __CHAR_UNSIGNED__ + yes +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_c_char_unsigned=yes +else + rm -rf conftest* + ac_cv_c_char_unsigned=no +fi +rm -f conftest* + +else +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <<EOF +#line 2134 "configure" +#include "confdefs.h" +/* volatile prevents gcc2 from optimizing the test away on sparcs. */ +#if !defined(__STDC__) || __STDC__ != 1 +#define volatile +#endif +main() { + volatile char c = 255; exit(c < 0); +} +EOF +if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_char_unsigned=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_char_unsigned=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6 +if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then + cat >> confdefs.h <<\EOF +#define __CHAR_UNSIGNED__ 1 +EOF + +fi + +echo $ac_n "checking size of char""... $ac_c" 1>&6 +echo "configure:2168: checking size of char" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_char=0 +else + cat > conftest.$ac_ext <<EOF +#line 2176 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(char)); + exit(0); +} +EOF +if { (eval echo configure:2187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_char=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_char=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_char" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +EOF + + +echo $ac_n "checking size of short""... $ac_c" 1>&6 +echo "configure:2207: checking size of short" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_short=0 +else + cat > conftest.$ac_ext <<EOF +#line 2215 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short)); + exit(0); +} +EOF +if { (eval echo configure:2226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +EOF + + +echo $ac_n "checking size of int""... $ac_c" 1>&6 +echo "configure:2246: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_int=0 +else + cat > conftest.$ac_ext <<EOF +#line 2254 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:2265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_INT $ac_cv_sizeof_int +EOF + + +echo $ac_n "checking size of long""... $ac_c" 1>&6 +echo "configure:2285: checking size of long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long=0 +else + cat > conftest.$ac_ext <<EOF +#line 2293 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long)); + exit(0); +} +EOF +if { (eval echo configure:2304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_LONG $ac_cv_sizeof_long +EOF + + +echo $ac_n "checking size of long long""... $ac_c" 1>&6 +echo "configure:2324: checking size of long long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_long=0 +else + cat > conftest.$ac_ext <<EOF +#line 2332 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long long)); + exit(0); +} +EOF +if { (eval echo configure:2343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +EOF + + +echo $ac_n "checking size of float""... $ac_c" 1>&6 +echo "configure:2363: checking size of float" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_float=0 +else + cat > conftest.$ac_ext <<EOF +#line 2371 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(float)); + exit(0); +} +EOF +if { (eval echo configure:2382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_float=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_float=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_float" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_FLOAT $ac_cv_sizeof_float +EOF + + +echo $ac_n "checking size of double""... $ac_c" 1>&6 +echo "configure:2402: checking size of double" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_double=0 +else + cat > conftest.$ac_ext <<EOF +#line 2410 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(double)); + exit(0); +} +EOF +if { (eval echo configure:2421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_double=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_double=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_double" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_DOUBLE $ac_cv_sizeof_double +EOF + + +echo $ac_n "checking size of long double""... $ac_c" 1>&6 +echo "configure:2441: checking size of long double" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_long_double=0 +else + cat > conftest.$ac_ext <<EOF +#line 2449 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long double)); + exit(0); +} +EOF +if { (eval echo configure:2460: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long_double=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long_double=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long_double" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double +EOF + + +echo $ac_n "checking size of void *""... $ac_c" 1>&6 +echo "configure:2480: checking size of void *" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_sizeof_void_p=0 +else + cat > conftest.$ac_ext <<EOF +#line 2488 "configure" +#include "confdefs.h" +#include <stdio.h> +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(void *)); + exit(0); +} +EOF +if { (eval echo configure:2499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_void_p=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_void_p=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_void_p" 1>&6 +cat >> confdefs.h <<EOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +EOF + + + +if test "x${GCC}" = "xyes" +then + CFLAGS="$CFLAGS" + echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6 +echo "configure:2523: checking "for gcc strength-reduce bug"" >&5 +if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_gcc_strength_bug="yes" +else + cat > conftest.$ac_ext <<EOF +#line 2531 "configure" +#include "confdefs.h" + +int main(void) { + static int Array[3]; + unsigned int B = 3; + int i; + for(i=0; i<B; i++) Array[i] = i - 3; + exit( Array[1] != -2 ); +} +EOF +if { (eval echo configure:2542: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_gcc_strength_bug="no" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_gcc_strength_bug="yes" +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_gcc_strength_bug" 1>&6 + if test "$ac_cv_c_gcc_strength_bug" = "yes" + then + CFLAGS="$CFLAGS -fno-strength-reduce" + fi +fi + + +echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6 +echo "configure:2565: checking "whether external symbols need an underscore prefix"" >&5 +if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + saved_libs=$LIBS +LIBS="conftest_asm.s $LIBS" +cat > conftest_asm.s <<EOF + .globl _ac_test +_ac_test: + .long 0 +EOF +cat > conftest.$ac_ext <<EOF +#line 2577 "configure" +#include "confdefs.h" +extern int ac_test; +int main() { +if (ac_test) return 1 +; return 0; } +EOF +if { (eval echo configure:2584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_c_extern_prefix="yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_extern_prefix="no" +fi +rm -f conftest* +LIBS=$saved_libs +fi + +echo "$ac_t""$ac_cv_c_extern_prefix" 1>&6 +if test "$ac_cv_c_extern_prefix" = "yes" +then + cat >> confdefs.h <<\EOF +#define NEED_UNDERSCORE_PREFIX 1 +EOF + +fi + +echo $ac_n "checking "which ANSI integer type is 16 bit"""... $ac_c" 1>&6 +echo "configure:2607: checking "which ANSI integer type is 16 bit"" >&5 +if eval "test \"`echo '$''{'ac_16bit_type'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_16bit_type= +else + cat > conftest.$ac_ext <<EOF +#line 2615 "configure" +#include "confdefs.h" + +int main(void) { + if (sizeof(short)==2) + return(0); + else if (sizeof(int)==2) + return(1); + else + return(2); +} +EOF +if { (eval echo configure:2627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_16bit_type="short" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_16bit_type="int" +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_16bit_type" 1>&6 +if test "$ac_16bit_type" = "short" +then + T1_AA_TYPE16="-DT1_AA_TYPE16=short" +else + T1_AA_TYPE16="-DT1_AA_TYPE16=int" +fi + + +echo $ac_n "checking "which ANSI integer type is 32 bit"""... $ac_c" 1>&6 +echo "configure:2651: checking "which ANSI integer type is 32 bit"" >&5 +if eval "test \"`echo '$''{'ac_32bit_type'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_32bit_type= +else + cat > conftest.$ac_ext <<EOF +#line 2659 "configure" +#include "confdefs.h" + +int main(void) { + if (sizeof(int)==4) + return(0); + else if (sizeof(long)==4) + return(1); + else + return(2); +} +EOF +if { (eval echo configure:2671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_32bit_type="int" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_32bit_type="long" +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_32bit_type" 1>&6 +if test "$ac_32bit_type" = "int" +then + T1_AA_TYPE32="-DT1_AA_TYPE32=int" +else + T1_AA_TYPE32="-DT1_AA_TYPE32=long" +fi + + +echo $ac_n "checking "which ANSI integer type is 64 bit"""... $ac_c" 1>&6 +echo "configure:2695: checking "which ANSI integer type is 64 bit"" >&5 +if eval "test \"`echo '$''{'ac_64bit_type'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <<EOF +#line 2703 "configure" +#include "confdefs.h" + +int main(void) { + if (sizeof(long)==8) + return(0); + else + return(1); +} +EOF +if { (eval echo configure:2713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_64bit_type="long" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_64bit_type="<none>" +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_64bit_type" 1>&6 +if test "$ac_64bit_type" = "long" +then + T1_AA_TYPE64="-DT1_AA_TYPE64=long" +else + T1_AA_TYPE64= +fi + + + + + +echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 +echo "configure:2740: checking whether stat file-mode macros are broken" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2745 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/stat.h> + +#if defined(S_ISBLK) && defined(S_IFDIR) +# if S_ISBLK (S_IFDIR) +You lose. +# endif +#endif + +#if defined(S_ISBLK) && defined(S_IFCHR) +# if S_ISBLK (S_IFCHR) +You lose. +# endif +#endif + +#if defined(S_ISLNK) && defined(S_IFREG) +# if S_ISLNK (S_IFREG) +You lose. +# endif +#endif + +#if defined(S_ISSOCK) && defined(S_IFREG) +# if S_ISSOCK (S_IFREG) +You lose. +# endif +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "You lose" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_header_stat_broken=yes +else + rm -rf conftest* + ac_cv_header_stat_broken=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_header_stat_broken" 1>&6 +if test $ac_cv_header_stat_broken = yes; then + cat >> confdefs.h <<\EOF +#define STAT_MACROS_BROKEN 1 +EOF + +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:2796: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2801 "configure" +#include "confdefs.h" + +int main() { + +/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *ccp; +char **p; +/* NEC SVR4.0.2 mips cc rejects this. */ +struct point {int x, y;}; +static struct point const zero = {0,0}; +/* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in an arm + of an if-expression whose if-part is not a constant expression */ +const char *g = "string"; +ccp = &g + (g ? g-g : 0); +/* HPUX 7.0 cc rejects these. */ +++ccp; +p = (char**) ccp; +ccp = (char const *const *) p; +{ /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; +} +{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; +} +{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; +} +{ /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:2850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:2871: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2876 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2884: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2901 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 2919 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext <<EOF +#line 2940 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:2951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:2975: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2980 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + + +ac_config_files="$ac_config_files Makefile" + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + + +trap 'rm -fr `echo "$ac_config_files sysconf.h:sysconf.h.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@T1LIB_LT_CURRENT@%$T1LIB_LT_CURRENT%g +s%@T1LIB_LT_REVISION@%$T1LIB_LT_REVISION%g +s%@T1LIB_LT_AGE@%$T1LIB_LT_AGE%g +s%@T1LIB_DATA_DIR@%$T1LIB_DATA_DIR%g +s%@T1LIB_IDENTIFIER@%$T1LIB_IDENTIFIER%g +s%@T1LIB_VERSION@%$T1LIB_VERSION%g +s%@T1LIB_REVISION@%$T1LIB_REVISION%g +s%@T1LIB_PATCHLEVEL@%$T1LIB_PATCHLEVEL%g +s%@T1LIB_VERSIONSTRING@%$T1LIB_VERSIONSTRING%g +s%@T1_AA_TYPE16@%$T1_AA_TYPE16%g +s%@T1_AA_TYPE32@%$T1_AA_TYPE32%g +s%@T1_AA_TYPE64@%$T1_AA_TYPE64%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@X_CFLAGS@%$X_CFLAGS%g +s%@X_PRE_LIBS@%$X_PRE_LIBS%g +s%@X_LIBS@%$X_LIBS%g +s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@RANLIB@%$RANLIB%g +s%@MAINT@%$MAINT%g +s%@LD@%$LD%g +s%@AR@%$AR%g +s%@ARFLAGS@%$ARFLAGS%g +s%@texmfmain@%$texmfmain%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"$ac_config_files"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*|[A-z]:/*) # Absolute path. + srcdir="$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + "") ;; + [/$]*|[A-z]:/*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + rm -f conftest.in + ac_file_inputs=`echo $ac_file_in|sed -e "s%:% $ac_given_srcdir/%g" -e "s%^%$ac_given_srcdir/%"` + cat $ac_file_inputs > conftest.in + # + # Replace lines of the form ac_include foo with the contents of foo: + # first, from the ac_include lines construct a list of file names. + # From that list, we construct a second list of those files that exist. + # Then we construct lists of sed commands for including those files, + # and a sed command that removes the ac_include lines. We don't attempt + # to read non-existent files because some (buggy) versions of sed choke + # on this. Have to use sed because old (Ultrix, SunOS) awk does not support + # getline or system. (Anyway, configure scripts aren't supposed to use awk.) + # Can't use only one -e and commands {dr foo} because foo has to be last. + # Be careful, because the filename may contain /. Be careful with + # whitespace; we need to use echo. + # + file_substs=`sed -n '/^ac_include/s%ac_include[ ]*\(.*\)%\1%p' conftest.in` + # Create the sed command line ... + if test -n "$file_substs"; then + echo "configure: warning: ac_include is obsolete; instead use kpse_include" 1>&2 + file_subst_cmd="sed -e 's/^ac_include/kpse_include/'" + else + file_subst_cmd='sed' + fi + kpse_substs=`sed -n '/^kpse_include/s%kpse_include[ ]*\(.*\)%\1%p' conftest.in` + for ac_inc in $file_substs $kpse_substs; do + if test -f "$ac_given_srcdir/$ac_inc"; then + ac_mung=`echo $ac_inc | sed 's,/,%,g'` + file_subst_cmd="$file_subst_cmd -e '/^kpse_include $ac_mung$/r $ac_given_srcdir/$ac_inc'" + fi + done + file_subst_cmd="$file_subst_cmd -e '/^kpse_include/d'" + # ... and fix the whitespace and escaped slashes. + file_subst_cmd=`echo "$file_subst_cmd" | sed -e 's,%,\\\/,g' \ +-e 's/kpse_include /kpse_include[ ]*/g'` + # I can't find any way to do variable substitution in the sed commands + # (so the user could have, e.g., $top_srcdir in their ac_include line). + (eval $file_subst_cmd conftest.in) \ + | sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* conftest.in + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ].*$%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS=" sysconf.h:sysconf.h.in" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%:% $ac_given_srcdir/%g" -e "s%^%$ac_given_srcdir/%"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + + + +EOF +cat >> $CONFIG_STATUS <<\EOF + + + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case "$ac_arg" in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + for ac_config_dir in : $subdirs; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + if test ! -d $srcdir/$ac_config_dir; then + continue + fi + + echo configuring in $ac_config_dir + + case "$srcdir" in + .) ;; + *) + if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; + else + { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } + fi + ;; + esac + + ac_popdir=`pwd` + cd $ac_config_dir + + # A "../" for each directory in /$ac_config_dir. + ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + + case "$srcdir" in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + /*|[A-z]:/*) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_config_dir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f ./configure; then + ac_sub_configure=./configure + elif test -f $ac_sub_srcdir/configure; then + ac_sub_configure=$ac_sub_srcdir/configure + elif test -f $ac_sub_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*|[A-z]:/*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + case "$ac_given_INSTALL" in + "") ;; + [/$]*|[A-z]:/*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" + # The eval makes quoting arguments work. + if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir + then : + else + { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } + fi + fi + + cd $ac_popdir + done +fi + diff --git a/Build/source/libs/t1lib/configure.in b/Build/source/libs/t1lib/configure.in new file mode 100644 index 00000000000..f20594ae17e --- /dev/null +++ b/Build/source/libs/t1lib/configure.in @@ -0,0 +1,179 @@ +AC_REVISION([configure.in 1.00]) +AC_INIT(t1base.c) +AC_CONFIG_HEADERS(sysconf.h:sysconf.h.in) +AC_CONFIG_AUX_DIR(../../config) + +define( MACRO_T1LIB_LT_CURRENT, 5) +define( MACRO_T1LIB_LT_REVISION, 2) +define( MACRO_T1LIB_LT_AGE, 0) + + +dnl ----------------------------------------------------------- +dnl ----------------------------------------------------------- +dnl +dnl Do not change anything below this line! +dnl +dnl ----------------------------------------------------------- +dnl ----------------------------------------------------------- + +dnl Build version string and setup stuff to be substituted in +dnl Makefile's and t1lib.h +define( MACRO_T1LIB_IDENTIFIER, "builtin(eval, MACRO_T1LIB_LT_CURRENT - MACRO_T1LIB_LT_AGE).builtin(eval, MACRO_T1LIB_LT_AGE).builtin(eval, MACRO_T1LIB_LT_REVISION)") + +T1LIB_LT_CURRENT=builtin(eval, MACRO_T1LIB_LT_CURRENT) +T1LIB_LT_REVISION=builtin(eval, MACRO_T1LIB_LT_REVISION) +T1LIB_LT_AGE=builtin(eval, MACRO_T1LIB_LT_AGE) +T1LIB_IDENTIFIER=MACRO_T1LIB_IDENTIFIER + +T1LIB_VERSION=builtin(eval, MACRO_T1LIB_LT_CURRENT - MACRO_T1LIB_LT_AGE) +T1LIB_REVISION=builtin(eval, MACRO_T1LIB_LT_AGE) +T1LIB_PATCHLEVEL=builtin(eval, MACRO_T1LIB_LT_REVISION) +T1LIB_VERSIONSTRING=\"MACRO_T1LIB_IDENTIFIER\" + +T1LIB_DATA_DIR="${datadir}/t1lib" + +dnl The following variables should be used + +AC_SUBST(T1LIB_LT_CURRENT) +AC_SUBST(T1LIB_LT_REVISION) +AC_SUBST(T1LIB_LT_AGE) +AC_SUBST(T1LIB_DATA_DIR) +AC_SUBST(T1LIB_IDENTIFIER) + +AC_SUBST(T1LIB_VERSION) +AC_SUBST(T1LIB_REVISION) +AC_SUBST(T1LIB_PATCHLEVEL) +AC_SUBST(T1LIB_VERSIONSTRING) + + +AC_SUBST(T1_AA_TYPE16) +AC_SUBST(T1_AA_TYPE32) +AC_SUBST(T1_AA_TYPE64) + +AC_PROG_MAKE_SET +AC_PROG_CC +AC_PROG_CPP +AC_PATH_XTRA +AC_PROG_INSTALL +AC_PROG_RANLIB + +sinclude(../../texk/kpathsea/withenable.ac) + +dnl **** Check for some compiler/system characteristics +AC_C_CHAR_UNSIGNED +AC_CHECK_SIZEOF(char,0) +AC_CHECK_SIZEOF(short,0) +AC_CHECK_SIZEOF(int,0) +AC_CHECK_SIZEOF(long,0) +AC_CHECK_SIZEOF(long long,0) +AC_CHECK_SIZEOF(float,0) +AC_CHECK_SIZEOF(double,0) +AC_CHECK_SIZEOF(long double,0) +AC_CHECK_SIZEOF(void *,0) + +dnl **** Check for gcc strength-reduce bug **** +if test "x${GCC}" = "xyes" +then + CFLAGS="$CFLAGS" + AC_CACHE_CHECK( "for gcc strength-reduce bug", ac_cv_c_gcc_strength_bug, + AC_TRY_RUN([ +int main(void) { + static int Array[[3]]; + unsigned int B = 3; + int i; + for(i=0; i<B; i++) Array[[i]] = i - 3; + exit( Array[[1]] != -2 ); +}], + ac_cv_c_gcc_strength_bug="no", + ac_cv_c_gcc_strength_bug="yes", + ac_cv_c_gcc_strength_bug="yes") ) + if test "$ac_cv_c_gcc_strength_bug" = "yes" + then + CFLAGS="$CFLAGS -fno-strength-reduce" + fi +fi + +dnl **** Check for underscore on external symbols **** + +AC_CACHE_CHECK("whether external symbols need an underscore prefix", + ac_cv_c_extern_prefix, +[saved_libs=$LIBS +LIBS="conftest_asm.s $LIBS" +cat > conftest_asm.s <<EOF + .globl _ac_test +_ac_test: + .long 0 +EOF +AC_TRY_LINK([extern int ac_test;],[if (ac_test) return 1], + ac_cv_c_extern_prefix="yes",ac_cv_c_extern_prefix="no") +LIBS=$saved_libs]) +if test "$ac_cv_c_extern_prefix" = "yes" +then + AC_DEFINE(NEED_UNDERSCORE_PREFIX) +fi + +dnl **** Check which ANSI integer type is 16 bit +AC_CACHE_CHECK( "which ANSI integer type is 16 bit", ac_16bit_type, + AC_TRY_RUN([ +int main(void) { + if (sizeof(short)==2) + return(0); + else if (sizeof(int)==2) + return(1); + else + return(2); +}], ac_16bit_type="short", ac_16bit_type="int", ac_16bit_type=)) +if test "$ac_16bit_type" = "short" +then + T1_AA_TYPE16="-DT1_AA_TYPE16=short" +else + T1_AA_TYPE16="-DT1_AA_TYPE16=int" +fi + + +dnl **** Check which ANSI integer type is 32 bit +AC_CACHE_CHECK( "which ANSI integer type is 32 bit", ac_32bit_type, + AC_TRY_RUN([ +int main(void) { + if (sizeof(int)==4) + return(0); + else if (sizeof(long)==4) + return(1); + else + return(2); +}], ac_32bit_type="int", ac_32bit_type="long", ac_32bit_type=)) +if test "$ac_32bit_type" = "int" +then + T1_AA_TYPE32="-DT1_AA_TYPE32=int" +else + T1_AA_TYPE32="-DT1_AA_TYPE32=long" +fi + + +dnl **** Check which ANSI integer type is 64 bit +AC_CACHE_CHECK( "which ANSI integer type is 64 bit", ac_64bit_type, + AC_TRY_RUN([ +int main(void) { + if (sizeof(long)==8) + return(0); + else + return(1); +}], ac_64bit_type="long", ac_64bit_type="<none>")) +if test "$ac_64bit_type" = "long" +then + T1_AA_TYPE64="-DT1_AA_TYPE64=long" +else + T1_AA_TYPE64= +fi + +AC_SUBST(T1LIB_IDENTIFIER) +AC_SUBST(T1LIB_DATA_DIR) + +dnl **** Check for functions and header files **** + +AC_HEADER_STAT() +AC_C_CONST() +AC_TYPE_SIZE_T() + +KPSE_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/Build/source/libs/t1lib/depend.mak b/Build/source/libs/t1lib/depend.mak new file mode 100644 index 00000000000..71670f05d9e --- /dev/null +++ b/Build/source/libs/t1lib/depend.mak @@ -0,0 +1,329 @@ +$(objdir)/t1trans.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1trans.h \ + t1base.h + +$(objdir)/t1win32.obj: \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/types.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1set.h \ + t1aaset.h \ + t1load.h \ + t1finfo.h \ + t1win32.h \ + t1base.h + +$(objdir)/t1enc.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1enc.h \ + t1env.h \ + t1base.h \ + t1finfo.h + +$(objdir)/t1outline.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + ../type1/paths.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1set.h \ + t1load.h \ + t1finfo.h \ + t1base.h \ + t1outline.h + +$(objdir)/t1x11.obj: \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/types.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1set.h \ + t1aaset.h \ + t1load.h \ + t1finfo.h \ + t1x11.h \ + t1base.h + +$(objdir)/t1aaset.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1aaset.h \ + t1set.h \ + t1load.h \ + t1finfo.h \ + t1base.h \ + t1outline.h + +$(objdir)/t1afmtool.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + ../type1/blues.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1finfo.h \ + t1base.h \ + t1set.h \ + t1load.h \ + t1afmtool.h + +$(objdir)/t1delete.obj: \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/types.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1delete.h \ + t1load.h \ + t1finfo.h \ + t1base.h + +$(objdir)/t1subset.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1finfo.h \ + t1base.h \ + t1subset.h + +$(objdir)/t1set.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1set.h \ + t1load.h \ + t1finfo.h \ + t1base.h + +$(objdir)/t1base.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + $(t1dir)/sysconf.h \ + t1base.h \ + t1types.h \ + t1global.h \ + t1misc.h \ + t1env.h \ + t1delete.h + +$(objdir)/t1finfo.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1finfo.h \ + t1base.h \ + t1set.h \ + t1load.h + +$(objdir)/t1env.obj: \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/types.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/fontmisc.h \ + $(t1dir)/sysconf.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1env.h \ + t1base.h + +$(objdir)/t1load.obj: \ + ../type1/ffilest.h \ + ../type1/types.h \ + ../type1/Xstuff.h \ + ../type1/fontmisc.h \ + ../type1/fontstruct.h \ + ../type1/font.h \ + ../type1/fsmasks.h \ + ../type1/fontfile.h \ + ../type1/fontxlfd.h \ + ../type1/types.h \ + parseAFM.h \ + ../type1/objects.h \ + ../type1/spaces.h \ + ../type1/util.h \ + ../type1/fontfcn.h \ + ../type1/blues.h \ + ../type1/regions.h \ + t1types.h \ + t1extern.h \ + t1misc.h \ + t1load.h \ + t1env.h \ + t1set.h \ + t1base.h \ + t1finfo.h \ + t1afmtool.h + +$(objdir)/parseAFM.obj: \ + parseAFM.h + diff --git a/Build/source/libs/t1lib/parseAFM.c b/Build/source/libs/t1lib/parseAFM.c new file mode 100644 index 00000000000..6a31d7f3443 --- /dev/null +++ b/Build/source/libs/t1lib/parseAFM.c @@ -0,0 +1,1302 @@ +/*-------------------------------------------------------------------------- + ----- File: parseAFM.c + ----- Author: Adobe Systems Inc., modifications by + Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-10-26 + ----- Description: This file is part of the t1-library. It is the original + parseAFM.h modified at a few points, especially for + reading MSDOS-style AFM files. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +/* + * (C) 1988, 1989, 1990 by Adobe Systems Incorporated. All rights reserved. + * + * This file may be freely copied and redistributed as long as: + * 1) This entire notice continues to be included in the file, + * 2) If the file has been modified in any way, a notice of such + * modification is conspicuously indicated. + * + * PostScript, Display PostScript, and Adobe are registered trademarks of + * Adobe Systems Incorporated. + * + * ************************************************************************ + * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT + * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS + * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR + * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY + * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, + * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * ************************************************************************ + */ + +/* parseAFM.c + * + * This file is used in conjuction with the parseAFM.h header file. + * This file contains several procedures that are used to parse AFM + * files. It is intended to work with an application program that needs + * font metric information. The program can be used as is by making a + * procedure call to "parseFile" (passing in the expected parameters) + * and having it fill in a data structure with the data from the + * AFM file, or an application developer may wish to customize this + * code. + * + * There is also a file, parseAFMclient.c, that is a sample application + * showing how to call the "parseFile" procedure and how to use the data + * after "parseFile" has returned. + * + * Please read the comments in parseAFM.h and parseAFMclient.c. + * + * History: + * original: DSM Thu Oct 20 17:39:59 PDT 1988 + * modified: DSM Mon Jul 3 14:17:50 PDT 1989 + * - added 'storageProblem' return code + * - fixed bug of not allocating extra byte for string duplication + * - fixed typos + * modified: DSM Tue Apr 3 11:18:34 PDT 1990 + * - added free(ident) at end of parseFile routine + * modified: DSM Tue Jun 19 10:16:29 PDT 1990 + * - changed (width == 250) to (width = 250) in initializeArray + */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> /* this seems to be necessary on some SCO-systems */ +#if !defined(_MSC_VER) +# include <sys/file.h> +#endif +#include <math.h> +#include <string.h> +#include "parseAFM.h" +#include "t1base.h" +#include "t1misc.h" + + +#define lineterm EOL /* line terminating character */ +#define normalEOF 1 /* return code from parsing routines used only */ + /* in this module */ +#define Space "space" /* used in string comparison to look for the width */ + /* of the space character to init the widths array */ +#define False "false" /* used in string comparison to check the value of */ + /* boolean keys (e.g. IsFixedPitch) */ + +#define MATCH(A,B) (strncmp((A),(B), MAX_NAME) == 0) + + + +/* Note: The functions token and linetoken are extended to be able + to parse AFM files with DOS-style line-ends under UNIX. I don't know + why AFM files which according to Adobe are explicitly intended to + be used under UNIX have MSDOS-style line ends. + + However, we parse the tokens based on the following atoms. This should + work on any system. +*/ +#define CR '\r' /* a carriage return */ +#define LF '\n' /* a linefeed, which is a newline under UNIX */ +#define CTRL_Z 0x1A /* some AFM files have this characters as an end + of file indicator. Who know why :) ? */ + + +/*************************** GLOBALS ***********************/ + +static char *ident = NULL; /* storage buffer for keywords */ + + +/* "shorts" for fast case statement + * The values of each of these enumerated items correspond to an entry in the + * table of strings defined below. Therefore, if you add a new string as + * new keyword into the keyStrings table, you must also add a corresponding + * parseKey AND it MUST be in the same position! + * + * IMPORTANT: since the sorting algorithm is a binary search, the strings of + * keywords must be placed in lexicographical order, below. [Therefore, the + * enumerated items are not necessarily in lexicographical order, depending + * on the name chosen. BUT, they must be placed in the same position as the + * corresponding key string.] The NOPE shall remain in the last position, + * since it does not correspond to any key string, and it is used in the + * "recognize" procedure to calculate how many possible keys there are. + */ + +typedef enum { + ASCENDER, CHARBBOX, CODE, COMPCHAR, CAPHEIGHT, CHARACTERSET, COMMENT, + DESCENDER, ENCODINGSCHEME, ENDCHARMETRICS, ENDCOMPOSITES, + ENDFONTMETRICS, ENDKERNDATA, ENDKERNPAIRS, ENDTRACKKERN, + FAMILYNAME, FONTBBOX, FONTNAME, FULLNAME, ISFIXEDPITCH, + ITALICANGLE, KERNPAIR, KERNPAIRXAMT, LIGATURE, CHARNAME, + NOTICE, COMPCHARPIECE, STARTCHARMETRICS, STARTCOMPOSITES, + STARTFONTMETRICS, STARTKERNDATA, STARTKERNPAIRS, + STARTTRACKKERN, STDHW, STDVW, TRACKKERN, UNDERLINEPOSITION, + UNDERLINETHICKNESS, VERSION, XYWIDTH, XWIDTH, WEIGHT, XHEIGHT, + NOPE} PARSEKEY; + + +/* keywords for the system: + * This a table of all of the current strings that are vaild AFM keys. + * Each entry can be referenced by the appropriate parseKey value (an + * enumerated data type defined above). If you add a new keyword here, + * a corresponding parseKey MUST be added to the enumerated data type + * defined above, AND it MUST be added in the same position as the + * string is in this table. + * + * IMPORTANT: since the sorting algorithm is a binary search, the keywords + * must be placed in lexicographical order. And, NULL should remain at the + * end. + */ + +static char *keyStrings[] = { + "Ascender", "B", "C", "CC", "CapHeight", "CharacterSet", "Comment", + "Descender", "EncodingScheme", "EndCharMetrics", "EndComposites", + "EndFontMetrics", "EndKernData", "EndKernPairs", "EndTrackKern", + "FamilyName", "FontBBox", "FontName", "FullName", "IsFixedPitch", + "ItalicAngle", "KP", "KPX", "L", "N", + "Notice", "PCC", "StartCharMetrics", "StartComposites", + "StartFontMetrics", "StartKernData", "StartKernPairs", + "StartTrackKern", "StdHW", "StdVW", "TrackKern", "UnderlinePosition", + "UnderlineThickness", "Version", "W", "WX", "Weight", "XHeight", + NULL }; + + +/*************************** PARSING ROUTINES **************/ + +/*************************** token *************************/ + +/* A "AFM File Conventions" tokenizer. That means that it will + * return the next token delimited by white space. See also + * the `linetoken' routine, which does a similar thing but + * reads all tokens until the next end-of-line. + */ +static char *token(stream) + FILE *stream; +{ + int ch, idx; + + /* skip over white space, instead of the systems EOL-character we check + explicitly for CR and LF as well as for ^Z. */ + while ((ch = fgetc(stream)) == ' ' || ch == CR || ch == LF || ch == CTRL_Z || + ch == ',' || ch == '\t' || ch == ';'); + + idx = 0; + + while (ch != EOF && ch != ' ' && ch != CR && ch != LF && + ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';'){ + ident[idx++] = ch; + ch = fgetc(stream); + } /* while */ + + if (ch == EOF && idx < 1) { + return ((char *)NULL); + } + if (idx >= 1 && ch != ':' ) { + ungetc(ch, stream); + } + if (idx < 1 ) { + ident[idx++] = ch; /* single-character token */ + } + ident[idx] = 0; + + return(ident); /* returns pointer to the token */ + +} /* token */ + + +/*************************** linetoken *************************/ + +/* "linetoken" will get read all tokens until the EOL character from + * the given stream. This is used to get any arguments that can be + * more than one word (like Comment lines and FullName). + */ + +static char *linetoken(stream) + FILE *stream; +{ + int ch, idx; + + while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); + + idx = 0; + while (ch != EOF && ch != CR && ch != LF && ch != CTRL_Z) + { + ident[idx++] = ch; + ch = fgetc(stream); + } /* while */ + + ungetc(ch, stream); + ident[idx] = 0; + + return(ident); /* returns pointer to the token */ + +} /* linetoken */ + + +/*************************** recognize *************************/ + +/* This function tries to match a string to a known list of + * valid AFM entries (check the keyStrings array above). + * "ident" contains everything from white space through the + * next space, tab, or ":" character. + * + * The algorithm is a standard Knuth binary search. + */ + +static PARSEKEY recognize(ident) + register char *ident; +{ + int lower = 0, upper = (int) NOPE, midpoint=NOPE, cmpvalue; + BOOL found = T1LIB_FALSE; + + while ((upper >= lower) && !found) + { + midpoint = (lower + upper)/2; + if (keyStrings[midpoint] == NULL) break; + cmpvalue = strncmp(ident, keyStrings[midpoint], MAX_NAME); + if (cmpvalue == 0) found = T1LIB_TRUE; + else if (cmpvalue < 0) upper = midpoint - 1; + else lower = midpoint + 1; + } /* while */ + + if (found) return (PARSEKEY) midpoint; + else return NOPE; + +} /* recognize */ + + +/************************* parseGlobals *****************************/ + +/* This function is called by "parseFile". It will parse the AFM File + * up to the "StartCharMetrics" keyword, which essentially marks the + * end of the Global Font Information and the beginning of the character + * metrics information. + * + * If the caller of "parseFile" specified that it wanted the Global + * Font Information (as defined by the "AFM File Specification" + * document), then that information will be stored in the returned + * data structure. + * + * Any Global Font Information entries that are not found in a + * given file, will have the usual default initialization value + * for its type (i.e. entries of type int will be 0, etc). + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static BOOL parseGlobals(fp, gfi) + FILE *fp; + register GlobalFontInfo *gfi; +{ + BOOL cont = T1LIB_TRUE, save = (gfi != NULL); + int error = ok; + register char *keyword; + + while (cont) + { + keyword = token(fp); + + if (keyword == NULL) + /* Have reached an early and unexpected EOF. */ + /* Set flag and stop parsing */ + { + error = earlyEOF; + break; /* get out of loop */ + } + if (!save) + /* get tokens until the end of the Global Font info section */ + /* without saving any of the data */ + switch (recognize(keyword)) + { + case STARTCHARMETRICS: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + default: + break; + } /* switch */ + else + /* otherwise parse entire global font info section, */ + /* saving the data */ + switch(recognize(keyword)) + { + case STARTFONTMETRICS: + keyword = token(fp); + gfi->afmVersion = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->afmVersion, keyword); + break; + case COMMENT: + /* We ignore the following keywords. They are only listed + here in order to prevent from "Unknown Keyword" errors. */ + case CHARACTERSET: + case STDHW: + case STDVW: + keyword = linetoken(fp); + break; + case FONTNAME: + keyword = linetoken(fp); + gfi->fontName = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->fontName, keyword); + break; + case ENCODINGSCHEME: + keyword = linetoken(fp); + gfi->encodingScheme = (char *) + malloc(strlen(keyword) + 1); + strcpy(gfi->encodingScheme, keyword); + break; + case FULLNAME: + keyword = linetoken(fp); + gfi->fullName = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->fullName, keyword); + break; + case FAMILYNAME: + keyword = linetoken(fp); + gfi->familyName = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->familyName, keyword); + break; + case WEIGHT: + keyword = linetoken(fp); + gfi->weight = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->weight, keyword); + break; + case ITALICANGLE: + keyword = token(fp); + gfi->italicAngle = atof(keyword); + if (errno == ERANGE) error = parseError; + break; + case ISFIXEDPITCH: + keyword = token(fp); + if (MATCH(keyword, False)) + gfi->isFixedPitch = 0; + else + gfi->isFixedPitch = 1; + break; + case UNDERLINEPOSITION: + keyword = token(fp); + gfi->underlinePosition = atoi(keyword); + break; + case UNDERLINETHICKNESS: + keyword = token(fp); + gfi->underlineThickness = atoi(keyword); + break; + case VERSION: + keyword = linetoken(fp); + gfi->version = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->version, keyword); + break; + case NOTICE: + keyword = linetoken(fp); + gfi->notice = (char *) malloc(strlen(keyword) + 1); + strcpy(gfi->notice, keyword); + break; + case FONTBBOX: + keyword = token(fp); + gfi->fontBBox.llx = atoi(keyword); + keyword = token(fp); + gfi->fontBBox.lly = atoi(keyword); + keyword = token(fp); + gfi->fontBBox.urx = atoi(keyword); + keyword = token(fp); + gfi->fontBBox.ury = atoi(keyword); + break; + case CAPHEIGHT: + keyword = token(fp); + gfi->capHeight = atoi(keyword); + break; + case XHEIGHT: + keyword = token(fp); + gfi->xHeight = atoi(keyword); + break; + case DESCENDER: + keyword = token(fp); + gfi->descender = atoi(keyword); + break; + case ASCENDER: + keyword = token(fp); + gfi->ascender = atoi(keyword); + break; + case STARTCHARMETRICS: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + T1_PrintLog( "parseGlobals()", "Unknown Keyword: %s", T1LOG_WARNING, keyword); + break; + } /* switch */ + } /* while */ + + return(error); + +} /* parseGlobals */ + + + +/************************* initializeArray ************************/ + +/* Unmapped character codes are (at Adobe Systems) assigned the + * width of the space character (if one exists) else they get the + * value of 250 ems. This function initializes all entries in the + * char widths array to have this value. Then any mapped character + * codes will be replaced with the width of the appropriate character + * when parsing the character metric section. + + * This function parses the Character Metrics Section looking + * for a space character (by comparing character names). If found, + * the width of the space character will be used to initialize the + * values in the array of character widths. + * + * Before returning, the position of the read/write pointer of the + * file is reset to be where it was upon entering this function. + */ + +/* We comment out the following function since it is not needed in t1lib + and we don't want compiler warnings */ +/* +static int initializeArray(fp, cwi) + FILE *fp; + register int *cwi; +{ + BOOL cont = T1LIB_TRUE, found = T1LIB_FALSE; + long opos = ftell(fp); + int code = 0, width = 0, i = 0, error = 0; + register char *keyword; + + while (cont) + { + keyword = token(fp); + if (keyword == NULL) + { + error = earlyEOF; + break; + } + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case CODE: + code = atoi(token(fp)); + break; + case XWIDTH: + width = atoi(token(fp)); + break; + case CHARNAME: + keyword = token(fp); + if (MATCH(keyword, Space)) + { + cont = T1LIB_FALSE; + found = T1LIB_TRUE; + } + break; + case ENDCHARMETRICS: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + break; + } + } + + if (!found) + width = 250; + + for (i = 0; i < 256; ++i) + cwi[i] = width; + + fseek(fp, opos, 0); + + return(error); + +} +*/ + +/************************* parseCharWidths **************************/ + +/* This function is called by "parseFile". It will parse the AFM File + * up to the "EndCharMetrics" keyword. It will save the character + * width info (as opposed to all of the character metric information) + * if requested by the caller of parseFile. Otherwise, it will just + * parse through the section without saving any information. + * + * If data is to be saved, parseCharWidths is passed in a pointer + * to an array of widths that has already been initialized by the + * standard value for unmapped character codes. This function parses + * the Character Metrics section only storing the width information + * for the encoded characters into the array using the character code + * as the index into that array. + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static int parseCharWidths(fp, cwi) + FILE *fp; + register int *cwi; +{ + BOOL cont = T1LIB_TRUE, save = (cwi != NULL); + int pos = 0, error = ok; + register char *keyword; + + while (cont) + { + keyword = token(fp); + /* Have reached an early and unexpected EOF. */ + /* Set flag and stop parsing */ + if (keyword == NULL) + { + error = earlyEOF; + break; /* get out of loop */ + } + if (!save) + /* get tokens until the end of the Char Metrics section without */ + /* saving any of the data*/ + switch (recognize(keyword)) + { + case ENDCHARMETRICS: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + default: + break; + } /* switch */ + else + /* otherwise parse entire char metrics section, saving */ + /* only the char x-width info */ + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case CODE: + keyword = token(fp); + pos = atoi(keyword); + break; + case XYWIDTH: + /* PROBLEM: Should be no Y-WIDTH when doing "quick & dirty" */ + keyword = token(fp); keyword = token(fp); /* eat values */ + error = parseError; + break; + case XWIDTH: + keyword = token(fp); + if (pos >= 0) /* ignore unmapped chars */ + cwi[pos] = atoi(keyword); + break; + case ENDCHARMETRICS: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case CHARNAME: /* eat values (so doesn't cause parseError) */ + keyword = token(fp); + break; + case CHARBBOX: + keyword = token(fp); keyword = token(fp); + keyword = token(fp); keyword = token(fp); + break; + case LIGATURE: + keyword = token(fp); keyword = token(fp); + break; + case NOPE: + default: + error = parseError; + break; + } /* switch */ + } /* while */ + + return(error); + +} /* parseCharWidths */ + + +/************************* parseCharMetrics ************************/ + +/* This function is called by parseFile if the caller of parseFile + * requested that all character metric information be saved + * (as opposed to only the character width information). + * + * parseCharMetrics is passed in a pointer to an array of records + * to hold information on a per character basis. This function + * parses the Character Metrics section storing all character + * metric information for the ALL characters (mapped and unmapped) + * into the array. + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static int parseCharMetrics(fp, fi) + FILE *fp; + register FontInfo *fi; +{ + BOOL cont = T1LIB_TRUE, firstTime = T1LIB_TRUE; + int error = ok, count = 0; + register CharMetricInfo *temp = fi->cmi; + register char *keyword; + + while (cont) + { + keyword = token(fp); + if (keyword == NULL) + { + error = earlyEOF; + break; /* get out of loop */ + } + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case CODE: + if (count < fi->numOfChars) + { + if (firstTime) firstTime = T1LIB_FALSE; + else temp++; + temp->code = atoi(token(fp)); + count++; + } + else + { + error = parseError; + cont = T1LIB_FALSE; + } + break; + case XYWIDTH: + temp->wx = atoi(token(fp)); + temp->wy = atoi(token(fp)); + break; + case XWIDTH: + temp->wx = atoi(token(fp)); + break; + case CHARNAME: + keyword = token(fp); + temp->name = (char *) malloc(strlen(keyword) + 1); + strcpy(temp->name, keyword); + break; + case CHARBBOX: + temp->charBBox.llx = atoi(token(fp)); + temp->charBBox.lly = atoi(token(fp)); + temp->charBBox.urx = atoi(token(fp)); + temp->charBBox.ury = atoi(token(fp)); + break; + case LIGATURE: { + Ligature **tail = &(temp->ligs); + Ligature *node = *tail; + + if (*tail != NULL) + { + while (node->next != NULL) + node = node->next; + tail = &(node->next); + } + + *tail = (Ligature *) calloc(1, sizeof(Ligature)); + keyword = token(fp); + (*tail)->succ = (char *) malloc(strlen(keyword) + 1); + strcpy((*tail)->succ, keyword); + keyword = token(fp); + (*tail)->lig = (char *) malloc(strlen(keyword) + 1); + strcpy((*tail)->lig, keyword); + break; } + case ENDCHARMETRICS: + cont = T1LIB_FALSE;; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + break; + } /* switch */ + } /* while */ + + if ((error == ok) && (count != fi->numOfChars)) + error = parseError; + + return(error); + +} /* parseCharMetrics */ + + + +/************************* parseTrackKernData ***********************/ + +/* This function is called by "parseFile". It will parse the AFM File + * up to the "EndTrackKern" or "EndKernData" keywords. It will save the + * track kerning data if requested by the caller of parseFile. + * + * parseTrackKernData is passed in a pointer to the FontInfo record. + * If data is to be saved, the FontInfo record will already contain + * a valid pointer to storage for the track kerning data. + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static int parseTrackKernData(fp, fi) + FILE *fp; + register FontInfo *fi; +{ + BOOL cont = T1LIB_TRUE, save = (fi->tkd != NULL); + int pos = 0, error = ok, tcount = 0; + register char *keyword; + + while (cont) + { + keyword = token(fp); + + if (keyword == NULL) + { + error = earlyEOF; + break; /* get out of loop */ + } + if (!save) + /* get tokens until the end of the Track Kerning Data */ + /* section without saving any of the data */ + switch(recognize(keyword)) + { + case ENDTRACKKERN: + case ENDKERNDATA: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + default: + break; + } /* switch */ + else + /* otherwise parse entire Track Kerning Data section, */ + /* saving the data */ + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case TRACKKERN: + if (tcount < fi->numOfTracks) + { + keyword = token(fp); + fi->tkd[pos].degree = atoi(keyword); + keyword = token(fp); + fi->tkd[pos].minPtSize = atof(keyword); + if (errno == ERANGE) error = parseError; + keyword = token(fp); + fi->tkd[pos].minKernAmt = atof(keyword); + if (errno == ERANGE) error = parseError; + keyword = token(fp); + fi->tkd[pos].maxPtSize = atof(keyword); + if (errno == ERANGE) error = parseError; + keyword = token(fp); + fi->tkd[pos++].maxKernAmt = atof(keyword); + if (errno == ERANGE) error = parseError; + tcount++; + } + else + { + error = parseError; + cont = T1LIB_FALSE; + } + break; + case ENDTRACKKERN: + case ENDKERNDATA: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + break; + } /* switch */ + } /* while */ + + if (error == ok && tcount != fi->numOfTracks) + error = parseError; + + return(error); + +} /* parseTrackKernData */ + + +/************************* parsePairKernData ************************/ + +/* This function is called by "parseFile". It will parse the AFM File + * up to the "EndKernPairs" or "EndKernData" keywords. It will save + * the pair kerning data if requested by the caller of parseFile. + * + * parsePairKernData is passed in a pointer to the FontInfo record. + * If data is to be saved, the FontInfo record will already contain + * a valid pointer to storage for the pair kerning data. + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static int parsePairKernData(fp, fi) + FILE *fp; + register FontInfo *fi; +{ + BOOL cont = T1LIB_TRUE, save = (fi->pkd != NULL); + int pos = 0, error = ok, pcount = 0; + register char *keyword; + + while (cont) + { + keyword = token(fp); + + if (keyword == NULL) + { + error = earlyEOF; + break; /* get out of loop */ + } + if (!save) + /* get tokens until the end of the Pair Kerning Data */ + /* section without saving any of the data */ + switch(recognize(keyword)) + { + case ENDKERNPAIRS: + case ENDKERNDATA: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + default: + break; + } /* switch */ + else + /* otherwise parse entire Pair Kerning Data section, */ + /* saving the data */ + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case KERNPAIR: + if (pcount < fi->numOfPairs) + { + keyword = token(fp); + fi->pkd[pos].name1 = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->pkd[pos].name1, keyword); + keyword = token(fp); + fi->pkd[pos].name2 = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->pkd[pos].name2, keyword); + keyword = token(fp); + fi->pkd[pos].xamt = atoi(keyword); + keyword = token(fp); + fi->pkd[pos++].yamt = atoi(keyword); + pcount++; + } + else + { + error = parseError; + cont = T1LIB_FALSE; + } + break; + case KERNPAIRXAMT: + if (pcount < fi->numOfPairs) + { + keyword = token(fp); + fi->pkd[pos].name1 = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->pkd[pos].name1, keyword); + keyword = token(fp); + fi->pkd[pos].name2 = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->pkd[pos].name2, keyword); + keyword = token(fp); + fi->pkd[pos++].xamt = atoi(keyword); + pcount++; + } + else + { + error = parseError; + cont = T1LIB_FALSE; + } + break; + case ENDKERNPAIRS: + case ENDKERNDATA: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + break; + } /* switch */ + } /* while */ + + if (error == ok && pcount != fi->numOfPairs) + error = parseError; + + return(error); + +} /* parsePairKernData */ + + +/************************* parseCompCharData **************************/ + +/* This function is called by "parseFile". It will parse the AFM File + * up to the "EndComposites" keyword. It will save the composite + * character data if requested by the caller of parseFile. + * + * parseCompCharData is passed in a pointer to the FontInfo record, and + * a boolean representing if the data should be saved. + * + * This function will create the appropriate amount of storage for + * the composite character data and store a pointer to the storage + * in the FontInfo record. + * + * This function returns an error code specifying whether there was + * a premature EOF or a parsing error. This return value is used by + * parseFile to determine if there is more file to parse. + */ + +static int parseCompCharData(fp, fi) + FILE *fp; + register FontInfo *fi; +{ + BOOL cont = T1LIB_TRUE, firstTime = T1LIB_TRUE, save = (fi->ccd != NULL); + int pos = 0, j = 0, error = ok, ccount = 0, pcount = 0; + register char *keyword; + + while (cont) + { + keyword = token(fp); + if (keyword == NULL) + /* Have reached an early and unexpected EOF. */ + /* Set flag and stop parsing */ + { + error = earlyEOF; + break; /* get out of loop */ + } + if (ccount > fi->numOfComps) + { + error = parseError; + break; /* get out of loop */ + } + if (!save) + /* get tokens until the end of the Composite Character info */ + /* section without saving any of the data */ + switch(recognize(keyword)) + { + case ENDCOMPOSITES: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + default: + break; + } /* switch */ + else + /* otherwise parse entire Composite Character info section, */ + /* saving the data */ + switch(recognize(keyword)) + { + case COMMENT: + keyword = linetoken(fp); + break; + case COMPCHAR: + if (ccount < fi->numOfComps) + { + keyword = token(fp); + if (pcount != fi->ccd[pos].numOfPieces) + error = parseError; + pcount = 0; + if (firstTime) firstTime = T1LIB_FALSE; + else pos++; + fi->ccd[pos].ccName = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->ccd[pos].ccName, keyword); + keyword = token(fp); + fi->ccd[pos].numOfPieces = atoi(keyword); + fi->ccd[pos].pieces = (Pcc *) + calloc(fi->ccd[pos].numOfPieces, sizeof(Pcc)); + j = 0; + ccount++; + } + else + { + error = parseError; + cont = T1LIB_FALSE; + } + break; + case COMPCHARPIECE: + if (pcount < fi->ccd[pos].numOfPieces) + { + keyword = token(fp); + fi->ccd[pos].pieces[j].pccName = (char *) + malloc(strlen(keyword) + 1); + strcpy(fi->ccd[pos].pieces[j].pccName, keyword); + keyword = token(fp); + fi->ccd[pos].pieces[j].deltax = atoi(keyword); + keyword = token(fp); + fi->ccd[pos].pieces[j++].deltay = atoi(keyword); + pcount++; + } + else + error = parseError; + break; + case ENDCOMPOSITES: + cont = T1LIB_FALSE; + break; + case ENDFONTMETRICS: + cont = T1LIB_FALSE; + error = normalEOF; + break; + case NOPE: + default: + error = parseError; + break; + } /* switch */ + } /* while */ + + if (error == ok && ccount != fi->numOfComps) + error = parseError; + + return(error); + +} /* parseCompCharData */ + + + + +/*************************** 'PUBLIC' FUNCTION ********************/ + + +/*************************** parseFile *****************************/ + +/* parseFile is the only 'public' procedure available. It is called + * from an application wishing to get information from an AFM file. + * The caller of this function is responsible for locating and opening + * an AFM file and handling all errors associated with that task. + * + * parseFile expects 3 parameters: a vaild file pointer, a pointer + * to a (FontInfo *) variable (for which storage will be allocated and + * the data requested filled in), and a mask specifying which + * data from the AFM File should be saved in the FontInfo structure. + * + * The file will be parsed and the requested data will be stored in + * a record of type FontInfo (refer to ParseAFM.h). + * + * parseFile returns an error code as defined in parseAFM.h. + * + * The position of the read/write pointer associated with the file + * pointer upon return of this function is undefined. + */ + +/* Note: function renamed to T1lib_parseFile in order to avoid name clushes + with other libraries that also use the Adobe parseAFM-package (RMz) */ +int T1lib_parseFile (fp, fi, flags) + FILE *fp; + FontInfo **fi; + FLAGS flags; +{ + + int code = ok; /* return code from each of the parsing routines */ + int error = ok; /* used as the return code from this function */ + + register char *keyword; /* used to store a token */ + + + /* storage data for the global variable ident */ + ident = (char *) calloc(MAX_NAME, sizeof(char)); + if (ident == NULL) {error = storageProblem; return(error);} + + (*fi) = (FontInfo *) calloc(1, sizeof(FontInfo)); + if ((*fi) == NULL) {error = storageProblem; return(error);} + + if (flags & P_G) + { + (*fi)->gfi = (GlobalFontInfo *) calloc(1, sizeof(GlobalFontInfo)); + if ((*fi)->gfi == NULL) {error = storageProblem; return(error);} + } + + /* The AFM File begins with Global Font Information. This section */ + /* will be parsed whether or not information should be saved. */ + code = parseGlobals(fp, (*fi)->gfi); + + if (code < 0) error = code; + + /* The Global Font Information is followed by the Character Metrics */ + /* section. Which procedure is used to parse this section depends on */ + /* how much information should be saved. If all of the metrics info */ + /* is wanted, parseCharMetrics is called. If only the character widths */ + /* is wanted, parseCharWidths is called. parseCharWidths will also */ + /* be called in the case that no character data is to be saved, just */ + /* to parse through the section. */ + + if ((code != normalEOF) && (code != earlyEOF)) + { + (*fi)->numOfChars = atoi(token(fp)); + if (flags & (P_M ^ P_W)) + { + (*fi)->cmi = (CharMetricInfo *) + calloc((*fi)->numOfChars, sizeof(CharMetricInfo)); + if ((*fi)->cmi == NULL) {error = storageProblem; return(error);} + code = parseCharMetrics(fp, *fi); + } + else + { + if (flags & P_W) + { + (*fi)->cwi = (int *) calloc(256, sizeof(int)); + if ((*fi)->cwi == NULL) + { + error = storageProblem; + return(error); + } + } + /* parse section regardless */ + code = parseCharWidths(fp, (*fi)->cwi); + } /* else */ + } /* if */ + + if ((error != earlyEOF) && (code < 0)) error = code; + + /* The remaining sections of the AFM are optional. This code will */ + /* look at the next keyword in the file to determine what section */ + /* is next, and then allocate the appropriate amount of storage */ + /* for the data (if the data is to be saved) and call the */ + /* appropriate parsing routine to parse the section. */ + + while ((code != normalEOF) && (code != earlyEOF)) { + keyword = token(fp); + if (keyword == NULL) + /* Have reached an early and unexpected EOF. */ + /* Set flag and stop parsing */ + { + code = earlyEOF; + break; /* get out of loop */ + } + switch(recognize(keyword)) + { + /* this case has been added for t1lib because otherwise comment line + between (i.e., outside) the main sections would lead to parse + errors. The Adobe spec does not seem to forbid comments at + such locations (2001-05-14, RMz) */ + case COMMENT: + keyword = linetoken(fp); + break; + case STARTKERNDATA: + break; + case ENDKERNDATA: + break; + case STARTTRACKKERN: + keyword = token(fp); + if (flags & P_T) + { + (*fi)->numOfTracks = atoi(keyword); + (*fi)->tkd = (TrackKernData *) + calloc((*fi)->numOfTracks, sizeof(TrackKernData)); + if ((*fi)->tkd == NULL) + { + error = storageProblem; + return(error); + } + } /* if */ + code = parseTrackKernData(fp, *fi); + break; + case STARTKERNPAIRS: + keyword = token(fp); + if (flags & P_P) + { + (*fi)->numOfPairs = atoi(keyword); + (*fi)->pkd = (PairKernData *) + calloc((*fi)->numOfPairs, sizeof(PairKernData)); + if ((*fi)->pkd == NULL) + { + error = storageProblem; + return(error); + } + } /* if */ + code = parsePairKernData(fp, *fi); + break; + case STARTCOMPOSITES: + keyword = token(fp); + if (flags & P_C) + { + (*fi)->numOfComps = atoi(keyword); + (*fi)->ccd = (CompCharData *) + calloc((*fi)->numOfComps, sizeof(CompCharData)); + if ((*fi)->ccd == NULL) + { + error = storageProblem; + return(error); + } + } /* if */ + code = parseCompCharData(fp, *fi); + break; + case ENDFONTMETRICS: + code = normalEOF; + break; + case NOPE: + default: + code = parseError; + break; + } /* switch */ + + if ((error != earlyEOF) && (code < 0)) error = code; + + } /* while */ + + if ((error != earlyEOF) && (code < 0)) error = code; + + if (ident != NULL) { free(ident); ident = NULL; } + + return(error); + +} /* parseFile */ diff --git a/Build/source/libs/t1lib/parseAFM.h b/Build/source/libs/t1lib/parseAFM.h new file mode 100644 index 00000000000..9b583a19ac8 --- /dev/null +++ b/Build/source/libs/t1lib/parseAFM.h @@ -0,0 +1,354 @@ +/*-------------------------------------------------------------------------- + ----- File: parseAFM.h + ----- Author: Adobe Systems Inc., modifications by + Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-04-01 + ----- Description: This file is part of the t1-library. It is the original + parseAFM.h modified at a few points. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +/* + * (C) 1988, 1989 by Adobe Systems Incorporated. All rights reserved. + * + * This file may be freely copied and redistributed as long as: + * 1) This entire notice continues to be included in the file, + * 2) If the file has been modified in any way, a notice of such + * modification is conspicuously indicated. + * + * PostScript, Display PostScript, and Adobe are registered trademarks of + * Adobe Systems Incorporated. + * + * ************************************************************************ + * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT + * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS + * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR + * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY + * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, + * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * ************************************************************************ + */ + +/* ParseAFM.h + * + * This header file is used in conjuction with the parseAFM.c file. + * Together these files provide the functionality to parse Adobe Font + * Metrics files and store the information in predefined data structures. + * It is intended to work with an application program that needs font metric + * information. The program can be used as is by making a procedure call to + * parse an AFM file and have the data stored, or an application developer + * may wish to customize the code. + * + * This header file defines the data structures used as well as the key + * strings that are currently recognized by this version of the AFM parser. + * This program is based on the document "Adobe Font Metrics Files, + * Specification Version 2.0". + * + * AFM files are separated into distinct sections of different data. Because + * of this, the parseAFM program can parse a specified file to only save + * certain sections of information based on the application's needs. A record + * containing the requested information will be returned to the application. + * + * AFM files are divided into five sections of data: + * 1) The Global Font Information + * 2) The Character Metrics Information + * 3) The Track Kerning Data + * 4) The Pair-Wise Kerning Data + * 5) The Composite Character Data + * + * Basically, the application can request any of these sections independent + * of what other sections are requested. In addition, in recognizing that + * many applications will want ONLY the x-width of characters and not all + * of the other character metrics information, there is a way to receive + * only the width information so as not to pay the storage cost for the + * unwanted data. An application should never request both the + * "quick and dirty" char metrics (widths only) and the Character Metrics + * Information since the Character Metrics Information will contain all + * of the character widths as well. + * + * There is a procedure in parseAFM.c, called parseFile, that can be + * called from any application wishing to get information from the AFM File. + * This procedure expects 3 parameters: a vaild file descriptor, a pointer + * to a (FontInfo *) variable (for which space will be allocated and then + * will be filled in with the data requested), and a mask specifying + * which data from the AFM File should be saved in the FontInfo structure. + * + * The flags that can be used to set the appropriate mask are defined below. + * In addition, several commonly used masks have already been defined. + * + * History: + * original: DSM Thu Oct 20 17:39:59 PDT 1988 + * modified: DSM Mon Jul 3 14:17:50 PDT 1989 + * - added 'storageProblem' return code + * - fixed typos + */ + +#include <stdio.h> + + + +/* your basic constants */ +#define T1LIB_TRUE 1 +#define T1LIB_FALSE 0 +#define EOL '\n' /* end-of-line indicator */ +#define MAX_NAME 4096 /* max length for identifiers */ +#define BOOL int +#define FLAGS int + + + +/* Flags that can be AND'ed together to specify exactly what + * information from the AFM file should be saved. + */ +#define P_G 0x01 /* 0000 0001 */ /* Global Font Info */ +#define P_W 0x02 /* 0000 0010 */ /* Character Widths ONLY */ +#define P_M 0x06 /* 0000 0110 */ /* All Char Metric Info */ +#define P_P 0x08 /* 0000 1000 */ /* Pair Kerning Info */ +#define P_T 0x10 /* 0001 0000 */ /* Track Kerning Info */ +#define P_C 0x20 /* 0010 0000 */ /* Composite Char Info */ + + +/* Commonly used flags + */ +#define P_GW (P_G | P_W) +#define P_GM (P_G | P_M) +#define P_GMP (P_G | P_M | P_P) +#define P_GMK (P_G | P_M | P_P | P_T) +#define P_ALL (P_G | P_M | P_P | P_T | P_C) + + + +/* Possible return codes from the parseFile procedure. + * + * ok means there were no problems parsing the file. + * + * parseError means that there was some kind of parsing error, but the + * parser went on. This could include problems like the count for any given + * section does not add up to how many entries there actually were, or + * there was a key that was not recognized. The return record may contain + * vaild data or it may not. + * + * earlyEOF means that an End of File was encountered before expected. This + * may mean that the AFM file had been truncated, or improperly formed. + * + * storageProblem means that there were problems allocating storage for + * the data structures that would have contained the AFM data. + */ +#define ok 0 +#define parseError -1 +#define earlyEOF -2 +#define storageProblem -3 + + + +/************************* TYPES *********************************/ +/* Below are all of the data structure definitions. These structures + * try to map as closely as possible to grouping and naming of data + * in the AFM Files. + */ + + +/* Bounding box definition. Used for the Font BBox as well as the + * Character BBox. + */ +typedef struct +{ + int llx; /* lower left x-position */ + int lly; /* lower left y-position */ + int urx; /* upper right x-position */ + int ury; /* upper right y-position */ +} BBox; + + +/* Global Font information. + * The key that each field is associated with is in comments. For an + * explanation about each key and its value please refer to the AFM + * documentation (full title & version given above). + */ +typedef struct +{ + char *afmVersion; /* key: StartFontMetrics */ + char *fontName; /* key: FontName */ + char *fullName; /* key: FullName */ + char *familyName; /* key: FamilyName */ + char *weight; /* key: Weight */ + float italicAngle; /* key: ItalicAngle */ + BOOL isFixedPitch; /* key: IsFixedPitch */ + BBox fontBBox; /* key: FontBBox */ + int underlinePosition; /* key: UnderlinePosition */ + int underlineThickness; /* key: UnderlineThickness */ + char *version; /* key: Version */ + char *notice; /* key: Notice */ + char *encodingScheme; /* key: EncodingScheme */ + int capHeight; /* key: CapHeight */ + int xHeight; /* key: XHeight */ + int ascender; /* key: Ascender */ + int descender; /* key: Descender */ +} GlobalFontInfo; + + +/* Ligature definition is a linked list since any character can have + * any number of ligatures. + */ +typedef struct _t_ligature +{ + char *succ, *lig; + struct _t_ligature *next; +} Ligature; + + +/* Character Metric Information. This structure is used only if ALL + * character metric information is requested. If only the character + * widths is requested, then only an array of the character x-widths + * is returned. + * + * The key that each field is associated with is in comments. For an + * explanation about each key and its value please refer to the + * Character Metrics section of the AFM documentation (full title + * & version given above). + */ +typedef struct +{ + int code, /* key: C */ + wx, /* key: WX */ + wy; /* together wx and wy are associated with key: W */ + char *name; /* key: N */ + BBox charBBox; /* key: B */ + Ligature *ligs; /* key: L (linked list; not a fixed number of Ls */ +} CharMetricInfo; + + +/* Track kerning data structure. + * The fields of this record are the five values associated with every + * TrackKern entry. + * + * For an explanation about each value please refer to the + * Track Kerning section of the AFM documentation (full title + * & version given above). + */ +typedef struct +{ + int degree; + float minPtSize, + minKernAmt, + maxPtSize, + maxKernAmt; +} TrackKernData; + + +/* Pair Kerning data structure. + * The fields of this record are the four values associated with every + * KP entry. For KPX entries, the yamt will be zero. + * + * For an explanation about each value please refer to the + * Pair Kerning section of the AFM documentation (full title + * & version given above). + */ +typedef struct +{ + char *name1; + char *name2; + int xamt, + yamt; +} PairKernData; + + +/* PCC is a piece of a composite character. This is a sub structure of a + * compCharData described below. + * These fields will be filled in with the values from the key PCC. + * + * For an explanation about each key and its value please refer to the + * Composite Character section of the AFM documentation (full title + * & version given above). + */ +typedef struct +{ + char *pccName; + int deltax, + deltay; +} Pcc; + + +/* Composite Character Information data structure. + * The fields ccName and numOfPieces are filled with the values associated + * with the key CC. The field pieces points to an array (size = numOfPieces) + * of information about each of the parts of the composite character. That + * array is filled in with the values from the key PCC. + * + * For an explanation about each key and its value please refer to the + * Composite Character section of the AFM documentation (full title + * & version given above). + + structure extended for use with t1lib. The fields "width" and bbox store + the composite characters escapement and its bounding box (2001-05-027, RMz) + */ +typedef struct +{ + int wx; /* these two will be filled by T1_LoadFont() */ + BBox charBBox; + char *ccName; + int numOfPieces; + Pcc *pieces; +} CompCharData; + + +/* FontInfo + * Record type containing pointers to all of the other data + * structures containing information about a font. + * A a record of this type is filled with data by the + * parseFile function. + */ +typedef struct +{ + GlobalFontInfo *gfi; /* ptr to a GlobalFontInfo record */ + int *cwi; /* ptr to 256 element array of just char widths */ + int numOfChars; /* number of entries in char metrics array */ + CharMetricInfo *cmi; /* ptr to char metrics array */ + int numOfTracks; /* number to entries in track kerning array */ + TrackKernData *tkd; /* ptr to track kerning array */ + int numOfPairs; /* number to entries in pair kerning array */ + PairKernData *pkd; /* ptr to pair kerning array */ + int numOfComps; /* number to entries in comp char array */ + CompCharData *ccd; /* ptr to comp char array */ +} FontInfo; + + + +/************************* PROCEDURES ****************************/ + +/* Call this procedure to do the grunt work of parsing an AFM file. + * + * "fp" should be a valid file pointer to an AFM file. + * + * "fi" is a pointer to a pointer to a FontInfo record sturcture + * (defined above). Storage for the FontInfo structure will be + * allocated in parseFile and the structure will be filled in + * with the requested data from the AFM File. + * + * "flags" is a mask with bits set representing what data should + * be saved. Defined above are valid flags that can be used to set + * the mask, as well as a few commonly used masks. + * + * The possible return codes from parseFile are defined above. + */ + +extern int T1lib_parseFile ( FILE *fp, FontInfo **fi, FLAGS flags ); diff --git a/Build/source/libs/t1lib/sysconf.h.in b/Build/source/libs/t1lib/sysconf.h.in new file mode 100644 index 00000000000..1809d651b9e --- /dev/null +++ b/Build/source/libs/t1lib/sysconf.h.in @@ -0,0 +1,40 @@ +/*-------------------------------------------------------------------------- + ----- File: sysconf.h.in + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-04-01 + ----- Description: This file is part of the t1-library. Some system + dependent definitions are stored here. sysconf.h + is generated from this file automatically by the + configure-script. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#undef __CHAR_UNSIGNED__ +#define SIZEOF_CHAR 0 +#define SIZEOF_SHORT 0 +#define SIZEOF_INT 0 +#define SIZEOF_LONG 0 +#define SIZEOF_LONG_LONG 0 +#define SIZEOF_FLOAT 0 +#define SIZEOF_DOUBLE 0 +#define SIZEOF_LONG_DOUBLE 0 +#define SIZEOF_VOID_P 0 diff --git a/Build/source/libs/t1lib/t1aaset.c b/Build/source/libs/t1lib/t1aaset.c new file mode 100644 index 00000000000..0244ca25c1d --- /dev/null +++ b/Build/source/libs/t1lib/t1aaset.c @@ -0,0 +1,1888 @@ +/*-------------------------------------------------------------------------- + ----- File: t1aaset.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + Subsampling based on code by Raph Levien (raph@acm.org) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + functions for antialiased setting of characters + and strings of characters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1AASET_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + +#include "t1types.h" +#include "t1extern.h" +#include "t1aaset.h" +#include "t1set.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1base.h" +#include "t1outline.h" + + +#define DEFAULTBPP 8 + + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + +/* In the following arrays take the gray values. Entry 0 is associated + with the white (background) value and the max entry is the + black (foreground) value. */ +static unsigned T1_AA_TYPE32 gv[5]={0,0,0,0,0}; +static unsigned T1_AA_TYPE32 gv_h[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +static unsigned T1_AA_TYPE32 gv_n[2]={0,0}; + +static int T1aa_level=T1_AA_LOW; /* The default value */ +static T1_AA_TYPE32 T1aa_lut[625]; +static int T1aa_count[256]; +static T1_AA_TYPE32 T1aa_h_lut[289]; +static int T1aa_h_count[256]; +static T1_AA_TYPE32 T1aa_n_lut[64]; + +/* This global is for querying the current bg from other parts + of t1lib */ +unsigned T1_AA_TYPE32 T1aa_bg=0; + +/* The limit values for smart antialiasing */ +float T1aa_smartlimit1=T1_AA_SMARTLIMIT1; +float T1aa_smartlimit2=T1_AA_SMARTLIMIT2; +int T1aa_SmartOn=0; /* We do not enable smart AA by default */ + +/* T1_AAInit: This function must be called whenever the T1aa_gray_val + or T1aa_bpp variables change, or the level changes. */ +static int T1_AAInit ( int level ) +{ + int i; + int i0, i1, i2, i3; + int movelow=0, movehigh=0, indlow=0, indhigh=0; + + /* Note: movelow, movehigh, indlow and indhigh take care for proper + byte swapping in dependence of endianess for level=4 */ + if (level==T1_AA_NONE){ + if (T1aa_bpp==8){ + if (pFontBase->endian){ + movelow=3; + movehigh=2; + } + else{ + movelow=0; + movehigh=1; + } + } + else if (T1aa_bpp==16){ + if (pFontBase->endian){ + movelow=1; + movehigh=0; + } + else{ + movelow=0; + movehigh=1; + } + } + } + + if (level==T1_AA_HIGH){ + + if (T1aa_bpp==8){ + if (pFontBase->endian){ + indlow=17; + indhigh=1; + movelow=3; + movehigh=2; + } + else{ + indlow=1; + indhigh=17; + movelow=0; + movehigh=1; + } + } + else if (T1aa_bpp==16){ + if (pFontBase->endian){ + indlow=17; + indhigh=1; + movelow=1; + movehigh=0; + } + else{ + indlow=1; + indhigh=17; + movelow=0; + movehigh=1; + } + } + else if (T1aa_bpp==32){ + indlow=1; + indhigh=17; + } + for (i = 0; i < 256; i++) { + T1aa_h_count[i] = 0; + if (i & 0x80) T1aa_h_count[i] += indhigh; + if (i & 0x40) T1aa_h_count[i] += indhigh; + if (i & 0x20) T1aa_h_count[i] += indhigh; + if (i & 0x10) T1aa_h_count[i] += indhigh; + if (i & 0x08) T1aa_h_count[i] += indlow; + if (i & 0x04) T1aa_h_count[i] += indlow; + if (i & 0x02) T1aa_h_count[i] += indlow; + if (i & 0x01) T1aa_h_count[i] += indlow; + } + } + + if (level == 2 && T1aa_bpp == 8) { + for (i0 = 0; i0 < 5; i0++) + for (i1 = 0; i1 < 5; i1++) + for (i2 = 0; i2 < 5; i2++) + for (i3 = 0; i3 < 5; i3++) { + ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4] = gv[i3]; + ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 1] = gv[i2]; + ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 2] = gv[i1]; + ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 3] = gv[i0]; + } + for (i = 0; i < 256; i++) { + T1aa_count[i] = 0; + if (i & 0x80) T1aa_count[i] += 125; + if (i & 0x40) T1aa_count[i] += 125; + if (i & 0x20) T1aa_count[i] += 25; + if (i & 0x10) T1aa_count[i] += 25; + if (i & 0x08) T1aa_count[i] += 5; + if (i & 0x04) T1aa_count[i] += 5; + if (i & 0x02) T1aa_count[i] += 1; + if (i & 0x01) T1aa_count[i] += 1; + } + return(0); + } else if (level == 2 && T1aa_bpp == 16) { + for (i0 = 0; i0 < 5; i0++) + for (i1 = 0; i1 < 5; i1++) { + ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2] = gv[i1]; + ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2 + 1] = gv[i0]; + } + for (i = 0; i < 256; i++) { + T1aa_count[i] = 0; + if (i & 0x80) T1aa_count[i] += 160; + if (i & 0x40) T1aa_count[i] += 160; + if (i & 0x20) T1aa_count[i] += 32; + if (i & 0x10) T1aa_count[i] += 32; + if (i & 0x08) T1aa_count[i] += 5; + if (i & 0x04) T1aa_count[i] += 5; + if (i & 0x02) T1aa_count[i] += 1; + if (i & 0x01) T1aa_count[i] += 1; + } + return(0); + } else if (level == 2 && T1aa_bpp == 32) { + for (i0 = 0; i0 < 5; i0++) + ((T1_AA_TYPE32 *)T1aa_lut)[i0] = gv[i0]; + for (i = 0; i < 256; i++) { + T1aa_count[i] = 0; + if (i & 0x80) T1aa_count[i] += 512; + if (i & 0x40) T1aa_count[i] += 512; + if (i & 0x20) T1aa_count[i] += 64; + if (i & 0x10) T1aa_count[i] += 64; + if (i & 0x08) T1aa_count[i] += 8; + if (i & 0x04) T1aa_count[i] += 8; + if (i & 0x02) T1aa_count[i] += 1; + if (i & 0x01) T1aa_count[i] += 1; + } + return(0); + } + else if (level == 4 && T1aa_bpp == 8) { + for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ + for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ + ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movelow] = gv_h[i1]; + ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movehigh] = gv_h[i0]; + } + } + return(0); + } + else if (level == 4 && T1aa_bpp == 16) { + for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ + for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ + ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movelow] = gv_h[i1]; + ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movehigh] = gv_h[i0]; + } + } + return(0); + } + else if (level == 4 && T1aa_bpp == 32) { + for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ + for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ + ((T1_AA_TYPE32 *)T1aa_h_lut)[(i0 * 17 + i1)] = gv_h[i1]; + } + } + return(0); + } + else if (level == 1 && T1aa_bpp == 8) { + for (i0=0; i0<16; i0++) { + ((char *)T1aa_n_lut)[i0*4+movelow]=gv_n[i0 & 0x01]; + ((char *)T1aa_n_lut)[i0*4+movelow+1]=gv_n[(i0>>1) & 0x01]; + ((char *)T1aa_n_lut)[i0*4+movelow+2]=gv_n[(i0>>2) & 0x01]; + ((char *)T1aa_n_lut)[i0*4+movelow+3]=gv_n[(i0>>3) & 0x01]; + } + return(0); + } + else if (level == 1 && T1aa_bpp == 16) { + for (i0=0; i0<4; i0++) { + ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2]=gv_n[i0 & 0x01]; + ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2+1]=gv_n[(i0>>1) & 0x01]; + } + return(0); + } + else if (level == 1 && T1aa_bpp == 32) { + for ( i0=0; i0<2; i0++) { + ((T1_AA_TYPE32 *)T1aa_n_lut)[i0]=gv_n[i0]; + } + return(0); + } + else { + /* unsupported combination of level and bpp -> we set T1_errno and + put an entry into the logfile! */ + T1_errno=T1ERR_INVALID_PARAMETER; + sprintf( err_warn_msg_buf, + "Unsupported AA specification: level=%d, bpp=%d", + level, T1aa_bpp); + T1_PrintLog( "T1_AAInit()", err_warn_msg_buf, T1LOG_WARNING); + } + return(1); +} + + +/* T1_AADoLine: Create a single scanline of antialiased output. The + (x, y) arguments refer to the number of pixels in the input image + to convert down. The width argument is the number of bytes + separating scanlines in the input. The quantity hcorr describes the + number of subpixels. It is the shift of the oversampled bitmap to + the right */ +static void T1_AADoLine ( int level, int x, int y, int width, + char *c_in_ptr, char *target_ptr, int hcorr ) +{ + int i=0; + int size; + int count=0; + int mod; + + unsigned char bcarry1=0, bcarry2=0, bcarry3=0, bcarry4=0; + + static char *align_buf = NULL; + static int align_buf_size = 0; + unsigned char *in_ptr; + + int new_size=55; + register char *optr; + + + + /* We convert the input pointer to unsigned since we use it as index! */ + in_ptr=(unsigned char*)c_in_ptr; + + + if ((long)target_ptr & 3){ + /* calculate new_size (size in bytes of output buffer */ + if (level == T1_AA_LOW){ + new_size=((x + hcorr + 1) >> 1) * (T1aa_bpp >> 3); + } + else{ /* T1_AA_HIGH */ + new_size = ((x + hcorr + 3) >> 2) * (T1aa_bpp >> 3); + } + if (new_size > align_buf_size) + { + if (align_buf) + free (align_buf); + /* Note: we allocate 12 more than necessary to have tolerance + at the end of line */ + align_buf = (char *)malloc(new_size+12); + align_buf_size = new_size; + } + optr = align_buf; + } + else + optr = target_ptr; + + + /* size: The number of valid byte in the input string, i.e., the number of bytes + partially filled with pixels before shifting with hcorr. + mod: Is 1 if after shifting with hcorr the last byte in the input line has an + overflow. + */ + + if (level == T1_AA_LOW) { + size=(x+7)>>3; + mod=(x+hcorr)>(size*8) ? 1 : 0; + + if (T1aa_bpp == 8) { + if (y == 2){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + } + } + else if (y == 1){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + } + } + if (mod) { + if (y == 2) + ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1] + + T1aa_count[bcarry2])]; + else if (y == 1) + ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1])]; + } + } + else if (T1aa_bpp == 16) { + if (y == 2){ + for (i = 0; i < size; i++) { + count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)]; + ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; + ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + } + } + else if (y == 1){ + for (i = 0; i < size; i++) { + count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]; + ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; + ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + } + } + if (mod){ + if (y == 2) + count = T1aa_count[bcarry1] + + T1aa_count[bcarry2]; + else if (y == 1) + count = T1aa_count[bcarry1]; + ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; + ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; + } + } + else if (T1aa_bpp == 32) { + if (y == 2){ + for (i = 0; i < size; i++) { + count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_count[(unsigned char)((in_ptr[i+width]<<hcorr)|bcarry2)]; + ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + } + } + else if (y == 1) { + for (i = 0; i < size; i++) { + count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]; + ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + } + } + if(mod) { + if (y == 2){ + count = T1aa_count[bcarry1] + + T1aa_count[bcarry2]; + } + else if (y == 1){ + count = T1aa_count[bcarry1]; + } + ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; + ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; + } + } + } + else if (level==T1_AA_HIGH){ + size=(x+7)>>3; + mod=(x+hcorr)>(size*8) ? 1 : 0; + + if (T1aa_bpp == 8) { + if (y == 4){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + bcarry3=in_ptr[i+2*width]>>(8-hcorr); + bcarry4=in_ptr[i+3*width]>>(8-hcorr); + } + } + else if (y == 3){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + bcarry3=in_ptr[i+2*width]>>(8-hcorr); + } + } + else if (y == 2){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + } + else if (y == 1){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + } + if (mod) { + if (y == 4) + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3] + + T1aa_h_count[bcarry4])]; + else if (y == 3) + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3])]; + else if (y == 2) + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2])]; + else if (y == 1) + ((T1_AA_TYPE16 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1])]; + } + } else if (T1aa_bpp == 16) { + if (y == 4){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + bcarry3=in_ptr[i+2*width]>>(8-hcorr); + bcarry4=in_ptr[i+3*width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + bcarry3=in_ptr[2*width]<<hcorr; + bcarry4=in_ptr[3*width]<<hcorr; + } + } + else if (y == 3){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+2*width]>>(8-hcorr); + bcarry3=in_ptr[i+3*width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + bcarry3=in_ptr[2*width]<<hcorr; + } + } + else if (y == 2){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + } + } + else if (y == 1){ + for (i = 0; i < size; i++) { + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + } + } + if (mod) { + if (y == 4) + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3] + + T1aa_h_count[bcarry4])]; + else if (y == 3) + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3])]; + else if (y == 2) + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2])]; + else if (y == 1) + ((T1_AA_TYPE32 *)optr)[i] = + T1aa_h_lut[(T1aa_h_count[bcarry1])]; + } + } + else if (T1aa_bpp == 32) { + if (y == 4){ + for (i = 0; i < size; i++) { + count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)]; + ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17]; + ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + bcarry3=in_ptr[i+2*width]>>(8-hcorr); + bcarry4=in_ptr[i+3*width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + bcarry3=in_ptr[2*width]<<hcorr; + bcarry4=in_ptr[3*width]<<hcorr; + } + } + else if (y == 3){ + for (i = 0; i < size; i++) { + count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)]; + ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17]; + ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + bcarry3=in_ptr[i+2*width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + bcarry3=in_ptr[2*width]<<hcorr; + } + } + else if (y == 2){ + for (i = 0; i < size; i++) { + count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)]; + ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17]; + ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17]; + bcarry1=in_ptr[i]>>(8-hcorr); + bcarry2=in_ptr[i+width]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + bcarry2=in_ptr[width]<<hcorr; + } + } + else if (y == 1){ + for (i = 0; i < size; i++) { + count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]; + ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17]; + ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17]; + bcarry1=in_ptr[i]>>(8-hcorr); + } + if (size==0){ + bcarry1=in_ptr[0]<<hcorr; + } + } + if (mod) { + if (y == 4){ + count=T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3] + + T1aa_h_count[bcarry4]; + } + else if (y == 3) + count=T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2] + + T1aa_h_count[bcarry3]; + else if (y == 2) + count=T1aa_h_count[bcarry1] + + T1aa_h_count[bcarry2]; + else if (y == 1) + count=T1aa_h_count[bcarry1]; + ((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17]; + ((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17]; + } + } + } + + /* Copy to target if necessary */ + if ((long)target_ptr & 3){ + memcpy (target_ptr, align_buf, new_size); + } + +} + + + +/* T1_DoLine(): Generate a scanline of bytes from a scanline of bits */ +static void T1_DoLine ( long wd, long paddedW, char *ptr, register char *target_ptr ) +{ + register int j; + register unsigned char *in_ptr; + T1_AA_TYPE16 *starget_ptr; + T1_AA_TYPE32 *ltarget_ptr; + + in_ptr=(unsigned char *)ptr; + + if (T1aa_bpp==8) { + for ( j=0; j<wd; j++ ){ + *target_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x0F]; + } + } + else if (T1aa_bpp==16) { + starget_ptr=(T1_AA_TYPE16 *)target_ptr; + for ( j=0; j<wd; j++){ + *starget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x03]; + } + } + else if (T1aa_bpp==32) { + ltarget_ptr=(T1_AA_TYPE32 *)target_ptr; + for ( j=0; j<wd; j++) + *ltarget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x01]; + } + return; +} + + + +/* T1_AASetChar(...): Generate the anti-aliased bitmap for a character */ +GLYPH *T1_AASetChar( int FontID, char charcode, float size, + T1_TMATRIX *transform) +{ + + GLYPH *glyph; /* pointer to bitmap glyph */ + static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */ + long asc, dsc, ht, wd; + long i; + long n_horz, n_horz_pad, n_vert, n_asc, n_dsc; + long v_start, v_end; + char *target_ptr; + long offset; + char *ptr; + int y; + long lsb, aalsb, aahstart; + int memsize; + LONG paddedW; + int savelevel; + FONTSIZEDEPS *font_ptr=NULL; + unsigned char ucharcode; + + + /* Reset character glyph, if necessary */ + if (aaglyph.bits!=NULL){ + free(aaglyph.bits); + aaglyph.bits=NULL; + } + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=0; + aaglyph.metrics.advanceY=0; + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + aaglyph.bpp=T1aa_bpp; + + + ucharcode=charcode; + + /* Check for smart antialiasing */ + savelevel=T1aa_level; + if (T1aa_SmartOn){ + if (size>=T1aa_smartlimit2) { + T1aa_level=T1_AA_NONE; + } + else if (size>=T1aa_smartlimit1) { + T1aa_level=T1_AA_LOW; + } + else { + T1aa_level=T1_AA_HIGH; + } + } + + + /* The following code is only exectued if caching of antialiased + chracters is enabled. */ + /* Check if char is in cache */ + if ((pFontBase->t1lib_flags & T1_AA_CACHING)) { + if (transform==NULL){ + /* if size/aa is not existent we create it */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, T1aa_level))==NULL){ + /* We create the required size struct and leave the rest + for T1_SetChar() */ + font_ptr=T1int_CreateNewFontSize( FontID, size, T1aa_level); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + T1aa_level=savelevel; + return(NULL); + } + } + else {/* size is already existent in cache */ + if (font_ptr->pFontCache[ucharcode].bits != NULL){ + /* Character is already in Chache -> create a copy of cache + and return a pointer to the result: */ + memcpy( &aaglyph, &(font_ptr->pFontCache[ucharcode]), sizeof(GLYPH)); + memsize = (aaglyph.metrics.ascent-aaglyph.metrics.descent) * + PAD((aaglyph.metrics.rightSideBearing-aaglyph.metrics.leftSideBearing) * + T1aa_bpp,pFontBase->bitmap_pad)/8; + aaglyph.bits = (char *)malloc(memsize*sizeof( char)); + if (aaglyph.bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + T1aa_level=savelevel; + return(NULL); + } + memcpy( aaglyph.bits, font_ptr->pFontCache[ucharcode].bits, memsize); + return(&(aaglyph)); + } + } + } /* (transform==NULL) */ + } /* T1_AA_CACHING */ + + + /* First, call routine to rasterize character, all error checking is + done in this function: */ + if ((glyph=T1_SetChar( FontID, charcode, T1aa_level*size, transform))==NULL){ + /* restore level */ + T1aa_level=savelevel; + return(NULL); /* An error occured */ + } + + /* In case there are no black pixels, we simply set the dimensions and + then return */ + if ( glyph->bits == NULL) { + aaglyph.bits=NULL; + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + /* restore level and return */ + T1aa_level=savelevel; + return(&aaglyph); + } + + /* Get dimensions of bitmap: */ + asc=glyph->metrics.ascent; + dsc=glyph->metrics.descent; + lsb=glyph->metrics.leftSideBearing; + ht=asc-dsc; + wd=glyph->metrics.rightSideBearing-lsb; + + + + if (T1aa_level==T1_AA_NONE){ + /* we only convert bitmap to bytemap */ + aaglyph=*glyph; + aaglyph.bpp=T1aa_bpp; + /* Compute scanline length and such */ + n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3; + /* Allocate memory for glyph */ + memsize = n_horz_pad*ht*8; + /* aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */ + aaglyph.bits = (char *)malloc(memsize*sizeof( char)); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* restore level */ + T1aa_level=savelevel; + return(NULL); + } + paddedW=PAD(wd,pFontBase->bitmap_pad)>>3; + ptr=glyph->bits; + target_ptr=aaglyph.bits; + for (i = 0; i < ht; i++) { + T1_DoLine ( wd, paddedW, ptr, target_ptr ); + ptr += paddedW; + target_ptr += n_horz_pad; + } + /* restore level */ + T1aa_level=savelevel; + return(&aaglyph); + } + + + /* Set some looping parameters for subsampling */ + if (lsb<0){ + aalsb=lsb/T1aa_level-1; + aahstart=T1aa_level+(lsb%T1aa_level); + } + else{ + aalsb=lsb/T1aa_level; + aahstart=lsb%T1aa_level; + } + + /* The horizontal number of steps: */ + n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level; + /* And the padded value */ + n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3; + + /* vertical number of steps: */ + if (asc % T1aa_level){ /* not aligned */ + if ( asc > 0){ + n_asc=asc/T1aa_level+1; + v_start=asc % T1aa_level; + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level + (asc % T1aa_level); + } + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level; + } + if (dsc % T1aa_level){ /* not aligned */ + if ( dsc < 0){ + n_dsc=dsc/T1aa_level-1; + v_end=-(dsc % T1aa_level); + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level - (dsc % T1aa_level); + } + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level; + } + /* the total number of lines: */ + n_vert=n_asc-n_dsc; + + /* Allocate memory for glyph */ + memsize = n_horz_pad*n_vert; + + /* Note: we allocate 12 bytes more than necessary */ + aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* restore level */ + T1aa_level=savelevel; + return(NULL); + } + + + paddedW=PAD(wd,pFontBase->bitmap_pad)/8; + offset=0; + target_ptr=aaglyph.bits; + + /* We must check for n_vert==1 because the computation above is not + valid in this case */ + if (n_vert==1) + v_start=v_start < v_end ? v_start : v_end; + + ptr = glyph->bits; + for (i = 0; i < n_vert; i++) { + if (i==0) + y=v_start; + else if (i==n_vert-1) + y=v_end; + else + y=T1aa_level; + T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart ); + ptr += y * paddedW; + target_ptr += n_horz_pad; + } + + /* .. and set them in aaglyph */ + aaglyph.metrics.leftSideBearing=aalsb; + aaglyph.metrics.rightSideBearing=aalsb + n_horz; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=n_asc; + aaglyph.metrics.descent=n_dsc; + aaglyph.pFontCacheInfo=NULL; + + + if ((pFontBase->t1lib_flags & T1_AA_CACHING) && (transform==NULL)) { + /* Put char into cache area */ + memcpy( &(font_ptr->pFontCache[ucharcode]), &aaglyph, sizeof(GLYPH)); + font_ptr->pFontCache[ucharcode].bits = (char *)malloc(memsize*sizeof( char)); + if (font_ptr->pFontCache[ucharcode].bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + T1aa_level=savelevel; + return(NULL); + } + memcpy( font_ptr->pFontCache[ucharcode].bits, aaglyph.bits, memsize); + } + + /* restore level */ + T1aa_level=savelevel; + + return(&aaglyph); +} + + + +/* T1_AASetString(...): Generate the antialiased bitmap for a + string of characters */ +GLYPH *T1_AASetString( int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + GLYPH *glyph; /* pointer to bitmap glyph */ + static GLYPH aastring_glyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */ + long asc, dsc, ht, wd; + long i; + long n_horz, n_horz_pad, n_vert, n_asc, n_dsc; + long v_start, v_end; + char *target_ptr; + long offset; + char *ptr; + int y; + long lsb, aalsb, aahstart; + int memsize; + LONG paddedW; + int savelevel; + + + /* Reset character glyph, if necessary */ + if (aastring_glyph.bits!=NULL){ + free(aastring_glyph.bits); + aastring_glyph.bits=NULL; + } + aastring_glyph.metrics.leftSideBearing=0; + aastring_glyph.metrics.rightSideBearing=0; + aastring_glyph.metrics.advanceX=0; + aastring_glyph.metrics.advanceY=0; + aastring_glyph.metrics.ascent=0; + aastring_glyph.metrics.descent=0; + aastring_glyph.pFontCacheInfo=NULL; + aastring_glyph.bpp=T1aa_bpp; + + + /* Check for smart antialiasing */ + savelevel=T1aa_level; + if (T1aa_SmartOn){ + if (size>=T1aa_smartlimit2) { + T1aa_level=T1_AA_NONE; + } + else if (size>=T1aa_smartlimit1) { + T1aa_level=T1_AA_LOW; + } + else { + T1aa_level=T1_AA_HIGH; + } + } + + /* First, call routine to rasterize character, all error checking is + done in this function: */ + if ((glyph=T1_SetString( FontID, string, len, spaceoff, + modflag, T1aa_level*size, transform))==NULL){ + /* restore level */ + T1aa_level=savelevel; + return(NULL); /* An error occured */ + } + + /* In case there are no black pixels, we simply set the dimensions and + then return */ + if ( glyph->bits == NULL) { + aastring_glyph.bits=NULL; + aastring_glyph.metrics.leftSideBearing=0; + aastring_glyph.metrics.rightSideBearing=0; + aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aastring_glyph.metrics.ascent=0; + aastring_glyph.metrics.descent=0; + aastring_glyph.pFontCacheInfo=NULL; + /* restore level and return */ + T1aa_level=savelevel; + return(&aastring_glyph); + } + + + /* Get dimensions of bitmap: */ + asc=glyph->metrics.ascent; + dsc=glyph->metrics.descent; + lsb=glyph->metrics.leftSideBearing; + ht=asc-dsc; + wd=glyph->metrics.rightSideBearing-lsb; + + if (T1aa_level==T1_AA_NONE){ + /* we only convert bitmap to bytemap */ + aastring_glyph=*glyph; + aastring_glyph.bpp=T1aa_bpp; + /* Compute scanline length and such */ + n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3; + /* Allocate memory for glyph */ + memsize = n_horz_pad*ht*8; + aastring_glyph.bits = (char *)malloc(memsize*sizeof( char)); + if (aastring_glyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* restore level */ + T1aa_level=savelevel; + return(NULL); + } + paddedW=PAD(wd,pFontBase->bitmap_pad)>>3; + ptr=glyph->bits; + target_ptr=aastring_glyph.bits; + for (i = 0; i < ht; i++) { + T1_DoLine ( wd, paddedW, ptr, target_ptr ); + ptr += paddedW; + target_ptr += n_horz_pad; + } + /* restore level */ + T1aa_level=savelevel; + return(&aastring_glyph); + } + + + /* Set some looping parameters for subsampling */ + if (lsb<0){ + aalsb=lsb/T1aa_level-1; + aahstart=T1aa_level+(lsb%T1aa_level); + } + else{ + aalsb=lsb/T1aa_level; + aahstart=lsb%T1aa_level; + } + + /* The horizontal number of steps: */ + n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level; + /* And the padded value */ + n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3; + + /* vertical number of steps: */ + if (asc % T1aa_level){ /* not aligned */ + if ( asc > 0){ + n_asc=asc/T1aa_level+1; + v_start=asc % T1aa_level; + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level + (asc % T1aa_level); + } + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level; + } + if (dsc % T1aa_level){ /* not aligned */ + if ( dsc < 0){ + n_dsc=dsc/T1aa_level-1; + v_end=-(dsc % T1aa_level); + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level - (dsc % T1aa_level); + } + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level; + } + /* the total number of lines: */ + n_vert=n_asc-n_dsc; + + /* Allocate memory for glyph */ + memsize = n_horz_pad*n_vert; + + /* Note: we allocate 12 bytes more than necessary */ + aastring_glyph.bits = (char *)malloc(memsize*sizeof( char) +12); + if (aastring_glyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + paddedW=PAD(wd,pFontBase->bitmap_pad)/8; + offset=0; + target_ptr=aastring_glyph.bits; + + /* We must check for n_vert==1 because the computation above is not + valid in this case */ + if (n_vert==1) + v_start=v_start < v_end ? v_start : v_end; + + ptr = glyph->bits; + for (i = 0; i < n_vert; i++) { + if (i==0) + y=v_start; + else if (i==n_vert-1) + y=v_end; + else + y=T1aa_level; + T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart ); + ptr += y * paddedW; + target_ptr += n_horz_pad; + } + + /* .. and set them in aastring_glyph */ + aastring_glyph.metrics.leftSideBearing=aalsb; + aastring_glyph.metrics.rightSideBearing=aalsb + n_horz; + aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aastring_glyph.metrics.ascent=n_asc; + aastring_glyph.metrics.descent=n_dsc; + aastring_glyph.pFontCacheInfo=NULL; + + /* restore level */ + T1aa_level=savelevel; + + return(&aastring_glyph); +} + + + +/* T1_AASetRect(): Raster a rectangle, whose size is given in charspace units. + The resulting glyph does not cause any escapement. */ +GLYPH* T1_AASetRect( int FontID, float size, + float width, float height, T1_TMATRIX *transform) +{ + GLYPH *glyph; /* pointer to bitmap glyph */ + static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */ + long asc, dsc, ht, wd; + long i; + long n_horz, n_horz_pad, n_vert, n_asc, n_dsc; + long v_start, v_end; + char *target_ptr; + long offset; + char *ptr; + int y; + long lsb, aalsb, aahstart; + int memsize; + LONG paddedW; + int savelevel; + + + /* Reset character glyph, if necessary */ + if (aaglyph.bits!=NULL){ + free(aaglyph.bits); + aaglyph.bits=NULL; + } + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=0; + aaglyph.metrics.advanceY=0; + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + aaglyph.bpp=T1aa_bpp; + + + /* Check for smart antialiasing */ + savelevel=T1aa_level; + if (T1aa_SmartOn){ + if (size>=T1aa_smartlimit2) { + T1aa_level=T1_AA_NONE; + } + else if (size>=T1aa_smartlimit1) { + T1aa_level=T1_AA_LOW; + } + else { + T1aa_level=T1_AA_HIGH; + } + } + + + /* First, call routine to rasterize character, all error checking is + done in this function: */ + if ((glyph=T1_SetRect( FontID, T1aa_level*size, width, height, transform))==NULL){ + /* restore level */ + T1aa_level=savelevel; + return(NULL); /* An error occured */ + } + + /* In case there are no black pixels, we simply set the dimensions and + then return */ + if ( glyph->bits == NULL) { + aaglyph.bits=NULL; + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + /* restore level and return */ + T1aa_level=savelevel; + return(&aaglyph); + } + + /* Get dimensions of bitmap: */ + asc=glyph->metrics.ascent; + dsc=glyph->metrics.descent; + lsb=glyph->metrics.leftSideBearing; + ht=asc-dsc; + wd=glyph->metrics.rightSideBearing-lsb; + + if (T1aa_level==T1_AA_NONE){ + /* we only convert bitmap to bytemap */ + aaglyph=*glyph; + aaglyph.bpp=T1aa_bpp; + /* Compute scanline length and such */ + n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3; + /* Allocate memory for glyph */ + memsize = n_horz_pad*ht*8; + /* aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */ + aaglyph.bits = (char *)malloc(memsize*sizeof( char)); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* restore level */ + T1aa_level=savelevel; + return(NULL); + } + paddedW=PAD(wd,pFontBase->bitmap_pad)>>3; + ptr=glyph->bits; + target_ptr=aaglyph.bits; + for (i = 0; i < ht; i++) { + T1_DoLine ( wd, paddedW, ptr, target_ptr ); + ptr += paddedW; + target_ptr += n_horz_pad; + } + /* restore level */ + T1aa_level=savelevel; + return(&aaglyph); + } + + + /* Set some looping parameters for subsampling */ + if (lsb<0){ + aalsb=lsb/T1aa_level-1; + aahstart=T1aa_level+(lsb%T1aa_level); + } + else{ + aalsb=lsb/T1aa_level; + aahstart=lsb%T1aa_level; + } + + /* The horizontal number of steps: */ + n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level; + /* And the padded value */ + n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3; + + /* vertical number of steps: */ + if (asc % T1aa_level){ /* not aligned */ + if ( asc > 0){ + n_asc=asc/T1aa_level+1; + v_start=asc % T1aa_level; + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level + (asc % T1aa_level); + } + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level; + } + if (dsc % T1aa_level){ /* not aligned */ + if ( dsc < 0){ + n_dsc=dsc/T1aa_level-1; + v_end=-(dsc % T1aa_level); + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level - (dsc % T1aa_level); + } + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level; + } + /* the total number of lines: */ + n_vert=n_asc-n_dsc; + + /* Allocate memory for glyph */ + memsize = n_horz_pad*n_vert; + + /* Note: we allocate 12 bytes more than necessary */ + aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* restore level */ + T1aa_level=savelevel; + return(NULL); + } + + + paddedW=PAD(wd,pFontBase->bitmap_pad)/8; + offset=0; + target_ptr=aaglyph.bits; + + /* We must check for n_vert==1 because the computation above is not + valid in this case */ + if (n_vert==1) + v_start=v_start < v_end ? v_start : v_end; + + ptr = glyph->bits; + for (i = 0; i < n_vert; i++) { + if (i==0) + y=v_start; + else if (i==n_vert-1) + y=v_end; + else + y=T1aa_level; + T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart ); + ptr += y * paddedW; + target_ptr += n_horz_pad; + } + + /* .. and set them in aaglyph */ + aaglyph.metrics.leftSideBearing=aalsb; + aaglyph.metrics.rightSideBearing=aalsb + n_horz; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=n_asc; + aaglyph.metrics.descent=n_dsc; + aaglyph.pFontCacheInfo=NULL; + + /* restore level */ + T1aa_level=savelevel; + + return(&aaglyph); + +} + + + +/* T1_AASetGrayValues(): Sets the byte values that are put into the + pixel position for the respective entries: + Returns 0 if successfull. + */ +int T1_AASetGrayValues(unsigned long white, + unsigned long gray75, + unsigned long gray50, + unsigned long gray25, + unsigned long black) +{ + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + gv[4]=(unsigned T1_AA_TYPE32)black; /* black value */ + gv[3]=(unsigned T1_AA_TYPE32)gray25; /* gray 25% value */ + gv[2]=(unsigned T1_AA_TYPE32)gray50; /* gray 50% value */ + gv[1]=(unsigned T1_AA_TYPE32)gray75; /* gray 75% value */ + gv[0]=(unsigned T1_AA_TYPE32)white; /* white value */ + + T1aa_bg=white; + + if ((T1_AAInit( T1_AA_LOW))) + return(-1); + return(0); + +} + + + +/* T1_AAHSetGrayValues(): Sets the byte values that are put into the + pixel position for the respective entries (for 17 gray levels): + Returns 0 if successfull. + */ +int T1_AAHSetGrayValues( unsigned long *grayvals) +{ + int i; + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + /* 0==white(background) ... 16==black(foreground) */ + for (i=0; i<17; i++){ + gv_h[i]=(unsigned T1_AA_TYPE32)grayvals[i]; + } + + + T1aa_bg=grayvals[0]; + + if ((T1_AAInit( T1_AA_HIGH))) + return(-1); + return(0); + +} + + + +/* T1_AANSetGrayValues(): Sets the byte values that are put into the + pixel position for the respective entries (for 2 gray levels): + Returns 0 if successfull. This is for the case the non-antialiased + "bytemaps" should be generated. + */ +int T1_AANSetGrayValues( unsigned long bg, unsigned long fg) +{ + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + gv_n[0]=bg; + gv_n[1]=fg; + + T1aa_bg=bg; + + if ((T1_AAInit( T1_AA_NONE))) + return(-1); + return(0); + +} + + + +/* Get the current setting of graylevels for 2x antialiasing. The 5 + values are stored at address pgrayvals in order from background to + foreground */ +int T1_AAGetGrayValues( long *pgrayvals) +{ + int i; + + if (T1_CheckForInit()) { + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + if (pgrayvals==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + + for ( i=0; i<5; i++) { /* bg (i=0) to fg (i=4) */ + pgrayvals[i]=gv[i]; + } + return( 0); + +} + + + +/* Get the current setting of graylevels for 2x antialiasing. The 17 + values are stored at address pgrayvals in order from background to + foreground */ +int T1_AAHGetGrayValues( long *pgrayvals) +{ + int i; + + if (T1_CheckForInit()) { + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + if (pgrayvals==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + + for ( i=0; i<17; i++) { /* bg (i=0) to fg (i=16) */ + pgrayvals[i]=gv[i]; + } + return( 0); +} + + + +/* Get the current setting of graylevels for 2x antialiasing. The 2 + values are stored at address pgrayvals in order from background to + foreground */ +int T1_AANGetGrayValues( long *pgrayvals) +{ + + if (T1_CheckForInit()) { + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + if (pgrayvals==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + pgrayvals[0]=gv[0]; /* background */ + pgrayvals[1]=gv[1]; /* foreground */ + return( 0); +} + + +/* T1_AASetBitsPerPixel(): Sets the depths of the antialiased glyph + pixel. Returns 0 if bpp is valid and -1 otherwise. If 24 is + specified, meaning to be the depth rather than the bpp-value, + automatically 32 bpp is chosen. */ +int T1_AASetBitsPerPixel( int bpp) +{ + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + + /* T1aa_level = 0; */ + + if (bpp==8){ + T1aa_bpp=8; + return(0); + } + if (bpp==16){ + T1aa_bpp=16; + return(0); + } + if ((bpp==32)|(bpp==24)){ + T1aa_bpp=32; + return(0); + } + + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); +} + + +/* T1_AAGetBitsPerPixel(): Return the number of bits per pixel set in + t1lib. +*/ +int T1_AAGetBitsPerPixel( void) +{ + return( T1aa_bpp); + +} + + +/* Set the Subsampling level for subsequent operations: */ +int T1_AASetLevel( int level) +{ + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + if (level==T1_AA_LOW){ + T1aa_level=T1_AA_LOW; + return(0); + } + else if (level==T1_AA_HIGH){ + T1aa_level=T1_AA_HIGH; + return(0); + } + else if (level==T1_AA_NONE){ + T1aa_level=T1_AA_NONE; + return(0); + } + + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + +} + + +/* Get the current subsampling level */ +int T1_AAGetLevel( void) +{ + return( T1aa_level); +} + + +/* T1_AAFillOutline(): Create a filled glyph from an outline description */ +GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag) +{ + + GLYPH *glyph; /* pointer to bitmap glyph */ + static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */ + long asc, dsc, ht, wd; + long i; + long n_horz, n_horz_pad, n_vert, n_asc, n_dsc; + long v_start, v_end; + char *target_ptr; + long offset; + char *ptr; + int y; + long lsb, aalsb, aahstart; + int memsize; + LONG paddedW; + + + /* Reset character glyph, if necessary */ + if (aaglyph.bits!=NULL){ + free(aaglyph.bits); + aaglyph.bits=NULL; + } + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=0; + aaglyph.metrics.advanceY=0; + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + aaglyph.bpp=T1aa_bpp; + + + /* First, scale outline appropriately: */ + path=T1_ScaleOutline( path, T1aa_level); + + /* Second, call routine to fill outline, all error checking is + done in this function: */ + if ((glyph=T1_FillOutline( path, modflag))==NULL) + return(NULL); /* An error occured */ + + /* In case there are no black pixels, we simply set the dimensions and + then return */ + if ( glyph->bits == NULL) { + aaglyph.bits=NULL; + aaglyph.metrics.leftSideBearing=0; + aaglyph.metrics.rightSideBearing=0; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=0; + aaglyph.metrics.descent=0; + aaglyph.pFontCacheInfo=NULL; + return(&aaglyph); + } + + /* Get dimensions of bitmap: */ + asc=glyph->metrics.ascent; + dsc=glyph->metrics.descent; + lsb=glyph->metrics.leftSideBearing; + ht=asc-dsc; + wd=glyph->metrics.rightSideBearing-lsb; + + + if (T1aa_level==T1_AA_NONE){ + /* we only convert bitmap to bytemap */ + aaglyph=*glyph; + aaglyph.bpp=T1aa_bpp; + /* Compute scanline length and such */ + n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3; + /* Allocate memory for glyph, we alloc 12 bytes more to simplify + subsampling! */ + memsize = n_horz_pad*ht*8; + aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + paddedW=PAD(wd,pFontBase->bitmap_pad)>>3; + ptr=glyph->bits; + target_ptr=aaglyph.bits; + for (i = 0; i < ht; i++) { + T1_DoLine ( wd, paddedW, ptr, target_ptr ); + ptr += paddedW; + target_ptr += n_horz_pad; + } + return(&aaglyph); + } + + + /* Set some looping parameters for subsampling */ + if (lsb<0){ + aalsb=lsb/T1aa_level-1; + aahstart=T1aa_level+(lsb%T1aa_level); + } + else{ + aalsb=lsb/T1aa_level; + aahstart=lsb%T1aa_level; + } + + /* The horizontal number of steps: */ + n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level; + /* And the padded value */ + n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3; + + /* vertical number of steps: */ + if (asc % T1aa_level){ /* not aligned */ + if ( asc > 0){ + n_asc=asc/T1aa_level+1; + v_start=asc % T1aa_level; + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level + (asc % T1aa_level); + } + } + else{ + n_asc=asc/T1aa_level; + v_start=T1aa_level; + } + if (dsc % T1aa_level){ /* not aligned */ + if ( dsc < 0){ + n_dsc=dsc/T1aa_level-1; + v_end=-(dsc % T1aa_level); + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level - (dsc % T1aa_level); + } + } + else{ + n_dsc=dsc/T1aa_level; + v_end=T1aa_level; + } + /* the total number of lines: */ + n_vert=n_asc-n_dsc; + + /* Allocate memory for glyph */ + memsize = n_horz_pad*n_vert; + + aaglyph.bits = (char *)malloc(memsize*sizeof( char)+12); + if (aaglyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + paddedW=PAD(wd,pFontBase->bitmap_pad)/8; + offset=0; + target_ptr=aaglyph.bits; + + /* We must check for n_vert==1 because the computation above is not + valid in this case */ + if (n_vert==1) + v_start=v_start < v_end ? v_start : v_end; + + ptr = glyph->bits; + for (i = 0; i < n_vert; i++) { + if (i==0) + y=v_start; + else if (i==n_vert-1) + y=v_end; + else + y=T1aa_level; + T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart ); + ptr += y * paddedW; + target_ptr += n_horz_pad; + } + + /* .. and set them in aaglyph */ + aaglyph.metrics.leftSideBearing=aalsb; + aaglyph.metrics.rightSideBearing=aalsb + n_horz; + aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5); + aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5); + aaglyph.metrics.ascent=n_asc; + aaglyph.metrics.descent=n_dsc; + aaglyph.pFontCacheInfo=NULL; + + return(&aaglyph); +} + + + +/* T1_AASetSmartLimits(): Set the limit-values for smart + antialiasing. Returns 0 if OK, and -1 else. */ +int T1_AASetSmartLimits( float limit1, float limit2) +{ + + if (limit1 > 0.0 && limit2 > 0.0 && limit2 >= limit2) { + T1aa_smartlimit1=limit1; + T1aa_smartlimit2=limit2; + return( 0); + } + else{ + T1_errno=T1ERR_INVALID_PARAMETER; + return( -1); + } +} + + + +/* T1_AASetSmartMode(): Enable or disable smart anialiasing */ +int T1_AASetSmartMode( int smart) +{ + + if (smart==T1_YES) { + T1aa_SmartOn=1; + } + else if (smart==T1_NO) { + T1aa_SmartOn=0; + } + else { + T1_errno=T1ERR_INVALID_PARAMETER; + return( -1); + } + return( 0); +} + + diff --git a/Build/source/libs/t1lib/t1aaset.h b/Build/source/libs/t1lib/t1aaset.h new file mode 100644 index 00000000000..1415ee5ce28 --- /dev/null +++ b/Build/source/libs/t1lib/t1aaset.h @@ -0,0 +1,85 @@ +/*-------------------------------------------------------------------------- + ----- File: t1aaset.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations for t1set.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1AASET_C + +GLYPH *T1_AASetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_AASetString( int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +GLYPH* T1_AASetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +int T1_AASetGrayValues( unsigned long white, + unsigned long gray75, + unsigned long gray50, + unsigned long gray25, + unsigned long black); +int T1_AAHSetGrayValues( unsigned long *grayvals); +int T1_AANSetGrayValues( unsigned long fg, unsigned long bg); +int T1_AAGetGrayValues( long *pgrayvals); +int T1_AAHGetGrayValues( long *pgrayvals); +int T1_AANGetGrayValues( long *pgrayvals); +int T1_AASetBitsPerPixel( int bpp); +int T1_AAGetBitsPerPixel( void); +int T1_AASetLevel( int level); +int T1_AAGetLevel( void); +GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag); +int T1_AASetSmartLimits( float limit1, float limit2); +int T1_AASetSmartMode( int smart); + +#else + +extern GLYPH *T1_AASetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetString( int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH* T1_AASetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern int T1_AASetGrayValues( unsigned long white, + unsigned long gray75, + unsigned long gray50, + unsigned long gray25, + unsigned long black); +extern int T1_AAHSetGrayValues( unsigned long *grayvals); +extern int T1_AANSetGrayValues( unsigned long bg, unsigned long fg); +extern int T1_AAGetGrayValues( long *pgrayvals); +extern int T1_AAHGetGrayValues( long *pgrayvals); +extern int T1_AANGetGrayValues( long *pgrayvals); +extern int T1_AASetBitsPerPixel( int bpp); +extern int T1_AAGetBitsPerPixel( void); +extern int T1_AASetLevel( int level); +extern int T1_AAGetLevel( void); +extern GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag); +extern int T1_AASetSmartLimits( float limit1, float limit2); +extern int T1_AASetSmartMode( int smart); + +#endif + diff --git a/Build/source/libs/t1lib/t1afmtool.c b/Build/source/libs/t1lib/t1afmtool.c new file mode 100644 index 00000000000..4e2cf1365b6 --- /dev/null +++ b/Build/source/libs/t1lib/t1afmtool.c @@ -0,0 +1,548 @@ +/*-------------------------------------------------------------------------- + ----- File: t1afmtool.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-08-17 + ----- Description: This file is part of the t1-library. It contains + functions for generating a fallback set of afm data + from type 1 font files. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1AFMTOOL_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" +#include "../type1/blues.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1finfo.h" +#include "t1base.h" +#include "t1misc.h" +#include "t1set.h" +#include "t1load.h" +#include "t1afmtool.h" + + +#define DELTA_MAX 30 +#define ENCODINGSIZE (int) 256 +#ifndef T1LIB_IDENT +#define T1LIB_IDENT "???.???" +#endif + + +extern char *t1_get_abort_message( int number); + + +/* T1_GenerateAFMFallbackInfo(): Generate fallback information from + Type 1 font file by rasterizing every character at 1000 bp. Returns + a pointer to a generated FontInfo struct or NULL in case of an error. + */ +FontInfo *T1_GenerateAFMFallbackInfo( int FontID) +{ + int i, j; + struct region *area; + struct XYspace *S; + int mode=0; + char **charnames; + int nochars=0; + FontInfo *pAFMData; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + sprintf( err_warn_msg_buf, + "Can't generate AFM Info from Font %d (invalid ID)\n", FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* Setup apropriate charspace matrix */ + S=(struct XYspace *)IDENTITY; + /* Make this permanent so that scaling it in fontfcnB_ByName will + make a duplicate of it, and this duplicate can thus be safely + destroyed. Fixes the somewhat smaller memory leak */ + S=(struct XYspace *)Permanent + (Transform(S, pFontBase->pFontArray[FontID].FontTransform[0], + pFontBase->pFontArray[FontID].FontTransform[1], + pFontBase->pFontArray[FontID].FontTransform[2], + pFontBase->pFontArray[FontID].FontTransform[3])); + + /* Alloc memory for FontInfo: */ + if ((pAFMData=(FontInfo *)malloc( sizeof(FontInfo)))==NULL){ + sprintf( err_warn_msg_buf, + "Failed to allocate memory for FontInfo in Font %d!", FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return( NULL); + } + /* Initialize pointers */ + pAFMData->gfi=NULL; + pAFMData->cwi=NULL; + pAFMData->numOfChars=0; + pAFMData->cmi=NULL; + pAFMData->numOfTracks=0; + pAFMData->tkd=NULL; + pAFMData->numOfPairs=0; + pAFMData->pkd=NULL; + pAFMData->numOfComps=0; + pAFMData->ccd=NULL; + + /* Get list of character name */ + charnames=T1_GetAllCharNames( FontID); + /* and count number of characters */ + nochars=0; + + while (charnames[nochars]!=NULL) + nochars++; + pAFMData->numOfChars=nochars; + /* Allocate memory for CharMetricInfo area */ + if ((pAFMData->cmi=(CharMetricInfo *) + malloc( nochars * sizeof( CharMetricInfo)))==NULL){ + sprintf( err_warn_msg_buf, + "Failed to allocate memory for CharMetricsInfo area in Font %d!", + FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_WARNING); + free( pAFMData); + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return( NULL); + } + /* Get metrics values */ + for (i=0; i<nochars; i++){ + area=fontfcnB_ByName( FontID, 0, S, charnames[i], &mode, + pFontBase->pFontArray[FontID].pType1Data, DO_RASTER); + + if (area==NULL){ + sprintf( err_warn_msg_buf, + "Could not get charspace representation of character %d (%s) Font %d!", + i, charnames[i], FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_WARNING); + /* Return since we don't know how to fill the values */ + for (j=i-1; j>=0; j--) + free( pAFMData->cmi[j].name); + if (pAFMData->cmi!=NULL) + free( pAFMData->cmi); + if (pAFMData!=NULL) + free( pAFMData); + T1_errno=mode; + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return( NULL); + } + else if ((pAFMData->cmi[i].name=(char *) + malloc( (size_t)(strlen( charnames[i])+1)))==NULL){ + sprintf( err_warn_msg_buf, + "Failed to allocate memory for CharName %d (%s) Font %d!", + i, charnames[i], FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_WARNING); + /* NULL-ptr in charnames is prone to SIGSEGV-errors, thus, + we have to return: */ + for (j=i; j>=0; j--) + free( pAFMData->cmi[j].name); + free( pAFMData->cmi); + free( pAFMData); + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return( NULL); + } + else{ + strcpy( pAFMData->cmi[i].name, charnames[i]); + pAFMData->cmi[i].code=T1_GetEncodingIndex( FontID, charnames[i]); + pAFMData->cmi[i].wx=NEARESTPEL(area->ending.x); + pAFMData->cmi[i].wy=NEARESTPEL(area->ending.y); + /* We check for a valid BBox and set it to zero otherwise */ + if ((int)area->xmax > (int)area->xmin){ + pAFMData->cmi[i].charBBox.llx =(int)area->xmin; + pAFMData->cmi[i].charBBox.urx =(int)area->xmax; + pAFMData->cmi[i].charBBox.lly =(int)area->ymin; + pAFMData->cmi[i].charBBox.ury =(int)area->ymax; + } + else{ + pAFMData->cmi[i].charBBox.llx =0; + pAFMData->cmi[i].charBBox.urx =0; + pAFMData->cmi[i].charBBox.lly =0; + pAFMData->cmi[i].charBBox.ury =0; + } + pAFMData->cmi[i].ligs=NULL; + /* We are done with area, so get rid of it. Solves the REALLY + HUGE memory leak */ + KillRegion (area); + } + } + sprintf( err_warn_msg_buf, + "Generated metric information for %d characters of font %d!", + nochars, FontID); + T1_PrintLog( "T1_GenerateAFMFallbackInfo()", err_warn_msg_buf, + T1LOG_STATISTIC); + + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return( pAFMData); +} + + +/* T1_WriteAFMFallbackFile(): Write a fallback AFM-file from AFM data + genarated for font FontID. returns + 0 if successful + -1 if afm-data was loaded from existent AFM-file + -2 if font is not loaded (invalid FontID) + -3 if for some reason the fonts' AFM-data has not been generated + -4 if the file could not be openend + -5 if an error occurred during write + -6 other error. + */ +int T1_WriteAFMFallbackFile( int FontID) +{ + + int i, j, k, l; + + int nochars; + int capheight, ascender, xheight, descender; + int min=0, delta; + time_t s_clock, *tp; + + char *afmfilename; + FILE *afmfile; + CharMetricInfo **cmi; + + + /* Check for valid font */ + if (T1_CheckForFontID(FontID)!=1){ + sprintf( err_warn_msg_buf, + "Warning: Invalid FontID, font %d not loaded!", + FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_INVALID_FONTID; + return(-2); + } + + /* Check for AFM-data to be existent */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL){ + sprintf( err_warn_msg_buf, + "Warning: No AFM-Data available for font %d", + FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_WARNING); + return(-3); + } + + /* Check if AFM data has been generated from existent afm file --> + no need to generate a new one. */ + if ((pFontBase->pFontArray[FontID].info_flags & AFM_SUCCESS) + || (pFontBase->pFontArray[FontID].info_flags & AFM_SLOPPY_SUCCESS)){ + sprintf( err_warn_msg_buf, + "Alert: Available AFM-Data for font %d is generated from existent AFM-file!", + FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_STATISTIC); + return(-1); + } + + /* Construct AFM-filename */ + i=strlen(pFontBase->pFontArray[FontID].pFontFileName); + if ((afmfilename=(char *)malloc((size_t)(i + 1) ))==NULL){ + sprintf( err_warn_msg_buf, + "Memory allocation error (fontID = %d)", + FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-6); + } + strcpy( afmfilename, pFontBase->pFontArray[FontID].pFontFileName); + while (afmfilename[i]!='.') + i--; + afmfilename[i+1]='a'; + afmfilename[i+2]='f'; + afmfilename[i+3]='m'; + + if ((afmfile=fopen( afmfilename, "wb"))==NULL){ + sprintf( err_warn_msg_buf, + "Could not open %s, (FontID = %d)", + afmfilename, FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_WARNING); + free( afmfilename); + T1_errno=T1ERR_FILE_OPEN_ERR; + return(-4); + } + + /* Set the creation time of afm file */ + tp=&s_clock; + s_clock=time( tp); + + /* Allocate a pointer-array to the metrics information, + of the size 256 + number of characters. */ + nochars=pFontBase->pFontArray[FontID].pAFMData->numOfChars; + if ((cmi=(CharMetricInfo **)calloc( nochars+ENCODINGSIZE, + sizeof(CharMetricInfo *)))==NULL){ + sprintf( err_warn_msg_buf, + "Memory allocation error (fontID = %d)", + FontID); + T1_PrintLog( "T1_WriteAFMFallbackFile()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-6); + } + /* Reset area */ + for ( i=0; i<(nochars+ENCODINGSIZE); i++) + cmi[i]=NULL; + /* First half of array is dedicated to encoded characters, the + second half for unencoded characters */ + k=ENCODINGSIZE; + for ( i=0; i<nochars; i++){ + j=T1_GetEncodingIndex( FontID, + pFontBase->pFontArray[FontID].pAFMData->cmi[i].name); + if (j>=0) + cmi[j]=&(pFontBase->pFontArray[FontID].pAFMData->cmi[i]); + else + cmi[k++]=&(pFontBase->pFontArray[FontID].pAFMData->cmi[i]); + } + + fprintf(afmfile, "StartFontMetrics 4.0\n"); + fprintf(afmfile, "Comment This is %s created from %s by t1lib V. %s.\n", + afmfilename, pFontBase->pFontArray[FontID].pFontFileName, + T1LIB_IDENT); + fprintf(afmfile, "Comment File creation date: %s", ctime(&s_clock)); + fprintf(afmfile, "Comment t1lib is copyright (c) Rainer Menzner, 1996-2001.\n"); + fprintf(afmfile, "Comment t1lib is distributed under the GNU General Public Library License (LGPL)\n"); + fprintf(afmfile, "FontName %s\n", T1_GetFontName( FontID)); + fprintf(afmfile, "FullName %s\n", T1_GetFullName( FontID)); + fprintf(afmfile, "FamilyName %s\n", T1_GetFamilyName( FontID)); + fprintf(afmfile, "Weight %s\n", T1_GetWeight( FontID)); + fprintf(afmfile, "ItalicAngle %d\n", (int)T1_GetItalicAngle( FontID)); + fprintf(afmfile, "IsFixedPitch %s\n", T1_GetIsFixedPitch( FontID) ? "true" : "false" ); + fprintf(afmfile, "FontBBox %d %d %d %d\n", + T1_GetFontBBox( FontID).llx, + T1_GetFontBBox( FontID).lly, + T1_GetFontBBox( FontID).urx, + T1_GetFontBBox( FontID).ury); + fprintf(afmfile, "UnderlinePosition %d\n", + (int)T1_GetUnderlinePosition( FontID)); + fprintf(afmfile, "UnderlineThickness %d\n", + (int)T1_GetUnderlineThickness( FontID)); + + fprintf(afmfile, "Version %s\n", T1_GetVersion( FontID)); + fprintf(afmfile, "Notice %s\n", T1_GetNotice( FontID)); + /* Encoding */ + if (pFontBase->pFontArray[FontID].pFontEnc==NULL){ + if (pFontBase->pFontArray[FontID].info_flags & USES_STANDARD_ENCODING){ + fprintf( afmfile, "EncodingScheme AdobeStandardEncoding\n"); + } + else{ + fprintf( afmfile, "EncodingScheme FontSpecific\n"); + } + } + else + fprintf( afmfile, "EncodingScheme FontSpecific\n"); + /* Values like capheight ascender xheight and descender */ + /* We start with the overshoot positions */ + i=pFontBase->pFontArray[FontID].pType1Data->BluesP->numBlueValues; + if (i>0){ + /* Capheight */ + if ((k=T1_GetEncodingIndex( FontID, "H"))!=-1){ + l=T1_GetCharBBox( FontID, (char) k).ury; + delta=10000; + for (j=0; j<i; j++){ + if (delta > abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l)){ + min=j; + delta=abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l); + } + } + if (min % 2) /* index is odd */ + min--; + /* Check for plausibility */ + if (abs( pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min] - l) + > DELTA_MAX) /* We probably did not found the right position */ + capheight=0; + else + capheight=pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min]; + } + else + capheight=0; + /* XHeight */ + if ((k=T1_GetEncodingIndex( FontID, "x"))!=-1){ + l=T1_GetCharBBox( FontID, (char) k).ury; + delta=10000; + for (j=0; j<i; j++){ + if (delta > abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l)){ + min=j; + delta=abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l); + } + } + if (min % 2) /* index is odd */ + min--; + /* Check for plausibility */ + if (abs( pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min] - l) + > DELTA_MAX) /* We probably did not found the right position */ + xheight=0; + else + xheight=pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min]; + } + else{ + xheight=0; + } + /* Ascender */ + if ((k=T1_GetEncodingIndex( FontID, "d"))!=-1){ + l=T1_GetCharBBox( FontID, (char) k).ury; + delta=10000; + for (j=0; j<i; j++){ + if (delta > abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l)){ + min=j; + delta=abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[j] - l); + } + } + if (min % 2) /* index is odd */ + min--; + /* Check for plausibility */ + if (abs( pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min] - l) + > DELTA_MAX) /* We probably did not found the right position */ + ascender=0; + else + ascender=pFontBase->pFontArray[FontID].pType1Data->BluesP->BlueValues[min]; + } + else{ + ascender=0; + } + } + else{ + capheight=0; + xheight=0; + ascender=0; + } + /* And now comes under shoot alignment position */ + i=pFontBase->pFontArray[FontID].pType1Data->BluesP->numOtherBlues; + if (i>0){ + /* Descender */ + if ((k=T1_GetEncodingIndex( FontID, "p"))!=-1){ + l=T1_GetCharBBox( FontID, (char) k).lly; + delta=10000; + for (j=0; j<i; j++){ + if (delta > abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->OtherBlues[j] - l)){ + min=j; + delta=abs(pFontBase->pFontArray[FontID].pType1Data->BluesP->OtherBlues[j] - l); + } + } + if ((min % 2)==0) /* index is even */ + min++; + /* Check for plausibility */ + if (abs( pFontBase->pFontArray[FontID].pType1Data->BluesP->OtherBlues[min] - l) + > DELTA_MAX) /* We probably did not found the right position */ + descender=0; + else + descender=pFontBase->pFontArray[FontID].pType1Data->BluesP->OtherBlues[min]; + } + else{ + descender=0; + } + } + else{ + descender=0; + } + if (capheight != 0) + fprintf( afmfile, "CapHeight %d\n", capheight); + if (xheight != 0) + fprintf( afmfile, "XHeight %d\n", xheight); + if (ascender != 0) + fprintf( afmfile, "Ascender %d\n", ascender); + if (descender != 0) + fprintf( afmfile, "Descender %d\n", descender); + if (pFontBase->pFontArray[FontID].pType1Data->BluesP->StdHW != 0.0) + fprintf( afmfile, "StdHW %d\n", + (int) pFontBase->pFontArray[FontID].pType1Data->BluesP->StdHW); + if (pFontBase->pFontArray[FontID].pType1Data->BluesP->StdVW != 0.0) + fprintf( afmfile, "StdVW %d\n", + (int) pFontBase->pFontArray[FontID].pType1Data->BluesP->StdVW); + + /* Now fill in the values (we omit the .notdef) */ + fprintf(afmfile, "StartCharMetrics %d\n", nochars-1); + for ( i=0; i<(nochars+ENCODINGSIZE); i++){ + if (cmi[i]!=NULL && strcmp(cmi[i]->name,".notdef")) + fprintf( afmfile, "C %3d ; WX %4d ; N %-20s ; B %5d %5d %5d %5d ;\n", + cmi[i]->code, cmi[i]->wx, cmi[i]->name, + cmi[i]->charBBox.llx, cmi[i]->charBBox.lly, + cmi[i]->charBBox.urx, cmi[i]->charBBox.ury); + } + fprintf(afmfile, "EndCharMetrics\nEndFontMetrics\n"); + + free(cmi); + fclose( afmfile); + return(0); +} + + diff --git a/Build/source/libs/t1lib/t1afmtool.h b/Build/source/libs/t1lib/t1afmtool.h new file mode 100644 index 00000000000..6d54751d98a --- /dev/null +++ b/Build/source/libs/t1lib/t1afmtool.h @@ -0,0 +1,43 @@ +/*-------------------------------------------------------------------------- + ----- File: t1afmtool.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-04-01 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1afmtool.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1AFMTOOL_C + +FontInfo *T1_GenerateAFMFallbackInfo( int FontID); +int T1_WriteAFMFallbackFile( int FontID); +extern struct region *fontfcnB_ByName( int FontID, int modflag, + struct XYspace *S, + char *charname, + int *mode, psfont *Font_Ptr, + int do_raster); + +#else + +extern FontInfo *T1_GenerateAFMFallbackInfo( int FontID); +extern int T1_WriteAFMFallbackFile( int FontID); + +#endif diff --git a/Build/source/libs/t1lib/t1base.c b/Build/source/libs/t1lib/t1base.c new file mode 100644 index 00000000000..d2d28dc6fd4 --- /dev/null +++ b/Build/source/libs/t1lib/t1base.c @@ -0,0 +1,1252 @@ +/*-------------------------------------------------------------------------- + ----- File: t1base.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2004-03-04 + ----- Description: This file is part of the t1-library. It contains basic + routines to initialize the data structures used + by the t1-library. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2004. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#define T1BASE_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <string.h> +#include <ctype.h> +#include <stdarg.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "sysconf.h" +#include "t1base.h" +#include "t1types.h" +#include "t1global.h" +#include "t1env.h" +#include "t1delete.h" + + +static int test_for_t1_file( char *buffer ); +static int T1_pad=0; + +/* A fix for Encoding Vector problem. Initialization / Deinitialization + is now done in T1_InitLib() / T1-CloseLib. */ +extern boolean Init_BuiltInEncoding( void); +extern psobj *StdEncArrayP; + +static const char* T1errmsg[] = { + "", /* -10 */ + "", /* -9 */ + "", /* -8 */ + "", /* -7 */ + "", /* -6 */ + "Attempt to Load Multiple Master Font", /* T1ERR_SCAN_FONT_FORMAT -5 */ + "Type 1 Font File Open Error", /* T1ERR_SCAN_FILE_OPEN_ERR -4 */ + "Virtual Memory Exceeded", /* T1ERR_SCAN_OUT_OF_MEMORY -3 */ + "Syntactical Error Scanning Font File", /* T1ERR_SCAN_ERROR -2 */ + "Premature End of Font File Encountered", /* T1ERR_SCAN_FILE_EOF -1 */ + "", /* 0 */ + "Path Construction Error", /* T1ERR_PATH_ERROR 1 */ + "Font is Corrupt", /* T1ERR_PARSE_ERROR 2 */ + "Rasterization Aborted", /* T1ERR_TYPE1_ABORT 3 */ + "", /* 4 */ + "", /* 5 */ + "", /* 6 */ + "", /* 7 */ + "", /* 8 */ + "", /* 9 */ + "Font ID Invalid in this Context", /* T1ERR_INVALID_FONTID 10 */ + "Invalid Argument in Function Call", /* T1ERR_INVALID_PARAMETER 11 */ + "Operation not Permitted", /* T1ERR_OP_NOT_PERMITTED 12 */ + "Memory Allocation Error", /* T1ERR_ALLOC_MEM 13 */ + "Error Opening File", /* T1ERR_FILE_OPEN_ERR 14 */ + "Unspecified T1Lib Error", /* T1ERR_UNSPECIFIED 15 */ + "Missing AFM Data", /* T1ERR_NO_AFM_DATA 16 */ + "X11 Interface Error", /* T1ERR_X11 17 */ + "Missing Component of Composite Character" /* T1ERR_COMPOSITE_CHAR 18 */ + "Error Scanning Encoding File", /* T1ERR_SCAN_ENCODING 19 */ + "", /* 20 */ +}; + + +/* T1_StrError(): Return an error message corresponding to the value of + t1err. */ +const char *T1_StrError( int t1err) +{ + int errind; + + errind = t1err + 10; + + if ( errind < 0 ) + errind = 0; + if ( errind > 29 ) + errind = 0; + + return T1errmsg[errind]; +} + + + +/* This function is to be called by the user to initialize + the font mechanism */ +void *T1_InitLib( int log) +{ + int result; + int i; + + char *usershome=NULL; + char *logfilepath=NULL; + char *envlogreq=NULL; + int usrforcelog=0; + + + + /* Reset T1_errno */ + T1_errno=0; + + /* Assign pointer to global struct and set entry padding: */ + pFontBase=&FontBase; + if (T1_pad) + pFontBase->bitmap_pad=T1_pad; + else + pFontBase->bitmap_pad=T1GLYPH_PAD; + + pFontBase->pFontArray = NULL; + pFontBase->t1lib_flags=0; + /* Check for AA-caching */ + if ((log & T1_AA_CACHING)){ + pFontBase->t1lib_flags |= T1_AA_CACHING; + } + /* Check for AFM disable */ + if ((log & T1_NO_AFM)) { + pFontBase->t1lib_flags |= T1_NO_AFM; + } + + /* Check environment variable ENV_LOG_STRING. By this means, a user may + generate a log file even if at compile time log file creation has + been suppressed. Of course, if the loglevel is reduced after + initialization by the programmer, this environment variable takes + no effect! */ + if ((envlogreq=getenv(ENV_LOG_STRING))!=NULL) { + if (strcmp( envlogreq, "logDebug")==0) + T1_SetLogLevel( T1LOG_DEBUG); + else if (strcmp( envlogreq, "logStatistic")==0) + T1_SetLogLevel( T1LOG_STATISTIC); + else if (strcmp( envlogreq, "logWarning")==0) + T1_SetLogLevel( T1LOG_WARNING); + else if (strcmp( envlogreq, "logError")==0) + T1_SetLogLevel( T1LOG_ERROR); + usrforcelog=1; + } + + /* Open log-file: */ + t1lib_log_file=NULL; + if ((log & LOGFILE) || (usrforcelog!=0)) { + pFontBase->t1lib_flags |= LOGFILE; + /* Try first opening in current directory: */ + if ((t1lib_log_file=fopen( T1_LOG_FILE, "wb"))==NULL) { + if ((usershome=getenv("HOME"))!=NULL) { + logfilepath=(char *)malloc((strlen(usershome) + + strlen(T1_LOG_FILE) + 2 + ) * sizeof(char)); + strcpy( logfilepath, usershome); + strcat( logfilepath, DIRECTORY_SEP); + strcat( logfilepath, T1_LOG_FILE); + if ((t1lib_log_file=fopen( logfilepath, "wb"))==NULL){ + t1lib_log_file=stderr; + } + free( logfilepath); + } + else { + t1lib_log_file=stderr; + } + } + if (t1lib_log_file==stderr) { + T1_PrintLog( "T1_InitLib()", "Unable to open a logfile, using stderr", + T1LOG_ERROR); + } + } + + T1_PrintLog( "T1_InitLib()", "Initialization started", + T1LOG_STATISTIC); + /* Check for representation of data in memory: */ + if ((pFontBase->endian=T1_CheckEndian())){ + T1_PrintLog( "T1_InitLib()", "Using Big Endian data presentation (MSBFirst)", + T1LOG_DEBUG); + pFontBase->endian=1; + } + else{ + T1_PrintLog( "T1_InitLib()", "Using Little Endian data presentation (LSBFirst)", + T1LOG_DEBUG); + pFontBase->endian=0; + } + + /* Save version identifier */ + sprintf( err_warn_msg_buf, "Version Identifier: %s", T1LIB_IDENT); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, + T1LOG_DEBUG); + /* Save how t1lib is initialized */ + sprintf( err_warn_msg_buf, "Initialization flags: 0x%X", log); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, + T1LOG_DEBUG); + /* Save padding value in log file */ + sprintf( err_warn_msg_buf, "Glyphs are padded to %d bits", + pFontBase->bitmap_pad); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, + T1LOG_DEBUG); +#ifdef __CHAR_UNSIGNED__ + T1_PrintLog( "T1_InitLib()", "System-Info: char is unsigned", + T1LOG_DEBUG); +#else + T1_PrintLog( "T1_InitLib()", "System-Info: char is signed", + T1LOG_DEBUG); +#endif + sprintf( err_warn_msg_buf, "System-Info: sizeof(char): %d", + SIZEOF_CHAR); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(short): %d", + SIZEOF_SHORT); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(int): %d", + SIZEOF_INT); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(long): %d", + SIZEOF_LONG); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(long long): %d", + SIZEOF_LONG_LONG); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(float): %d", + SIZEOF_FLOAT); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(double): %d", + SIZEOF_DOUBLE); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(long double): %d", + SIZEOF_LONG_DOUBLE); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "System-Info: sizeof(void *): %d", + SIZEOF_VOID_P); + T1_PrintLog( "T1_InitLib()", err_warn_msg_buf, T1LOG_DEBUG); + + intT1_SetupDefaultSearchPaths(); + if (log & IGNORE_CONFIGFILE) { + pFontBase->t1lib_flags |= IGNORE_CONFIGFILE; + T1_PrintLog( "T1_InitLib()", "Skipping configuration file search!", + T1LOG_STATISTIC); + } + else { + if ((result=intT1_ScanConfigFile())==0) + T1_PrintLog( "T1_InitLib()", "Warning t1lib configuration file not found!", + T1LOG_WARNING); + } + + /* Initialize builtin Standard Encoding */ + if ( !(Init_BuiltInEncoding()) ) { + T1_PrintLog( "T1_InitLib()", "Unable initialize internal StandardEncoding!", + T1LOG_ERROR); + } + + /* Set the default encoding to the fonts' internal encoding */ + pFontBase->default_enc=NULL; + + /* Initialize the no_fonts... values */ + pFontBase->no_fonts=0; + pFontBase->no_fonts_ini=pFontBase->no_fonts; + pFontBase->no_fonts_limit=pFontBase->no_fonts; + + + /* Check whether to read font database */ + if ((log & IGNORE_FONTDATABASE)){ + pFontBase->t1lib_flags |= IGNORE_FONTDATABASE; + + T1_Up=1; /* System has been initialized ! */ + T1_PrintLog( "T1_InitLib()", "Initialization successfully finished (Database empty)", + T1LOG_STATISTIC); + + return((void *) pFontBase); + } + + result=0; + /* Read fontdatabase(s) */ + i=0; + while (T1_FDB_ptr[i]!=NULL) { + if ((result=intT1_scanFontDBase(T1_FDB_ptr[i]))==-1){ + T1_PrintLog( "T1_InitLib()", "Fatal error scanning Font Database File %s", + T1LOG_WARNING, T1_FDB_ptr[i]); + } + if (result>-1) + pFontBase->no_fonts+=result; + i++; + + } + if (result == 0){ + T1_PrintLog( "T1_InitLib()", "No fonts from Font Database File(s) found (T1_errno=%d)", + T1LOG_ERROR, T1_errno); + return(NULL); + } + + /* Initialize the no_fonts... values */ + pFontBase->no_fonts_ini=pFontBase->no_fonts; + pFontBase->no_fonts_limit=pFontBase->no_fonts; + + T1_Up=1; /* System has been initialized ! */ + T1_PrintLog( "T1_InitLib()", "Initialization successfully finished", + T1LOG_STATISTIC); + + return((void *) pFontBase); +} + + + +/* intT1_scanFontDBase(): + - opens the file with the font definitions, + - reads the number of fonts defined and saves this in FontBase, + - allocates memory for all the filenames of the Type1 files + - tests for .pfa und .pfb files and saves the name found + - initializes an array that allows to acces these names by an + index number, the font_ID + - returns -1 on fatal error and the number of fonts located + successfullly + */ +int intT1_scanFontDBase( char *filename) +{ + int fd; + int filesize, i, j, k, m; + int found=0, located=0; + char *filebuffer; + int nofonts=0; + FONTPRIVATE* fontarrayP=NULL; + +#ifndef O_BINARY +# define O_BINARY 0x0 +#endif + + if ((fd=open( filename, O_RDONLY | O_BINARY))<3){ + T1_PrintLog( "intT1_scanFontDBase()", "Font Database File %s not found!", + T1LOG_WARNING, filename); + T1_errno=T1ERR_FILE_OPEN_ERR; + return(-1); + } + + /* Get the file size */ + filesize=lseek( fd, 0, 2); + /* Reset fileposition to start */ + lseek (fd, 0, 0); + + if ((filebuffer=(char *)malloc(filesize*sizeof(char) + )) == NULL){ + T1_PrintLog( "intT1_scanFontDBase()", + "Couldn't allocate memory for loading font database file %s", + T1LOG_ERROR, filename); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + + i=read( fd, filebuffer, filesize); + close(fd); /* Close font database file */ + + i=j=m=0; + + while (i<filesize) { + if (filebuffer[i]=='\n'){ /* We are at the end of line */ + if (j==0) { /* Read the first line as the number of fonts */ + filebuffer[i]=0; + sscanf( &filebuffer[0], "%d", &nofonts); + filebuffer[i]='\n'; /* Because it gives a better feeling */ + /* (Re)Allocate memory for 'no_fonts' structures: */ + if ((FontBase.pFontArray=(FONTPRIVATE *) + realloc( FontBase.pFontArray, (FontBase.no_fonts+nofonts)*sizeof(FONTPRIVATE))) == NULL) { + T1_PrintLog( "inT1_scanFontDBase()", + "Failed to allocate memory for FONTPRIVATE-area while scanning %s", + T1LOG_ERROR, filename); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* setup pointer to newly allocated area and do a reset */ + fontarrayP=&(FontBase.pFontArray[FontBase.no_fonts]); + memset(fontarrayP, 0, nofonts*sizeof(FONTPRIVATE)); + located=1; /* In order to increment m */ + } + else { /* We are in the second or higher line */ + k=i; + while (isspace((int)filebuffer[k])){ + k--; + } + /* We are at the last printable character of a line; let's + step back (over the [afm/sfm]) to the period and replace it + by an ASCII 0 */ + while ((filebuffer[k]!='.') && (!isspace((int)filebuffer[k])) ){ + k--; + } + if (filebuffer[k]=='.'){ /* We have a name terminated with . */ + filebuffer[k]=0; /* termination for string reading */ + while (!isspace((int)filebuffer[k])){ + k--; + } + } + else { /* The filename was without . and / or the first on the line */ + ; + } + sscanf( &(filebuffer[k+1]), "%s", &(linebuf[0])); + /* We print error string before testing because after the call + to test_for_t1_file() filename is substituted by an emty + string if the file was not found: */ + sprintf( err_warn_msg_buf, "Type 1 Font file %s.[pfa/pfb] not found (FontID=%d, SearchPath=%s)", + linebuf, m-1, T1_GetFileSearchPath(T1_PFAB_PATH)); + if ((test_for_t1_file( &linebuf[0]))){ + T1_PrintLog( "intT1_scanFontDBase()", err_warn_msg_buf, T1LOG_WARNING); + located=0; + } + else{ + /* linebuf contains now the valid Type1 filename; let's + now copy this string into the appropriate place in the + FONTPRIVATE-struct: */ + found++; + located=1; + if ((fontarrayP[m-1].pFontFileName=(char *) + calloc( strlen( &linebuf[0])+1, sizeof(char))) == NULL){ + T1_PrintLog( "intT1_scanFontDBase()", + "Failed to allocate memory for Filename %s (FontID=%d)", + T1LOG_ERROR, &linebuf[0], m-1); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( fontarrayP[m-1].pFontFileName, &linebuf[0]); + } + } + j++; /* Advance line counter */ + if ((located)) + m++; + } + if (j>nofonts) /* to ignore especially white space at end */ + break; + i++; /* Step further in file position */ + } + /* Return the memory for file reading */ + free(filebuffer); + + return( found); +} + + +/* T1_CloseLib(): Close the library and free all associated memory */ +int T1_CloseLib( void) +{ + + int i, j, error=0; + + if (T1_Up){ + for (i=pFontBase->no_fonts; i; i--){ + /* Free filename only if not NULL and if the font is physical! + Do it before removing the font since the physical information + is no more available afterwards. If necessary, an explicitly + specified AFM filename is also freed. + */ + if ((pFontBase->pFontArray[i-1].pFontFileName!=NULL) + && (pFontBase->pFontArray[i-1].physical==1)){ + free( pFontBase->pFontArray[i-1].pFontFileName); + pFontBase->pFontArray[i-1].pFontFileName=NULL; + if (pFontBase->pFontArray[i-1].pAfmFileName!=NULL){ + free( pFontBase->pFontArray[i-1].pAfmFileName); + pFontBase->pFontArray[i-1].pAfmFileName=NULL; + } + } + + /* Now, remove font: */ + if ((j=T1_DeleteFont( i-1))){ + error=1; + sprintf( err_warn_msg_buf, "T1_DeleteFont() returned %d for Font %d", + j, i-1); + T1_PrintLog( "T1_CloseLib()", err_warn_msg_buf, T1LOG_ERROR); + } + } + /* Free the FONTPRIVATE area */ + if (pFontBase->pFontArray) + free( pFontBase->pFontArray); + else + error=1; + + /* Get rid of internal StandardEncoding vector */ + if ( StdEncArrayP != NULL ) { + free( StdEncArrayP); + StdEncArrayP = NULL; + } + + /* Free search paths */ + intT1_FreeSearchPaths(); + + /* Reset the flags */ + pFontBase->t1lib_flags=0; + + /* Indicate Library is no longer initialized */ + pFontBase=NULL; + T1_Up=0; + T1_PrintLog( "T1_CloseLib()", "Library closed", T1LOG_STATISTIC); + if ((t1lib_log_file!=NULL) && (t1lib_log_file!=stderr)) + fclose(t1lib_log_file); + t1lib_log_file=NULL; + } + + return( error); +} + + +/* T1_AddFont(): Add a new fontfile to the fontdatabase. + Return values: >0: Assigned FontID + -1: Fontfile not found + -2: Error allocating memory for FONTPRIVATE-area + -3: No memory for saving font filename + */ +int T1_AddFont( char *fontfilename) +{ + + char *FullName; + FONTPRIVATE *save_ptr; + int i; + int new_ID; + + + if (fontfilename==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + + /* Check for existence of fontfile */ + if ((FullName=intT1_Env_GetCompletePath(fontfilename,T1_PFAB_ptr))==NULL) { + T1_errno=T1ERR_FILE_OPEN_ERR; + return(-1); + } + free(FullName); + + /* Check if free space for a new FONTPRIVATE is available; if not, + realloc memory some amount larger */ + save_ptr=pFontBase->pFontArray; + if (pFontBase->no_fonts==pFontBase->no_fonts_limit){ + if (pFontBase->pFontArray == NULL) { + /* In case this is the first font */ + pFontBase->pFontArray=(FONTPRIVATE *)calloc(pFontBase->no_fonts_limit + + ADVANCE_FONTPRIVATE, + sizeof(FONTPRIVATE)); + } + else { + /* We already have some fonts */ + pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray, + (pFontBase->no_fonts_limit + + ADVANCE_FONTPRIVATE) + * sizeof(FONTPRIVATE)); + if (pFontBase->pFontArray==NULL){ + /* Restore pointer */ + pFontBase->pFontArray=save_ptr; + T1_errno=T1ERR_ALLOC_MEM; + return(-2); /* No memory available */ + } + } + pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE; + /* First, initialize newly allocated to be not used */ + for ( i=pFontBase->no_fonts; + i<pFontBase->no_fonts+ADVANCE_FONTPRIVATE; i++){ + pFontBase->pFontArray[i].pFontFileName=NULL; + pFontBase->pFontArray[i].pAfmFileName=NULL; + pFontBase->pFontArray[i].pAFMData=NULL; + pFontBase->pFontArray[i].pType1Data=NULL; + pFontBase->pFontArray[i].pEncMap=NULL; + pFontBase->pFontArray[i].pKernMap=NULL; + pFontBase->pFontArray[i].pFontEnc=NULL; + pFontBase->pFontArray[i].pFontSizeDeps=NULL; + pFontBase->pFontArray[i].vm_base=NULL; + pFontBase->pFontArray[i].FontMatrix[0]=0.0; + pFontBase->pFontArray[i].FontMatrix[1]=0.0; + pFontBase->pFontArray[i].FontMatrix[2]=0.0; + pFontBase->pFontArray[i].FontMatrix[3]=0.0; + pFontBase->pFontArray[i].FontTransform[0]=0.0; + pFontBase->pFontArray[i].FontTransform[1]=0.0; + pFontBase->pFontArray[i].FontTransform[2]=0.0; + pFontBase->pFontArray[i].FontTransform[3]=0.0; + pFontBase->pFontArray[i].slant=0.0; + pFontBase->pFontArray[i].extend=0.0; + pFontBase->pFontArray[i].physical=0; + pFontBase->pFontArray[i].refcount=0; + pFontBase->pFontArray[i].space_position=0; + pFontBase->pFontArray[i].info_flags=0; + } + } + /* no_fonts-1 was the largest allowed font ID */ + new_ID=pFontBase->no_fonts; + pFontBase->no_fonts++; + + if ((FontBase.pFontArray[new_ID].pFontFileName=(char *) + calloc( strlen( fontfilename)+1, sizeof(char))) == NULL){ + T1_PrintLog( "T1_AddFont()", + "Failed to allocate memory for Filename %s (FontID=%d)", + T1LOG_ERROR, fontfilename, new_ID); + T1_errno=T1ERR_ALLOC_MEM; + return(-3); + } + strcpy( FontBase.pFontArray[new_ID].pFontFileName, fontfilename); + + /* Generate logfile entry */ + sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s", + new_ID, FontBase.pFontArray[new_ID].pFontFileName); + T1_PrintLog( "T1_AddFont()", err_warn_msg_buf, + T1LOG_STATISTIC); + /* Return FontID of newly declared font */ + return( new_ID); + +} + + +/* T1_PrintLog() generates entries in the log file. msg_txt is subject to scan + conversion and ... signifies a accordingly lrge variable list. */ +void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...) +{ + va_list vararg; + static char levelid[4]={ 'E', 'W', 'S', 'D'}; + time_t s_clock, *tp; + + if (t1lib_log_file==NULL) + return; + if ((level>t1lib_log_level) || (level<1)){ + return; + } + else{ + /* initialize argument list */ + va_start( vararg, level); + + tp=&s_clock; + s_clock=time( tp); + /* + fprintf( t1lib_log_file, "(%c) (%.24s) %s: ", + levelid[level-1], ctime(&s_clock), func_ident); + */ + /* Don't print the time stamp */ + fprintf( t1lib_log_file, "(%c) %s: ", levelid[level-1], func_ident ); + vfprintf( t1lib_log_file, msg_txt, vararg ); + fprintf( t1lib_log_file, "\n"); + fflush( t1lib_log_file); + + /* cleanup variable list */ + va_end( vararg); + + return; + } +} + + +/* T1_SetLogLevel(): Set the level which a message must have so + that it is printed into the logfile. This function may be called + before T1_InitLib(). */ +void T1_SetLogLevel( int level) +{ + if ((level>0) && (level<5)) + t1lib_log_level=level; + return; +} + + + +/* T1_CheckForInit(): If no initialization of font mechanism has been + done, return -1, indicating an error. */ +int T1_CheckForInit(void) +{ + if(T1_Up) + return(0); + else + return(-1); + +} + + + +/* T1_CheckForFontID(): Checks the font mechanism concerning the specified + ID. It returns: + 0 if font belonging to FontID has not yet been loaded + 1 if font belonging to FontID has already been loaded + -1 if FontID is an invalid specification or t1lib not + initialized + */ +int T1_CheckForFontID( int FontID) +{ + + /* FontID is invalid */ + if ((FontID<0)||(FontID>(pFontBase->no_fonts - 1))||(T1_Up==0)) + return(-1); + + if (pFontBase->pFontArray[FontID].pType1Data==NULL) + return(0); /* has not yet been loaded */ + else + return(1); /* has already been loaded */ +} + + + + +/* test_for_t1_file returns 0 if a file "name.pfa" or "name.pfb" + was found. Else, -1 is returned. If successful, buffer contains the + found filename string */ +static int test_for_t1_file( char *buffer ) +{ + int i=0; + char *FullName; + + /* First case: A PostScript Font ASCII File without extension + (according to some UNIX-conventions) */ + if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) { + free(FullName); + return(0); + } + + while (buffer[i]!=0){ + i++; + } + buffer[i]='.'; + buffer[i+1]='p'; + buffer[i+2]='f'; + buffer[i+4]=0; + + + /* Second case: A PostScript Font ASCII File */ + buffer[i+3]='a'; + if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) { + free(FullName); + return(0); + } + /* Third case: A PostScript Font Binary File */ + buffer[i+3]='b'; + if ((FullName=intT1_Env_GetCompletePath(buffer,T1_PFAB_ptr))!=NULL) { + free(FullName); + return(0); + } + + /* If we get here no file was found => Set buffer + to an empty string and return -1 */ + + buffer[0]=0; + return(-1); +} + + +/* T1_GetFontFileName() returns a pointer to the filename of the font, + associated with FontID. This filename does not contain a full path. + */ +char *T1_GetFontFileName( int FontID) +{ + + static char filename[MAXPATHLEN+1]; + + if (T1_CheckForInit())return(NULL); + + /* Check first for valid FontID */ + if ((FontID<0) || (FontID>FontBase.no_fonts)){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strcpy( filename, pFontBase->pFontArray[FontID].pFontFileName); + + return( filename); + +} + + + +/* As suggested by Nicolai Langfeldt, we make it possible to specify + a completely independent path for the afm filename. This should + make t1lib usable in context with using the kpathsearch-library. + We allow setting those pathīs after initialization, but before a + font is loaded. + returns 0: OK + -1: Operation could not be performed +*/ +int T1_SetAfmFileName( int FontID, char *afm_name) +{ + + if (T1_CheckForFontID(FontID)!=0){ + /* Operation may not be applied because FontID is invalid + or font is loaded */ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + if (afm_name==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL){ + /* we first free the current name */ + free( pFontBase->pFontArray[FontID].pAfmFileName); + pFontBase->pFontArray[FontID].pAfmFileName=NULL; + } + + if ((pFontBase->pFontArray[FontID].pAfmFileName= + (char *)malloc( (strlen(afm_name)+1)*sizeof( char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( -1); + } + strcpy( pFontBase->pFontArray[FontID].pAfmFileName, afm_name); + + return(0); + +} + + + +/* We have a function for querying the name. Returns a pointer + to the string or NULL if name was not explicitly set .*/ +char *T1_GetAfmFileName( int FontID) +{ + + static char filename[MAXPATHLEN+1]; + + if (T1_CheckForInit())return(NULL); + + /* Check first for valid FontID */ + if ((FontID<0) || (FontID>FontBase.no_fonts)){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + if (pFontBase->pFontArray[FontID].pAfmFileName==NULL) { + return( NULL); + } + + strcpy( filename, pFontBase->pFontArray[FontID].pAfmFileName); + return( filename); + +} + + + +/* T1_GetNoFonts(): Return the number of declared fonts */ +int T1_GetNoFonts(void) +{ + if (T1_CheckForInit()) + return(-1); + return(FontBase.no_fonts); +} + + + +/* T1_SetDeviceResolutions( x_res, y_res): Set the device's physical + resolution in horizontal and vertical direction, mesured in DPI + (Dots Per Inch). This should be done before the first font is + loaded! */ +int T1_SetDeviceResolutions( float x_res, float y_res) +{ + + int i; + + if (T1_CheckForInit()) + ; /* Not initialized -> no size dependent data -> OK */ + else + /* Check if size-dependent data is existent */ + for ( i=T1_GetNoFonts(); i; i--) + if (pFontBase->pFontArray[i-1].pFontSizeDeps!=NULL){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); /* There's is size dependent data for a font */ + } + + /* Save resolutions and calculate horizontal and vertical + scale factors to map desired bp to device pixel */ + DeviceSpecifics.x_resolution=(float) x_res; + DeviceSpecifics.y_resolution=(float) y_res; + DeviceSpecifics.scale_x=(float)(((float)x_res)/BIGPOINTSPERINCH); + DeviceSpecifics.scale_y=(float)(((float)y_res)/BIGPOINTSPERINCH); + return(0); +} + + +/* T1_QueryX11Support(): Check at runtime to see if t1lib was compiled + with X11 interface: */ +int T1_QueryX11Support( void) +{ +#ifndef T1LIB_NO_X11_SUPPORT + return(1); +#else + return(0); +#endif +} + + + + +/* int T1_CopyFont(): Copies the font associated with FontID to another + location. The pointers to type1- , afm- and encoding data as well as + the matrices remain completely untouched. However, size dependent data + is not copied. The produced font is marked as a "logical" font. + If no memory is available in the FONTPRIVATE-array, there's realloc'ed + some more memory. The FontID which is assigned to the newly generated + font is given as the return value, or < 0 if an error occurs. Also, + the refcount entry of the source font is incremented by one. + + Return value -1: invalid FontID specified + -2: source font is not a "physical" font + -3: no memory for reallocation of FONTPRIVATEs + -4: no memory for one of the mapping tables + */ +int T1_CopyFont( int FontID) +{ + FONTPRIVATE *save_ptr; + int k; + int new_ID; + + + /* Check for a valid source font */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + + /* Check if the font in question is a "physical" font, otherwise it may + not be copied */ + if (pFontBase->pFontArray[FontID].physical==0){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-2); + } + + + /* Check if free space for a new FONTPRIVATE is available; if not, + realloc memory some amount larger */ + save_ptr=pFontBase->pFontArray; + if (pFontBase->no_fonts==pFontBase->no_fonts_limit){ + pFontBase->pFontArray=(FONTPRIVATE *)realloc(pFontBase->pFontArray, + (pFontBase->no_fonts_limit + + ADVANCE_FONTPRIVATE) + * sizeof(FONTPRIVATE)); + if (pFontBase->pFontArray==NULL){ + /* Restore pointer */ + pFontBase->pFontArray=save_ptr; + T1_errno=T1ERR_ALLOC_MEM; + return(-3); + } + /* We zero the newly allocated memory */ + if (pFontBase->pFontArray != NULL) { + memset( pFontBase->pFontArray + pFontBase->no_fonts_limit, 0, + ADVANCE_FONTPRIVATE * sizeof(FONTPRIVATE)); + } + pFontBase->no_fonts_limit += ADVANCE_FONTPRIVATE; + } + /* no_fonts-1 was the largest allowed font ID */ + new_ID=pFontBase->no_fonts; + /* Copy FONTPRIVATE-structure: */ + pFontBase->pFontArray[new_ID]=pFontBase->pFontArray[FontID]; + /* (Re)Set some values explicitly, others remain untouched: */ + pFontBase->pFontArray[new_ID].pFontSizeDeps=NULL; + pFontBase->pFontArray[new_ID].physical=0; + /* AFM-mapping tables are to be setup for logical fonts separately + (if AFM data is there) */ + /* first, kerning map */ + if (pFontBase->pFontArray[new_ID].pAFMData) { + k=pFontBase->pFontArray[new_ID].pAFMData->numOfPairs; + if (k>0){ /* kern map exists only if kerning pairs exist! */ + if ((pFontBase->pFontArray[new_ID].pKernMap= + (METRICS_ENTRY *)malloc( k*sizeof( METRICS_ENTRY)))==NULL){ + sprintf( err_warn_msg_buf, "Error allocating memory for kerning map (new_ID=%d)", + new_ID); + T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-4); + } + memcpy( pFontBase->pFontArray[new_ID].pKernMap, + pFontBase->pFontArray[FontID].pKernMap, + k*sizeof( METRICS_ENTRY)); + } + else { /* no kerning pairs, bu AFM data present */ + pFontBase->pFontArray[new_ID].pKernMap=NULL; + } + } + else { /* AFM data not present at all */ + pFontBase->pFontArray[new_ID].pKernMap=NULL; + } + + /* second, encoding map */ + if (pFontBase->pFontArray[FontID].pEncMap!=NULL) { + if ((pFontBase->pFontArray[new_ID].pEncMap= + (int *)calloc(256,sizeof(int)))==NULL){ + sprintf( err_warn_msg_buf, + "Error allocating memory for encoding map (new_ID=%d)", + new_ID); + T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-4); + } + memcpy( pFontBase->pFontArray[new_ID].pEncMap, + pFontBase->pFontArray[FontID].pEncMap, + 256*sizeof( int)); + } + + /* New font is logical --> indicate to which physical font it + refers by setting refcount: */ + pFontBase->pFontArray[new_ID].refcount=FontID; + + /* Now the struct is setup; increment no_fonts by 1 because + new_ID is a valid font specification from now on. */ + pFontBase->no_fonts++; + /* Increment refcount in source font */ + pFontBase->pFontArray[FontID].refcount++; + + /* Generate logfile entry */ + sprintf( err_warn_msg_buf, "Assigned FontID %d to fontfile %s", + new_ID, FontBase.pFontArray[new_ID].pFontFileName); + T1_PrintLog( "T1_CopyFont()", err_warn_msg_buf, + T1LOG_STATISTIC); + return(new_ID); +} + + + +/* T1_SetBitmapPad(): Set the value to which bitmap-scanlines are padded. + This has to be done before initialization because it is a very + rudimentary operation. + */ +int T1_SetBitmapPad( int pad) +{ + if (T1_Up){ + /* Library is initialized --> return error */ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + else{ + switch (pad){ + case 8: + T1_pad=8; + return(0); + case 16: + T1_pad=16; + return(0); +#ifdef T1_AA_TYPE64 + case 32: + T1_pad=32; + return(0); +#endif + default: + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + } +} + + + +/* T1_GetBitmapPad(): Read the value to which scanlines of bitmap are + padded. This can be done before or after initialization. */ +int T1_GetBitmapPad( void) +{ + if (pFontBase) /* T1lib initialized --> return value from struct */ + return( pFontBase->bitmap_pad); + else{ + if (T1_pad) + return(T1_pad); /* pad is explicitly set --> return that value */ + else + return( T1GLYPH_PAD); /* not expl. set --> return compilation default */ + } +} + + + +/* CheckEndian(): Checks whether the current machine is of little or big + endian architecture. This is important for concatenating bitmaps. + Function returns 0 if LittleEndian and 1 if BigEndian representation + is used on the current hardware. + */ +int T1_CheckEndian() +{ + unsigned char *charptr; + + /* Generate test value */ + unsigned short test=0x0001; + + /* Read out memory as unsigned char */ + charptr=(unsigned char *)(&test)+1; + + /* Return value will be 1 if Big- and 0 if Little Endian */ + return((int) *charptr); + +} + + + +/* T1_GetLibIdent(): Return the identifier string for the current version + of t1lib */ +char *T1_GetLibIdent( void) +{ + static char buf[15]; + + sprintf( buf, "%s", T1LIB_IDENT); + + return( (char *)buf); +} + + + +/* T1_SetRasterFlags(): Enable/Disable certain features in + the rasterizer */ +extern void T1_SetRasterFlags( int flags) +{ + + T1_Type1OperatorFlags=flags; + return; + +} + + + +/* T1_GetFontFileName(): returns a pointer to the complete path filename + of the font, associated with FontID as it is in use by t1lib. + */ +char *T1_GetFontFilePath( int FontID) +{ + + static char filepath[MAXPATHLEN+1]; + char *FileNamePath=NULL; + + /* is initialzed? */ + if (T1_CheckForInit()) { + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* Check first for valid FontID */ + if ((FontID<0) || (FontID>FontBase.no_fonts)){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* lib is initialized and FontID is valid -> + we can really expect a name */ + if ((FileNamePath=intT1_Env_GetCompletePath( pFontBase->pFontArray[FontID].pFontFileName, + T1_PFAB_ptr))==NULL) { + T1_PrintLog( "T1_GetFontFilePath()", "Couldn't locate font file for font %d in %s", + T1LOG_WARNING, FontID, T1_GetFileSearchPath(T1_PFAB_PATH)); + T1_errno=T1ERR_FILE_OPEN_ERR; + return(NULL); + } + + strcpy( filepath, FileNamePath); + free( FileNamePath); + + return( filepath); + +} + + + +/* We have a function for querying the name. Returns a pointer + to the string or NULL if name was not explicitly set .*/ +char *T1_GetAfmFilePath( int FontID) +{ + + static char filepath[MAXPATHLEN+1]; + char *FontFileName; + char *AFMFilePath; + int i, j; + + /* is initialized? */ + if ((T1_CheckForInit())) { + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* Check first for valid FontID */ + if ((FontID<0) || (FontID>FontBase.no_fonts)){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* Check wether AFM-file loading was suppressed on user's request */ + if ((pFontBase->t1lib_flags & T1_NO_AFM)!=0) { + /* this is no error condition, we simply return (NULL) */ + return( NULL); + } + + /* Check for explicitly associated metrics filename (via + "T1_SetAfmFileName()"). If it exists, we return it! */ + if (pFontBase->pFontArray[FontID].pAfmFileName!=NULL) { + strcpy( filepath, pFontBase->pFontArray[FontID].pAfmFileName); + sprintf( err_warn_msg_buf, "Returning explicitly specified path %s for Font %d", + filepath, FontID); + T1_PrintLog( "T1_GetAfmFilePath()", err_warn_msg_buf, T1LOG_DEBUG); + return( filepath); + } + + /* we have the usual case that the name of the metrics file has to be + deduced from the font file name */ + FontFileName=T1_GetFontFileName( FontID); + i=strlen(FontFileName); + j=i; + strcpy( filepath, FontFileName); + while ( filepath[i] != '.'){ + if (i==0) break; + else i--; + } + if (i==0){ + /* We have a filename without extension -> append extension */ + filepath[j]='.'; + filepath[j+1]='a'; + filepath[j+2]='f'; + filepath[j+3]='m'; + filepath[j+4]='\0'; + } + else{ + /* we found a '.' -> replace extension */ + filepath[i+1]='a'; + filepath[i+2]='f'; + filepath[i+3]='m'; + filepath[i+4]='\0'; + } + /* Get full path of the afm file (The case of a full path name + name specification is valid) */ + if ((AFMFilePath=intT1_Env_GetCompletePath( filepath, T1_AFM_ptr)) == NULL) { + return NULL; + } + + strcpy( filepath, AFMFilePath); + free( AFMFilePath); + + return( filepath); + +} + + diff --git a/Build/source/libs/t1lib/t1base.h b/Build/source/libs/t1lib/t1base.h new file mode 100644 index 00000000000..a14b73afafa --- /dev/null +++ b/Build/source/libs/t1lib/t1base.h @@ -0,0 +1,82 @@ +/*-------------------------------------------------------------------------- + ----- File: t1base.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-08 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1base.c + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1BASE_C + +void *T1_InitLib( int log); +int intT1_scanFontDBase( char *filename); +int T1_CloseLib( void); +int T1_AddFont( char *fontfilename); +void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...); +void T1_SetLogLevel( int level); +int T1_CheckForInit(void); +int T1_CheckForFontID( int FontID); +char *T1_GetFontFileName( int FontID); +int T1_GetNoFonts(void); +int T1_SetDeviceResolutions( float x_res, float y_res); +int T1_CopyFont( int FontID); +int T1_QueryX11Support( void); +int T1_CheckEndian(void); +int T1_SetBitmapPad( int pad); +int T1_GetBitmapPad( void); +char *T1_GetLibIdent( void); +void T1_SetRasterFlags( int flags); +char *T1_GetAfmFileName( int FontID); +int T1_SetAfmFileName( int FontId, char *afm_name); +char *T1_GetFontFilePath( int FontID); +char *T1_GetAfmFilePath( int FontID); +const char *T1_StrError( int t1err); + +extern int T1_Type1OperatorFlags; + +#else + +extern void *T1_InitLib( int log); +extern int intT1_scanFontDBase( char *filename); +extern int T1_CloseLib( void); +extern int T1_AddFont( char *fontfilename); +extern void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...); +extern void T1_SetLogLevel( int level); +extern int T1_CheckForInit(void); +extern int T1_CheckForFontID( int FontID); +extern char *T1_GetFontFileName( int FontID); +extern int T1_GetNoFonts(void); +extern int T1_SetDeviceResolutions( float x_res, float y_res); +extern int T1_QueryX11Support( void); +extern int T1_CopyFont( int FontID); +extern int T1_CheckEndian(void); +extern int T1_SetBitmapPad( int pad); +extern int T1_GetBitmapPad( void); +extern char *T1_GetLibIdent( void); +extern void T1_SetRasterFlags( int flags); +extern char *T1_GetAfmFileName( int FontID); +extern int T1_SetAfmFileName( int FontId, char *afm_name); +extern char *T1_GetFontFilePath( int FontID); +extern char *T1_GetAfmFilePath( int FontID); +extern const char *T1_StrError( int t1err); + +#endif diff --git a/Build/source/libs/t1lib/t1delete.c b/Build/source/libs/t1lib/t1delete.c new file mode 100644 index 00000000000..fea216b3222 --- /dev/null +++ b/Build/source/libs/t1lib/t1delete.c @@ -0,0 +1,362 @@ +/*-------------------------------------------------------------------------- + ----- File: t1delete.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-02 + ----- Description: This file is part of the t1-library. It contains + functions for giving free previously allocated + memory areas and similar things. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1DELETE_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> + + +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" + +#include "t1types.h" +#include "t1extern.h" +#include "t1delete.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1base.h" + + + +/* T1_DeleteSize(): Gives back all the memory allocated for size to the + system. If size is somewhere in the middle of a linked list of sizes, + it further takes care that the remaining list is linked in a proper + way. Function returns 0 if successful and otherwise -1*/ +int T1_DeleteSize( int FontID, float size) +{ + int i, j; + FONTSIZEDEPS *ptr, *next_ptr, *prev_ptr; + int jobs=0; + int antialias; + int level[4]={0,T1_AA_NONE,T1_AA_LOW,T1_AA_HIGH}; + + + for ( j=0; j<4; j++){ + antialias=level[j]; + /* Check if size exists; if not, return 1 */ + if ((ptr=T1int_QueryFontSize( FontID, size, antialias))!=NULL){ + /* We have to remove a size-> */ + jobs++; + /* Get pointers to structure which is before/after the structure + to be deleted in the linked list and properly relink + structures */ + next_ptr=((FONTSIZEDEPS *)ptr)->pNextFontSizeDeps; + prev_ptr=((FONTSIZEDEPS *)ptr)->pPrevFontSizeDeps; + + if ((prev_ptr==NULL)&&(next_ptr==NULL)){ + /* There's only one single size, no relink is necessary + => reset the initial pointer to indicate that no size + dependent data is available */ + pFontBase->pFontArray[FontID].pFontSizeDeps=NULL; + } + else{ + if (prev_ptr!=NULL) + /* We are at the first size of the linked list and + there are still some sizes left after removing the + current */ + prev_ptr->pNextFontSizeDeps=next_ptr; + else + pFontBase->pFontArray[FontID].pFontSizeDeps=next_ptr; + if (next_ptr!=NULL) + /* We are at the end of an list of at least two sizes: */ + next_ptr->pPrevFontSizeDeps=prev_ptr; + } + + /* Now, that the list is properly linked, free the memory used by size: */ + /* Free the bitmaps memory: */ + for (i=0; i<256; i++) + if (ptr->pFontCache[i].bits) + free(ptr->pFontCache[i].bits); + + /* Free memory for glyphs: */ + free(ptr->pFontCache); + /* Free the structure itself: */ + free(ptr); + /* Print log: */ + sprintf( err_warn_msg_buf, "Size %f deleted for FontID %d (antialias=%d)", + size, FontID, antialias); + T1_PrintLog( "T1_DeleteSize()", err_warn_msg_buf, T1LOG_STATISTIC); + } + } + + /* Return the appropriate value */ + if (jobs==0) + return(-1); + else + return(0); + +} + + +/* T1_DeleteAllSizes(): Gives back all the memory allocated for all sizes + to the system. Function returns the number of removed sizes or -1 if an + error ocurred. */ +int T1_DeleteAllSizes( int FontID) +{ + int sizecount; + float currsize; + + FONTSIZEDEPS *ptr; + + if (T1_CheckForFontID(FontID)!=1) + return(-1); + + /* Start deleting at the end of the linked list: */ + sizecount=0; + if ((ptr=T1int_GetLastFontSize( FontID))==NULL){ + /* There has not been any size dependent data: */ + return(0); + } + + while (((ptr=T1int_GetLastFontSize(FontID)) != NULL)){ + currsize=ptr->size; + T1_DeleteSize( FontID, currsize); + sizecount++; + + } + + return(sizecount); +} + + +/* T1_FreeGlyph(): Gives the memory used by a glyph back to the system. */ +int T1_FreeGlyph( GLYPH *glyph) +{ + if (glyph!=NULL) { + if (glyph->bits!=NULL) { + free(glyph->bits); + } + free(glyph); + } + return(0); +} + + +/* T1_FreeCompCharData(): Return emory used by a composite character + data information structure to the system */ +int T1_FreeCompCharData( T1_COMP_CHAR_INFO *cci) +{ + + if (cci!=NULL) { + if (cci->pieces!=NULL) { + free( cci->pieces); + } + free( cci); + } + return( 0); +} + + +/* T1_DeleteFont(): Gives all memory used by a font back to the system. + If the font is successfully deinstalled 0 is returned. A positive value + indicates an error. */ +int T1_DeleteFont( int FontID) +{ + + int result; + + + if (T1_CheckForFontID(FontID)==-1){ /* Invalid ID */ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + if (T1_CheckForFontID(FontID)==0) /* Font is not loaded */ + return(0); + + /* Memory freeing must be done hierachical, start with size dependent + data: */ + result=T1_DeleteAllSizes(FontID); + + /* Next we delete the AFM-mapping tables */ + if (pFontBase->pFontArray[FontID].pEncMap!=NULL) + free( pFontBase->pFontArray[FontID].pEncMap); + if (pFontBase->pFontArray[FontID].pKernMap!=NULL) + free( pFontBase->pFontArray[FontID].pKernMap); + + /* We do not touch the file name because this is only to be done by + T1_CloseLib(): */ + + /* The Type-1 area and tyhe AFM-area may only be free'ed, if the + font is a "physical" font and if its reference counter is 1, or + if it is a logical font. Otherwise, other logical font use this + physical one and it may not be free'ed. In this case, return the + number of logical fonts which refer to this physical font. */ + if ((pFontBase->pFontArray[FontID].physical==1)&& + (pFontBase->pFontArray[FontID].refcount==1)){ + /* Now handle the type 1 data: */ + if (pFontBase->pFontArray[FontID].pType1Data!=NULL){ + /* First: VM, which includes CharStrings, Private, .... */ + free(pFontBase->pFontArray[FontID].vm_base); + /* .. then the struct itself: */ + free(pFontBase->pFontArray[FontID].pType1Data); + pFontBase->pFontArray[FontID].pType1Data=NULL; + } + + /* afm-data is yet there -> */ + if (pFontBase->pFontArray[FontID].pAFMData!=NULL){ + result=FreeAFMData(pFontBase->pFontArray[FontID].pAFMData); + pFontBase->pFontArray[FontID].pAFMData=NULL; + } + } + else{ + if (pFontBase->pFontArray[FontID].physical==1){ + /* font is physical and is referred to by other fonts -> + Do nothing further and return number of references: */ + + return(pFontBase->pFontArray[FontID].refcount - 1); + } + } + + /* If we get here and the font is logical, we have to + decrement the refcount of the referred physical font */ + if (pFontBase->pFontArray[FontID].physical==0){ + pFontBase->pFontArray[pFontBase->pFontArray[FontID].refcount].refcount--; + } + + + /* Set remaining area explicitly to 0 (all but pFontFileName and + pAfmFileName!) */ + pFontBase->pFontArray[FontID].pAFMData=NULL; + pFontBase->pFontArray[FontID].pType1Data=NULL; + pFontBase->pFontArray[FontID].pEncMap=NULL; + pFontBase->pFontArray[FontID].pKernMap=NULL; + pFontBase->pFontArray[FontID].pFontEnc=NULL; + pFontBase->pFontArray[FontID].pFontSizeDeps=NULL; + pFontBase->pFontArray[FontID].vm_base=NULL; + pFontBase->pFontArray[FontID].FontMatrix[0]=0.0; + pFontBase->pFontArray[FontID].FontMatrix[1]=0.0; + pFontBase->pFontArray[FontID].FontMatrix[2]=0.0; + pFontBase->pFontArray[FontID].FontMatrix[3]=0.0; + pFontBase->pFontArray[FontID].FontTransform[0]=0.0; + pFontBase->pFontArray[FontID].FontTransform[1]=0.0; + pFontBase->pFontArray[FontID].FontTransform[2]=0.0; + pFontBase->pFontArray[FontID].FontTransform[3]=0.0; + pFontBase->pFontArray[FontID].slant=0.0; + pFontBase->pFontArray[FontID].extend=0.0; + pFontBase->pFontArray[FontID].UndrLnPos=0.0; + pFontBase->pFontArray[FontID].UndrLnThick=0.0; + pFontBase->pFontArray[FontID].OvrLnPos=0.0; + pFontBase->pFontArray[FontID].OvrLnThick=0.0; + pFontBase->pFontArray[FontID].OvrStrkPos=0.0; + pFontBase->pFontArray[FontID].OvrStrkThick=0.0; + pFontBase->pFontArray[FontID].physical=0; + pFontBase->pFontArray[FontID].refcount=0; + pFontBase->pFontArray[FontID].space_position=0; + pFontBase->pFontArray[FontID].info_flags=0; + + return(0); + +} + + + +/* FreeAFMData(): Give all memory used by afm-Information back to the + system. */ +int FreeAFMData( FontInfo *pAFMData) +{ + if (pAFMData != NULL){ + if (pAFMData->gfi != NULL){ + free(pAFMData->gfi->afmVersion); pAFMData->gfi->afmVersion = NULL; + free(pAFMData->gfi->fontName); pAFMData->gfi->fontName = NULL; + free(pAFMData->gfi->fullName); pAFMData->gfi->fullName = NULL; + free(pAFMData->gfi->familyName); pAFMData->gfi->familyName = NULL; + free(pAFMData->gfi->weight); pAFMData->gfi->weight = NULL; + free(pAFMData->gfi->version); pAFMData->gfi->version = NULL; + free(pAFMData->gfi->notice); pAFMData->gfi->notice = NULL; + free(pAFMData->gfi->encodingScheme); pAFMData->gfi->encodingScheme = NULL; + free(pAFMData->gfi); pAFMData->gfi = NULL; + } + + if (pAFMData->cwi != NULL){ + free(pAFMData->cwi); pAFMData->cwi = NULL; + } + + if (pAFMData->cmi != NULL){ + int i = 0; + CharMetricInfo *temp = pAFMData->cmi; + Ligature *node = temp->ligs; + for (i = 0; i < pAFMData->numOfChars; ++i){ + for (node = temp->ligs; node != NULL; node = node->next){ + free(node->succ); node->succ = NULL; + free(node->lig); node->lig = NULL; + } + free(temp->name); temp->name = NULL; + temp++; + } + free(pAFMData->cmi); pAFMData->cmi = NULL; + } + + if (pAFMData->tkd != NULL){ + free(pAFMData->tkd); pAFMData->tkd = NULL; + } + + if (pAFMData->pkd != NULL){ + int i = 0; + for (i = 0; i < pAFMData->numOfPairs; ++i){ + free(pAFMData->pkd[i].name1); pAFMData->pkd[i].name1 = NULL; + free(pAFMData->pkd[i].name2); pAFMData->pkd[i].name2 = NULL; + } + free(pAFMData->pkd); pAFMData->pkd = NULL; + } + + if (pAFMData->ccd != NULL){ + int i = 0, j = 0; + CompCharData *ccd = pAFMData->ccd; + for (i = 0; i < pAFMData->numOfComps; ++i){ + for (j = 0; j < ccd[i].numOfPieces; ++j){ + free(ccd[i].pieces[j].pccName); + ccd[i].pieces[j].pccName = NULL; + } + free(ccd[i].ccName); ccd[i].ccName = NULL; + } + free(pAFMData->ccd); pAFMData->ccd = NULL; + } + free(pAFMData); + } + return(0); + +} + diff --git a/Build/source/libs/t1lib/t1delete.h b/Build/source/libs/t1lib/t1delete.h new file mode 100644 index 00000000000..62c42aac818 --- /dev/null +++ b/Build/source/libs/t1lib/t1delete.h @@ -0,0 +1,49 @@ +/*-------------------------------------------------------------------------- + ----- File: t1delete.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-06-03 + ----- Description: This file is part of the t1-library. It contains + functions for setting characters and strings of + characters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1DELETE_C + +int T1_DeleteSize( int FontID, float size); +int T1_DeleteAllSizes( int FontID); +int T1_FreeGlyph( GLYPH *glyph); +int T1_FreeCompCharData( T1_COMP_CHAR_INFO *cci); +int T1_DeleteFont( int FontID); +int FreeAFMData( FontInfo *pAFMData); + +#else + +extern int T1_DeleteSize( int FontID, float size); +extern int T1_DeleteAllSizes( int FontID); +extern int T1_FreeGlyph( GLYPH *glyph); +extern int T1_FreeCompCharData( T1_COMP_CHAR_INFO *cci); +extern int T1_DeleteFont( int FontID); +extern int FreeAFMData( FontInfo *pAFMData); + +#endif + + diff --git a/Build/source/libs/t1lib/t1enc.c b/Build/source/libs/t1lib/t1enc.c new file mode 100644 index 00000000000..4e3ec2aa717 --- /dev/null +++ b/Build/source/libs/t1lib/t1enc.c @@ -0,0 +1,807 @@ +/*-------------------------------------------------------------------------- + ----- File: t1enc.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-05 + ----- Description: This file is part of the t1-library. It contains + functions encoding handling at runtime. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1ENC_C + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <ctype.h> + + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1enc.h" +#include "t1env.h" +#include "t1base.h" +#include "t1finfo.h" + + +static char defaultencodingname[]="Unspecified"; + +/* This struct is retunred by the tokenizer. It contains indices + in linebuf for the first and the last character in a token */ +typedef struct +{ + int first; + int last; +} CNTOKEN; + + + +/* ScanForWord(): Tokenizer for ScanEncodingFile. + + - and return the first and last index in linebuf of the token + + - skips whitespace and comments + + - the vector marks [ and ] are considered token-delimiters + and also treated as independent tokens + + - the literal escape char "/" is also considered as a token + delimiter but is not returned as a token. + + This function leaves linebuf unmodified so that in case of a + failure, TryT1LibEncoding() will receive a clean buffer! */ +static CNTOKEN *ScanForWord( char *lb, int size) +{ + static int i=-1; + int j; + int comment; + + static CNTOKEN currtoken={-1,-1}; + + /* Reset tokenizer */ + if (lb==NULL) { + i=-1; + currtoken.first=-1; + currtoken.last=-1; + return NULL; + } + + comment=0; + j=-1; + + while (++i<size) { + + /* Inside word */ + if (j!=-1) { + /* Whitespace, comment, mark or literal ends word */ + if ( (lb[i]=='%') || + (lb[i]=='[') || + (lb[i]==']') || + (lb[i]=='/') || + isspace((int)lb[i]) ) { + currtoken.last=i-1; + if ( (lb[i]=='[') || + (lb[i]==']') || + (lb[i]=='/') ) { + i--; + } + return &currtoken; + } + /* End not found, try next char */ + continue; + } + + /* first, check for special tokens */ + if ( ( (lb[i]=='[') || (lb[i]==']')) ) { + currtoken.first=i; + currtoken.last=i; + return &currtoken; + } + + /* Inside coment */ + if (comment) { + if (lb[i]=='\n') + comment=0; + continue; + } + if (lb[i]=='%') { + comment=1; + continue; + } + + /* **Whitespace */ + if (isspace((int)lb[i])) + continue; + + /* **Something else => word */ + if (j==-1) { + j=i; + currtoken.first=j; + continue; + } + } + + /* We're at the end of the buffer. Do we have a word? */ + if (j!=-1) { + currtoken.last=i-1; + return &currtoken; + } + + /* We have nothing */ + return NULL; +} + + +/* tokcpy(): Copy a token from linebuf and append \0 */ +static char *tokcpy( char *dest, const char *src, + int first, int last) +{ + /* we do not do any range or error checking in this function */ + memcpy( dest, &(src[first]), last-first+1); + dest[last-first+1]='\0'; + return dest; +} + + +/* TryDVIPSEncoding(): Try to read an encoding file conforming to the + dvips specification. The file's contents is expected in a buffer + "linebuf" of size "filesize". Function returns the actual size of the + charnames memory or -1. */ +static int TryDVIPSEncoding( char *linebuf, int filesize, char *charnames) +{ + + char token[256]; + char *encname; + int charname_count=0; + int k=0; + CNTOKEN *currtokenP; + + + /* Initialize tokenizer */ + currtokenP=ScanForWord( NULL, filesize); + + + currtokenP=ScanForWord(linebuf,filesize); + if ( (currtokenP!=NULL) && + (linebuf[currtokenP->first]=='/')) { + /* / indicates start of postscript string literal, so this + could be a postscript .enc file */ + if ((encname=(char *)malloc( (currtokenP->last - currtokenP->first + 1 + 1) * + sizeof( char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return -1; + } + else { + /* store encoding name */ + if (currtokenP->first==currtokenP->last) { + /* PostScript encoding requires an identifier + so this does not seem to be a valid encoding file */ + free( encname); + return( -1); + } + tokcpy( encname, linebuf, currtokenP->first+1, currtokenP->last); + + } + + + /* Next, the PostScript "mark" character is expected */ + if ( ((currtokenP=ScanForWord(linebuf,filesize))!=NULL) && + (currtokenP->first==currtokenP->last) && + (linebuf[currtokenP->first]!='[') ) { + /* Since we got up to here, there is a certain probability that + we have a PostScript encoding definition, but with invalid + syntax. So put log message. */ + sprintf( err_warn_msg_buf, + "Expected encoding definition after %s, but did not find \"[\"-character", + encname); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + if (encname!=NULL) + free( encname); + return( -1); + } + + /* now, try to read 256 literal character names. We do not check + for charname count because this would bypass error checking. */ + while((currtokenP=ScanForWord(linebuf,filesize))!=NULL) { + + /* End of vector operator? */ + if ( (currtokenP->first==currtokenP->last) && /* one character? */ + (linebuf[currtokenP->first]==']')) { + break; + } + /* We drop the escape character if it is present. However, + non-literal name specifications are not allowed in + encoding vectors. */ + if (linebuf[currtokenP->first]!='/') { + sprintf( err_warn_msg_buf, + "Found non-literal name (c=%c (first=%d, last=%d)) at slot %d while scanning encoding vector %s.", + linebuf[currtokenP->first], + currtokenP->first, currtokenP->last, + charname_count, encname); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + if (encname!=NULL) + free( encname); + return( -1); + } + else { + /* OK, first char in token is "/". Does there follow a name? */ + if ( currtokenP->first==currtokenP->last) { + sprintf( err_warn_msg_buf, + "Empty literal name at slot %d while scanning encoding vector %s.", + charname_count, encname); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + if (encname!=NULL) + free( encname); + return( -1); + } + } + + /* We seem to have a valid name -> copy name to *charnames-array */ + tokcpy( &(charnames[k]), linebuf, + currtokenP->first+1, currtokenP->last); + k+=currtokenP->last-currtokenP->first+1; /* note: we have omitted "/"! */ + /* Increment character counter */ + charname_count++; + /* set index to start of next word/line */ + } /* end of loop scanning character names */ + + if (currtokenP==NULL) { + /* In this case loop has been stopped because buffer end has been + reached. Since we did not alreay read the ]-character, this is + an error condition. */ + sprintf( err_warn_msg_buf, + "Premature end of encoding definition encountered." ); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + free(encname); + return( -1); + } + /* Since the above loop has not been finished due to a NULL-ptr, + the token ] must have been encountered. Thus, read ahead and look + for def: */ + if ((currtokenP=ScanForWord(linebuf,filesize))==NULL) { + sprintf( err_warn_msg_buf, + "Premature end of encoding definition encountered."); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + free(encname); + return( -1); + } + + if (strcmp(tokcpy( &(charnames[k]), linebuf, + currtokenP->first, currtokenP->last), "def")!=0) { + /* we store the current token in charnames only temporarily, so we + do not increment k! */ + sprintf( err_warn_msg_buf, + "Closing token \"def\" expected but found \"%s\".", + &(charnames[k])); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + free(encname); + return( -1); + } + /* Encoding definition is complete. we do not allow any further tokens + except comments. */ + if ((currtokenP=ScanForWord(linebuf,filesize))!=NULL) { + tokcpy( token, linebuf, currtokenP->first, currtokenP->last); + sprintf( err_warn_msg_buf, + "Token \"%s\" after closing \"def\" in successfully scanned encoding file makes encoding definition file invalid", token); + T1_PrintLog( "TryDVIPSEncoding()", err_warn_msg_buf, T1LOG_WARNING); + free(encname); + return( -1); + } + + /* we allow less than 256 character names. The missing ones are filled + now with .notdef */ + for ( ; charname_count<256; charname_count++) { + tokcpy( &(charnames[k]), ".notdef", 0, 6); + k+=8; + } + + /* Append the string for the encoding's name */ + strcpy( &(charnames[k]), encname); + k +=strlen(encname)+1; + + free(encname); + + return( k); + + } /* file does not start with / -> no dvips-encoding file */ + + return( -1); + +} + + + +/* TryT1LibEncoding(): Try to read an encoding file conforming to the + t1lib specification. The file's contents is expected in a buffer + "linebuf" of size "filesize". Function returns the actual size of the + charnames memory or -1. */ +static int TryT1LibEncoding( char *linebuf, int filesize, char *charnames) +{ + int i=0, j=0, k=0, l=0; + + char save_char; + int charname_count=0; + + while(i<filesize){ + j=i; /* Save index of beginning of line */ + while ( (i<filesize) && + (isspace((int)linebuf[i])==0) ) + i++; + if (i==filesize) + continue; /* this will leave this loop */ + save_char=linebuf[i]; + linebuf[i]=0; /* replace ' ' by ASCII-0 */ + if (strncmp( "Encoding=", &linebuf[j], strlen("Encoding="))==0) { + /* We save the current file position to read the encoding name + later */ + l=j+strlen("Encoding="); + /* set index to start of next line */ + if (save_char=='\n') + i++; + else { + while ( (i<filesize) && + (linebuf[i]!='\n') ) + i++; + if (i==filesize) + continue; /* this will leave this loop */ + i++; + } + /* keyword found => now, 256 lines should follow, each + specifying a character name and optionally some comment + to enhance readability: */ + break; + } + i++; + } + + + while((i<filesize) && (charname_count<256)){ + j=i; /* Save index of beginning of line */ + while ( (i<filesize) && + (isspace((int)linebuf[i])==0)) + i++; + if (i==filesize) + continue; /* this will leave this loop */ + save_char=linebuf[i]; + linebuf[i]=0; /* replace whitespace by ASCII-0 */ + /* Copy Name to *char_names-array */ + while (linebuf[j]) + charnames[k++]=linebuf[j++]; + /* Append ASCII-0 */ + charnames[k++]=linebuf[j++]; + /* set index to start of next line */ + if (save_char=='\n') + i++; + else { + while ( (i<filesize) && + (linebuf[i]!='\n')) + i++; + if (i==filesize) + continue; /* this will leave this loop */ + i++; + } + /* Increment character counter */ + charname_count++; + } + + /* Check if exactly 256 characters have been defined, if not, + return NULL: */ + if (charname_count!=256){ + return( -1); + } + + /* Append the string for the encoding's name */ + i=l; + while (isspace((int)linebuf[i])==0 && linebuf[i]!='\0'){ + charnames[k++]=linebuf[i++]; + } + + if (i==l){ + strcpy(&(charnames[k]), defaultencodingname); + k +=strlen(defaultencodingname+1); + charnames[k++]='\0'; + } + else{ + charnames[k++]='\0'; + } + + return( k); + +} + + + +/* ScanEncodingFile(): Read an encoding file of an appropriate format + and prepare the read data for usage with the type1 rasterizer, i.e. + generate an array char *enc[257]. Return the pointer to the data area + or NULL in case of an error. + */ +static char **ScanEncodingFile( char *FileName) +{ + + char *linebuf; + char **encoding; /* charnames array */ + char *charnames=NULL; /* charnames memory */ + + int cnsize; /* size of charnames memory, this will be + set from the Try...() function */ + + FILE *enc_fp; + int filesize; + int i=0, j=0; + + if ((enc_fp=fopen( FileName,"rb"))==NULL){ + T1_errno=T1ERR_FILE_OPEN_ERR; + return(NULL); /* file could not be opened + => no encoding read */ + } + + + /* enc_fp points now to a (hopefully) valid encoding file */ + /* Get the file size */ + fseek( enc_fp, 0, SEEK_END); + filesize=ftell(enc_fp); + /* Reset fileposition to start */ + fseek( enc_fp, 0, SEEK_SET); + + if ((linebuf=(char *)calloc( filesize, + sizeof(char)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + /* Allocate space for character names, assume the worst case and realloc + later. The DVIPS-parser requires one more char in order to work properly */ + if ((charnames=(char *)calloc( filesize + strlen(defaultencodingname+1), + sizeof(char)))==NULL){ + free( linebuf); + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + fread((char *)linebuf, sizeof(char), filesize, enc_fp); + fclose(enc_fp); + + + /* file is read. Operate now on the buffer. */ + + + /* try dvips encoding file */ + cnsize=TryDVIPSEncoding( linebuf, filesize, charnames); + if ( cnsize>-1) { + /* a debug message to log file */ + sprintf( err_warn_msg_buf, + "Scanned file %s (%d bytes) as dvips-encoding file.", + FileName, filesize); + T1_PrintLog( "ScanEncodingFile()", err_warn_msg_buf, T1LOG_DEBUG); + } + else { + /* try t1lib encoding file */ + cnsize=TryT1LibEncoding( linebuf, filesize, charnames); + if ( cnsize>-1) { + /* write a debug message to log file */ + sprintf( err_warn_msg_buf, + "Scanned file %s (%d bytes) as t1lib-encoding file.", + FileName, filesize); + T1_PrintLog( "ScanEncodingFile()", err_warn_msg_buf, T1LOG_DEBUG); + } + else { + /* write a warning message because loading encoding + entirely failed */ + sprintf( err_warn_msg_buf, + "Scanning file %s (%d bytes) as encoding file failed.", + FileName, filesize); + T1_PrintLog( "ScanEncodingFile()", err_warn_msg_buf, T1LOG_WARNING); + } + } + + if ( cnsize<0) { + T1_errno=T1ERR_SCAN_ENCODING; + if ( charnames!=NULL) { + free(charnames); + } + free(linebuf); + return( NULL); + } + + + /* cnsize contains the size of the charnames' memory, so let's + now realloc charnames */ + charnames=(char *)realloc( charnames, cnsize*sizeof(char)); + /* Now initialize the array with the start-addresses of the character + name strings */ + /* We alloc 257 to save the encoding's name at the 257th entry */ + if ((encoding=(char **)malloc(257*sizeof(char *)))==NULL) { + if ( charnames!=NULL) { + free(charnames); + } + free(linebuf); + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + while (i<257) { + encoding[i]=&charnames[j]; + while (charnames[j]) + j++; + j++; + i++; + } + + free( linebuf); + return(encoding); + +} + + + +/* T1_LoadEncoding(): Load an encoding file to have a new encoding + available. If successful, the pointer to the encoding array is + returned. In case of an error, the return value is NULL. + */ +char **T1_LoadEncoding( char *FileName) +{ + char **Encoding; + char *EncFileName; + + if( FileName==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + if ((EncFileName=intT1_Env_GetCompletePath( FileName, T1_ENC_ptr))==NULL){ + T1_errno=T1ERR_FILE_OPEN_ERR; + return(NULL); + } + Encoding=ScanEncodingFile(EncFileName); + free(EncFileName); + + return(Encoding); +} + + + +/* T1_DeleteEncoding() free a previously loaded encoding */ +int T1_DeleteEncoding( char **encoding) +{ + if (encoding){ + /* First free character names memory */ + free( encoding[0]); + /* then, free pointer array */ + free( encoding); + } + return(0); + +} + + + +/* T1_ReencodeFont(): Assign a new encoding to an existent font. This is + only allowed if no size dependent data exists for the font in question. + Moreover, the font must be loaded already since must get the position + of the space-character. Function returns 0 if successful, and -1 otherwise. + */ +int T1_ReencodeFont( int FontID, char **Encoding) +{ + int i, j, k, l, m; + char *charname; + PairKernData *pkd; + METRICS_ENTRY *kern_tbl; + int char1, char2; + + + /* First, check for valid font ID residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + /* Second, check whether size-dependent data exists: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pFontBase->pFontArray[FontID].pFontEnc=Encoding; + + + /* We have to update the space_position-entry in the FONTPRIVATE. + If space is not found (not encoded), set it to -1: */ + pFontBase->pFontArray[FontID].space_position=-1; + i=0; + if (Encoding){ /* external encoding */ + while (i<256){ + if (strcmp( (char *)pFontBase->pFontArray[FontID].pFontEnc[i], + "space")==0){ + /* space found at position i: */ + pFontBase->pFontArray[FontID].space_position=i; + break; + } + i++; + } + } + else{ /* reencoding to internal encoding */ + while (i<256){ + if (strcmp( (char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[i].data.arrayP, + "space")==0){ + /* space found at position i: */ + pFontBase->pFontArray[FontID].space_position=i; + break; + } + i++; + } + } + + /* Now update afm index mapping: */ + if (pFontBase->pFontArray[FontID].pAFMData != NULL){ + for (i=0; i<256; i++) { + charname=T1_GetCharName( FontID, i); + /* in a first loop check for ordinary characters */ + for ( j=0; j<pFontBase->pFontArray[FontID].pAFMData->numOfChars; j++) { + if (strcmp( charname, + pFontBase->pFontArray[FontID].pAFMData->cmi[j].name)==0) { + pFontBase->pFontArray[FontID].pEncMap[i]=j+1; /* index 0 is reserved! */ + continue; + } + } + /* if nothing has been found, check for composite characters */ + for ( j=0; j<pFontBase->pFontArray[FontID].pAFMData->numOfComps; j++) { + if (strcmp( charname, + pFontBase->pFontArray[FontID].pAFMData->ccd[j].ccName)==0) { + pFontBase->pFontArray[FontID].pEncMap[i]=-(j+1); /* index 0 is reserved! */ + /* Note: Metrics of composite characters already exist so that there is + no need to recalculate them! */ + continue; + } + } + } + /* Update kerning table */ + pFontBase->pFontArray[FontID].KernMapSize=0; + k=pFontBase->pFontArray[FontID].pAFMData->numOfPairs; + if (k>0){ /* i.e., there are any pairs */ + /* OK, it does not suffice to alloc numOfPairs METRICS_ENTRYs, because + a given character might be encoded at several locations and kerning + should still work. As a worst case estimation, we allocate 256^2 + and realloc later. */ + if ((pFontBase->pFontArray[FontID].pKernMap= + (METRICS_ENTRY *)malloc( (256*256) *sizeof( METRICS_ENTRY)))==NULL){ + sprintf( err_warn_msg_buf, "Error allocating memory for metrics map (FontID=%d)", + FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + kern_tbl=pFontBase->pFontArray[FontID].pKernMap; + pkd=pFontBase->pFontArray[FontID].pAFMData->pkd; + j=0; + for ( i=0; i<k; i++) { + /* We do not check T1_GetEncodingIndices() against the return value + NULL because we just loading the font in question: */ + l=0; + while ((char1=(T1_GetEncodingIndices( FontID, pkd[i].name1))[l++])!=-1) { + /* pair could be relevant in current encoding */ + m=0; + while ((char2=(T1_GetEncodingIndices( FontID, pkd[i].name2))[m++])!=-1) { + /* Since we get here we have a relevant pair --> + Put char1 in higher byte and char2 in LSB: */ + kern_tbl[j].chars=(char1 << 8) | char2; + /* We only make use of horizontal kerning */ + kern_tbl[j].hkern=pkd[i].xamt; + j++; + } /* while (char2) */ + } /* while (char1) */ + } /* for */ + /* We are done, realloc memory: */ + kern_tbl=(METRICS_ENTRY*) realloc( kern_tbl, j*sizeof(METRICS_ENTRY)); + /* We now sort the kerning array with respect to char indices */ + qsort( kern_tbl, (size_t) j, sizeof(METRICS_ENTRY), + &cmp_METRICS_ENTRY ); + /* Finally write back pointer for the case that realloc changed the + pointer */ + pFontBase->pFontArray[FontID].pKernMap=kern_tbl; + pFontBase->pFontArray[FontID].KernMapSize=j; + } + else { + pFontBase->pFontArray[FontID].pKernMap=NULL; + } + } + return(0); +} + + + +/* T1_SetDefaultEncoding(): Set the default encoding vector that's + used when fonts are loaded. + */ +int T1_SetDefaultEncoding( char **encoding) +{ + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pFontBase->default_enc=encoding; + return(0); +} + + +/* T1_GetEncodingScheme(): Get the name associated with the current + encoding vector of font FontID */ +char *T1_GetEncodingScheme( int FontID) +{ + + static char enc_scheme[256]; + + /* First, check for valid font ID residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + if (pFontBase->pFontArray[FontID].pFontEnc==NULL){ + if (pFontBase->pFontArray[FontID].info_flags & USES_STANDARD_ENCODING){ + strcpy( enc_scheme, "StandardEncoding"); + } + else { + strcpy( enc_scheme, "FontSpecific"); + } + } + else + strcpy( enc_scheme, pFontBase->pFontArray[FontID].pFontEnc[256]); + + return(enc_scheme); + +} + + +/* A function for comparing METRICS_ENTRY structs */ +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2) +{ + if (((METRICS_ENTRY *)entry1)->chars < + ((METRICS_ENTRY *)entry2)->chars) + return(-1); + if (((METRICS_ENTRY *)entry1)->chars > + ((METRICS_ENTRY *)entry2)->chars) + return(1); + return(0); /* This should not happen */ +} + diff --git a/Build/source/libs/t1lib/t1enc.h b/Build/source/libs/t1lib/t1enc.h new file mode 100644 index 00000000000..df9a07ad95f --- /dev/null +++ b/Build/source/libs/t1lib/t1enc.h @@ -0,0 +1,47 @@ +/*-------------------------------------------------------------------------- + ----- File: t1enc.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-06-16 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t11enc.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1ENC_C + +static char **ScanEncodingFile( char *FileName); +char **T1_LoadEncoding( char *FileName); +int T1_DeleteEncoding( char **encoding); +int T1_ReencodeFont( int FontID, char **Encoding); +int T1_SetDefaultEncoding( char **encoding); +char *T1_GetEncodingScheme( int FontID); +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2); + +#else + +extern char **T1_LoadEncoding( char *FileName); +extern int T1_DeleteEncoding( char **encoding); +extern int T1_ReencodeFont( int FontID, char **Encoding); +extern int T1_SetDefaultEncoding( char **encoding); +extern char *T1_GetEncodingScheme( int FontID); + +#endif + diff --git a/Build/source/libs/t1lib/t1env.c b/Build/source/libs/t1lib/t1env.c new file mode 100644 index 00000000000..282b68b339a --- /dev/null +++ b/Build/source/libs/t1lib/t1env.c @@ -0,0 +1,1044 @@ +/*-------------------------------------------------------------------------- + ----- File: t1env.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-11-27 + ----- Description: This file is part of the t1-library. It implements + the reading of a configuration file and path-searching + of type1-, afm- and encoding files. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#define T1ENV_C + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <ctype.h> + + +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/fontmisc.h" + +#include "sysconf.h" +#include "t1types.h" +#include "t1extern.h" +#include "t1env.h" +#include "t1misc.h" +#include "t1base.h" + + +/* The following static variables are used to store information on the distinct + file search paths: + + -1 t1lib has not yet been initialized! + 0 t1lib has been initialized and default paths have been setup + n (>0) there are n path elements for current search path type, either built + from a FontDataBase file or from explicit fucntion calls. +*/ + +static int pfab_no=-1; +static int afm_no=-1; +static int enc_no=-1; +static int fdb_no=-1; + +static char path_sep_char='\0'; +static char path_sep_string[2]; + +static char pathbuf[2048]; + +/* Define some default search paths */ +#ifndef VMS +static char T1_pfab[]="."; +static char T1_afm[]="."; +static char T1_enc[]="."; +#else +static char T1_pfab[]="sys$disk:[]"; +static char T1_afm[]="sys$disk:[]"; +static char T1_enc[]="sys$disk:[]"; +#endif +char T1_fdb[]="FontDataBase"; + + +/* keywords recognized in config file */ +static const char enc_key[]="ENCODING"; +static const char pfab_key[]="TYPE1"; +static const char afm_key[]="AFM"; +static const char fdb_key[]="FONTDATABASE"; + + +/* qstrncpy(): Copy bytes from srcP to to destP. srcP is count bytes long + and destP is the number of quoted characters shorter. That is, count + refers to the number of characters including the escapement chars in + srcP! */ +static void qstrncpy( char *destP, const char *srcP, long nochars) +{ + long i; + long j; + + i=0; /* dest-index */ + j=0; /* src-index */ + + while (j<nochars) { + if (srcP[j]=='\\') { + if (srcP[j+1]=='"') { + j++; /* escaped quotation character --> omit escape char. */ + } + } + else { /* normal character */ + destP[i++]=srcP[j++]; + } + } +} + + + + +/* Setup the default paths for searching the distinct file types. If + paths have been setup explicitly, skip the step of setting up a default path. */ +void intT1_SetupDefaultSearchPaths( void) +{ + + path_sep_char=PATH_SEP_CHAR; + sprintf( path_sep_string, "%c", path_sep_char); + + /* We set the number of stored path elements 0 so that we can distiguish + between explicitly setup paths and default paths in intT1_ScanConfigFile(). */ + if (pfab_no==-1) { + T1_PFAB_ptr=(char**) calloc( 2, sizeof(char*)); + T1_PFAB_ptr[0]=(char*)malloc(strlen(T1_pfab)+1); + strcpy(T1_PFAB_ptr[0],T1_pfab); + pfab_no=0; + } + + if (afm_no==-1) { + T1_AFM_ptr=(char**) calloc( 2, sizeof(char*)); + T1_AFM_ptr[0]=(char*)malloc(strlen(T1_afm)+1); + strcpy(T1_AFM_ptr[0],T1_afm); + afm_no=0; + } + + if (enc_no==-1) { + T1_ENC_ptr=(char**) calloc( 2, sizeof(char*)); + T1_ENC_ptr[0]=(char*)malloc(strlen(T1_enc)+1); + strcpy(T1_ENC_ptr[0],T1_enc); + enc_no=0; + } + + if (fdb_no==-1) { + T1_FDB_ptr=(char**) calloc( 2, sizeof(char*)); + T1_FDB_ptr[0]=(char*)malloc(strlen(T1_fdb)+1); + strcpy(T1_FDB_ptr[0],T1_fdb); + fdb_no=0; + } +} + + +/* This function is called from T1_CloseLib(). We have to indicate the state + of a non-initialzed t1lib! */ +void intT1_FreeSearchPaths( void) +{ + int i; + + i=0; + if (T1_PFAB_ptr!=NULL) { + while (T1_PFAB_ptr[i]!=NULL) { + free(T1_PFAB_ptr[i]); + T1_PFAB_ptr[i]=NULL; + } + free( T1_PFAB_ptr); + } + i=0; + if (T1_AFM_ptr!=NULL) { + while (T1_AFM_ptr[i]!=NULL) { + free(T1_AFM_ptr[i]); + T1_AFM_ptr[i]=NULL; + } + free( T1_AFM_ptr); + } + i=0; + if (T1_ENC_ptr!=NULL) { + while (T1_ENC_ptr[i]!=NULL) { + free(T1_ENC_ptr[i]); + T1_ENC_ptr[i]=NULL; + } + free( T1_ENC_ptr); + } + i=0; + if (T1_FDB_ptr!=NULL) { + while (T1_FDB_ptr[i]!=NULL) { + free(T1_FDB_ptr[i]); + T1_FDB_ptr[i]=NULL; + } + free( T1_FDB_ptr); + } + /* indicate t1lib non-initialized */ + pfab_no=-1; + afm_no=-1; + enc_no=-1; + fdb_no=-1; + + return; +} + + +/* ScanConfigFile(): Read a configuration file and scan and save the + environment strings used for searching pfa/pfb-, afm- and encoding + files as well as the name of the font database file. */ +int intT1_ScanConfigFile( void) +{ + + char *env_str; + char *linebuf; + char *usershome; + char *cnffilepath; + char *globalcnffilepath; + static int linecnt; + char local_path_sep_char; + int quoted=0; + int quotecnt=0; + FILE *cfg_fp; + int filesize, i, j, k; + int ignoreline=0; + + char*** destP=NULL; + int *idestP=NULL; + char* curr_key=NULL; + + /* First, get the string stored in the environment variable: */ + env_str=getenv(ENV_CONF_STRING); + linecnt=1; + + if (env_str==NULL) { + /* environment variable not set, try to open default file + in user's home directory and afterwards global config file */ + if ((usershome=getenv("HOME"))!=NULL) { + cnffilepath=(char *)malloc((strlen(usershome) + + strlen(T1_CONFIGFILENAME) + 2 + ) * sizeof(char)); + if (cnffilepath==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( cnffilepath, usershome); + } + else { + cnffilepath=(char *)malloc((strlen(T1_CONFIGFILENAME) + 2 + ) * sizeof(char)); + } + strcat( cnffilepath, DIRECTORY_SEP); + strcat( cnffilepath, T1_CONFIGFILENAME); + + globalcnffilepath=(char*)malloc((strlen(GLOBAL_CONFIG_DIR) + + strlen(GLOBAL_CONFIG_FILE) + 2 + ) * sizeof(char)); + if (globalcnffilepath==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( globalcnffilepath, GLOBAL_CONFIG_DIR); + strcat( globalcnffilepath, DIRECTORY_SEP); + strcat( globalcnffilepath, GLOBAL_CONFIG_FILE); + + if ((cfg_fp=fopen( cnffilepath, "rb"))==NULL){ + sprintf( err_warn_msg_buf, "Could not open configfile %s", + cnffilepath); + T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_STATISTIC); + /* Try global config file */ + if ((cfg_fp=fopen( globalcnffilepath, "rb"))==NULL){ + sprintf( err_warn_msg_buf, "Could not open global configfile %s", + globalcnffilepath); + T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_WARNING); + } + else{ + sprintf( err_warn_msg_buf, "Using %s as Configfile (global)", + cnffilepath); + T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_STATISTIC); + } + } + else{ + sprintf( err_warn_msg_buf, "Using %s as Configfile (user's)", + cnffilepath); + T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_STATISTIC); + } + free( cnffilepath); + free( globalcnffilepath); + if (cfg_fp==NULL){ + T1_PrintLog( "ScanConfigFile()", + "Neither user's nor global Configfile has been found", + T1LOG_WARNING); + return(0); + } + } + else { + /* open specified file for reading the configuration */ + if ((cfg_fp=fopen(env_str,"rb"))==NULL){ + T1_PrintLog( "ScanConfigFile()", + "Configfile as specified by Environment has not been found", + T1LOG_WARNING); + return(0); /* specified file could not be openend + => no config paths read */ + } + else { + sprintf( err_warn_msg_buf, "Using %s as Configfile (environment)", + env_str); + T1_PrintLog( "ScanConfigFile()", err_warn_msg_buf, T1LOG_STATISTIC); + } + } + + + /* cfg_fp points now to a valid config file */ + /* Get the file size */ + fseek( cfg_fp, 0, SEEK_END); + filesize=ftell(cfg_fp); + /* Reset fileposition to start */ + fseek( cfg_fp, 0, SEEK_SET); + + if ((linebuf=(char *)calloc( filesize+1, + sizeof(char)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + + fread((char *)linebuf, sizeof(char), filesize, cfg_fp); + fclose(cfg_fp); + + i=0; + + /* this might be overwritten on a per file basis */ + local_path_sep_char=path_sep_char; + + while(i<filesize) { + ignoreline=0; + j=i; /* Save index of beginning of line */ + while ((linebuf[i]!='=') && (linebuf[i]!='\n') && (i<filesize)) { + i++; + } + if (i==filesize) { + free( linebuf); + return(i); + } + + if (strncmp( enc_key, &linebuf[j], 8)==0) { + /* setup target */ + destP=&T1_ENC_ptr; + idestP=&enc_no; + curr_key=(char*)enc_key; + } + else if (strncmp( "TYPE1", &linebuf[j], 5)==0) { + /* setup target */ + destP=&T1_PFAB_ptr; + idestP=&pfab_no; + curr_key=(char*)pfab_key; + } + else if (strncmp( afm_key, &linebuf[j], 3)==0) { + /* setup target */ + destP=&T1_AFM_ptr; + idestP=&afm_no; + curr_key=(char*)afm_key; + } + else if (strncmp( fdb_key, &linebuf[j], 12)==0) { + /* setup target */ + destP=&T1_FDB_ptr; + idestP=&fdb_no; + curr_key=(char*)fdb_key; + } + else { + ignoreline=1; + T1_PrintLog( "ScanConfigFile()", "Ignoring line %d", + T1LOG_DEBUG, linecnt); + } + + /* If appropriate, scan this line. */ + if (ignoreline==0) { + /* Check for an explicitly assigned value */ + if (*idestP==0) { /* default paths are currently setup, get rid of them */ + free((*destP)[0]); + } + else { /* append to existing paths */ + T1_PrintLog( "ScanConfigFile()", + "Appending to existing %s search path", + T1LOG_DEBUG, curr_key); + } + while ( (!isspace((int)linebuf[i])) && (i<filesize) ) { + k=++i; /* index to current path element */ + (*idestP)++; + quotecnt=0; + if (linebuf[i]=='"') { /* We have a quoted string */ + quoted=1; + k=++i; + while ( 1) { + if ( linebuf[i]=='"' ) { /* we find a quote-char */ + if ( linebuf[i-1]!='\\' ) + break; /* not escaped --> end of path specification */ + else + quotecnt++; + } /* some other char */ + if (linebuf[i]=='\n') { /* a newline in a quoted string? Perhabs, quotes do not match! */ + T1_PrintLog( "ScanConfigFile()", + "Newline in quoted %s-string in line %d, column %d, of config file! Closing quote missing?", + T1LOG_WARNING, curr_key, linecnt, i-j+1); + j=i+1; /* resynchronize linecount */ + linecnt++; + } + if (i<filesize) { /* filesize not exceeded? */ + i++; + } + else { /* issue error msg because end of quotation is missing */ + T1_PrintLog( "ScanConfigFile()", "Unterminated quoted string in config file", + T1LOG_ERROR); + return -1; + } + } + } + else { + quoted=0; + while ( (linebuf[i]!=local_path_sep_char) && (!isspace((int)linebuf[i])) && (i<filesize) ) + i++; + } + if (((*destP)=(char**)realloc( (*destP), ((*idestP)+1)*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + if (((*destP)[(*idestP)-1]=(char*)malloc((i-k-quotecnt+1)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + if (quoted==0) { + strncpy( (*destP)[*idestP-1], &(linebuf[k]), i-k); + (*destP)[(*idestP)-1][i-k]='\0'; + } + else { + qstrncpy( (*destP)[(*idestP)-1], &(linebuf[k]), i-k); + (*destP)[(*idestP)-1][i-k-quotecnt]='\0'; + i++; /* step over closing quote */ + } + (*destP)[(*idestP)]=NULL; /* indicate end of string list */ + } + } + + /* skip remaining of line or file */ + while ((linebuf[i]!='\n')&&(i<filesize)) + i++; + i++; + linecnt++; + } + /* file should now be read in */ + free( linebuf); + + return(i); + +} + + + +/* intT1_Env_GetCompletePath( ): Get a full path name from the file specified by + argument 1 in the environment specified by argument 2. Return the pointer + to the path string or NULL if no file was found.*/ +char *intT1_Env_GetCompletePath( char *FileName, + char **env_ptr ) +{ + struct stat filestats; /* A structure where fileinfo is stored */ + int fnamelen, i, j; + char *FullPathName; + char *StrippedName; + + + if (FileName==NULL) + return(NULL); + fnamelen=strlen(FileName); + + /* We check whether absolute or relative pathname is given. If so, + stat() it and if appropriate, return that string immediately. */ + if ( (FileName[0]==DIRECTORY_SEP_CHAR) + || + ((fnamelen>1) && (FileName[0]=='.') && + (FileName[1]==DIRECTORY_SEP_CHAR)) + || + ((fnamelen>2) && (FileName[0]=='.') && + (FileName[1]=='.') && (FileName[2]==DIRECTORY_SEP_CHAR)) +#if defined(MSDOS) | defined(_WIN32) | defined (__EMX__) + || + ((isalpha(FileName[0])) && (FileName[1]==':')) +#endif +#ifdef VMS + || (strchr(FileName,':') != NULL) +#endif + ) + { + /* Check for existence of the path: */ + if (!stat( FileName, &filestats)) { + if (t1lib_log_file!=NULL) { + sprintf( err_warn_msg_buf, "stat()'ing complete path %s successful", + FileName); + T1_PrintLog( "intT1_Env_GetCompletePath()", err_warn_msg_buf, + T1LOG_DEBUG); + } + /* Return a copy of the string */ + if ((FullPathName=(char *)malloc( fnamelen + 1))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + strcpy( FullPathName, FileName); + return(FullPathName); + } + if (t1lib_log_file!=NULL){ + sprintf( err_warn_msg_buf, "stat()'ing complete path %s failed", + FileName); + T1_PrintLog( "intT1_Env_GetCompletePath()", err_warn_msg_buf, + T1LOG_DEBUG); + } + /* Trying to locate absolute path spec. failed. We try to recover + by removing the path component and searching in the remaining search + path entries. This depends on the OS. */ + i=fnamelen-1; + StrippedName=&(FileName[i]); + while ( FileName[i]!=DIRECTORY_SEP_CHAR +#if defined(VMS) + /* What exactly to do for VMS? */ +#elif defined(MSDOS) | defined(_WIN32) | defined (__EMX__) | defined(_MSC_VER) + /* We take a drive specification into account. This means we + step back until the directory separator or a drive specifier + appears! */ + && FileName[i]!=':' +#endif + ) { + i--; + } + i++; + StrippedName=&FileName[i]; + if (t1lib_log_file!=NULL){ + sprintf( err_warn_msg_buf, "path %s stripped to %s", + FileName, StrippedName); + T1_PrintLog( "intT1_Env_GetCompletePath()", err_warn_msg_buf, + T1LOG_DEBUG); + } + } + else{ /* We have a relative path name */ + StrippedName=&FileName[0]; + } + + i=0; + while (env_ptr[i]!=NULL) { + /* Copy current path element: */ + strcpy( pathbuf, env_ptr[i]); + /* cut a trailing directory separator */ + j=strlen(pathbuf); + if (pathbuf[j-1]==DIRECTORY_SEP_CHAR) + pathbuf[j--]='\0'; + /* Add the directory separator: */ +#ifdef VMS + { char *p= strrchr(pathbuf, DIRECTORY_SEP_CHAR); + if (p && *(p+1) == '\0') + *p = '\0'; + } +#endif + strcat( pathbuf, DIRECTORY_SEP); + /* And finally the filename: */ + strcat( pathbuf, StrippedName); + + /* Check for existence of the path: */ + if (!stat( pathbuf, &filestats)) { + if ((FullPathName=(char*)malloc( (j+fnamelen+2)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + strcpy( FullPathName, pathbuf); + if (t1lib_log_file!=NULL){ + sprintf( err_warn_msg_buf, "stat()'ing %s successful", + FullPathName); + T1_PrintLog( "intT1_Env_GetCompletePath()", err_warn_msg_buf, + T1LOG_DEBUG); + } + return(FullPathName); + } + if (t1lib_log_file!=NULL){ + sprintf( err_warn_msg_buf, "stat()'ing %s failed", + pathbuf); + T1_PrintLog( "intT1_Env_GetCompletePath()", err_warn_msg_buf, + T1LOG_DEBUG); + } + /* We didn't find the file --> try next path entry */ + i++; + } + /* If we get here, no file was found at all, so return a NULL-pointer */ + return(NULL); +} + + + +/* T1_SetFileSearchPath(): Set the search path to find files of the + specified type and return 0 if successful and -1 otherwise. An existing + path is overwritten rigorously, unless the database already contains fonts. + In the latter case the function returns with an error status. + Multiple path types may be specified as a bitmask! +*/ +int T1_SetFileSearchPath( int type, char *pathname) +{ + + int i; + int pathlen; + + + if (pathname==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + + /* We do not allow to change the searchpath if the database already + contains one or more entries. */ + if (T1_GetNoFonts()>0){ + sprintf( err_warn_msg_buf, "Path %s not set, database is not empty", + pathname); + T1_PrintLog( "T1_SetFileSearchPath()", err_warn_msg_buf, + T1LOG_STATISTIC); + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pathlen=strlen(pathname)+1; + /* Throw away a possibly existing path */ + if (type & T1_PFAB_PATH){ + if (pfab_no==-1) { + T1_PFAB_ptr=NULL; /* realloc() will do a malloc() */ + } + else { + /* throw away current paths */ + i=0; + while (T1_PFAB_ptr[i]!=NULL) { + free (T1_PFAB_ptr[i++]); + } + } + if ((T1_PFAB_ptr=(char**)realloc( T1_PFAB_ptr, 2*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + if ((T1_PFAB_ptr[0]=(char*)malloc(pathlen*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( T1_PFAB_ptr[0], pathname); + T1_PFAB_ptr[1]=NULL; + pfab_no=1; + } + if (type & T1_AFM_PATH){ + if (afm_no==-1) { + T1_AFM_ptr=NULL; /* realloc() will do a malloc() */ + } + else { + /* throw away current paths */ + i=0; + while (T1_AFM_ptr[i]!=NULL) { + free (T1_AFM_ptr[i++]); + } + } + if ((T1_AFM_ptr=(char**)realloc( T1_AFM_ptr, 2*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + if ((T1_AFM_ptr[0]=(char*)malloc(pathlen*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( T1_AFM_ptr[0], pathname); + T1_AFM_ptr[1]=NULL; + afm_no=1; + } + if (type & T1_ENC_PATH){ + if (enc_no==-1) { + T1_ENC_ptr=NULL; /* realloc() will do a malloc() */ + } + else { + /* throw away current paths */ + i=0; + while (T1_ENC_ptr[i]!=NULL) { + free (T1_ENC_ptr[i++]); + } + } + if ((T1_ENC_ptr=(char**)realloc( T1_ENC_ptr, 2*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + if ((T1_ENC_ptr[0]=(char*)malloc(pathlen*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( T1_ENC_ptr[0], pathname); + T1_ENC_ptr[1]=NULL; + enc_no=1; + } + + return(0); + +} + + + +/* T1_GetFileSearchPath(): Return the specified file search path + or NULL if an error occurred. Note: We do only one path at a + time, so that if a bitmask is specified, the first match wins. + The returned path is formatted using the actual PATH_SEP_CHAR. */ +char *T1_GetFileSearchPath( int type) +{ + static char *out_ptr; + int i; + int pathlen; + char **src_ptr=NULL; + + + if (out_ptr!=NULL) + free( out_ptr); + out_ptr=NULL; + + if (type & T1_PFAB_PATH) { + src_ptr=T1_PFAB_ptr; + } + else if (type & T1_AFM_PATH) { + src_ptr=T1_AFM_ptr; + } + else if (type & T1_ENC_PATH) { + src_ptr=T1_ENC_ptr; + } + else if (type & T1_FDB_PATH) { + src_ptr=T1_FDB_ptr; + } + + + i=0; + pathlen=0; + while (src_ptr[i]!=NULL) { + pathlen +=strlen( src_ptr[i++]); + pathlen+=1; /* path separator */ + } + if ((out_ptr=(char *)malloc(pathlen+1))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + strcpy( out_ptr, src_ptr[0]); + i=1; + while (src_ptr[i]!=NULL) { + strcat( out_ptr, path_sep_string); + strcat( out_ptr, src_ptr[i++]); + } + + return( out_ptr); + +} + + +/* T1_AddToFileSearchPath(): Add the specified path element to + the specified search path. If the existing path is the default path, + it will not be replaced by the new path element. Since this function might + be called before initialization, we have to be aware that even the default + path could be missing. Multiple path types may be specified as a bitmask! + Return value is 0 if successful and -1 otherwise */ +int T1_AddToFileSearchPath( int pathtype, int mode, char *pathname) +{ + int i; + int pathlen; + char* newpath = NULL; + int nofonts; + + + if (pathname==NULL) + return(-1); + + nofonts=T1_GetNoFonts(); + + pathlen=strlen(pathname); + + if (pathtype & T1_PFAB_PATH){ + /* Allocate meory for string */ + if ((newpath=(char*)malloc( (pathlen+1)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Check for and handle the existing path configuration */ + if (pfab_no==0) { /* do not free the default path but establish it + as a regularly setup path, if database not empty! */ + if (nofonts>0) { + pfab_no++; + } + else { + free( T1_AFM_ptr[0]); + } + } + if (pfab_no==-1) { /* not initialized! */ + pfab_no=0; + T1_PFAB_ptr=NULL; /* realloc() will do the malloc()! */ + } + if ((T1_PFAB_ptr=(char**)realloc( T1_PFAB_ptr, (++pfab_no+1)*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Insert the new path element: */ + if (mode & T1_PREPEND_PATH){ /* prepend */ + i=pfab_no-2; + while (i>=0) { + T1_PFAB_ptr[i+1]=T1_PFAB_ptr[i]; + i--; + } + T1_PFAB_ptr[0]=newpath; + } + else{ /* append */ + T1_PFAB_ptr[pfab_no-1]=newpath; + } + T1_PFAB_ptr[pfab_no]=NULL; + } + if (pathtype & T1_AFM_PATH){ + /* Allocate meory for string */ + if ((newpath=(char*)malloc( (pathlen+1)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Check for and handle the existing path configuration */ + if (afm_no==0) { /* do not free the default path but establish it + as a regularly setup path, if database not empty! */ + if (nofonts>0) { + afm_no++; + } + else { + free( T1_AFM_ptr[0]); + } + } + if (afm_no==-1) { /* not initialized! */ + afm_no=0; + T1_AFM_ptr=NULL; /* realloc() will do the malloc()! */ + } + if ((T1_AFM_ptr=(char**)realloc( T1_AFM_ptr, (++afm_no+1)*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Insert the new path element */ + if (mode & T1_PREPEND_PATH){ /* prepend */ + i=afm_no-2; + while (i>=0) { + T1_AFM_ptr[i+1]=T1_AFM_ptr[i]; + i--; + } + T1_AFM_ptr[0]=newpath; + } + else{ /* append */ + T1_AFM_ptr[afm_no-1]=newpath; + } + T1_AFM_ptr[afm_no]=NULL; + } + if (pathtype & T1_ENC_PATH){ + /* Allocate meory for string */ + if ((newpath=(char*)malloc( (pathlen+1)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Check for and handle the existing path configuration */ + if (enc_no==0) { /* do not free the default path but establish it + as a regularly setup path, if database not empty! */ + if (nofonts>0) { + enc_no++; + } + else { + free( T1_ENC_ptr[0]); + } + } + if (enc_no==-1) { /* not initialized! */ + enc_no=0; + T1_ENC_ptr=NULL; /* realloc() will do the malloc()! */ + } + if ((T1_ENC_ptr=(char**)realloc( T1_ENC_ptr, (++enc_no+1)*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Insert the new path element: */ + if (mode & T1_PREPEND_PATH){ /* prepend */ + i=enc_no-2; + while (i>=0) { + T1_ENC_ptr[i+1]=T1_ENC_ptr[i]; + i--; + } + T1_ENC_ptr[0]=newpath; + } + else{ /* append */ + T1_ENC_ptr[enc_no-1]=newpath; + } + T1_ENC_ptr[enc_no]=NULL; + } + + /* Copy new path to where it belongs ... */ + if (newpath) + strcpy(newpath, pathname); + + return(0); + +} + + + +/* T1_SetFontDataBase(): Set a new name for the font database. It replaces the default + name and any names specified previously with this function. + Return value: 0 if OK, and -1 if filename not valid or an allocation + error occurred */ +int T1_SetFontDataBase( char *filename) +{ + int pathlen; + int i; + int result=0; + + + /* chekc filename */ + if (filename==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return -1; + } + + /* this function must be called before any font is in the database, that is, usually, + before initialization! */ + if ( pFontBase!=NULL && pFontBase->no_fonts>0) { + T1_errno=T1ERR_OP_NOT_PERMITTED; + return -1; + } + + + pathlen=strlen(filename)+1; + /* Throw away a possibly existing font database-statement */ + if (fdb_no==-1) { + T1_FDB_ptr=NULL; /* realloc() will do a malloc() */ + } + else { + /* throw away current paths */ + i=0; + while (T1_FDB_ptr[i]!=NULL) { + free (T1_FDB_ptr[i++]); + } + } + + if ((T1_FDB_ptr=(char**)realloc( T1_FDB_ptr, 2*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return -1; + } + + if ((T1_FDB_ptr[0]=(char*)malloc(pathlen*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return -1; + } + strcpy( T1_FDB_ptr[0], filename); + T1_FDB_ptr[1]=NULL; + fdb_no=1; + + /* Load database immediately if t1lib already is initailzed */ + if (T1_CheckForInit()==0) { + if ((result=intT1_scanFontDBase(T1_FDB_ptr[0]))==-1) { + T1_PrintLog( "T1_AddFontDataBase()", "Fatal error scanning Font Database File %s (T1_errno=%d)", + T1LOG_WARNING, T1_FDB_ptr[0], T1_errno); + } + if (result>-1) + pFontBase->no_fonts+=result; + result=pFontBase->no_fonts; + } + return result; + +} + + +/* T1_AddFontDataBase(): Add a new font database file to the list. If the + lib is already initialzed, then the new database is immediately loaded. + Otherwise it is simply appended to the list and loaded at the time of + initialization. + Returns: -1 an error occured + 0 successfully inserted but not loaded because lib not initilized + n>0 the highest defined FontID +*/ +int T1_AddFontDataBase( int mode, char *filename) +{ + int i; + int pathlen; + int result=0; + char* newpath; + + + if (filename==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(-1); + } + + pathlen=strlen(filename); + + /* Allocate memory for string */ + if ((newpath=(char*)malloc( (pathlen+1)*sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + strcpy( newpath, filename); + /* Check for and handle the existing path configuration */ + if (fdb_no==0) { /* defauls setup, free the path */ + free( T1_FDB_ptr[0]); + } + if (fdb_no==-1) { /* not initialized! */ + fdb_no=0; + T1_FDB_ptr=NULL; /* realloc() will do the malloc()! */ + } + + if ((T1_FDB_ptr=(char**)realloc( T1_FDB_ptr, (++fdb_no+1)*sizeof(char*)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + /* Insert the new database. If t1lib is already initialzed, the database can only + be appended. Otherwise. prepending is also possible.*/ + if ((mode & T1_PREPEND_PATH) && (T1_CheckForInit()!=0) ) { /* prepend */ + i=fdb_no-2; + while (i>=0) { + T1_FDB_ptr[i+1]=T1_FDB_ptr[i]; + i--; + } + T1_FDB_ptr[0]=newpath; + result=0; + } + else { /* append */ + T1_FDB_ptr[fdb_no-1]=newpath; + if (T1_CheckForInit()==0) { + if ((result=intT1_scanFontDBase(T1_FDB_ptr[fdb_no-1]))==-1) { + T1_PrintLog( "T1_AddFontDataBase()", "Fatal error scanning Font Database File %s (T1_errno=%d)", + T1LOG_WARNING, T1_FDB_ptr[fdb_no-1], T1_errno); + } + if (result>-1) + pFontBase->no_fonts+=result; + result=pFontBase->no_fonts; + } + } + T1_FDB_ptr[fdb_no]=NULL; + return result; + +} + + diff --git a/Build/source/libs/t1lib/t1env.h b/Build/source/libs/t1lib/t1env.h new file mode 100644 index 00000000000..d332500be77 --- /dev/null +++ b/Build/source/libs/t1lib/t1env.h @@ -0,0 +1,54 @@ +/*-------------------------------------------------------------------------- + ----- File: t1env.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-09-26 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1env.c + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifdef T1ENV_C + +void intT1_FreeSearchPaths( void); +void intT1_SetupDefaultSearchPaths( void); +int intT1_ScanConfigFile( void); +char *intT1_Env_GetCompletePath( char *FileName, char **env_ptr ); +int T1_SetFileSearchPath( int type, char *pathname); +int T1_AddToFileSearchPath( int pathtype, int mode, char *pathname); +char *T1_GetFileSearchPath( int type); +int T1_SetFontDataBase( char *filename); +int T1_AddFontDataBase( int mode, char *filename); + +#else + +extern void intT1_FreeSearchPaths( void); +extern void intT1_SetupDefaultSearchPaths( void); +extern int intT1_ScanConfigFile( void); +extern char *intT1_Env_GetCompletePath( char *FileName, char **env_ptr ); +extern int T1_SetFileSearchPath( int type, char *pathname); +extern int T1_AddToFileSearchPath( int pathtype, int mode, char *pathname); +extern char *T1_GetFileSearchPath( int type); +extern int T1_SetFontDataBase( char *filename); +extern int T1_AddFontDataBase( int mode, char *filename); + +#endif + diff --git a/Build/source/libs/t1lib/t1extern.h b/Build/source/libs/t1lib/t1extern.h new file mode 100644 index 00000000000..e0f4b47af30 --- /dev/null +++ b/Build/source/libs/t1lib/t1extern.h @@ -0,0 +1,105 @@ +/*-------------------------------------------------------------------------- + ----- File: t1extern.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-10-03 + ----- Description: This file is part of the t1-library. It contains + external declarations used by the t1-library. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#include "t1misc.h" + + +/* Following struct will allow all accesses to font data! */ +extern struct FONTBASE +{ + int t1lib_flags; /* Global library flags */ + int no_fonts_ini; /* The number of fonts initially declared in + Font database file. */ + int no_fonts; /* The number of currently allocated fonts including + logical fonts produced by T1_CopyFont() */ + int no_fonts_limit; /* The maximum number of font for which is memory + currently available. */ + int bitmap_pad; /* The value to which bitmap-scanlines are padded */ + int endian; /* 1 if little endian representation and 0 otherwise */ + char **default_enc; /* The default encoding vector */ + FONTPRIVATE *pFontArray; /* Points to first element of font pointer array */ +} FontBase; +extern struct FONTBASE *pFontBase; + + +/* Further we need a struct where to save device dependent data such as + resolution. The values in this struct may be altered using + T1_SetDeviceRes(x_res,y_res). Generally, the fontsize is to be specified + in BigPoints ("bp")---this is the default PostScript unit. It is + 1in=72bp. + */ +extern struct +{ + float x_resolution; /* Value must be specified in DPI */ + float y_resolution; /* Value must be specified in DPI */ + float scale_x; /* horizontal scale-value to get a + matrix scaled to 1b */ + float scale_y; /* vertical scale-value to get a + matrix scaled to 1b */ +} DeviceSpecifics; + + +extern struct stat filestats; /* A structure where fileinfo is stored */ +extern char linebuf[BUF_SIZE]; /* A buffer for reading files line + by line */ +extern int T1_Up; /* This one is for initialization-checking */ + +/* The width of AA-pixels */ +extern int T1aa_bpp; + +/* The follwoing variable allows the primary rastering functions + to check for the caller */ +extern int SetFuncRequestID; + +/* The following variable allows to suppress rastering at 1000 bp + for getting a correct bounding box for slanted characters --> + should only internally be used */ +extern int ForceAFMBBox; + +extern struct XYspace *IDENTITY; + +extern int errornumber; /* for debugging purposes */ + +extern char **T1_PFAB_ptr; +extern char **T1_AFM_ptr; +extern char **T1_ENC_ptr; +extern char **T1_FDB_ptr; + +/* We use a uchar buffer for error and warning messages: */ +extern char err_warn_msg_buf[1024]; + +/* file pointer for log-file */ +extern FILE *t1lib_log_file; +extern int t1lib_log_level; + +/* The errno for t1lib */ +extern int T1_errno; + +/* A variable for saving stack info */ +extern jmp_buf stck_state; + diff --git a/Build/source/libs/t1lib/t1finfo.c b/Build/source/libs/t1lib/t1finfo.c new file mode 100644 index 00000000000..211abf360c4 --- /dev/null +++ b/Build/source/libs/t1lib/t1finfo.c @@ -0,0 +1,1365 @@ +/*-------------------------------------------------------------------------- + ----- File: t1finfo.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-04 + ----- Description: This file is part of the t1-library. It contains + functions for accessing afm-data and some other + fontinformation data. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1FINFO_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1finfo.h" +#include "t1base.h" +#include "t1misc.h" +#include "t1set.h" +#include "t1load.h" + + +/* The following variable controls the computation of the bbox internal + to T1_GetMetricsInfo(). Its influence may be overridden by the + global variable ForceAFMBBox: */ +static int ForceAFMBBoxInternal=0; + + +extern int ForceAFMBBox; +extern char *t1_get_abort_message( int number); + + +/* int T1_GetKerning(): This function returns the amount of kerning that + is specified in the afm-file for the supplied character-pair. If an + an extension has been applied to the font in question, this is taken + into account. + If for whatever reason there's no afm information available (that's not + deadly), simply 0 is returned, indicating that no kerning should be used. + The value returned is meant to be in character space coordinates. Thus, + it must be transformed to be applicable in device space. + */ +int T1_GetKerning( int FontID, char char1, char char2) +{ + METRICS_ENTRY entry; + METRICS_ENTRY *target_pair=NULL; + + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( 0); + } + + /* if there's no kerning info, return immediately */ + if (pFontBase->pFontArray[FontID].KernMapSize==0) + return( 0); + + entry.chars=(char1<<8) | char2; + if ((target_pair=(METRICS_ENTRY *) + bsearch( &entry, pFontBase->pFontArray[FontID].pKernMap, + (size_t) pFontBase->pFontArray[FontID].KernMapSize, + sizeof(METRICS_ENTRY), + &cmp_METRICS_ENTRY))==NULL) + return(0); + else + return( target_pair->hkern * pFontBase->pFontArray[FontID].extend); + +} + + + +/* int T1_GetCharWidth(): This function returns the characterwidth + specified in the .afm-file. If no .afm-file is loaded for that font, + 0 is returned. Note that if one tries to raster strings, afm data + must always be available. The returned character width is corrected + using a possibly applied font extension! + */ +int T1_GetCharWidth( int FontID, char char1) +{ + unsigned char uchar1; + + uchar1=(unsigned char) char1; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( 0); + } + + /* return appriate value */ + if (pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]>0) { /* ordinary character */ + return((int) ((pFontBase->pFontArray[FontID].pAFMData->cmi[pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]-1].wx) * pFontBase->pFontArray[FontID].extend)); + } + else if (pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]<0) { /* composite character */ + return((int) ((pFontBase->pFontArray[FontID].pAFMData->ccd[-(pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]+1)].wx) * pFontBase->pFontArray[FontID].extend)); + } + else { /* undefined or .notdef */ + return(0); + } + +} + + + +/* T1_GetCharBBox(): Get the BoundingBox of specified character. If an + extension factor has been applied to the font in question, this + is taken into account. However, a slant factor which has been applied + to the font, also affects the bounding box of a character. The + only way to determine its influence on the character bounding box + is to compute the exact shape of that slanted character. There's no + simple way to extract the new bounding box from the former bounding + box. Thus, if a font has been slanted, the characters outline itself + is examined. Since this must be done at 1000 bp it takes considerably + longer than reading afm data. */ +BBox T1_GetCharBBox( int FontID, char char1) +{ + + struct region *area; + struct XYspace *S; + int mode=0; + int i; + + BBox NullBBox= { 0, 0, 0, 0}; /* A bounding box containing all 0's. */ + BBox ResultBox= { 0, 0, 0, 0}; /* The Box returned if char is found */ + + unsigned char uchar1; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetCharBBox()", err_warn_msg_buf, + T1LOG_ERROR); + return( NullBBox); + } + + + uchar1=(unsigned char) char1; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NullBBox); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( NullBBox); + } + + + /* Check for a font slant */ + if ((pFontBase->pFontArray[FontID].slant!=0.0) + &&(ForceAFMBBox==0) + &&(ForceAFMBBoxInternal==0)){ + /* We have a font slant -> character outline must be examined in order + to determine bounding box */ + /* Set up an identity charspace matrix + and take a slant and an extension into account */ + /* And make it permanent, to plug a memory leak */ + S=(struct XYspace *)IDENTITY; + S=(struct XYspace *)Permanent + (Transform(S, pFontBase->pFontArray[FontID].FontTransform[0], + pFontBase->pFontArray[FontID].FontTransform[1], + pFontBase->pFontArray[FontID].FontTransform[2], + pFontBase->pFontArray[FontID].FontTransform[3])); + /* Genrate an edgelist for the current character at size 1000bp + using current transformation and encoding: */ + area=fontfcnB( FontID, 0, S, + pFontBase->pFontArray[FontID].pFontEnc, + (int) uchar1, &mode, + pFontBase->pFontArray[FontID].pType1Data, + DO_RASTER,0.0f); + /* Read out bounding box */ + ResultBox.llx =area->xmin; + ResultBox.urx =area->xmax; + ResultBox.lly =area->ymin; + ResultBox.ury =area->ymax; + + /* Reset AFM-switch and return BBox */ + ForceAFMBBoxInternal=0; + /* make sure to destroy 'area' before leaving! */ + KillRegion (area); + /* make sure to free S */ + if (S) { + KillSpace (S); + } + return(ResultBox); + } + else{ + /* Assign bounding box for the different cases: */ + /* Check if character is */ + if (pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]>0) { /* ordinary char */ + ResultBox=(pFontBase->pFontArray[FontID].pAFMData->cmi[pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]-1].charBBox); + } + else if (pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]<0) { /* composite char */ + ResultBox=(pFontBase->pFontArray[FontID].pAFMData->ccd[-(pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]+1)].charBBox); + } + else { /* undefined char */ + return(NullBBox); + } + + /* .. and apply transformations: */ + ResultBox.llx *=pFontBase->pFontArray[FontID].extend; + ResultBox.urx *=pFontBase->pFontArray[FontID].extend; + + return(ResultBox); + } +} + + + +/* int T1_GetUnderlinePosition(): Return underline position of specified + font in charspace units. If 0 is returned, it indicated that the font + is not yet loaded into memory. or an invalid ID has been specified. */ +float T1_GetUnderlinePosition( int FontID) +{ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return((float)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[UNDERLINEPOSITION].value.data.real)); +} + + + +/* int T1_GetUnderlineThickness(): Return underline thickness of specified + font in charspace units. If 0 is returned, it indicated that the font + is not yet loaded into memory. or an invalid ID has been specified. */ +float T1_GetUnderlineThickness( int FontID) +{ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return((float)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[UNDERLINETHICKNESS].value.data.real)); +} + + +/* int T1_ItalicAngle(): Return underline position of specified + font in charspace units. If 0.0 is returned, it indicated that the font + is not yet loaded into memory. or an invalid ID has been specified. */ +float T1_GetItalicAngle( int FontID) +{ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return((float)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ITALICANGLE].value.data.real)); +} + + + +/* int T1_GetUnderlinePosition(): Return underline position of specified + font in charspace units. If 0 is returned, it indicated that the font + is not yet loaded into memory. or an invalid ID has been specified. */ +int T1_GetIsFixedPitch( int FontID) +{ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return((int)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ISFIXEDPITCH].value.data.boolean)); +} + + + +/* char *T1_GetFontName( FontID): Get the PostScript FontName of + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetFontName( int FontID) +{ + static char fontname[MAXPSNAMELEN]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(fontname, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTNAME].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTNAME].value.len); + fontname[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTNAME].value.len]=0; + + return(fontname); + +} + + +/* char *T1_GetFullName( FontID): Get the Full Name from + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetFullName( int FontID) +{ + static char fullname[MAXPSNAMELEN]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(fullname, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FULLNAME].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FULLNAME].value.len); + fullname[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FULLNAME].value.len]=0; + + return(fullname); + +} + + +/* char *T1_GetFamilyName( FontID): Get the Family Name of + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetFamilyName( int FontID) +{ + static char familyname[MAXPSNAMELEN]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(familyname, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FAMILYNAME].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FAMILYNAME].value.len); + familyname[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FAMILYNAME].value.len]=0; + + return(familyname); + +} + + +/* char *T1_GetWeight( FontID): Get the Weight entry from + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetWeight( int FontID) +{ + static char weight[128]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(weight, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[WEIGHT].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[WEIGHT].value.len); + weight[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[WEIGHT].value.len]=0; + + return(weight); + +} + + +/* char *T1_GetFontName( FontID): Get the Version entry from + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetVersion( int FontID) +{ + static char version[2048]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(version, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[VERSION].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[VERSION].value.len); + version[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[VERSION].value.len]=0; + + return(version); + +} + + +/* char *T1_GetNotice( FontID): Get the Notice entry from + the font dictionary associated with the specified font, or NULL if + an error occurs. */ +char *T1_GetNotice( int FontID) +{ + static char notice[2048]; + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + strncpy(notice, + (char *)(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[NOTICE].value.data.nameP), + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[NOTICE].value.len); + notice[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[NOTICE].value.len]=0; + + return(notice); + +} + + + + +/* char *T1_GetCharName(): Get the PostScript character name of + the character indexed by char1. */ +char *T1_GetCharName( int FontID, char char1) +{ + static char cc_name1[256]; + char *c1; + + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + if (pFontBase->pFontArray[FontID].pFontEnc==NULL){ + /* We have to get the names from the fonts internal encoding */ + c1= (char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].data.arrayP; + strncpy(cc_name1, + (char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].data.arrayP, + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].len); + cc_name1[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].len]=0; + } + else{ + /* Take names from explicitly loaded and assigned encoding */ + c1=pFontBase->pFontArray[FontID].pFontEnc[(unsigned char)char1]; + strcpy(cc_name1,c1); + } + + /* Return address of charname */ + return(cc_name1); + +} + + + +/* T1_QueryLigs(): Get the number of ligatures defined in the font FontID for + the character which is located at position char1 in the current encoding + vector! + Function returns the number of defined ligs (including 0) or -1 if an + error occured. + */ +int T1_QueryLigs( int FontID, char char1, char **successors, + char **ligatures) +{ + + FontInfo *afm_ptr; + CharMetricInfo *m_ptr; + char *c_name; + char cc_name[128]; + static char succ[MAX_LIGS]; + int succ_index; + static char lig[MAX_LIGS]; + int lig_index; + + Ligature *ligs; + int i,j; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( -1); + } + + /* All OK, ... */ + afm_ptr=pFontBase->pFontArray[FontID].pAFMData; + m_ptr=afm_ptr->cmi; + + /* Get the name of the character: */ + if (pFontBase->pFontArray[FontID].pFontEnc==NULL){ + /* We have to get the name from the fonts internal encoding */ + c_name=(char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].data.arrayP; + strncpy(cc_name, + (char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].data.arrayP, + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].len); + cc_name[pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[(unsigned char)char1].len]=0; + } + else{ + /* Take name from explicitly loaded and assigned encoding */ + c_name=pFontBase->pFontArray[FontID].pFontEnc[(unsigned char)char1]; + strcpy(cc_name,c_name); + } + + for (i=0; i<afm_ptr->numOfChars; i++){ + if (strcmp(m_ptr[i].name,cc_name)==0) + break; + } + + + if (i==afm_ptr->numOfChars) /* we didn't find the characters name */ + return(-1); + + ligs=m_ptr[i].ligs; + + j=0; + if (ligs==NULL) + return(0); + + while (ligs!=NULL) { + /* Get indices of the two characters: */ + if ((succ_index=T1_GetEncodingIndex( FontID, (char*) ligs->succ))==-1) { + /* successor is not current encoding */ + ligs=ligs->next; + continue; + } + if ((lig_index=T1_GetEncodingIndex( FontID, (char*) ligs->lig))==-1) { + /* Specified ligature is not in current encoding */ + ligs=ligs->next; + continue; + } + succ[j]=(char)succ_index; + lig[j]=(char)lig_index; + j++; + ligs=ligs->next; + } + + *successors=succ; + *ligatures=lig; + + return(j); +} + + + +/* T1_GetEncodingIndex(): Return the Index of char1 in the current + encoding vector of font FontID */ +int T1_GetEncodingIndex( int FontID, char *char1) +{ + int i; + int len1; + int result_index; + char **extern_enc; + psobj *objptr; + + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + extern_enc=pFontBase->pFontArray[FontID].pFontEnc; + + len1=strlen( char1); + + /* The default return-value if character is not found: */ + result_index=-1; + + if (extern_enc==NULL) { + objptr=&(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[0]); + /* We have to search the fonts internal encoding */ + for (i=0;i<256;i++){ + if (len1==objptr[i].len){ + if (strncmp((char *)objptr[i].data.arrayP, + char1, objptr[i].len)==0){ + result_index=i; + break; + } + } + } + + } + else { + /* Take name from explicitly loaded and assigned encoding */ + for (i=0;i<256;i++){ + if (strcmp(extern_enc[i], char1)==0){ + result_index=i; + break; + } + } + } + + return(result_index); +} + + +/* T1_GetEncodingIndices(): Return all indices of char1 in the current + encoding vector of font FontID. */ +int *T1_GetEncodingIndices( int FontID, char *char1) +{ + int i; + int endmark=0; + int len1; + char **extern_enc; + psobj *objptr; + /* the following array suffices for the extreme unlikely case of a font + where one single fillsthe whole encoding vector */ + static int indices[257]; + + + if (T1_CheckForFontID(FontID)!=1) { + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + extern_enc=pFontBase->pFontArray[FontID].pFontEnc; + + len1=strlen( char1); + + if (extern_enc==NULL) { + objptr=&(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[0]); + /* We have to search the fonts internal encoding */ + for (i=0;i<256;i++){ + if (len1==objptr[i].len){ + if (strncmp((char *)objptr[i].data.arrayP, + char1, objptr[i].len)==0){ + indices[endmark++]=i; + } + } + } + } + else { + /* Take name from explicitly loaded and assigned encoding */ + for (i=0;i<256;i++){ + if (strcmp(extern_enc[i], char1)==0){ + indices[endmark++]=i; + } + } + } + + indices[endmark]=-1; + return((int *)indices); +} + + +/* int T1_GetStringWidth(): This function returns the width of string + in .afm-file units. If no .afm-file is loaded for font FontID, + 0 is returned. Note that if one tries to raster strings, afm data + should always be available. The returned character width is corrected + using a possibly applied font extension! + */ +int T1_GetStringWidth( int FontID, char *string, + int len, long spaceoff, int kerning) +{ + + int no_chars; /* Number of chars in string */ + int i; + int *kern_pairs; + int *charwidths; + int spacewidth; + int stringwidth; + + unsigned char *ustring; + + ustring=(unsigned char *) string; + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( 0); + } + + /* Get length of string: */ + if (len<0 || ustring == NULL){ /* invalid length or NULL-pointer */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(0); + } + if (len==0) /* should be computed assuming "normal" 0-terminated string */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + switch (no_chars) { + case 0: + /* Empty string has width 0 */ + stringwidth=0; + break; + + case 1: + /* Width of string with 1 character is the width of that character. + If the character is a space, adjust by the value of spaceoff. + */ + stringwidth=T1_GetCharWidth(FontID,ustring[0]); + if (ustring[0]==pFontBase->pFontArray[FontID].space_position) + stringwidth+=spaceoff; + break; + + default: + /* Two or more characters. Add widths of characters and adjust by + the adjustment widths for any kerning pairs. For spaces, use the + width of the space character in the font adjusted by the value of + spaceoff. + */ + + /* Allocate room for temporary arrays of kerning and width arrays: */ + kern_pairs=(int *)calloc(no_chars -1, sizeof(int)); + if (kern_pairs==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(0); + } + charwidths=(int *)calloc(no_chars, sizeof(int)); + if (charwidths==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(0); + } + + /* If kerning is requested, get kerning amounts and fill the array: */ + if (kerning){ + for (i=0; i<no_chars -1; i++){ + kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); + } + } + + /* Compute the correct spacewidth value (in charspace units): */ + spacewidth=T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff; + + /* Fill the width-array: */ + for (i=0; i<no_chars; i++){ + if (ustring[i]==pFontBase->pFontArray[FontID].space_position) + charwidths[i]=(int)spacewidth; + else + charwidths[i]=T1_GetCharWidth(FontID,ustring[i]); + } + + /* Accumulate width: */ + stringwidth=0; + for (i=0; i<no_chars-1; i++){ + stringwidth += kern_pairs[i]; + } + for (i=0; i<no_chars; i++){ + stringwidth += charwidths[i]; + } + + /* free memory: */ + free( charwidths); + free( kern_pairs); + + break; + } + + /* .. and return result: */ + return( stringwidth); +} + + + +/* int T1_GetStringBBox(): This function returns the bounding box of string + in .afm-file units. If no .afm-file is loaded for font FontID, + 0 is returned. Note that if one tries to raster strings, afm data + should always be available. The returned character width is corrected + using a possibly applied font extension! + */ +BBox T1_GetStringBBox( int FontID, char *string, + int len, long spaceoff, int kerning) +{ + + BBox NullBBox= { 0, 0, 0, 0}; /* A bounding box containing all 0's. */ + BBox tmp_BBox= { 0, 0, 0, 0}; + BBox ResultBBox= { 0, 0, 0, 0}; /* The resulting BBox */ + int i; + int no_chars; + int curr_width=0; + int spacewidth=0; + + int rsb_max=-30000; + int lsb_min= 30000; + int overallascent=-30000; + int overalldescent=30000; + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NullBBox); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( NullBBox); + } + + /* Get length of string: */ + if (len<0 || string==NULL) { /* invalid length or NULL-pointer */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NullBBox); + } + if (len==0) /* should be computed assuming "normal" 0-terminated string */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + spacewidth= + T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff; + + /* Accumulate metrics: */ + for (i=0; i<no_chars; i++){ + if (string[i]==pFontBase->pFontArray[FontID].space_position) + curr_width +=spacewidth; + else{ + tmp_BBox=T1_GetCharBBox( FontID, string[i]); + if (curr_width+tmp_BBox.llx < lsb_min) + lsb_min=curr_width+tmp_BBox.llx; + if (curr_width+tmp_BBox.urx > rsb_max) + rsb_max=curr_width+tmp_BBox.urx; + if (tmp_BBox.lly < overalldescent) + overalldescent=tmp_BBox.lly; + if (tmp_BBox.ury > overallascent) + overallascent=tmp_BBox.ury; + curr_width +=T1_GetCharWidth( FontID, string[i]); + if ((i<no_chars-1) && (kerning != 0)) + curr_width += T1_GetKerning( FontID, string[i], string[i+1]); + } + } + + ResultBBox.llx=lsb_min; + ResultBBox.lly=overalldescent; + ResultBBox.urx=rsb_max; + ResultBBox.ury=overallascent; + + return( ResultBBox); + +} + + +/* T1_GetMetricsInfo(): Return a structure containing metrics information + about the string to the user. */ +METRICSINFO T1_GetMetricsInfo( int FontID, char *string, + int len, long spaceoff, int kerning) +{ + + BBox NullBBox= { 0, 0, 0, 0}; /* A bounding box containing all 0's. */ + BBox tmp_BBox= { 0, 0, 0, 0}; + + + int i; + int no_chars; + + int curr_width=0; + int spacewidth=0; + + int rsb_max=-30000; + int lsb_min= 30000; + int overallascent=-30000; + int overalldescent=30000; + + static METRICSINFO metrics={ 0, {0, 0, 0, 0}, 0, NULL}; + + unsigned char *ustring; + + + ustring=(unsigned char *) string; + + /* Reset struct: */ + metrics.width=0; + metrics.bbox=NullBBox; + metrics.numchars=0; + if (metrics.charpos != NULL){ + free( metrics.charpos); + metrics.charpos=NULL; + } + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(metrics); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( metrics); + } + + /* Get length of string: */ + if (len<0 || ustring==NULL ) { /* invalid length or NULL_pointer */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(metrics); + } + + if (len==0) /* should be computed assuming "normal" 0-terminated string */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + /* Compute the correct spacewidth value (in charspace units): */ + spacewidth=T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff; + + /* Allocate memory for character positions array: */ + metrics.charpos=(int *)calloc(no_chars, sizeof(int)); + + metrics.numchars=no_chars; + + /* Accumulate metrics: */ + for (i=0; i<no_chars; i++){ + /* Save current offst to array */ + metrics.charpos[i]=curr_width; + if (string[i]==pFontBase->pFontArray[FontID].space_position) + curr_width +=spacewidth; + else{ + tmp_BBox=T1_GetCharBBox( FontID, string[i]); + if (curr_width+tmp_BBox.llx < lsb_min) + lsb_min=curr_width+tmp_BBox.llx; + if (curr_width+tmp_BBox.urx > rsb_max) + rsb_max=curr_width+tmp_BBox.urx; + if (tmp_BBox.lly < overalldescent) + overalldescent=tmp_BBox.lly; + if (tmp_BBox.ury > overallascent) + overallascent=tmp_BBox.ury; + curr_width +=T1_GetCharWidth( FontID, string[i]); + if ((i<no_chars-1) && (kerning != 0)) + curr_width += T1_GetKerning( FontID, string[i], string[i+1]); + } + } + + metrics.width =curr_width; + metrics.bbox.llx=lsb_min; + metrics.bbox.lly=overalldescent; + metrics.bbox.urx=rsb_max; + metrics.bbox.ury=overallascent; + + return( metrics); + +} + + + +/* T1_GetFontBBox(): Return the font's bounding box. Note: The font + BBox is taken is taken from the font file rather than from afm + file since I have seen some afm with rather inaccurate BBoxes.: */ +BBox T1_GetFontBBox( int FontID) +{ + + BBox outbox= { 0, 0, 0, 0}; + struct ps_obj *obj; + + /* return Null-box if font not loaded */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(outbox); + } + + /* As suggested by Derek B. Noonburg (xpdf-Author), we allow the + FontBBox also to be specified by real numbers. */ + obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[0]); + outbox.llx = + objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? + (int) ceil(obj->data.real) : (int) floor(obj->data.real); + obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[1]); + outbox.lly = + objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? + (int) ceil(obj->data.real) : (int) floor(obj->data.real); + obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[2]); + outbox.urx = + objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? + (int) ceil(obj->data.real) : (int) floor(obj->data.real); + obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[3]); + outbox.ury = + objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? + (int) ceil(obj->data.real) : (int) floor(obj->data.real); + + return( outbox); +} + + + +/* T1_GetAllCharNames(): Get a list of all defined character names in + in the font FontID: */ +char **T1_GetAllCharNames( int FontID) +{ + static char **bufmem=NULL; + register char *namedest; + psdict *pCharStrings; + int len, i, j; + long nameoffset; + + int bufmemsize=0; + + /* return NULL if font not loaded */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( NULL); + } + + pCharStrings=pFontBase->pFontArray[FontID].pType1Data->CharStringsP; + + /* First, get number of charstrings: */ + len=pCharStrings[0].key.len; + + /* We must be careful here: size of the charstrings dict might be larger + than the actual number of charstrings. We correct for this by reducing + the value of len appropriately */ + for ( i=1; i<=len; i++){ + /* calculate room for each characters name plus the prepending \0 */ + if ((j=pCharStrings[i].key.len)){ + bufmemsize += j + 1; + } + else{ /* we skip this (the remaining) entries */ + len--; + i--; + } + } + /* Now we reserve memory for the pointers (including final NULL) */ + nameoffset=(len+1)*sizeof( char *); + bufmemsize += nameoffset; + + /* Now allocate memory, copy strings and initialize pointers */ + if (bufmem!=NULL) + free(bufmem); + if ((bufmem=(char **)malloc( bufmemsize))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + namedest=(char *)((long)bufmem + nameoffset); + j=0; + for ( i=0; i<len; i++){ + bufmem[i]=&(namedest[j]); + strncpy( &(namedest[j]), pCharStrings[i+1].key.data.nameP, + pCharStrings[i+1].key.len); + j += pCharStrings[i+1].key.len; + namedest[j++]='\0'; + } + bufmem[i++]=NULL; + + return( bufmem); + +} + + + +/* T1_GetNoKernPairs(): Return the number of kerning pairs defined + for font FontID */ +int T1_GetNoKernPairs( int FontID) +{ + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( -1); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( -1); + } + + return( pFontBase->pFontArray[FontID].pAFMData->numOfPairs); + +} + + + +/* A function for comparing METRICS_ENTRY structs */ +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2) +{ + if (((METRICS_ENTRY *)entry1)->chars < + ((METRICS_ENTRY *)entry2)->chars) + return(-1); + if (((METRICS_ENTRY *)entry1)->chars > + ((METRICS_ENTRY *)entry2)->chars) + return(1); + return(0); /* This should not happen */ +} + + + +/* A few functions for accessing composite character data: */ +/* T1_GetNoCompositeChars(): Return the number of characters for + for which composite character information is available + for font FontID */ +int T1_GetNoCompositeChars( int FontID) +{ + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( -1); + } + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( -1); + } + + return( pFontBase->pFontArray[FontID].pAFMData->numOfComps); + +} + + + +/* T1_QueryCompositeChar(): Query whether char1 from font FontID + is a composite character. If so, the index of the composite + character data within the afm array is returned. The index can + be used to retrieve the retrieve the composite character data. + + retval>=0: index into AFM-array where the corresponding + composite char data is located + retval=-1: No composite character, but result is valid, + retval=-2: No composite character, but result is invalid. + T1_errno indicated the reason. +*/ +int T1_QueryCompositeChar( int FontID, char char1) +{ + unsigned char uchar1; + + uchar1=char1; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( -2); + } + + /* If no AFM info is present, we return -2 */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( -2); + } + + if (pFontBase->pFontArray[FontID].pEncMap[ uchar1]<0) { /* composite char */ + return( -(pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]+1)); + } + + return(-1); + +} + + + +/* T1_GetCompCharData(): Retrieve data to construct composite + character char1 from font FontID. In case of an error NULL is returned + and T1_errno is set appropriately. */ +T1_COMP_CHAR_INFO *T1_GetCompCharData( int FontID, char char1) +{ + T1_COMP_CHAR_INFO *cci=NULL; + CompCharData *ccd=NULL; + int afmind=-1; + int i; + unsigned char uchar1; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( cci); + } + + /* If no AFM info is present, we return -2 */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( cci); + } + + if ((cci=(T1_COMP_CHAR_INFO*)malloc( sizeof(T1_COMP_CHAR_INFO)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( cci); + } + + uchar1=(unsigned char)char1; + + /* set default values */ + cci->compchar=uchar1; + cci->numPieces=1; + cci->pieces=NULL; + + /* check char1 */ + if ((afmind=pFontBase->pFontArray[FontID].pEncMap[uchar1]) >= 0) { + /* char is no composite char */ + return(cci); + } + + /* character is a composite char-> retrieve index and pointer into + AFM data */ + afmind=-(afmind+1); + ccd=&(pFontBase->pFontArray[FontID].pAFMData->ccd[afmind]); + + /* cci->compchar is already setup correctly because char1 is a + composite character */ + cci->numPieces=ccd->numOfPieces; + /* we expect numPieces to be >1 */ + if ((cci->pieces=(T1_COMP_PIECE *)malloc( sizeof(T1_COMP_PIECE)* + cci->numPieces))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( cci); + return( NULL); + } + /* Copy information */ + for (i=0; i<cci->numPieces; i++) { + cci->pieces[i].piece=T1_GetEncodingIndex( FontID, ccd->pieces[i].pccName); + cci->pieces[i].deltax=ccd->pieces[i].deltax; + cci->pieces[i].deltay=ccd->pieces[i].deltay; + } + return( cci); + +} + + + +/* T1_GetCompCharDataByIndex(): Retrieve data to construct composite + characters form font FontID. The data is addressed by index which + may, for example, have been obtained by a call to + T1_QueryCompositeChar(). + In case of error NULL is returned and T1_errno is set appropriately. +*/ +T1_COMP_CHAR_INFO *T1_GetCompCharDataByIndex( int FontID, int index) +{ + T1_COMP_CHAR_INFO *cci=NULL; + CompCharData *ccd=NULL; + int i; + + /* Check whether font is loaded: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( cci); + } + + /* If no AFM info is present, we return -2 */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return( cci); + } + + /* range check for index */ + if ((index < 0) || + (index >= pFontBase->pFontArray[FontID].pAFMData->numOfComps)) { + T1_errno=T1ERR_INVALID_PARAMETER; + return( cci); + } + + /* Alloc mem */ + if ((cci=(T1_COMP_CHAR_INFO*)malloc( sizeof(T1_COMP_CHAR_INFO)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( cci); + } + + /* set source pointer */ + ccd=&(pFontBase->pFontArray[FontID].pAFMData->ccd[index]); + /* and copy information */ + cci->compchar=T1_GetEncodingIndex( FontID, ccd->ccName); + cci->numPieces=ccd->numOfPieces; + /* we expect numPieces to be >1 */ + if ((cci->pieces=(T1_COMP_PIECE *)malloc( sizeof(T1_COMP_PIECE)* + cci->numPieces))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( cci); + return( NULL); + } + /* Copy information */ + for (i=0; i<cci->numPieces; i++) { + cci->pieces[i].piece=T1_GetEncodingIndex( FontID, ccd->pieces[i].pccName); + cci->pieces[i].deltax=ccd->pieces[i].deltax; + cci->pieces[i].deltay=ccd->pieces[i].deltay; + } + return( cci); + +} + + + +/* T1_IsInternalChar(): Query whether the character in encoding slot + char1 of font FontID has an internal definition (CharString) or + whether it is constructed by t1lib from elementary units */ +int T1_IsInternalChar( int FontID, char char1) +{ + unsigned char uchar1; + char *charname; + psdict *pCharStrings; + int len, i, j; + + /* return NULL if font not loaded */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return( -1); + } + + pCharStrings=pFontBase->pFontArray[FontID].pType1Data->CharStringsP; + uchar1=(unsigned char)char1; + + charname=T1_GetCharName( FontID, uchar1); + + /* First, get the maximum number of charstrings: */ + len=pCharStrings[0].key.len; + + /* Check all CharString definitions */ + for ( i=1; i<=len; i++) { + /* if len=0, then the CharStrings dict is larger that required which + is valid and allowed by the spec.*/ + if ((j=pCharStrings[i].key.len)!=0) { + if ( (j==strlen(charname)) && + (strncmp( charname, pCharStrings[i].key.data.nameP, j)==0) ) { + /* we have found an internal definition */ + return( 1); + } + } + } + return( 0); +} diff --git a/Build/source/libs/t1lib/t1finfo.h b/Build/source/libs/t1lib/t1finfo.h new file mode 100644 index 00000000000..7334f0130c8 --- /dev/null +++ b/Build/source/libs/t1lib/t1finfo.h @@ -0,0 +1,104 @@ +/*-------------------------------------------------------------------------- + ----- File: t1finfo.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-06-03 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1finfo.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifdef T1FINFO_C + + +int T1_GetKerning( int FontID, char char1, char char2); +int T1_GetCharWidth( int FontID, char char1); +BBox T1_GetCharBBox( int FontID, char char1); +float T1_GetUnderlinePosition( int FontID); +float T1_GetUnderlineThickness( int FontID); +float T1_GetItalicAngle( int FontID); +int T1_GetIsFixedPitch( int FontID); +char *T1_GetFontName( int FontID); +char *T1_GetFullName( int FontID); +char *T1_GetFamilyName( int FontID); +char *T1_GetWeight( int FontID); +char *T1_GetVersion( int FontID); +char *T1_GetNotice( int FontID); +char *T1_GetCharName( int FontID, char char1); +int T1_QueryLigs( int FontID, char char1, char **successors, char **ligatures); +int T1_GetEncodingIndex( int FontID, char *char1); +int *T1_GetEncodingIndices( int FontID, char *char1); +int T1_GetStringWidth( int FontID, char *string, + int len, long spaceoff,int kerning); +BBox T1_GetStringBBox( int FontID, char *string, + int len, long spaceoff, int kerning); +METRICSINFO T1_GetMetricsInfo( int FontID, char *string, + int len, long spaceoff, int kerning); +BBox T1_GetFontBBox( int FontID); +char **T1_GetAllCharNames( int FontID); +int T1_GetNoKernPairs( int FontID); +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2); +int T1_GetNoCompositeChars( int FontID); +int T1_QueryCompositeChar( int FontID, char char1); +T1_COMP_CHAR_INFO *T1_GetCompCharData( int FontID, char char1); +T1_COMP_CHAR_INFO *T1_GetCompCharDataByIndex( int FontID, int index); +int T1_IsInternalChar( int FontID, char char1); + + +#else + + +extern int T1_GetKerning( int FontID, char char1, + char char2); +extern int T1_GetCharWidth( int FontID, char char1); +extern BBox T1_GetCharBBox( int FontID, char char1); +extern float T1_GetUnderlinePosition( int FontID); +extern float T1_GetUnderlineThickness( int FontID); +extern float T1_GetItalicAngle( int FontID); +extern int T1_GetIsFixedPitch( int FontID); +extern char *T1_GetFontName( int FontID); +extern char *T1_GetFullName( int FontID); +extern char *T1_GetFamilyName( int FontID); +extern char *T1_GetWeight( int FontID); +extern char *T1_GetVersion( int FontID); +extern char *T1_GetNotice( int FontID); +extern char *T1_GetCharName( int FontID, char char1); +extern int T1_QueryLigs( int FontID, char char1, char **successors, char **ligatures); +extern int T1_GetEncodingIndex( int FontID, char *char1); +extern int *T1_GetEncodingIndices( int FontID, char *char1); +extern int T1_GetStringWidth( int FontID, char *string, + int len, long spaceoff,int kerning); +extern BBox T1_GetStringBBox( int FontID, char *string, + int len, long spaceoff, int kerning); +extern METRICSINFO T1_GetMetricsInfo( int FontID, char *string, + int len, long spaceoff, int kerning); +extern BBox T1_GetFontBBox( int FontID); +extern int T1_GetNoKernPairs( int FontID); +extern char **T1_GetAllCharNames( int FontID); +extern int T1_GetNoCompositeChars( int FontID); +extern int T1_QueryCompositeChar( int FontID, char char1); +extern T1_COMP_CHAR_INFO *T1_GetCompCharData( int FontID, char char1); +extern T1_COMP_CHAR_INFO *T1_GetCompCharDataByIndex( int FontID, int index); +extern int T1_IsInternalChar( int FontID, char char1); + + +#endif + diff --git a/Build/source/libs/t1lib/t1global.h b/Build/source/libs/t1lib/t1global.h new file mode 100644 index 00000000000..c62ed2d5c0a --- /dev/null +++ b/Build/source/libs/t1lib/t1global.h @@ -0,0 +1,115 @@ +/*-------------------------------------------------------------------------- + ----- File: t1global.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-04-01 + ----- Description: This file is part of the t1-library. It contains + global declarations used by the t1-library. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#include "t1misc.h" + + +/* Following struct will allow all accesses to font data! */ +struct FONTBASE +{ + int t1lib_flags; /* Global library flags */ + int no_fonts_ini; /* The number of fonts initially declared in + Font database file. */ + int no_fonts; /* The number of currently allocated fonts including + logical fonts produced by T1_CopyFont() */ + int no_fonts_limit; /* The maximum number of font for which is memory + currently available. */ + int bitmap_pad; /* The value to which bitmap-scanlines are padded */ + int endian; /* 1 if little endian representation and 0 otherwise */ + char **default_enc; /* The default encoding vector */ + FONTPRIVATE *pFontArray; /* Points to first element of font pointer array */ +} FontBase; +struct FONTBASE *pFontBase=NULL; + + + +/* Further we need a struct where to save device dependent data such as + resolution. The values in this struct may be altered using + T1_SetDeviceRes(x_res,y_res). Generally, the fontsize is to be specified + in BigPoints ("bp")---this is the default PostScript unit. It is + 1in=72bp. + */ +typedef struct +{ + float x_resolution; /* Value must be specified in DPI */ + float y_resolution; /* Value must be specified in DPI */ + float scale_x; /* horizontal scale-value to get a + matrix scaled to 1b */ + float scale_y; /* vertical scale-value to get a + matrix scaled to 1b */ +} DEVICESPECIFICS; + +DEVICESPECIFICS DeviceSpecifics = { DEFAULT_RES, + DEFAULT_RES, + DEFAULT_RES/BIGPOINTSPERINCH, + DEFAULT_RES/BIGPOINTSPERINCH +}; + + + +struct stat filestats; /* A structure where fileinfo is stored */ +char linebuf[BUF_SIZE]; /* A buffer for reading files line + by line */ +int T1_Up=0; /* This one is for initialization-checking */ + +/* The width of AA-pixels */ +int T1aa_bpp; + +/* The follwoing variable allows the primary rastering functions + to check for the caller */ +int SetFuncRequestID=0; + +/* The following variable allows to suppress rastering at 1000 bp + for getting a correct bounding box for slanted characters --> + should only internally be used */ +int ForceAFMBBox=0; + +extern struct XYspace *IDENTITY; + +int errornumber; /* for debugging purposes */ + +/* The following pointers should be set to path-strings--used for locating + type1, afm and encoding files */ +char** T1_PFAB_ptr=NULL; +char** T1_AFM_ptr=NULL; +char** T1_ENC_ptr=NULL; +char** T1_FDB_ptr=NULL; + +/* We use a uchar buffer for error and warning messages: */ +char err_warn_msg_buf[1024]; + +/* file pointer for log-file */ +FILE *t1lib_log_file=NULL; +int t1lib_log_level=2; + +/* The errno for t1lib */ +int T1_errno=0; + +/* A variable for saving stack info */ +jmp_buf stck_state; + diff --git a/Build/source/libs/t1lib/t1lib.ac b/Build/source/libs/t1lib/t1lib.ac new file mode 100644 index 00000000000..570587e44e2 --- /dev/null +++ b/Build/source/libs/t1lib/t1lib.ac @@ -0,0 +1,99 @@ +if test "$needs_libt1" = no; then + LIBT1CPPFLAGS= + LDLIBT1= + LIBT1DEP= +else + EXTRA_LIBT1_INCLUDE= + EXTRA_LIBT1_LIBDIR= + + if test "$with_system_t1lib" = yes; then + if test "x$with_t1lib_libdir" != x; then + EXTRA_LIBT1_LIBDIR="-L$with_t1lib_libdir" + fi + if test "x$with_t1lib_include" != x; then + EXTRA_LIBT1_INCLUDE="-I$with_t1lib_include" + fi + fi + + OLD_LDFLAGS=$LDFLAGS + OLD_CPP=$CPP + OLDCPPFLAGS=$CPPFLAGS + OLD_LIBS=$LIBS + + LDFLAGS="$LDFLAGS $EXTRA_LIBT1_LIBDIR" + CPP="$CPP $EXTRA_LIBT1_INCLUDE" + CPPFLAGS="$CPPFLAGS $EXTRA_LIBT1_INCLUDE" + + if test "$with_system_t1lib" = yes; then + AC_CHECK_LIB(t1, T1_AddFont, + t1lib=-lt1, + AC_MSG_WARN(Standard T1 library not found. Compiling my own.) + with_system_t1lib=no, + -lz -lm) + fi + + LIBS="-lt1 -lm $LIBS" + if test "$with_system_t1lib" = yes; then + AC_MSG_CHECKING(whether installed T1 lib is >= v 5.0.0 ) + AC_TRY_RUN([ +#include <stdlib.h> +#include "t1lib.h" +#define BUFLEN 128 +int main() { + char *t1libId = T1_GetLibIdent(); + char testbuf[BUFLEN]; + char *p = testbuf; + int i; + int version_num; + /* T1_GetLibIdent() might return something like '0.8-beta2'; + convert the leading numbers to a single digit: */ + for (i = 0; i < BUFLEN - 1; i++) { + if (t1libId[i] >= '0' && t1libId[i] <= '9') + *p++ = t1libId[i]; + else if (t1libId[i] != '.' && t1libId[i] != '_' && t1libId[i] != '-') + break; + } + *p = '\0'; + version_num = strtoul(testbuf, (char **)NULL, 10); + /* xdvik needs >= 5.0.0. + Try to deal with version strings with 1 or more digits. */ + if (version_num >= 500 + || (version_num < 100 && version_num >= 50) + || (version_num < 10 && version_num >= 5)) + exit(0); + exit(1); +} + ], + ac_compile_t1lib=0, + ac_compile_t1lib=1, + ac_compile_t1lib=1 + ]) + if test $ac_compile_t1lib = 0; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT([no, will compile my own version]) + with_system_t1lib=no + fi + fi + + LDFLAGS=$OLD_LDFLAGS + CPP=$OLD_CPP + CPPFLAGS=$OLDCPPFLAGS + LIBS=$OLD_LIBS + + if test "$with_system_t1lib" != yes; then + LIBT1CPPFLAGS='-I$(LIBT1DIR) -I$(LIBT1SRCDIR) -I$(LIBT1DIR)/../type1 -I$(LIBT1SRCDIR)/../type1' + LDLIBT1='$(LIBT1DIR)/libt1.a $(LIBT1DIR)/../type1/libtype1.a' + LIBT1DEP='$(LIBT1DIR)/libt1.a $(LIBT1DIR)/../type1/libtype1.a' + using_system_t1lib=no + else + LIBT1CPPFLAGS="$EXTRA_LIBT1_INCLUDE" + LDLIBT1="$EXTRA_LIBT1_LIBDIR -lt1" + LIBT1DEP= + using_system_t1lib=yes + fi +fi + +AC_SUBST(LIBT1CPPFLAGS) +AC_SUBST(LDLIBT1) +AC_SUBST(LIBT1DEP) diff --git a/Build/source/libs/t1lib/t1lib.h b/Build/source/libs/t1lib/t1lib.h new file mode 100644 index 00000000000..1c578c6cb1d --- /dev/null +++ b/Build/source/libs/t1lib/t1lib.h @@ -0,0 +1,465 @@ +/*-------------------------------------------------------------------------- + ----- File: t1lib.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2004-02-04 + ----- Description: This file is part of the t1-library. It must be + included by the user of the t1lib. It contains + function declarations and some basic data types, the + user must deal with. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2004. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifndef T1LIB_H_INCLUDED + +#define T1LIB_H_INCLUDED + +/* type definitions, needed by the user: */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Version information filled in by configure */ +#define T1LIB_VERSION 5 +#define T1LIB_REVISION 0 +#define T1LIB_PATCHLEVEL 1 +#define T1LIB_VERSIONSTRING "5.0.1" + + +/* the data structure which contains the character bitmap description */ +typedef struct +{ + char *bits; /* A pointer to the characters local bitmap */ + struct /* A struct containing diverse metric information */ + { + int ascent; + int descent; + int leftSideBearing; + int rightSideBearing; + int advanceX; + int advanceY; + } metrics; + void *pFontCacheInfo; + unsigned long bpp; +} GLYPH; + + +/* A structure representing a matrix */ +typedef struct +{ + double cxx; + double cyx; + double cxy; + double cyy; +} T1_TMATRIX; + + +/* the bounding box data structure: */ +typedef struct +{ + int llx; /* lower left x-position */ + int lly; /* lower left y-position */ + int urx; /* upper right x-position */ + int ury; /* upper right y-position */ +} BBox; + + +/* A data that makes most important information available to user. */ +typedef struct +{ + int width; /* The glyph's width */ + BBox bbox; /* The glyph's bounding box */ + int numchars; /* The number of characters in the glyph (string) */ + int *charpos; /* A pointer to an integer array were the horizontal + positions in (afm units) of the individual + characters in the string are stored */ +} METRICSINFO; + + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + +/* def's for T1_InitLib() */ +#define NO_LOGFILE 0x0 +#define LOGFILE 0x1 +#define IGNORE_FONTDATABASE 0x2 /* Default is to read database */ +#define IGNORE_CONFIGFILE 0x4 /* Default is to read config file */ +#define T1_AA_CACHING 0x8 /* Cache aa-bytes */ +#define T1_NO_AFM 0x10 /* Do not load or generate AFM data */ + + + +/* common 'yes'/'no' */ +#define T1_YES 0x1 +#define T1_NO 0x0 + + +/* logfile levels: */ +#define T1LOG_ERROR 1 +#define T1LOG_WARNING 2 +#define T1LOG_STATISTIC 3 +#define T1LOG_DEBUG 4 + + +/* #define's for manipulating searchpaths */ +#define T1_PFAB_PATH 0x01 +#define T1_AFM_PATH 0x02 +#define T1_ENC_PATH 0x04 +#define T1_FDB_PATH 0x08 +#define T1_APPEND_PATH 0x00 +#define T1_PREPEND_PATH 0x01 + + +/* #define's for character/string properties (not all implemented) */ +#define T1_DEFAULT 0x0000 +#define T1_UNDERLINE 0x0001 +#define T1_OVERLINE 0x0002 +#define T1_OVERSTRIKE 0x0004 +#define T1_DOUBLEOVERSTRIKE 0x0008 +#define T1_RIGHT_TO_LEFT 0x0010 +#define T1_SUBSCRIPT 0x0100 +#define T1_SUPERSCRIPT 0x0200 +#define T1_STROKED 0x1000 +#define T1_KERNING 0x2000 + + +/* Setting the subsampling value */ +#define T1_AA_NONE 1 +#define T1_AA_LOW 2 +#define T1_AA_HIGH 4 + + +/* Error handling: */ +extern int T1_errno; + +/* These are from scanning a font file */ +#define T1ERR_SCAN_FONT_FORMAT -5 +#define T1ERR_SCAN_FILE_OPEN_ERR -4 +#define T1ERR_SCAN_OUT_OF_MEMORY -3 +#define T1ERR_SCAN_ERROR -2 +#define T1ERR_SCAN_FILE_EOF -1 +/* These are from generating paths */ +#define T1ERR_PATH_ERROR 1 +#define T1ERR_PARSE_ERROR 2 +#define T1ERR_TYPE1_ABORT 3 +/* These are from t1lib */ +#define T1ERR_INVALID_FONTID 10 +#define T1ERR_INVALID_PARAMETER 11 +#define T1ERR_OP_NOT_PERMITTED 12 +#define T1ERR_ALLOC_MEM 13 +#define T1ERR_FILE_OPEN_ERR 14 +#define T1ERR_UNSPECIFIED 15 +#define T1ERR_NO_AFM_DATA 16 +#define T1ERR_X11 17 +#define T1ERR_COMPOSITE_CHAR 18 +#define T1ERR_SCAN_ENCODING 19 + + +/* Flags to control the rasterizer */ +#define T1_IGNORE_FORCEBOLD 0x0001 +#define T1_IGNORE_FAMILYALIGNMENT 0x0002 +#define T1_IGNORE_HINTING 0x0004 + +#define T1_DEBUG_LINE 0x0100 +#define T1_DEBUG_REGION 0x0200 +#define T1_DEBUG_PATH 0x0400 +#define T1_DEBUG_FONT 0x0800 +#define T1_DEBUG_HINT 0x1000 + + +/* definitions for outline handling */ +#define FRACTBITS 16 /* number of fractional bits in 'fractpel' */ +/* From/to conversion of pels/fractpels */ +#define T1_TOPATHPOINT(p) (((long)p)<<FRACTBITS) +#define PPHALF (1<<(FRACTBITS-1)) +#define T1_NEARESTPOINT(fp) (((fp)+PPHALF)>>FRACTBITS) + +/* A fractional point */ +typedef struct { + long x; + long y; +} T1_PATHPOINT; + + +/* A straight outline segment, stroked or not stroked */ +typedef struct pathsegment { + char type; /* type of segment (line or move) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* size of the structure */ + unsigned char context; /* index to device context */ + struct pathsegment *link; /* pointer to next structure in linked list */ + struct pathsegment *last; /* pointer to last structure in list */ + T1_PATHPOINT dest; /* relative ending location of path segment */ +} T1_PATHSEGMENT; + +/* A third order bezier segment */ +typedef struct bezierpathsegment { + char type; /* type of segment (bezier) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* as with any 'segment' type */ + unsigned char context; /* as with any 'segment' type */ + T1_PATHSEGMENT *link; /* as with any 'segment' type */ + T1_PATHSEGMENT *last; /* as with any 'segment' type */ + T1_PATHPOINT dest; /* ending point (D) */ + T1_PATHPOINT B; /* control point B */ + T1_PATHPOINT C; /* control point C */ +} T1_BEZIERSEGMENT; + +typedef T1_PATHSEGMENT T1_OUTLINE; + +#define T1_PATHTYPE_LINE 0x10 +#define T1_PATHTYPE_BEZIER 0x12 +#define T1_PATHTYPE_MOVE 0x15 + + +/* Definitions for font subsetting */ +#define T1_SUBSET_DEFAULT 0x00 +#define T1_SUBSET_FORCE_REENCODE 0x01 +#define T1_SUBSET_SKIP_REENCODE 0x02 +#define T1_SUBSET_ENCRYPT_BINARY 0x04 +/* This is only for debugging, it does not produce valid font-files! + This flag is not in the documented API!. */ +#define T1_SUBSET_ENCRYPT_NONE 0x08 + + +/* Two structures for handling composite character data */ +/* One structure for each symbol of the composite character */ +typedef struct +{ + int piece; /* the index of the current symbol */ + int deltax; /* horizontal displacement of current symbol in CS */ + int deltay; /* vertical displacement of current symbol in CS */ +} T1_COMP_PIECE; + +/* This one defines the composite character, the number of pieces and how to + access their data. */ +typedef struct +{ + int compchar; /* the base character in the current encoding */ + int numPieces; /* the number of defined pieces including the base char */ + T1_COMP_PIECE *pieces; /* a pointer to the pieces' information */ +} T1_COMP_CHAR_INFO; + + + +/* function declarations: */ + +/* from t1base.c */ +extern void *T1_InitLib( int log); +extern int T1_CloseLib( void); +extern int T1_AddFont( char *fontfilename); +extern void T1_PrintLog( char *func_ident, char *msg_txt, int level, ...); +extern void T1_SetLogLevel( int level); +extern int T1_CheckForInit(void); +extern int T1_CheckForFontID( int FontID); +extern char *T1_GetFontFileName( int FontID); +extern int T1_GetNoFonts(void); +extern int T1_SetDeviceResolutions( float x_res, float y_res); +extern int T1_CopyFont( int FontID); +extern int T1_QueryX11Support( void); +extern int T1_CheckEndian(void); +extern int T1_SetBitmapPad( int pad); +extern int T1_GetBitmapPad( void); +extern char *T1_GetLibIdent( void); +extern void T1_SetRasterFlags( int flags); +extern char *T1_GetAfmFileName( int FontID); +extern int T1_SetAfmFileName( int FontId, char *afm_name); +extern char *T1_GetFontFilePath( int FontID); +extern char *T1_GetAfmFilePath( int FontID); +extern const char *T1_StrError( int t1err); + +/* from t1delete.c */ +extern int T1_DeleteSize( int FontID, float size); +extern int T1_DeleteAllSizes( int FontID); +extern int T1_FreeGlyph( GLYPH *glyph); +extern int T1_FreeCompCharData( T1_COMP_CHAR_INFO *cci); +extern int T1_DeleteFont( int FontID); + +/* from t1enc.c */ +extern char **T1_LoadEncoding( char *FileName); +extern int T1_DeleteEncoding( char **encoding); +extern int T1_ReencodeFont( int FontID, char **Encoding); +extern int T1_SetDefaultEncoding( char **encoding); +extern char *T1_GetEncodingScheme( int FontID); + +/* from t1env.c */ +extern int T1_SetFileSearchPath( int type, char *pathname); +extern int T1_AddToFileSearchPath( int pathtype, int mode, char *pathname); +extern char *T1_GetFileSearchPath( int type); +extern int T1_SetFontDataBase( char *filename); +extern int T1_AddFontDataBase( int mode, char *filename); + +/* from t1finfo.c */ +extern int T1_GetKerning( int FontID, char char1, + char char2); +extern int T1_GetCharWidth( int FontID, char char1); +extern BBox T1_GetCharBBox( int FontID, char char1); +extern float T1_GetUnderlinePosition( int FontID); +extern float T1_GetUnderlineThickness( int FontID); +extern float T1_GetItalicAngle( int FontID); +extern int T1_GetIsFixedPitch( int FontID); +extern char *T1_GetFontName( int FontID); +extern char *T1_GetFullName( int FontID); +extern char *T1_GetFamilyName( int FontID); +extern char *T1_GetWeight( int FontID); +extern char *T1_GetVersion( int FontID); +extern char *T1_GetNotice( int FontID); +extern char *T1_GetCharName( int FontID, char char1); +extern int T1_QueryLigs( int FontID, + char char1, + char **successors, + char **ligatures); +extern int T1_GetEncodingIndex( int FontID, char *char1); +extern int *T1_GetEncodingIndices( int FontID, char *char1); +extern int T1_GetStringWidth( int FontID, char *string, + int len, long spaceoff, int kerning); +extern BBox T1_GetStringBBox( int FontID, char *string, + int len, long spaceoff, int kerning); +extern METRICSINFO T1_GetMetricsInfo( int FontID, char *string, + int len, long spaceoff, int kerning); +extern BBox T1_GetFontBBox( int FontID); +extern char **T1_GetAllCharNames( int FontID); +extern int T1_GetNoKernPairs( int FontID); +extern int T1_GetNoCompositeChars( int FontID); +extern int T1_QueryCompositeChar( int FontID, char char1); +extern T1_COMP_CHAR_INFO *T1_GetCompCharData( int FontID, char char1); +extern T1_COMP_CHAR_INFO *T1_GetCompCharDataByIndex( int FontID, int index); +extern int T1_IsInternalChar( int FontID, char char1); + +/* from t1load.c */ +extern int T1_LoadFont( int FontID); +extern void *T1_QueryFontSize( int FontID, float size, int aa); + +/* from t1set.c */ +extern GLYPH *T1_SetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetString( int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH* T1_SetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern GLYPH *T1_CopyGlyph(GLYPH *glyph); +extern void T1_DumpGlyph( GLYPH *glyph); +extern GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2, + int x_off, int y_off, int modflag); +extern void T1_DumpPixmap( GLYPH *glyph); +extern GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag); + +/* from t1trans.c */ +extern int T1_ExtendFont( int FontID, double extend); +extern int T1_SlantFont( int FontID, double slant); +extern int T1_TransformFont( int FontID, T1_TMATRIX *matrix); +extern double T1_GetExtend( int FontID); +extern double T1_GetSlant( int FontID); +extern T1_TMATRIX T1_GetTransform( int FontID); +extern int T1_SetLinePosition( int FontID, int linetype, float value); +extern int T1_SetLineThickness( int FontID, int linetype, float value); +extern float T1_GetLinePosition( int FontID, int linetype); +extern float T1_GetLineThickness( int FontID, int linetype); +extern T1_TMATRIX *T1_RotateMatrix( T1_TMATRIX *matrix, double angle); +extern T1_TMATRIX *T1_MirrorHMatrix( T1_TMATRIX *matrix); +extern T1_TMATRIX *T1_MirrorVMatrix( T1_TMATRIX *matrix); +extern T1_TMATRIX *T1_ShearHMatrix( T1_TMATRIX *matrix, double shear); +extern T1_TMATRIX *T1_ShearVMatrix( T1_TMATRIX *matrix, double shear); +extern T1_TMATRIX *T1_ExtendHMatrix( T1_TMATRIX *matrix, double extent); +extern T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX *matrix, double extent); +extern T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix, + double cxx, double cyx, + double cxy, double cyy); +extern int T1_StrokeFont( int FontID, int dostroke); +extern int T1_SetStrokeFlag( int FontID); +extern int T1_ClearStrokeFlag( int FontID); +extern int T1_GetStrokeMode( int FontID); +extern int T1_SetStrokeWidth( int FontID, float strokewidth); +extern float T1_GetStrokeWidth( int FontID); + + +/* from t1aaset.c */ +extern GLYPH *T1_AASetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetString( int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH* T1_AASetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern int T1_AASetGrayValues(unsigned long white, + unsigned long gray75, + unsigned long gray50, + unsigned long gray25, + unsigned long black); +extern int T1_AAHSetGrayValues( unsigned long *grayvals); +extern int T1_AANSetGrayValues( unsigned long bg, unsigned long fg); +extern int T1_AAGetGrayValues( long *pgrayvals); +extern int T1_AAHGetGrayValues( long *pgrayvals); +extern int T1_AANGetGrayValues( long *pgrayvals); +extern int T1_AASetBitsPerPixel( int bpp); +extern int T1_AAGetBitsPerPixel( void); +extern int T1_AASetLevel( int level); +extern int T1_AAGetLevel( void); +extern GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag); +extern int T1_AASetSmartLimits( float limit1, float limit2); +extern int T1_AASetSmartMode( int smart); + + +/* from t1afmtool.c */ +extern int T1_WriteAFMFallbackFile( int FontID); + +/* from t1outline.c */ +extern T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern T1_OUTLINE *T1_ConcatOutlines( T1_OUTLINE *path1, + T1_OUTLINE *path2); +extern T1_OUTLINE *T1_ScaleOutline( T1_OUTLINE *path, float scale); +extern T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, + float size, T1_TMATRIX *transform); +extern void T1_DumpPath( T1_OUTLINE *path); +extern void T1_AbsolutePath( T1_OUTLINE *rpath); +extern void T1_RelativePath( T1_OUTLINE *apath); +extern void T1_ManipulatePath( T1_OUTLINE *path, + void (*manipulate)(long *x,long *y,int type)); +extern T1_OUTLINE *T1_CopyOutline( T1_OUTLINE *path); +extern void T1_FreeOutline( T1_OUTLINE *path); + + +/* from t1subset.c */ +extern char *T1_SubsetFont( int FontID, + char *mask, + unsigned int flags, + int linewidth, + unsigned long maxblocksize, + unsigned long *bufsize); +extern char *T1_GetCharString( int FontID, char *charname, int *len); +extern int T1_GetlenIV( int FontID); + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* T1LIB_H_INCLUDED */ diff --git a/Build/source/libs/t1lib/t1libx.h b/Build/source/libs/t1lib/t1libx.h new file mode 100644 index 00000000000..e29e1543e46 --- /dev/null +++ b/Build/source/libs/t1lib/t1libx.h @@ -0,0 +1,93 @@ +/*-------------------------------------------------------------------------- + ----- File: t1libx.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It must be + included by the user of the t1lib. It contains + function declarations for the X11 wrapper. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifndef T1LIBX_H_INCLUDED + +#define T1LIBX_H_INCLUDED + + +#ifndef _XLIB_H_ +#include <X11/Xlib.h> +#endif + + +#define T1LIB_X11_SUPPORT + +/* For paint mode of X-rastering functions */ +#define T1_OPAQUE 0x1 +#define T1_TRANSPARENT 0x0 + + +/* type definitions, needed by the user: */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + + +/* from t1x11.c */ +extern int T1_SetX11Params( Display *display, + Visual *visual, + unsigned int depth, + Colormap colormap); +extern GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern int T1_ComputeAAColorsX( unsigned long fg, + unsigned long bg, + int nolevels); +extern int T1_GetDepthOfDrawable( Drawable drawable); +extern void T1_LogicalPositionX( int pos_switch); +extern XImage *T1_XImageFromGlyph( GLYPH *pglyph); + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* T1LIBX_H_INCLUDED */ diff --git a/Build/source/libs/t1lib/t1load.c b/Build/source/libs/t1lib/t1load.c new file mode 100644 index 00000000000..cce22e72c7f --- /dev/null +++ b/Build/source/libs/t1lib/t1load.c @@ -0,0 +1,1013 @@ +/*-------------------------------------------------------------------------- + ----- File: t1load.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-11-27 + ----- Description: This file is part of the t1-library. It contains + functions for loading fonts and for managing size + dependent data. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1LOAD_C + +/* + SU: Enabling this causes a segfault on OSF1/V5.1 alpha. Since it + appears to be an optimization only, I've disabled it until Rainer + has a fix. + */ +/* #define ANSI_REALLOC_VM */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/blues.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1load.h" +#include "t1env.h" +#include "t1set.h" +#include "t1base.h" +#include "t1finfo.h" +#include "t1afmtool.h" + + + +extern psobj *StdEncArrayP; /* For checking of a fonts encoding */ +extern char not_def[]; /* for checking the ".notdef"-string */ + + + +/* T1_LoadFont(FontID): Loads a Type1 font into memory and allocates all + memory, necessary for this. */ + +int T1_LoadFont( int FontID) +{ + int i, j, k, l, m; + char *FileName, *FileNamePath; + int mode; /* This is used by the type1-library for error reporting */ + char *charname; + + /* The following vars are used for reallocation of VM */ + long tmp_size; + float ascender; +#ifdef ANSI_REALLOC_VM + unsigned long shift; + unsigned long ldummy; + char *tmp_ptr; +#endif + + struct region *area; + struct XYspace *S; + + /* These are for constructing the kerning lookup table: */ + PairKernData *pkd; + METRICS_ENTRY *kern_tbl; + int char1, char2; + + + if (T1_CheckForInit()){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + + i=T1_CheckForFontID(FontID); + if (i==1) + return(0); /* Font already loaded */ + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); /* illegal FontID */ + } + + /* Allocate memory for ps_font structure: */ + if ((pFontBase->pFontArray[FontID].pType1Data=(psfont *)malloc(sizeof(psfont)))==NULL){ + T1_PrintLog( "T1_LoadFont()", "Failed to allocate memory for psfont-struct (FontID=%d)", + T1LOG_ERROR, FontID); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + + /* Check for valid filename */ + if ((FileName=T1_GetFontFileName(FontID))==NULL){ + T1_PrintLog( "T1_LoadFont()", "No font file name for font %d", T1LOG_ERROR, FontID); + return(-1); + } + + /* Fetch the full path of type1 font file */ + if ((FileNamePath=intT1_Env_GetCompletePath( FileName, + T1_PFAB_ptr))==NULL){ + T1_PrintLog( "T1_LoadFont()", "Couldn't locate font file for font %d in %s", + T1LOG_ERROR, FontID, T1_GetFileSearchPath(T1_PFAB_PATH)); + T1_errno=T1ERR_FILE_OPEN_ERR; + return(-1); + } + + /* And load all PostScript information into memory */ + if (fontfcnA( FileNamePath, &mode, + pFontBase->pFontArray[FontID].pType1Data) == FALSE){ + T1_PrintLog( "T1_LoadFont()", "Loading font with ID = %d failed! (mode = %d)", + T1LOG_ERROR, FontID, mode); + free(FileNamePath); + pFontBase->pFontArray[FontID].pType1Data=NULL; + T1_errno=mode; + return(-1); + } + free(FileNamePath); + + + /* Store the base address of virtual memory and realloc in order not + to waste too much memory: */ + pFontBase->pFontArray[FontID].vm_base=vm_base; +#ifdef ANSI_REALLOC_VM + /* We first get the size of pointers on the current system */ + /* Get size of VM, ... */ + tmp_size=((unsigned long)vm_used - (unsigned long)vm_base); + /* ... realloc to that size ... */ + tmp_ptr=(char *)realloc(vm_base, tmp_size); + /* ... and shift all pointers refering to that area */ + if (tmp_ptr > vm_base){ + shift= (unsigned long)tmp_ptr - (unsigned long)vm_base; + sprintf( err_warn_msg_buf, + "Old VM at 0x%lX, new VM at 0x%lX, shifting up by %lu", + (unsigned long)vm_base, (unsigned long)tmp_ptr, tmp_size); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + + /* We start by shifting the topmost pointers: */ + pFontBase->pFontArray[FontID].vm_base=tmp_ptr; + + ldummy=(long)(pFontBase->pFontArray[FontID].pType1Data->vm_start); + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->vm_start=(char *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP=(psdict *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->Private=(psdict *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP=(psdict *)ldummy; + + ldummy=(long)(pFontBase->pFontArray[FontID].pType1Data->BluesP); + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->BluesP=(struct blues_struct *)ldummy; + + /* We now have to care for correcting all pointers which are in the VM + and refer to some place in the VM! Note: Instead of selecting the + appropriate pointer-elements of the union we simply shift the + unspecified pointer "valueP". + Note: The filename entry does not need to be modified since it does not + need to be shifted since it points to memory managed by t1lib. + */ + /* FontInfo-dictionary: All name-pointers and the pointers to all array + types have to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->fontInfoP[0].key.len; + for (j=1; j<=i; j++){ + if ((pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ARRAY) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_STRING) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_NAME) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_FILE)){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy; + } + /* The encoding needs special treatment: */ + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ENCODING){ + /* If a builtin encoding is used, it is sufficient to shift the pointer + to the Encoding since the character-namestrings of builtin encodings + are static and thus located on the heap. + For font-specific encoding, character-namestrings reside in VM and + thus each entry has to be shifted. + Caution: We still have to shift the builtin encoding-pointer, since + they also point to are located in VM: */ + ldummy=(long)StdEncArrayP; + ldummy +=shift; + StdEncArrayP=(psobj *)ldummy; + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy; + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP + == StdEncArrayP){ /* Font uses builtin standard encoding */ + ; + } + else{ /* Font-specific encoding */ + for (k=0; k<256; k++){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP; + /* The ".notdef" is also static and may not be shifted (Thanks, Derek ;) */ + if (ldummy != (unsigned long)not_def) { + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP=(struct ps_obj *)ldummy; + } + } + } + } /* end of encoding-handling */ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].key.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].key.data.valueP=(char *)ldummy; + } /* fontinfo-dict done */ + + /* Private-dictionary: All name-pointers and the pointers to all array + types have to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->Private[0].key.len; + for (j=1; j<=i; j++){ + if ((pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_ARRAY) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_STRING) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_NAME) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_FILE)){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private[j].value.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->Private[j].value.data.valueP=(char *)ldummy; + } + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private[j].key.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->Private[j].key.data.valueP=(char *)ldummy; + } + + /* BluesP: The entry "next" is the only pointer in blues_struct. Although it is + not used anywhere we should shift it for correctness reasons (in case its not + NULL)! */ + if (pFontBase->pFontArray[FontID].pType1Data->BluesP->next != NULL){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->BluesP->next; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->BluesP->next=(struct blues_struct *)ldummy; + } + + /* The CharStrings-dictionary: Every namepointer and its corresponding + charstring has to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->CharStringsP[0].key.len; + for (j=1; j<=i; j++){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].value.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].value.data.valueP=(char *)ldummy; + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].key.data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].key.data.valueP=(char *)ldummy; + } + + /* The Subroutines have also to be reorganized: */ + i=pFontBase->pFontArray[FontID].pType1Data->Subrs.len; + /* First, shift pointer to array-start and after that the pointers to + each command string: */ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP=(struct ps_obj *)ldummy; + for (j=0; j<i; j++) { + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP[j].data.valueP; + ldummy +=shift; + pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP[j].data.valueP=(char *)ldummy; + } + } /* end of if( tmp_ptr > vm_base ) */ + else if ( vm_base > tmp_ptr){ + shift= (unsigned long)vm_base - (unsigned long)tmp_ptr; + sprintf( err_warn_msg_buf, + "Old VM at 0x%lX, new VM at 0x%lX, shifting down by %lu", + (unsigned long)vm_base, (unsigned long)tmp_ptr, tmp_size); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + + /* We start by shifting the topmost pointers: */ + pFontBase->pFontArray[FontID].vm_base=tmp_ptr; + + ldummy=(long)(pFontBase->pFontArray[FontID].pType1Data->vm_start); + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->vm_start=(char *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP=(psdict *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->Private=(psdict *)ldummy; + + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP=(psdict *)ldummy; + + ldummy=(long)(pFontBase->pFontArray[FontID].pType1Data->BluesP); + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->BluesP=(struct blues_struct *)ldummy; + + /* We now have to care for correcting all pointers which are in the VM + and refer to some place in the VM! Note: Instead of selecting the + appropriate pointer-elements of the union we simply shift the + unspecified pointer "valueP". + Note: The filename entry does not need to be modified since it does not + need to be shifted since it points to memory managed by t1lib. + */ + /* FontInfo-dictionary: All name-pointers and the pointers to all array + types have to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->fontInfoP[0].key.len; + for (j=1; j<=i; j++){ + if ((pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ARRAY) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_STRING) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_NAME) || + (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_FILE)){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy; + } + /* The encoding needs special treatment: */ + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.type==OBJ_ENCODING){ + /* If a builtin encoding is used, it is sufficient to shift the pointer + to the Encoding since the character-namestrings of builtin encodings + are static and thus located on the heap. + For font-specific encoding, character-namestrings reside in VM and + thus each entry has to be shifted. + Caution: We still have to shift the builtin encoding-pointer, since + they also point to are located in VM: */ + ldummy=(long)StdEncArrayP; + ldummy -=shift; + StdEncArrayP=(psobj *)ldummy; + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.valueP=(char *)ldummy; + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP + == StdEncArrayP){ /* Font uses builtin encoding */ + ; + } + else{ /* Font-specific encoding */ + for (k=0; k<256; k++){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP; + /* The ".notdef" is also static and may not be shifted (Thanks, Derek ;) */ + if (ldummy != (unsigned long)not_def) { + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].value.data.arrayP[k].data.arrayP=(struct ps_obj *)ldummy; + } + } + } + } /* end of encoding-handling */ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].key.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[j].key.data.valueP=(char *)ldummy; + } /* fontinfo-dict done */ + + /* Private-dictionary: All name-pointers and the pointers to all array + types have to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->Private[0].key.len; + for (j=1; j<=i; j++){ + if ((pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_ARRAY) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_STRING) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_NAME) || + (pFontBase->pFontArray[FontID].pType1Data->Private[j].value.type==OBJ_FILE)){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private[j].value.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->Private[j].value.data.valueP=(char *)ldummy; + } + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Private[j].key.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->Private[j].key.data.valueP=(char *)ldummy; + } + + /* BluesP: The entry "next" is the only pointer in blues_struct. Although it is + not used anywhere we should shift it for correctness reasons (in case its not + NULL)! */ + if (pFontBase->pFontArray[FontID].pType1Data->BluesP->next != NULL){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->BluesP->next; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->BluesP->next=(struct blues_struct *)ldummy; + } + + /* The CharStrings-dictionary: Every namepointer and its corresponding + charstring has to be shifted: */ + i=pFontBase->pFontArray[FontID].pType1Data->CharStringsP[0].key.len; + for (j=1; j<=i; j++){ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].value.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].value.data.valueP=(char *)ldummy; + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].key.data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->CharStringsP[j].key.data.valueP=(char *)ldummy; + } + + /* The Subroutines have also to be reorganized: */ + i=pFontBase->pFontArray[FontID].pType1Data->Subrs.len; + /* First, shift pointer to array-start and after that the pointers to + each command string: */ + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP=(struct ps_obj *)ldummy; + for (j=0; j<i; j++) { + ldummy=(long)pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP[j].data.valueP; + ldummy -=shift; + pFontBase->pFontArray[FontID].pType1Data->Subrs.data.arrayP[j].data.valueP=(char *)ldummy; + } + } /* end of if( vm_base > tmp_ptr ) */ + else{ /* VM addess has not changed during reallocation */ + sprintf( err_warn_msg_buf, + "Old VM and new VM at 0x%lX, no pointer-shifting", + (unsigned long)vm_base); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + } +#endif + + /* Generate a message how much VM the current font consumes */ + sprintf( err_warn_msg_buf, + "VM for Font %d: %d bytes", FontID, (int) tmp_size); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_STATISTIC); + + + /* Set the matrix for common transformations to "no transformations" */ + pFontBase->pFontArray[FontID].FontTransform[0]=1.0; + pFontBase->pFontArray[FontID].FontTransform[1]=0.0; + pFontBase->pFontArray[FontID].FontTransform[2]=0.0; + pFontBase->pFontArray[FontID].FontTransform[3]=1.0; + + /* Now, that the font has been loaded into memory, try to find the + FontMatrix in the font info dictionary. If it exists, load it into + our local fontmatrix, otherwise use a default matrix which scales to + 1/1000 (since font outlines are defined in a 1000 point space) + and does no further transformations. */ + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTMATRIX].value.data.arrayP == NULL){ + pFontBase->pFontArray[FontID].FontMatrix[0]=0.001; + pFontBase->pFontArray[FontID].FontMatrix[1]=0.0; + pFontBase->pFontArray[FontID].FontMatrix[2]=0.0; + pFontBase->pFontArray[FontID].FontMatrix[3]=0.001; + } + else{ + pFontBase->pFontArray[FontID].FontMatrix[0]= (double)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTMATRIX].value.data.arrayP[0].data.real; + pFontBase->pFontArray[FontID].FontMatrix[1]= (double)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTMATRIX].value.data.arrayP[1].data.real; + pFontBase->pFontArray[FontID].FontMatrix[2]= (double)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTMATRIX].value.data.arrayP[2].data.real; + pFontBase->pFontArray[FontID].FontMatrix[3]= (double)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTMATRIX].value.data.arrayP[3].data.real; + } + + /* Set the default values for transformation: */ + pFontBase->pFontArray[FontID].slant=0.0; + pFontBase->pFontArray[FontID].extend=1.0; + + + /* Now try to load afm-structures from corresponding .afm-file (if + not suppressed by the user). */ + if ((pFontBase->t1lib_flags & T1_NO_AFM)!=0) { + pFontBase->pFontArray[FontID].pAFMData = NULL; + T1_PrintLog( "T1_LoadFont()", + "Suppressing AFM data handling on user request", + T1LOG_STATISTIC); + } + else { + if ((i=openFontMetricsFile( FontID, 0))){ + /* Try a fallback, opening sloppy: */ + if ((i=openFontMetricsFile( FontID, 1))) { + sprintf( err_warn_msg_buf, + "Alert: Error (%d) sloppy-processing afm-file for Font %d!", + i ,FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_STATISTIC); + if ((pFontBase->pFontArray[FontID].pAFMData= + T1_GenerateAFMFallbackInfo(FontID))==NULL){ + sprintf( err_warn_msg_buf, + "Ultimately failed to generate metrics information Font %d!", + FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_WARNING); + } + else { + pFontBase->pFontArray[FontID].info_flags |=AFM_SELFGEN_SUCCESS; + T1_PrintLog( "T1_LoadFont()", + "Generating AFM-information from fontfile successful!", + T1LOG_STATISTIC); + } + } + else { + pFontBase->pFontArray[FontID].info_flags |=AFM_SLOPPY_SUCCESS; + sprintf( err_warn_msg_buf, + "Alert: Limited afm-information for Font %d",FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_STATISTIC); + } + } + else { + pFontBase->pFontArray[FontID].info_flags |=AFM_SUCCESS; + } + } + + + /* Now, set Encodingvector entry to default if the font's + internal encoding is "StandardEncoding". + */ + if (pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP + == StdEncArrayP) { + pFontBase->pFontArray[FontID].info_flags |=USES_STANDARD_ENCODING; + pFontBase->pFontArray[FontID].pFontEnc=pFontBase->default_enc; + sprintf( err_warn_msg_buf, + "Font %d reencoded to default",FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + } + else { + sprintf( err_warn_msg_buf, + "Font %d not reencoded to default",FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + pFontBase->pFontArray[FontID].pFontEnc = NULL; + } + + + /* If AFM-Info available we try to speed up some things: */ + if (pFontBase->pFontArray[FontID].pAFMData != NULL) { + /* We have to fill the array that maps the current encodings' indices to the + indices used in afm file. The interpretation has been changed in + in t1lib-1.2. We now use positive values for indexing into the charmetrics + array and negative values for indexing into the composite character array. + an index of zero indicates that no metrics are defined for this character. + This may happen because (a) not all AFM-files define metrics for the .notdef + character, and (b) because font and AFM-file do not match. */ + if ((pFontBase->pFontArray[FontID].pEncMap= + (int *)calloc(256,sizeof(int)))==NULL) { + sprintf( err_warn_msg_buf, "Error allocating memory for encoding map (FontID=%d)", + FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + for (i=0; i<256; i++) { + charname=T1_GetCharName( FontID, i); + /* in a first loop check for ordinary characters */ + for ( j=0; j<pFontBase->pFontArray[FontID].pAFMData->numOfChars; j++) { + if (strcmp( charname, + pFontBase->pFontArray[FontID].pAFMData->cmi[j].name)==0) { + pFontBase->pFontArray[FontID].pEncMap[i]=j+1; /* index 0 is reserved! */ + continue; + } + } + /* if nothing has been found, check for composite characters */ + for ( j=0; j<pFontBase->pFontArray[FontID].pAFMData->numOfComps; j++) { + if (strcmp( charname, + pFontBase->pFontArray[FontID].pAFMData->ccd[j].ccName)==0) { + pFontBase->pFontArray[FontID].pEncMap[i]=-(j+1); /* index 0 is reserved! */ + continue; + } + } + } + + /* For composite characters, we still have to compute the width and bbox */ + for ( j=0; j<pFontBase->pFontArray[FontID].pAFMData->numOfComps; j++) { + /*and bounding box by ourselves. First, set up an identity charspace + matrix and then generate an edgelist for the composite character at + size 1000bp using no transformation and current encoding. Note: This + action is only required when loading a font at first time, but not + when reencoding a font. */ + S=(struct XYspace *)IDENTITY; + S=(struct XYspace *)Permanent + (Transform(S, pFontBase->pFontArray[FontID].FontTransform[0], + pFontBase->pFontArray[FontID].FontTransform[1], + pFontBase->pFontArray[FontID].FontTransform[2], + pFontBase->pFontArray[FontID].FontTransform[3])); + + area=fontfcnB_ByName( FontID, 0, S, + pFontBase->pFontArray[FontID].pAFMData->ccd[j].ccName, + &mode, pFontBase->pFontArray[FontID].pType1Data, + DO_RASTER); + /* Store bounding box ... */ + pFontBase->pFontArray[FontID].pAFMData->ccd[j].charBBox.llx=area->xmin; + pFontBase->pFontArray[FontID].pAFMData->ccd[j].charBBox.urx=area->xmax; + pFontBase->pFontArray[FontID].pAFMData->ccd[j].charBBox.lly=area->ymin; + pFontBase->pFontArray[FontID].pAFMData->ccd[j].charBBox.ury=area->ymax; + /* ... and character width. This should be the width of the base character + of the composite! */ + pFontBase->pFontArray[FontID].pAFMData->ccd[j].wx=NEARESTPEL(area->ending.x); + /* clean up. */ + KillRegion (area); + if (S!=NULL) { + KillSpace (S); + S=NULL; + } + } + /* We now create an encoding-specific kerning table which will speed up + looking for kerning pairs! */ + pFontBase->pFontArray[FontID].KernMapSize=0; + /* First, get number of defined kerning pairs: */ + k=pFontBase->pFontArray[FontID].pAFMData->numOfPairs; + if (k>0){ /* i.e., there are any pairs */ + /* OK, it does not suffice to alloc numOfPairs METRICS_ENTRYs, because + a given character might be encoded at several locations and kerning + should still work. As a worst case estimation, we allocate 256^2 + and realloc later. */ + if ((pFontBase->pFontArray[FontID].pKernMap= + (METRICS_ENTRY *)malloc( (256*256) *sizeof( METRICS_ENTRY)))==NULL){ + sprintf( err_warn_msg_buf, "Error allocating memory for metrics map (FontID=%d)", + FontID); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, + T1LOG_WARNING); + T1_errno=T1ERR_ALLOC_MEM; + return(-1); + } + kern_tbl=pFontBase->pFontArray[FontID].pKernMap; + pkd=pFontBase->pFontArray[FontID].pAFMData->pkd; + j=0; + for ( i=0; i<k; i++) { + /* We do not check T1_GetEncodingIndices() against the return value + NULL because we just loading the font in question: */ + l=0; + while ((char1=(T1_GetEncodingIndices( FontID, pkd[i].name1))[l++])!=-1) { + /* pair could be relevant in current encoding */ + m=0; + while ((char2=(T1_GetEncodingIndices( FontID, pkd[i].name2))[m++])!=-1) { + /* Since we get here we have a relevant pair --> + Put char1 in higher byte and char2 in LSB: */ + kern_tbl[j].chars=(char1 << 8) | char2; + /* We only make use of horizontal kerning */ + kern_tbl[j].hkern=pkd[i].xamt; + j++; + } /* while (char2) */ + } /* while (char1) */ + } /* for */ + /* We are done, realloc memory: */ + kern_tbl=(METRICS_ENTRY*) realloc( kern_tbl, j*sizeof(METRICS_ENTRY)); + /* We now sort the kerning array with respect to char indices */ + qsort( kern_tbl, (size_t) j, sizeof(METRICS_ENTRY), + &cmp_METRICS_ENTRY ); + /* Finally write back pointer for the case that realloc changed the + pointer */ + pFontBase->pFontArray[FontID].pKernMap=kern_tbl; + pFontBase->pFontArray[FontID].KernMapSize=j; + } + else + pFontBase->pFontArray[FontID].pKernMap=NULL; + } + else { /* no AFM data */ + pFontBase->pFontArray[FontID].pKernMap=NULL; + pFontBase->pFontArray[FontID].pEncMap=NULL; + } + /* End of "if (AFM-info ..)" */ + + + /* We have just loaded a physical font into memory, thus .... */ + pFontBase->pFontArray[FontID].physical=1; + + /* Set reference-counter to 1: */ + pFontBase->pFontArray[FontID].refcount=1; + + /* Get the index into encoding vector where the space character is + found. If not encoded, set space_position to -1. */ + pFontBase->pFontArray[FontID].space_position=-1; + i=0; + if (pFontBase->pFontArray[FontID].pFontEnc) { /* external default encoding */ + while (i<256) { + if (strcmp( (char *)pFontBase->pFontArray[FontID].pFontEnc[i], + "space")==0){ + /* space found at position i: */ + pFontBase->pFontArray[FontID].space_position=i; + break; + } + i++; + } + } + else { /* internal encoding */ + while (i<256) { + if (strcmp( (char *)pFontBase->pFontArray[FontID].pType1Data->fontInfoP[ENCODING].value.data.arrayP[i].data.arrayP, + "space")==0){ + /* space found at position i: */ + pFontBase->pFontArray[FontID].space_position=i; + break; + } + i++; + } + } + + + /* Set the lining rule parameters to default values */ + pFontBase->pFontArray[FontID].UndrLnPos= + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[UNDERLINEPOSITION].value.data.real; + pFontBase->pFontArray[FontID].UndrLnThick= + pFontBase->pFontArray[FontID].pType1Data->fontInfoP[UNDERLINETHICKNESS].value.data.real; + + /* We have to set the value for the typographic ascender. If possible, + we get it from the afm-File. But be aware this value might be undefined! + This value should in any acse explicitly be set later by the user! */ + if (pFontBase->pFontArray[FontID].pAFMData!=NULL && + pFontBase->pFontArray[FontID].pAFMData->gfi!=NULL) { + ascender=(float) pFontBase->pFontArray[FontID].pAFMData->gfi->ascender; + } + else { + ascender=(float) T1_GetCharBBox( FontID, T1_GetEncodingIndex( FontID, "d")).ury; + } + + pFontBase->pFontArray[FontID].OvrLnPos=ascender + + (float) abs( (double)pFontBase->pFontArray[FontID].UndrLnPos); + pFontBase->pFontArray[FontID].OvrStrkPos=ascender / 2.0; + pFontBase->pFontArray[FontID].OvrLnThick=pFontBase->pFontArray[FontID].UndrLnThick; + pFontBase->pFontArray[FontID].OvrStrkThick=pFontBase->pFontArray[FontID].UndrLnThick; + + + /* Finally, set the font size dependencies pointer to NULL since we can + assume, that at load time of a font, no size specific data of this + font is available. + */ + + pFontBase->pFontArray[FontID].pFontSizeDeps=NULL; + + /* If wanted, some debugging information is put into logfile */ + sprintf( err_warn_msg_buf, "Pointer vm_base: 0x%lX", + (long)pFontBase->pFontArray[FontID].vm_base); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "Pointer vm_start: 0x%lX", + (long)pFontBase->pFontArray[FontID].pType1Data->vm_start); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "Pointer CharStringsP: 0x%lX", + (long)pFontBase->pFontArray[FontID].pType1Data->CharStringsP); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "Pointer Private: 0x%lX", + (long)pFontBase->pFontArray[FontID].pType1Data->Private); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + sprintf( err_warn_msg_buf, "Pointer fontInfoP: 0x%lX", + (long)pFontBase->pFontArray[FontID].pType1Data->fontInfoP); + T1_PrintLog( "T1_LoadFont()", err_warn_msg_buf, T1LOG_DEBUG); + + return(0); +} + + +/* openFontMetricsFile( FontID, open_sloppy): Gets the fontfilename + corresponding to FontID, opens the corresponding afm-file and fills + the data structures. return-value is the value returned by the + T1lib_parseFile() function. If open_sloppy is set, the minimum + information needed is read from AFM file. This can be considered a + fallback for problematic AFM files. */ +static int openFontMetricsFile( int FontID, int open_sloppy) +{ + char *FontFileName; + char *AFMFileName; + char *afm_name; + char *AFMFileNamePath; + + int i, j; + FILE *metricsfile; + + + afm_name=T1_GetAfmFileName(FontID); + + if (afm_name!=NULL) { /* We have name explicitly specified */ + /* It needs to be freeable */ + if ((AFMFileName= + (char *)malloc( (strlen(afm_name)+1)*sizeof( char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( -6); + } + strcpy( AFMFileName, afm_name); + } + else { + FontFileName=T1_GetFontFileName( FontID); + i=strlen(FontFileName); + j=i; + AFMFileName=(char *)malloc( i+5); + strcpy( AFMFileName, FontFileName); + while ( AFMFileName[i] != '.'){ + if (i==0) break; + else i--; + } + if (i==0){ + /* We have a filename without extension -> append extension */ + AFMFileName[j]='.'; + AFMFileName[j+1]='a'; + AFMFileName[j+2]='f'; + AFMFileName[j+3]='m'; + AFMFileName[j+4]='\0'; + } + else{ + /* we found a '.' -> replace extension */ + AFMFileName[i+1]='a'; + AFMFileName[i+2]='f'; + AFMFileName[i+3]='m'; + AFMFileName[i+4]='\0'; + } + } + + /* Get full path of the afm file (The case of a full path name + name specification is valid */ + AFMFileNamePath=intT1_Env_GetCompletePath( AFMFileName, T1_AFM_ptr); + free( AFMFileName); + + /* open afm-file: */ + if (AFMFileNamePath!=NULL){ + if ((metricsfile=fopen(AFMFileNamePath,"rb"))==NULL){ + free(AFMFileNamePath); + return(-4); + } + else { + free(AFMFileNamePath); + } + } + else{ + return( -5); + } + + /* Call procedure to read afm-file and store the data formatted. + Flags used here: P_M All Metrics Information + P_P Pair Kerning Information + P_C Composite Character Data (since t1lib V.1.2) + The P_G flag to get global font information should not be used + if not absolutely needed. When parsing an unknown keyword, which + may be harmless, the T1lib_parseFile function returns the error code + -1 (parseError). On the other hand, all other really relevant + data may habe been parsed and stored correctly. In such a case, + There's no way to make a serious decision whether an error has + occured or not. + */ + if (open_sloppy!=0) + i=T1lib_parseFile( (FILE *) metricsfile, + (FontInfo **) &(FontBase.pFontArray[FontID].pAFMData), + P_M ); + else + i=T1lib_parseFile( (FILE *) metricsfile, + (FontInfo **) &(FontBase.pFontArray[FontID].pAFMData), + P_G | P_M | P_P | P_C ); + fclose(metricsfile); + return(i); +} + + + +/* T1int_CreateNewFontSize( FontID, size): Create a new size "size" of font + "FontID" and allocate all data necessary for this. The data + structure is connected to the linked list of FontSizeDeps for this + font. Returns a pointer to the newly created FontSizeDeps-struct + if all went correct and NULL otherwise. + Since of version 0.3 a member antialias has been added to the + FONTSIZEDEPS structure! This can be: + + 0: bitmaps are stored in this struct + 1: non-antialiased bytemaps are stored in this struct + 2: low-antialiased bytemaps are stored in this struct + 4: high-antialiased bytemaps are stored in this struct + */ +FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa) +{ + + FONTSIZEDEPS *pFontSizeDeps, *pPrev; + + + /* First, get to the last font size in the linked list for this font. + The following routine returns the address of the last struct in the + linked list of FONTSIZEDEPS or NULL if none exists. */ + pFontSizeDeps=T1int_GetLastFontSize( FontID); + pPrev=pFontSizeDeps; + + + if (pFontSizeDeps==NULL){ + /* Allocate memory for first FontSizeDeps-structure: */ + if ((pFontBase->pFontArray[FontID].pFontSizeDeps=(FONTSIZEDEPS *)malloc(sizeof(FONTSIZEDEPS)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + pFontSizeDeps=pFontBase->pFontArray[FontID].pFontSizeDeps; + } + else{ + /* A valid address of an existing structure was found */ + if ((pFontSizeDeps->pNextFontSizeDeps=(FONTSIZEDEPS *)malloc(sizeof(FONTSIZEDEPS)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + pFontSizeDeps=pFontSizeDeps->pNextFontSizeDeps; + } + + /* The pointer to the previous struct */ + pFontSizeDeps->pPrevFontSizeDeps=pPrev; + /* Put the size into this structure */ + pFontSizeDeps->size=size; + /* Set the antialias mark: */ + pFontSizeDeps->antialias=aa; + + /* Just the current becomes now the last item in the linked list: */ + pFontSizeDeps->pNextFontSizeDeps=NULL; + /* Setup CharSpaceMatrix for this font: */ + pFontSizeDeps->pCharSpaceLocal=(struct XYspace *) IDENTITY; + /* Apply transformation with font matrix: */ + pFontSizeDeps->pCharSpaceLocal=(struct XYspace *) + Transform(pFontSizeDeps->pCharSpaceLocal, + pFontBase->pFontArray[FontID].FontMatrix[0], + pFontBase->pFontArray[FontID].FontMatrix[1], + pFontBase->pFontArray[FontID].FontMatrix[2], + pFontBase->pFontArray[FontID].FontMatrix[3]); + /* Apply a further transformation (optionally): */ + pFontSizeDeps->pCharSpaceLocal=(struct XYspace *) + Transform(pFontSizeDeps->pCharSpaceLocal, + pFontBase->pFontArray[FontID].FontTransform[0], + pFontBase->pFontArray[FontID].FontTransform[1], + pFontBase->pFontArray[FontID].FontTransform[2], + pFontBase->pFontArray[FontID].FontTransform[3]); + /* Apply desired scaling factor, and make it Permanent */ + pFontSizeDeps->pCharSpaceLocal=(struct XYspace *) Permanent + (Scale(pFontSizeDeps->pCharSpaceLocal, size, size)); + + /* We should now allocate memory for the glyph area of the font + cache: */ + if ((pFontSizeDeps->pFontCache=(GLYPH *)calloc(256,sizeof(GLYPH))) + ==NULL) + return(NULL); + + sprintf( err_warn_msg_buf, "New Size %f created for FontID %d (antialias=%d)", + pFontSizeDeps->size, FontID, pFontSizeDeps->antialias); + T1_PrintLog( "CreateNewFontSize()", err_warn_msg_buf, T1LOG_STATISTIC); + /* We are done */ + return(pFontSizeDeps); + +} + + + + +/* T1_QueryFontSize( FontID, size, aa): Search if a requested size of font + FontID is already existing. If so, it returns a pointer to the + respective FontSizeDeps-structure, otherwise NULL is returned: */ +FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa) +{ + + FONTSIZEDEPS *link_ptr; + + + /* There's not yet one size: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps == NULL) + return(pFontBase->pFontArray[FontID].pFontSizeDeps); + + + /* There's already existing one or more size */ + link_ptr=pFontBase->pFontArray[FontID].pFontSizeDeps; + + while (((link_ptr->size != size)||(link_ptr->antialias != aa)) + &&(link_ptr->pNextFontSizeDeps != NULL)) + link_ptr=link_ptr->pNextFontSizeDeps; + + if ((link_ptr->size != size)||(link_ptr->antialias != aa)) + return( NULL); /* requested size/aa-combination was not found */ + else + return(link_ptr); /* return pointer to requested struct */ + +} + +/* FONTSIZEDEPS *T1int_GetLastFontSize( FontID): Get the address of the + last struct in the linked list of FontSizeDeps or NULL if there is + no existing size dependent data. */ +FONTSIZEDEPS *T1int_GetLastFontSize( int FontID) +{ + FONTSIZEDEPS *link_ptr, *result_ptr; + + + /* There's not yet one size: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps == NULL) + return((FONTSIZEDEPS *) (pFontBase->pFontArray[FontID].pFontSizeDeps)); + + + /* There's already existing one or more size */ + link_ptr=pFontBase->pFontArray[FontID].pFontSizeDeps; + + while (link_ptr != NULL){ + result_ptr=link_ptr; + link_ptr=link_ptr->pNextFontSizeDeps; + } + + return((FONTSIZEDEPS *)(result_ptr)); +} + + +/* A function for comparing METRICS_ENTRY structs */ +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2) +{ + if (((METRICS_ENTRY *)entry1)->chars < + ((METRICS_ENTRY *)entry2)->chars) + return(-1); + if (((METRICS_ENTRY *)entry1)->chars > + ((METRICS_ENTRY *)entry2)->chars) + return(1); + return(0); /* This should not happen */ +} + + diff --git a/Build/source/libs/t1lib/t1load.h b/Build/source/libs/t1lib/t1load.h new file mode 100644 index 00000000000..534a18b5b1d --- /dev/null +++ b/Build/source/libs/t1lib/t1load.h @@ -0,0 +1,48 @@ +/*-------------------------------------------------------------------------- + ----- File: t1load.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-02 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1load.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifdef T1LOAD_C + +int T1_LoadFont( int FontID); +static int openFontMetricsFile( int FontID, int open_sloppy); +FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa); +FONTSIZEDEPS *T1int_GetLastFontSize( int FontID); +FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa); +int fontfcnA( char *env, int *mode, psfont *Font_Ptr); +static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2); +extern char *vm_base; /* from fontfcn.c in initfont()! */ +extern char *vm_used; /* from fontfcn.c in fontfcnA()! */ + +#else + +extern int T1_LoadFont( int FontID); +extern FONTSIZEDEPS *T1int_CreateNewFontSize( int FontID, float size, int aa); +extern FONTSIZEDEPS *T1int_GetLastFontSize( int FontID); +extern FONTSIZEDEPS *T1int_QueryFontSize( int FontID, float size, int aa); + +#endif diff --git a/Build/source/libs/t1lib/t1misc.h b/Build/source/libs/t1lib/t1misc.h new file mode 100644 index 00000000000..c45c55962e4 --- /dev/null +++ b/Build/source/libs/t1lib/t1misc.h @@ -0,0 +1,214 @@ +/*-------------------------------------------------------------------------- + ----- File: t1misc.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2004-03-03 + ----- Description: This file is part of the t1-library. It contains + some miscellaneous definitions. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2004. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#include <setjmp.h> + +#define LINE_BUF 512 +#define BUF_SIZE 512 +#define NULLPTR (void *) 0 + + +/* t1lib-glyphs are padded to this value by default: */ +#define T1GLYPH_PAD 8 +#define T1GLYPH_BIT 0 +#define T1GLYPH_BYTE 0 +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + +/* For debugging purposes: */ +#define SLEEP for(j=0; j<50; j++){for (k=0; k<65536; k++);} + + +#define KERN_FLAG 0x01 +#define LIGATURE_FLAG 0x02 + + +/* common 'yes'/'no' */ +#define T1_YES 0x1 +#define T1_NO 0x0 + + +/* The maximum length of a PostScript name of a font: */ +#define MAXPSNAMELEN 256 +#define MAXPATHLEN 4096 + +/* The default resolution used by the library */ +#define DEFAULT_RES 72.0 +#define BIGPOINTSPERINCH 72.0 + +/* Defaults for configuration file searching: */ +/* (Note: The directory where the global config will be located is + determined by configure at compile time) */ +#define T1_CONFIGFILENAME ".t1librc" +#define ENV_CONF_STRING "T1LIB_CONFIG" +#define GLOBAL_CONFIG_FILE "t1lib.config" +/* Directory separator is operating system dependent */ +#if defined(VMS) +# define DIRECTORY_SEP "]" +# define DIRECTORY_SEP_CHAR ']' +#elif defined(MSDOS) | defined(_WIN32) | defined(_MSC_VER) +# define DIRECTORY_SEP "\\" +# define DIRECTORY_SEP_CHAR '\\' +#else +# define DIRECTORY_SEP "/" +# define DIRECTORY_SEP_CHAR '/' +#endif +/* For EMX-, WIN32-, MSDOS-environment, we define the default path separator to + be ';' instead of ':' */ +#if defined(MSDOS) | defined(_WIN32) | defined(__EMX__) | defined(_MSC_VER) | defined(VMS) +#define PATH_SEP ";" +#define PATH_SEP_CHAR ';' +#else +#define PATH_SEP ":" +#define PATH_SEP_CHAR ':' +#endif +/* This non printable character is used internally */ +#define INTERNAL_PATH_SEP "\001" +#define INTERNAL_PATH_SEP_CHAR '\1' + + +/* Default name for t1lib-logfile: */ +#define ENV_LOG_STRING "T1LIB_LOGMODE" +#define T1_LOG_FILE "t1lib.log" +/* logfile levels: */ +#define T1LOG_ERROR 1 +#define T1LOG_WARNING 2 +#define T1LOG_STATISTIC 3 +#define T1LOG_DEBUG 4 + + +/* def's for T1_InitLib() */ +#define NO_LOGFILE 0x0 +#define LOGFILE 0x1 +#define IGNORE_FONTDATABASE 0x2 /* Default is to read database */ +#define IGNORE_CONFIGFILE 0x4 /* Default is to read config file */ +#define T1_AA_CACHING 0x8 /* Cache aa-bytes */ +#define T1_NO_AFM 0x10 /* Don't load AFM files or generate AFM data */ + + +/* How may ligatures a character may have at maximum: */ +#define MAX_LIGS 20 + + +/* The maximum number of gray-levels in antialiasing */ +#define AAMAXPLANES 17 +#define T1_AA_NONE 1 +#define T1_AA_LOW 2 +#define T1_AA_HIGH 4 + +/* The default limits for no/low/high AA */ +#define T1_AA_SMARTLIMIT1 20.0 +#define T1_AA_SMARTLIMIT2 60.0 + +/* How much to advance the number of FONTPRIVATE structures when + reallocating for new fonts? */ +#define ADVANCE_FONTPRIVATE 10 + +#define NO_ANTIALIAS 0 +#define ANTIALIAS 1 + + +/* #define's for manipulating searchpaths */ +#define T1_PFAB_PATH 0x01 +#define T1_AFM_PATH 0x02 +#define T1_ENC_PATH 0x04 +#define T1_FDB_PATH 0x08 +#define T1_APPEND_PATH 0x00 +#define T1_PREPEND_PATH 0x01 + + +/* #define's for character/string properties (not all implemented) */ +#define T1_DEFAULT 0x0000 +#define T1_UNDERLINE 0x0001 +#define T1_OVERLINE 0x0002 +#define T1_OVERSTRIKE 0x0004 +#define T1_DOUBLEOVERSTRIKE 0x0008 +#define T1_RIGHT_TO_LEFT 0x0010 +#define T1_SUBSCRIPT 0x0100 +#define T1_SUPERSCRIPT 0x0200 +#define T1_STROKED 0x1000 +#define T1_KERNING 0x2000 + + +/* Error handling: */ +/* These are from scanning a font file */ +#define T1ERR_SCAN_FONT_FORMAT -5 +#define T1ERR_SCAN_FILE_OPEN_ERR -4 +#define T1ERR_SCAN_OUT_OF_MEMORY -3 +#define T1ERR_SCAN_ERROR -2 +#define T1ERR_SCAN_FILE_EOF -1 +/* These are from generating paths */ +#define T1ERR_PATH_ERROR 1 +#define T1ERR_PARSE_ERROR 2 +#define T1ERR_TYPE1_ABORT 3 +/* These are from t1lib */ +#define T1ERR_INVALID_FONTID 10 +#define T1ERR_INVALID_PARAMETER 11 +#define T1ERR_OP_NOT_PERMITTED 12 +#define T1ERR_ALLOC_MEM 13 +#define T1ERR_FILE_OPEN_ERR 14 +#define T1ERR_UNSPECIFIED 15 +#define T1ERR_NO_AFM_DATA 16 +#define T1ERR_X11 17 +#define T1ERR_COMPOSITE_CHAR 18 +#define T1ERR_SCAN_ENCODING 19 + + +/* The info_flags meaning */ +#define AFM_SUCCESS (short)0x0001 +#define AFM_SLOPPY_SUCCESS (short)0x0002 +#define AFM_SELFGEN_SUCCESS (short)0x0004 +#define USES_STANDARD_ENCODING (short)0x0008 +#define RASTER_STROKED (short)0x0010 +#define CACHE_STROKED (short)0x0020 +#define FONT_NOCACHING (short)0x0100 + +#ifndef PI +#define PI 3.1415927 +#endif + + +/* Flags to control the rasterizer */ +#define T1_IGNORE_FORCEBOLD 0x0001 +#define T1_IGNORE_FAMILYALIGNMENT 0x0002 +#define T1_IGNORE_HINTING 0x0004 + +#define T1_DEBUG_LINE 0x0100 +#define T1_DEBUG_REGION 0x0200 +#define T1_DEBUG_PATH 0x0400 +#define T1_DEBUG_FONT 0x0800 +#define T1_DEBUG_HINT 0x1000 + + +/* */ +#define DO_RASTER 0x1 +#define DO_NOT_RASTER 0x0 + + +/* this definition reports a character substitution from fontfcn */ +#define FF_NOTDEF_SUBST -1 diff --git a/Build/source/libs/t1lib/t1outline.c b/Build/source/libs/t1lib/t1outline.c new file mode 100644 index 00000000000..23942780dd3 --- /dev/null +++ b/Build/source/libs/t1lib/t1outline.c @@ -0,0 +1,766 @@ +/*-------------------------------------------------------------------------- + ----- File: t1outline.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-02 + ----- Description: This file is part of the t1-library. It contains + functions for getting glyph outline descriptions of + strings and characters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1OUTLINE_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <setjmp.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" +#include "../type1/paths.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1set.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1base.h" +#include "t1outline.h" + + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + +extern char *t1_get_abort_message( int number); +extern struct segment *Type1Line(psfont *env, struct XYspace *S, + float line_position, + float line_thickness, + float line_length); +extern struct segment *t1_Join( struct segment *path1, + struct segment *path2); +extern struct segment *CopyPath( struct segment *p); +extern void KillPath( struct segment *p); + + + + +/* T1_SetChar(...): Generate the bitmap for a character */ +T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size, + T1_TMATRIX *transform) +{ + int i; + int mode; + T1_PATHSEGMENT *charpath; + struct XYspace *Current_S; + unsigned char ucharcode; + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + /* We don't implement underlining for characters, but the rasterer + implements it. Thus, we use a modflag of constant 0 */ + int modflag=0; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetCharOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + ucharcode=(unsigned char)charcode; + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL) { + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + + /* fnt_ptr now points to the correct FontSizeDeps-struct => + lets now raster the character */ + mode=0; + charpath=(T1_PATHSEGMENT *)fontfcnB( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + ucharcode, &mode, + fontarrayP->pType1Data, + DO_NOT_RASTER,0.0f); + KillSpace (Current_S); + + return((T1_OUTLINE *)charpath); +} + + + +/* T1_GetStringOutline(...): Generate the outline for a string of + characters */ +T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + int i; + int mode; + /* initialize this to NULL just to be on the safe side */ + T1_PATHSEGMENT *charpath = NULL; + struct XYspace *Current_S; + int *kern_pairs; /* use for accessing the kern pairs if kerning is + requested */ + int no_chars=0; /* The number of characters in the string */ + static int lastno_chars=0; + long spacewidth; /* This is given to fontfcnb_string() */ + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + static int *pixel_h_anchor_corr=NULL; + static int *flags=NULL; + + unsigned char *ustring; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + /* force string elements into unsigned */ + ustring=(unsigned char*)string; + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return(NULL); + } + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Now comes string specific stuff: Get length of string and create an + array of integers where to store the bitmap positioning dimens: */ + if (len<0){ /* invalid length */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + if (len==0) /* should be computed assuming "normal" 0-terminated string */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + /* If necessary, allocate memory */ + if (no_chars>lastno_chars){ + if (pixel_h_anchor_corr!=NULL){ + free(pixel_h_anchor_corr); + } + if (flags!=NULL){ + free(flags); + } + + pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int)); + flags=(int *)calloc(no_chars, sizeof(int)); + lastno_chars=no_chars; + } + else{ + /* Reset flags and position array */ + for (i=0; i<no_chars; i++){ + flags[i]=0; + pixel_h_anchor_corr[i]=0; + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + /* Compute the correct spacewidth value (in charspace units). The + value supplied by the user is interpreted as an offset in + char space units: + */ + spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff; + + mode=0; + kern_pairs=(int *)calloc(no_chars, sizeof(int)); + if ((modflag & T1_KERNING)) + for (i=0; i<no_chars -1; i++) + kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); + charpath=(T1_PATHSEGMENT *) fontfcnB_string( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + (unsigned char *)string, + no_chars, &mode, + fontarrayP->pType1Data, + kern_pairs, spacewidth, + DO_NOT_RASTER,0.0f); + KillSpace (Current_S); + + /* In all cases, free memory for kerning pairs */ + free(kern_pairs); + + /* fill the string_glyph-structure */ + if (mode != 0) { + sprintf( err_warn_msg_buf, "fontfcnB_string() set mode=%d", mode); + T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + /* make sure to get rid of path if it's there */ + if (charpath){ + KillRegion (charpath); + } + return(NULL); + } + if (charpath == NULL){ + T1_PrintLog( "T1_GetStringOutline()", "path=NULL returned by fontfcnB_string()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + + return( (T1_OUTLINE *)charpath); +} + + +/* T1_GetMoveOutline(...): Generate the "outline" for a movement + */ +T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, + float size, T1_TMATRIX *transform) +{ + int i; + FONTSIZEDEPS *font_ptr; + struct segment *path, *tmppath; + struct XYspace *Current_S; + psfont *FontP; + float length; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_GetMoveOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + FontP=pFontBase->pFontArray[i].pType1Data; + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (transform!=NULL){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + + path=(struct segment *)ILoc( Current_S, deltax, deltay); + + /* Take care for underlining and such */ + length=(float) deltax; + if (modflag & T1_UNDERLINE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].UndrLnPos, + pFontBase->pFontArray[FontID].UndrLnThick, + length); + path=(struct segment *)Join(path,tmppath); + } + if (modflag & T1_OVERLINE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].OvrLnPos, + pFontBase->pFontArray[FontID].OvrLnThick, + length); + path=(struct segment *)Join(path,tmppath); + } + if (modflag & T1_OVERSTRIKE){ + tmppath=(struct segment *)Type1Line(FontP,Current_S, + pFontBase->pFontArray[FontID].OvrStrkPos, + pFontBase->pFontArray[FontID].OvrStrkThick, + length); + path=(struct segment *)Join(path,tmppath); + } + + KillSpace( Current_S); + + return( (T1_OUTLINE *)path); + +} + + +/* T1_ConcatOutlines(): Concatenate two outline to one path */ +T1_OUTLINE *T1_ConcatOutlines( T1_OUTLINE *path1, T1_OUTLINE *path2) +{ + + return( (T1_OUTLINE *) t1_Join( (struct segment *) path1, + (struct segment *) path2)); + +} + + +/* T1_ScaleOutline(): Scale an outline */ +T1_OUTLINE *T1_ScaleOutline( T1_OUTLINE *path, float scale) +{ + struct segment *ipath; + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x = (fractpel) (ipath->dest.x * scale); + ipath->dest.y = (fractpel) (ipath->dest.y * scale); + } + if (ipath->type==CONICTYPE){ + ((struct conicsegment *)ipath)->dest.x = + (fractpel) ((struct conicsegment *)ipath)->dest.x * scale; + ((struct conicsegment *)ipath)->dest.y = + (fractpel) ((struct conicsegment *)ipath)->dest.y * scale; + ((struct conicsegment *)ipath)->M.x = + (fractpel) ((struct conicsegment *)ipath)->M.x * scale; + ((struct conicsegment *)ipath)->M.y = + (fractpel) ((struct conicsegment *)ipath)->M.y * scale; + } + if (ipath->type==MOVETYPE){ + ipath->dest.x = (fractpel) (ipath->dest.x * scale); + ipath->dest.y = (fractpel) (ipath->dest.y * scale); + } + if (ipath->type==BEZIERTYPE){ + ((struct beziersegment *)ipath)->B.x = + (fractpel) (((struct beziersegment *)ipath)->B.x * scale); + ((struct beziersegment *)ipath)->B.y = + (fractpel) (((struct beziersegment *)ipath)->B.y * scale); + ((struct beziersegment *)ipath)->C.x = + (fractpel) (((struct beziersegment *)ipath)->C.x * scale); + ((struct beziersegment *)ipath)->C.y = + (fractpel) (((struct beziersegment *)ipath)->C.y * scale); + ((struct beziersegment *)ipath)->dest.x = + (fractpel) (((struct beziersegment *)ipath)->dest.x * scale); + ((struct beziersegment *)ipath)->dest.y = + (fractpel) (((struct beziersegment *)ipath)->dest.y * scale); + } + if (ipath->type==HINTTYPE){ + ((struct hintsegment *)ipath)->dest.x = + (fractpel) (((struct hintsegment *)ipath)->dest.x * scale); + ((struct hintsegment *)ipath)->dest.y = + (fractpel) (((struct hintsegment *)ipath)->dest.y * scale); + ((struct hintsegment *)ipath)->ref.x = + (fractpel) (((struct hintsegment *)ipath)->ref.x * scale); + ((struct hintsegment *)ipath)->ref.y = + (fractpel) (((struct hintsegment *)ipath)->ref.y * scale); + ((struct hintsegment *)ipath)->width.x = + (fractpel) (((struct hintsegment *)ipath)->width.x * scale); + ((struct hintsegment *)ipath)->width.y = + (fractpel) (((struct hintsegment *)ipath)->width.y * scale); + } + if (ipath->type==TEXTTYPE) + ; + ipath=ipath->link; + + } while (ipath!=NULL); + + return( path); + +} + + +/* dump a description of path elements to stdout */ +void T1_DumpPath( T1_OUTLINE *path) +{ + + struct segment *ipath; + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); + } + if (ipath->type==MOVETYPE){ + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); + } + if (ipath->type==BEZIERTYPE){ + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + +/* convert a relative path to an absolute path */ +void T1_AbsolutePath( T1_OUTLINE *rpath) +{ + + struct segment *ipath; + fractpel xcurr=0, ycurr=0; + + /* Step through the path list */ + ipath=(struct segment *)rpath; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + if (ipath->type==MOVETYPE){ + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + if (ipath->type==BEZIERTYPE){ + ((struct beziersegment *)ipath)->B.x +=xcurr; + ((struct beziersegment *)ipath)->B.y +=ycurr; + ((struct beziersegment *)ipath)->C.x +=xcurr; + ((struct beziersegment *)ipath)->C.y +=ycurr; + ipath->dest.x +=xcurr; + ipath->dest.y +=ycurr; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + xcurr=ipath->dest.x; + ycurr=ipath->dest.y; + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + + +/* convert path into a relative path as needed by the rasterizer */ +void T1_RelativePath( T1_OUTLINE *apath) +{ + + struct segment *ipath; + fractpel xcurr=0, ycurr=0; + + + /* Step through the path list */ + ipath=(struct segment *)apath; + + do { + if (ipath->type==LINETYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f), curr=(%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF), + xcurr/(double)(0xFFFF), -ycurr/(double)(0xFFFF)); +#endif + } + if (ipath->type==MOVETYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f), curr=(%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF), + xcurr/(double)(0xFFFF), -ycurr/(double)(0xFFFF)); +#endif + } + if (ipath->type==BEZIERTYPE){ + ipath->dest.x -=xcurr; + ipath->dest.y -=ycurr; + ((struct beziersegment *)ipath)->C.x -=xcurr; + ((struct beziersegment *)ipath)->C.y -=ycurr; + ((struct beziersegment *)ipath)->B.x -=xcurr; + ((struct beziersegment *)ipath)->B.y -=ycurr; + xcurr +=ipath->dest.x; + ycurr +=ipath->dest.y; +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + +/* maniuplate the coordinata points of a path */ +void T1_ManipulatePath( T1_OUTLINE *path, + void (*manipulate)(fractpel *x,fractpel *y,int type)) +{ + + struct segment *ipath; + + + /* Step through the path list */ + ipath=(struct segment *)path; + + do { + if (ipath->type==LINETYPE){ + manipulate( &(ipath->dest.x), &ipath->dest.y, LINETYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Line-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + } + if (ipath->type==MOVETYPE){ + manipulate( &(ipath->dest.x), &ipath->dest.y, MOVETYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Move-Segment: -> (%f,%f)\n", + (ipath->dest.x)/(double)(0xFFFF), + -(ipath->dest.y)/(double)(0xFFFF)); +#endif + } + if (ipath->type==BEZIERTYPE){ + manipulate( &((struct beziersegment *)ipath)->B.x, + &((struct beziersegment *)ipath)->B.y, + BEZIERTYPE); + manipulate( &((struct beziersegment *)ipath)->C.x, + &((struct beziersegment *)ipath)->C.y, + BEZIERTYPE); + manipulate( &((struct beziersegment *)ipath)->dest.x, + &((struct beziersegment *)ipath)->dest.y, + BEZIERTYPE); +#ifdef PRINT_PATHS_TO_STDOUT + printf("Bezier-Segment: ... (%f,%f) ... (%f,%f) -> (%f,%f)\n", + (((struct beziersegment *)ipath)->B.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->B.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->C.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->C.y)/(double)(0xFFFF), + (((struct beziersegment *)ipath)->dest.x)/(double)(0xFFFF), + -(((struct beziersegment *)ipath)->dest.y)/(double)(0xFFFF)); +#endif + } + ipath=ipath->link; + } while (ipath!=NULL); + +} + + + +/* T1_CopyOutline(): Copy an outline physically. + Returns a pointer to the path or NULL */ +T1_OUTLINE *T1_CopyOutline( T1_OUTLINE *path) +{ + + return( (T1_OUTLINE *) CopyPath( (struct segment *)path)); + +} + + + +/* T1_FreeOutline(): Free an outline. */ +void T1_FreeOutline( T1_OUTLINE *path) +{ + + KillPath( (struct segment *)path); + return; + +} + diff --git a/Build/source/libs/t1lib/t1outline.h b/Build/source/libs/t1lib/t1outline.h new file mode 100644 index 00000000000..c7d2bd3023f --- /dev/null +++ b/Build/source/libs/t1lib/t1outline.h @@ -0,0 +1,90 @@ +/*-------------------------------------------------------------------------- + ----- File: t1outline.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-10-18 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations for t1outline.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1OUTLINE_C + +T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size, + T1_TMATRIX *transform); +T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform); +T1_OUTLINE *T1_ConcatOutlines( T1_OUTLINE *path1, T1_OUTLINE *path2); +T1_OUTLINE *T1_ScaleOutline( T1_OUTLINE *path, float scale); +T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, + float size, T1_TMATRIX *transform); +void T1_DumpPath( T1_OUTLINE *path); +void T1_AbsolutePath( T1_OUTLINE *rpath); +void T1_RelativePath( T1_OUTLINE *apath); +void T1_ManipulatePath( T1_OUTLINE *path, + void (*manipulate)(fractpel *x,fractpel *y,int type)); +T1_OUTLINE *T1_CopyOutline( T1_OUTLINE *path); +void T1_FreeOutline( T1_OUTLINE *path); + + +#else + +extern T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size, + T1_TMATRIX *transform); +extern T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform); +extern T1_OUTLINE *T1_ConcatOutlines( T1_OUTLINE *path1, + T1_OUTLINE *path2); +extern T1_OUTLINE *T1_ScaleOutline( T1_OUTLINE *path, float scale); +extern T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, + float size, T1_TMATRIX *transform); +extern void T1_DumpPath( T1_OUTLINE *path); +extern void T1_AbsolutePath( T1_OUTLINE *rpath); +extern void T1_RelativePath( T1_OUTLINE *apath); +extern void T1_ManipulatePath( T1_OUTLINE *path, + void (*manipulate)(fractpel *x,fractpel *y,int type)); +extern T1_OUTLINE *T1_CopyOutline( T1_OUTLINE *path); +extern void T1_FreeOutline( T1_OUTLINE *path); + +#endif + + +extern struct region *fontfcnB(int FontID, int modflag, + struct XYspace *S, char **ev, + unsigned char index, int *mode, + psfont *Font_Ptr, + int do_raster, + float strokewidth); +extern struct region *fontfcnB_string( int FontID, int modflag, + struct XYspace *S, char **ev, + unsigned char *string, int no_chars, + int *mode, psfont *Font_Ptr, + int *kern_pairs, long spacewidth, + int do_raster, + float strokewidth); +extern struct region *fontfcnB_ByName( int FontID, int modflag, + struct XYspace *S, + char *charname, + int *mode, psfont *Font_Ptr, + int do_raster); + + diff --git a/Build/source/libs/t1lib/t1set.c b/Build/source/libs/t1lib/t1set.c new file mode 100644 index 00000000000..30e9a4a1be4 --- /dev/null +++ b/Build/source/libs/t1lib/t1set.c @@ -0,0 +1,2239 @@ +/*-------------------------------------------------------------------------- + ----- File: t1set.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + functions for setting characters and strings of + characters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1SET_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <setjmp.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1set.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1base.h" + + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + +extern char *t1_get_abort_message( int number); +extern struct region *Interior(struct segment *path, int fillrule); +extern unsigned T1_AA_TYPE32 T1aa_bg; /* white value */ + + +static void T1_ComputeLineParameters( int FontID, int width, + int mode, float size, + int *startx, int *endx, + int *starty, int *endy); + + + +static int T1_bit=T1GLYPH_BIT; +static int T1_byte; +static int T1_pad; +static int T1_wordsize; + +static int c_shift=8; +static int s_shift=16; +static int l_shift=32; + + + +/* bin_dump(): Print a binary dump of a byte, short and + long variable (used for debug purposes only): */ +static void bin_dump_c(unsigned char value, char space_flag) +{ + int i,j; + + for (i=0;i<=7;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + if (space_flag) + printf(" "); + +} + +static void bin_dump_s(unsigned short value, char space_flag) +{ + int i,j; + + if (T1_CheckEndian()){ + for (i=8;i<=15;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + for (i=0;i<=7;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + } + else{ + for (i=0;i<=15;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + } + if (space_flag) + printf(" "); + +} + +static void bin_dump_l(unsigned long value, char space_flag) +{ + int i,j; + + if (T1_CheckEndian()){ + for (i=24;i<=31;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + for (i=16;i<=23;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + for (i=8;i<=15;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + for (i=0;i<=7;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + } + else{ + for (i=0;i<=31;i++){ + if ((j=((value)>>i)&0x01)) + printf("X"); + else + printf("."); + } + } + if (space_flag) + printf(" "); + +} + + + +/* T1_SetChar(...): Generate the bitmap for a character */ +GLYPH *T1_SetChar( int FontID, char charcode, float size, + T1_TMATRIX *transform) +{ + int i; + int mode; + struct region *area; + struct XYspace *Current_S; + int cache_flag = 1; + int rot_flag = 0; + unsigned char ucharcode; + float strokewidth = 0.0f; + volatile int strokeextraflag = 0; + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + volatile int memsize=0; + LONG h,w; + LONG paddedW; + + /* We don't implement underlining for characters, but the rasterer + implements it. Thus, we use a modflag of constant 0 */ + int modflag=0; + + static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_SetChar()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + ucharcode=(unsigned char)charcode; + + + /* Reset character glyph, if necessary */ + if (glyph.bits!=NULL){ + free(glyph.bits); + glyph.bits=NULL; + } + glyph.metrics.leftSideBearing=0; + glyph.metrics.rightSideBearing=0; + glyph.metrics.advanceX=0; + glyph.metrics.advanceY=0; + glyph.metrics.ascent=0; + glyph.metrics.descent=0; + glyph.pFontCacheInfo=NULL; + glyph.bpp=1; + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + /* Assign padding value */ + T1_pad=pFontBase->bitmap_pad; + if (pFontBase->endian) + T1_byte=1; + else + T1_byte=0; + T1_wordsize=T1_pad; + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* Check if rotation is requested */ + if (transform!=NULL){ + /* there's rotation requested => do not cache the resulting bitmap */ + rot_flag=1; + cache_flag=0; + } + else { + rot_flag=0; + cache_flag=1; + } + + /* handle stroking stuff */ + if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) { + /* Stroking requested. If caching is not desired, clear cache_flag. + Otherwise, leave it unaffected. */ + if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) { + /* filled glyphs are cached, indicate that character is to be rendered + on the fly and not to be cached */ + strokeextraflag = 1; + cache_flag = 0; + } + strokewidth = pFontBase->pFontArray[FontID].StrokeWidth; + } + else { + /* filling requested. */ + if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) { + /* stroked glyphs are cached, indicate that character is to be rendered + on the fly and not to be cached */ + strokeextraflag = 1; + cache_flag = 0; + } + strokewidth = 0.0f; + } + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + else {/* size is already existent in cache */ + /* If no rotation and no noncached stroking , try to get character from cache */ + if ( (rot_flag==0) && (strokeextraflag==0) ) { + /* we don't use the .bits entry to check because in newer releases + also white glyphs (bits=NULL) are allowed. Rather, we check + whether bpp > 0! */ + if (font_ptr->pFontCache[ucharcode].bpp > 0){ + /* Character is already in Chache -> create a copy of cache + and return a pointer to the result: */ + memcpy( &glyph, &(font_ptr->pFontCache[ucharcode]), sizeof(GLYPH)); + paddedW = PAD((glyph.metrics.rightSideBearing-glyph.metrics.leftSideBearing), + T1_pad); + if (font_ptr->pFontCache[ucharcode].bits!=NULL) { + memsize = (glyph.metrics.ascent-glyph.metrics.descent)*paddedW / 8; + glyph.bits = (char *)malloc(memsize*sizeof( char)); + if (glyph.bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + memcpy( glyph.bits, font_ptr->pFontCache[ucharcode].bits, memsize); + } + return(&(glyph)); + } + } + } + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (rot_flag){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + /* fnt_ptr now points to the correct FontSizeDeps-struct => + lets now raster the character */ + mode=0; + area=fontfcnB( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + ucharcode, &mode, + fontarrayP->pType1Data, + DO_RASTER, + strokewidth); + KillSpace (Current_S); + + /* fill the glyph-structure */ + if (mode > 0) { + sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode); + T1_PrintLog( "T1_SetChar()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + if (area == NULL){ + T1_PrintLog( "T1_SetChar()", "area=NULL returned by fontfcnB()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + + if (mode == FF_NOTDEF_SUBST) { + sprintf( err_warn_msg_buf, + "\".notdef\" substituted for character %d from font %d", + ucharcode, FontID); + T1_PrintLog( "T1_SetChar()", err_warn_msg_buf, T1LOG_WARNING); + mode=0; + } + + paddedW = PAD(w, T1_pad); + + if (h > 0 && w > 0) { + memsize = h * paddedW / 8 + 1; + /* This is for the users copy of the character, for security-reasons + the original pointer to the cache area is not used. The entry glyph.bits + is free'ed every time this function is called: */ + glyph.bits = (char *)malloc(memsize*sizeof( char)); + if (glyph.bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to get rid of 'area' before leaving! */ + KillRegion (area); + return(NULL); + } + } + else { + h = w = 0; + area->xmin = area->xmax = 0; + area->ymin = area->ymax = 0; + } + + /* Assign metrics */ + glyph.metrics.leftSideBearing = area->xmin; + glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); + glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); + glyph.metrics.rightSideBearing = area->xmax; + glyph.metrics.descent = - area->ymax; + glyph.metrics.ascent = - area->ymin; + + + if (h > 0 && w > 0) { + (void) memset(glyph.bits, 0, memsize); + fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); + } + + /* make sure to get rid of 'area' before leaving! */ + KillRegion (area); + + /* Cache glyph if requested, also if it contains only white space */ + if (cache_flag){ + /* Copy glyph to cache but be careful not to modify the pixmap + entry */ + font_ptr->pFontCache[ucharcode].metrics.leftSideBearing=glyph.metrics.leftSideBearing; + font_ptr->pFontCache[ucharcode].metrics.rightSideBearing=glyph.metrics.rightSideBearing; + font_ptr->pFontCache[ucharcode].metrics.advanceX=glyph.metrics.advanceX; + font_ptr->pFontCache[ucharcode].metrics.advanceY=glyph.metrics.advanceY; + font_ptr->pFontCache[ucharcode].metrics.ascent=glyph.metrics.ascent; + font_ptr->pFontCache[ucharcode].metrics.descent=glyph.metrics.descent; + font_ptr->pFontCache[ucharcode].pFontCacheInfo=glyph.pFontCacheInfo; + font_ptr->pFontCache[ucharcode].bpp=glyph.bpp; + if (glyph.bits==NULL) { + font_ptr->pFontCache[ucharcode].bits=NULL; + } + else { + font_ptr->pFontCache[ucharcode].bits = (char *)malloc(memsize*sizeof( char)); + if (font_ptr->pFontCache[ucharcode].bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* ... and copy bitmap to cache area: */ + memcpy( font_ptr->pFontCache[ucharcode].bits, glyph.bits, memsize); + } + + } + + + return(&glyph); +} + + + +/* T1_SetString(...): Generate the bitmap for a string of characters */ +GLYPH *T1_SetString( int FontID, char *string, volatile int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + volatile int i, j=0, k; + int mode; + /* initialize this to NULL just to be on the safe side */ + struct region *area = NULL; + struct XYspace *Current_S, *S; + int cache_flag=1; + volatile int rot_flag=0; + int *kern_pairs; /* use for accessing the kern pairs if kerning is + requested */ + int no_chars=0; /* The number of characters in the string */ + static int lastno_chars=0; + float factor; + long spacewidth; /* This is given to fontfcnb_string() */ + float strokewidth = 0.0f; + volatile int strokeextraflag = 0; + + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + + volatile int memsize=0; + + long h,w; + long paddedW, char_paddedW; + int h_anchor, v_anchor; + static int *pixel_h_anchor_corr=NULL; + static int *flags=NULL; + int lsb_min, rsb_max; + long overallwidth=0; + long overallascent=0; + long overalldescent=0; + + int underline_startx, underline_starty, underline_endx, underline_endy; + int overline_startx, overline_starty, overline_endx, overline_endy; + int overstrike_startx, overstrike_starty, overstrike_endx, overstrike_endy; + int start, middle; + int afm_ind; + + char startmask, endmask; + static unsigned char *r2lstring; + static int r2l_len=0; + + static GLYPH string_glyph={NULL,{0,0,0,0,0,0},NULL,1}; + GLYPH *currchar; + + + + /* The following are for bitmap blitting */ + long BitShift; + long ByteOffset; + /* pad=8 */ + unsigned T1_AA_TYPE16 BitBuf_c; + unsigned char *p_c; + unsigned char *Target_c; + /* pad=16 */ + unsigned T1_AA_TYPE32 BitBuf_s; + unsigned T1_AA_TYPE16 *p_s; + unsigned T1_AA_TYPE16 *Target_s; +#ifdef T1_AA_TYPE64 + /* pad=32 */ + unsigned T1_AA_TYPE64 BitBuf_l; + unsigned T1_AA_TYPE32 *p_l; + unsigned T1_AA_TYPE32 *Target_l; +#endif + unsigned char *ustring; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + /* force string elements into unsigned */ + ustring=(unsigned char*)string; + + + /* Check for valid string */ + if (string==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + /* Reorganize if required */ + if (modflag & T1_RIGHT_TO_LEFT){ + if (len) + i=len; + else + i=j=strlen( string); + if (i+1>r2l_len){ + if (r2lstring!=NULL) + free( r2lstring); + r2lstring=(unsigned char *)malloc( (i+1)*sizeof(char)); + r2l_len=i+1; + } + j--; + while ( i--) { + r2lstring[j-i]=ustring[i]; + } + ustring=r2lstring; + len=j+1; + } + + + /* Reset string glyph, if necessary */ + if (string_glyph.bits!=NULL){ + free(string_glyph.bits); + string_glyph.bits=NULL; + } + string_glyph.metrics.leftSideBearing=0; + string_glyph.metrics.rightSideBearing=0; + string_glyph.metrics.advanceX=0; + string_glyph.metrics.advanceY=0; + string_glyph.metrics.ascent=0; + string_glyph.metrics.descent=0; + string_glyph.pFontCacheInfo=NULL; + string_glyph.bpp=1; + + /* We don't want to cache the resulting bitmap: */ + cache_flag=0; + + /* First, check for a correct ID */ + i=T1_CheckForFontID(FontID); + if (i==-1){ + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + /* if necessary load font into memory */ + if (i==0) + if (T1_LoadFont(FontID)) + return(NULL); + + /* If no AFM info is present, we return an error */ + if (pFontBase->pFontArray[FontID].pAFMData==NULL) { + T1_errno=T1ERR_NO_AFM_DATA; + return(NULL); + } + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + /* Assign padding value */ + T1_pad=pFontBase->bitmap_pad; + if (pFontBase->endian) + T1_byte=1; + else + T1_byte=0; + T1_wordsize=T1_pad; + + fontarrayP=&(pFontBase->pFontArray[FontID]); + + /* Check if rotation is requested */ + if (transform!=NULL){ + /* there's rotation requested => do not cache the resulting bitmap */ + rot_flag=1; + cache_flag=0; + } + + /* handle stroking stuff */ + if ( pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) { + /* Stroking requested. If caching is not desired, clear cache_flag. + Otherwise, leave it unaffected. */ + if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) == 0 ) { + /* filled glyphs are cached, indicate that character is to be rendered + on the fly and not to be cached */ + strokeextraflag = 1; + cache_flag = 0; + } + strokewidth = pFontBase->pFontArray[FontID].StrokeWidth; + } + else { + /* filling requested. */ + if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) { + /* stroked glyphs are cached, indicate that character is to be rendered + on the fly and not to be cached */ + strokeextraflag = 1; + cache_flag = 0; + } + strokewidth = 0.0f; + } + + /* font is now loaded into memory => + Check for size: */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* Now comes string specific stuff: Get length of string and create an + array of integers where to store the bitmap positioning dimens: */ + if (len<0){ /* invalid length */ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + if (len==0) /* should be computed assuming "normal" 0-terminated string, + or R2L-part has already been computed! */ + no_chars=strlen(string); + else /* use value given on command line */ + no_chars=len; + + /* If necessary, allocate memory */ + if (no_chars>lastno_chars){ + if (pixel_h_anchor_corr!=NULL){ + free(pixel_h_anchor_corr); + } + if (flags!=NULL){ + free(flags); + } + pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int)); + flags=(int *)calloc(no_chars, sizeof(int)); + lastno_chars=no_chars; + } + else{ + /* Reset flags and position array */ + for (i=0; i<no_chars; i++){ + flags[i]=0; + pixel_h_anchor_corr[i]=0; + } + } + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if (rot_flag){ + Current_S=(struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S=(struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + /* Compute the correct spacewidth value (in charspace units). The + value supplied by the user is interpreted as an offset in + char space units: + */ + spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff; + + + /* The following if (rot_flag==0){ ... } contains the whole code + to execute when the string is oriented horizontal. Then, there's + the possibility of concatenating most probably existent bitmaps + from the Cache, which should be much faster than every time raster + all the characters. + */ + /* First, ensure that all needed characters are in the Cache; if not, + generate them */ + if ( (rot_flag==0) && (strokeextraflag==0) ){ + overallwidth=0; + for (i=0; i<no_chars; i++) { + currchar= &(font_ptr->pFontCache[ustring[i]]); + if (currchar->bpp<1) { + flags[i]=0; + mode=0; + /* Don't try to generate space-character: */ + if (ustring[i]!=fontarrayP->space_position){ + /* Note: Never underline etc. cached chars --> modflag=0 */ + area=fontfcnB( FontID, 0, Current_S, + fontarrayP->pFontEnc, + ustring[i], &mode, + fontarrayP->pType1Data, + DO_RASTER, + strokewidth); + + /* fill the glyph-structure */ + if (mode > 0) { + sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + /* Make sure to free the region if it's non-NULL */ + if (area){ + KillRegion (area); + } + return(NULL); + } + if (area == NULL){ + T1_PrintLog( "T1_SetString()", "area=NULL returned by fontfcnB()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + + if (mode == FF_NOTDEF_SUBST) { + sprintf( err_warn_msg_buf, + "\".notdef\" substituted in string[%d] (=character %d) from font %d", + i, ustring[i], FontID); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); + mode=0; + flags[i]=1; /* indicates that .notdef has been substituted */ + } + + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + + if (h > 0 && w > 0) { /* bitmap contains pixels */ + paddedW = PAD(w, T1_pad); + memsize = h * paddedW / 8 + 1; + currchar->bits = (char *)malloc(memsize*sizeof( char)); + if (currchar->bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* Make sure to free up the region if it's non-NULL */ + if (area){ + KillRegion (area); + } + return(NULL); + } + (void) memset(currchar->bits, 0, memsize); + fill(currchar->bits, h, paddedW, area, + T1_byte, T1_bit, T1_wordsize ); + } + /* area valid -> set metrics in cache for that character */ + currchar->metrics.leftSideBearing = area->xmin; + currchar->metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); + currchar->metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); + currchar->metrics.rightSideBearing = area->xmax; + currchar->metrics.descent = - area->ymax; + currchar->metrics.ascent = - area->ymin; + currchar->bpp=1; + + /* By this point, it's clear that the 'area' struct exists, + and that we no longer need it, so free it up. */ + KillRegion (area); + } + } /* end of if ( ... ), needed characters are now in cache! */ + } /* end of for (i<no_chars) loop */ + /* we still have to delete the Space */ + KillSpace (Current_S); + + /* We've to compute the scale factor: */ + factor=size*DeviceSpecifics.scale_x/1000; + + /* h_anchor is the horizontal position in the resulting bitmap; + it is incremented on the fly and of course initially 0! */ + h_anchor=0; + /* These are the initial values for left and right sidebearing */ + rsb_max=-30000; + lsb_min= 30000; + overallascent=-30000; + overalldescent=30000; + for (i=0;i<no_chars;i++){ + /* first get index into AFM-tables */ + afm_ind=pFontBase->pFontArray[FontID].pEncMap[(int) ustring[i]]; + /* Advance to next character in high resolution */ + if (ustring[i]==fontarrayP->space_position) + h_anchor +=(int)spacewidth; + /* check for a substituted char or notdef and get missing escapement */ + else if (afm_ind==0) { + /* Setup apropriate charspace matrix */ + S=(struct XYspace *)IDENTITY; + /* Make this permanent so that scaling it in fontfcnB_ByName will + make a duplicate of it, and this duplicate can thus be safely + destroyed. Fixes the somewhat smaller memory leak */ + S=(struct XYspace *)Permanent + (Transform(S, pFontBase->pFontArray[FontID].FontTransform[0], + pFontBase->pFontArray[FontID].FontTransform[1], + pFontBase->pFontArray[FontID].FontTransform[2], + pFontBase->pFontArray[FontID].FontTransform[3])); + /* Get metrics values */ + area=fontfcnB_ByName( FontID, 0, S, ".notdef", &mode, + pFontBase->pFontArray[FontID].pType1Data, DO_RASTER); + if (area==NULL || mode!=0){ + sprintf( err_warn_msg_buf, + "Could not get charspace representation of \".notdef\", Font %d, mode=%d!", + FontID, mode); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, + T1LOG_ERROR); + T1_errno=mode; + return( NULL); + } + /* value to add to hanchor */ + h_anchor +=NEARESTPEL(area->ending.x); + /* make sure to free S */ + if (S) { + KillSpace (S); + } + /* make sure to free area */ + if (area) { + KillRegion (area); + } + } + else{ + currchar=&(font_ptr->pFontCache[ustring[i]]); + pixel_h_anchor_corr[i]=((int)floor(h_anchor*factor+0.5)); + /* Store maximum rsb ...*/ + if ( pixel_h_anchor_corr[i]+currchar->metrics.rightSideBearing > rsb_max){ + rsb_max=pixel_h_anchor_corr[i]+currchar->metrics.rightSideBearing; + } + /* ... and minimum lsb */ + if ( pixel_h_anchor_corr[i]+currchar->metrics.leftSideBearing < lsb_min){ + lsb_min=pixel_h_anchor_corr[i]+currchar->metrics.leftSideBearing; + } + /* Advance by current chars width */ + /* h_anchor +=T1_GetCharWidth( FontID, ustring[i]); */ + if (afm_ind>0) { /* we have a standard character */ + h_anchor +=(fontarrayP->pAFMData->cmi[afm_ind-1].wx) * fontarrayP->extend; + } + else { /* afm_ind must be negative so that we have a composite char */ + h_anchor +=(fontarrayP->pAFMData->ccd[-(afm_ind+1)].wx) * fontarrayP->extend; + } + /* If kerning, insert kerning amount */ + if ((i<no_chars -1) && (modflag & T1_KERNING)) + h_anchor +=T1_GetKerning( FontID, ustring[i], ustring[i+1]); + + /* We still have to care for vertical metrics: */ + if (currchar->metrics.ascent>overallascent) + overallascent=currchar->metrics.ascent; + if (currchar->metrics.descent<overalldescent) + overalldescent=currchar->metrics.descent; + } + } + string_glyph.metrics.advanceX=(int)floor(h_anchor*factor+0.5); + + /* We have to check for underlining and such things. They may affect the + bounding box of the glyph */ + if (modflag & T1_UNDERLINE){ + T1_ComputeLineParameters( FontID, T1_UNDERLINE, + string_glyph.metrics.advanceX, + size, + &underline_startx, &underline_endx, + &underline_starty, &underline_endy); + /* Check whether rsb is affected ...*/ + if ( underline_endx > rsb_max){ + rsb_max=underline_endx; + } + /* ... and for lsb */ + if ( underline_startx < lsb_min){ + lsb_min=underline_startx; + } + + /* Vertical metrics may also be affected. */ + if (underline_starty > overallascent) + overallascent=underline_starty; + if (underline_endy < overalldescent) + overalldescent=underline_endy; + } + if (modflag & T1_OVERLINE){ + T1_ComputeLineParameters( FontID, T1_OVERLINE, + string_glyph.metrics.advanceX, + size, + &overline_startx, &overline_endx, + &overline_starty, &overline_endy); + /* Check whether rsb is affected ...*/ + if ( overline_endx > rsb_max){ + rsb_max=overline_endx; + } + /* ... and for lsb */ + if ( overline_startx < lsb_min){ + lsb_min=overline_startx; + } + + /* Vertical metrics may also be affected. */ + if (overline_starty > overallascent) + overallascent=overline_starty; + if (overline_endy < overalldescent) + overalldescent=overline_endy; + } + if (modflag & T1_OVERSTRIKE){ + T1_ComputeLineParameters( FontID, T1_OVERSTRIKE, + string_glyph.metrics.advanceX, + size, + &overstrike_startx, &overstrike_endx, + &overstrike_starty, &overstrike_endy); + /* Check whether rsb is affected ...*/ + if ( overstrike_endx > rsb_max){ + rsb_max=overstrike_endx; + } + /* ... and for lsb */ + if ( overstrike_startx < lsb_min){ + lsb_min=overstrike_startx; + } + + /* Vertical metrics may also be affected. */ + if (overstrike_starty > overallascent) + overallascent=overstrike_starty; + if (overstrike_endy < overalldescent) + overalldescent=overstrike_endy; + } + + + + /* Set the string-glyphs' metrics: */ + /* Bearings: */ + string_glyph.metrics.rightSideBearing=rsb_max; + string_glyph.metrics.leftSideBearing=lsb_min; + /* ascent and descent: */ + string_glyph.metrics.ascent=overallascent; + string_glyph.metrics.descent=overalldescent; + + + + /* Now, allocate memory for the resulting bitmap and set it to 0: */ + h=overallascent - overalldescent; + w=string_glyph.metrics.rightSideBearing-string_glyph.metrics.leftSideBearing; + + paddedW = PAD( w, T1_pad); + if ( h > 0 && w > 0){ + memsize = h * paddedW / 8; + /* We alloc some amount more in order to avoid alignment check in + bit-blitting loop */ + memsize += T1_pad/8; + string_glyph.bits = (char *)malloc( memsize); + if (string_glyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + } + else { + /* We have only characters without pixels in the string -> + we allow this and only set the advance width in the glyph. + The bits pointer will be NULL. We reset rsb and lsb */ + string_glyph.metrics.rightSideBearing=0; + string_glyph.metrics.leftSideBearing=0; + string_glyph.metrics.ascent=0; + string_glyph.metrics.descent=0; + } + + if (string_glyph.bits != NULL) { + + memset(string_glyph.bits, 0, memsize); + + /* Now comes the loop for bitmap blitting: */ + for (i=0;i<no_chars;i++){ + /* Get pointer to character number i of string: */ + currchar=&(font_ptr->pFontCache[ustring[i]]); + + /* First, we have to correct the positioning values to refer to + the bitmap BBox */ + pixel_h_anchor_corr[i] -= lsb_min; + pixel_h_anchor_corr[i] += currchar->metrics.leftSideBearing; + + /* Compute vertical anchor for current char-bitmap: */ + v_anchor=overallascent - currchar->metrics.ascent; + char_paddedW=PAD( currchar->metrics.rightSideBearing + - currchar->metrics.leftSideBearing , T1_pad); + /* We have to check for Big Endian. In that case, we have to + act on byte-level */ + if (T1_byte){ + BitShift = pixel_h_anchor_corr[i] % 8; + ByteOffset = pixel_h_anchor_corr[i] / 8; + } + else { + BitShift = pixel_h_anchor_corr[i] % T1_pad; + ByteOffset = pixel_h_anchor_corr[i] / T1_pad; + if (T1_pad==32) + ByteOffset *=4; + else if (T1_pad==16) + ByteOffset *=2; + } +#ifdef T1_AA_TYPE64 + /* We compile this part only if long is 64 bits to be conform to ANSI C */ + if (T1_pad==32 && T1_byte==0){ + /* The following loop steps through the lines of the character bitmap: */ + for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){ + Target_l= (unsigned T1_AA_TYPE32 *)(string_glyph.bits +((v_anchor+j)*paddedW/8) + +ByteOffset); + /* The following loop copies the scanline of a character bitmap: */ + if (currchar->bits != NULL) { + p_l = (unsigned T1_AA_TYPE32 *)(currchar->bits+(char_paddedW/8*j)); + if (BitShift == 0) { + for (k=char_paddedW >> 5; k; k--) + *Target_l++ |= *p_l++; + } else { + for (k=0; k < char_paddedW / 32 ; k++){ + BitBuf_l= ((T1_AA_TYPE64)(*p_l++)) << BitShift; + *Target_l++ |= BitBuf_l; + *Target_l |= BitBuf_l>>l_shift; + } /* End of for ( .. ) stepping through columns */ + } + } /* End of if(currchar->bits != NULL) */ + } /* End of for( .. ) steppin' through lines of char bitmap */ + }/* end if (T1_pad==32) */ + else +#endif + if (T1_pad==16 && T1_byte==0){ + /* The following loop steps through the lines of the character bitmap: */ + for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){ + Target_s= (unsigned T1_AA_TYPE16 *)(string_glyph.bits +((v_anchor+j)*paddedW/8) + +ByteOffset); + /* The following loop copies the scanline of a character bitmap: */ + if (currchar->bits != NULL) { + p_s = (unsigned T1_AA_TYPE16 *)(currchar->bits+(char_paddedW/8*j)); + if (BitShift == 0) { + for (k=char_paddedW >> 4; k; k--) + *Target_s++ |= *p_s++; + } + else{ + for (k=char_paddedW >> 4; k; k--){ + BitBuf_s= ((T1_AA_TYPE32)(*p_s++))<<BitShift; + *Target_s++ |= BitBuf_s; + *Target_s |= BitBuf_s>>s_shift; + } /* End of for ( .. ) stepping through columns */ + } + } /* End of if(currchar->bits != NULL) */ + } /* End of for( .. ) steppin' through lines of char bitmap */ + }/* end if (T1_pad==16 */ + else{ /* T1_pad = 8 or Big Endian machine */ + /* The following loop steps through the lines of the character bitmap: */ + for (j=0;j<currchar->metrics.ascent-currchar->metrics.descent;j++){ + Target_c= (unsigned char *)(string_glyph.bits +((v_anchor+j)*paddedW/8) + +ByteOffset); + /* The following loop copies the scanline of a character bitmap: */ + if (currchar->bits != NULL) { + p_c = (unsigned char *)(currchar->bits+(char_paddedW/8*j)); + if (BitShift == 0){ + for (k=char_paddedW >> 3; k; k--) + *Target_c++ |= *p_c++; + } + else{ + for (k=char_paddedW >> 3; k; k--){ + BitBuf_c = ((T1_AA_TYPE16)(*p_c++)) << BitShift; + *Target_c++ |= BitBuf_c; + *Target_c |= BitBuf_c>>c_shift; + } /* End of for ( .. ) stepping through columns */ + } + } /* End of if(currchar->bits != NULL) */ + } /* End of for( .. ) steppin' through lines of char bitmap */ + } /* end if (T1_pad==8) and/or BigEndian */ + } + } /* if (string_glyph.bits != NULL) */ + + + /* We now put the underlining rule on the glyph */ + if (modflag & T1_UNDERLINE){ + start=-string_glyph.metrics.leftSideBearing; + for (i=string_glyph.metrics.ascent-underline_starty; + i<string_glyph.metrics.ascent-underline_endy; i++){ + start =-string_glyph.metrics.leftSideBearing + + (int) floor((double)(string_glyph.metrics.ascent-i) + *fontarrayP->slant+0.5); + middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); + startmask = 0xFF << (start % 8); + endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); + Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + + (start / 8)); + j=middle; + if (j == 0) + *Target_c++ |= startmask & endmask; + else { + *Target_c++ |= startmask; + while (--j > 0) + *Target_c++ = (unsigned char) 0xFF; + if ((endmask)) + *Target_c |= endmask; + } + } + } + /* Put an overstrike rule on the glyph */ + if (modflag & T1_OVERSTRIKE){ + start=-string_glyph.metrics.leftSideBearing; + for (i=string_glyph.metrics.ascent-overstrike_starty; + i<string_glyph.metrics.ascent-overstrike_endy; i++){ + start =-string_glyph.metrics.leftSideBearing + + (int) floor((double)(string_glyph.metrics.ascent-i) + *fontarrayP->slant+0.5); + middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); + startmask = 0xFF << (start % 8); + endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); + Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + + (start / 8)); + j=middle; + if (j == 0) + *Target_c++ |= startmask & endmask; + else { + *Target_c++ |= startmask; + while (--j > 0) + *Target_c++ = (unsigned char) 0xFF; + if ((endmask)) + *Target_c |= endmask; + } + } + } + /* Put an overline rule */ + if (modflag & T1_OVERLINE){ + start=-string_glyph.metrics.leftSideBearing; + for (i=string_glyph.metrics.ascent-overline_starty; + i<string_glyph.metrics.ascent-overline_endy; i++){ + start =-string_glyph.metrics.leftSideBearing + + (int) floor((double)(string_glyph.metrics.ascent-i) + *fontarrayP->slant+0.5); + middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); + startmask = 0xFF << (start % 8); + endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); + Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + + (start / 8)); + j=middle; + if (j == 0) + *Target_c++ |= startmask & endmask; + else { + *Target_c++ |= startmask; + while (--j > 0) + *Target_c++ = (unsigned char) 0xFF; + if ((endmask)) + *Target_c |= endmask; + } + } + } + + /* Check for writing direction and re-compute dimensions appropriately: */ + if (modflag & T1_RIGHT_TO_LEFT){ + string_glyph.metrics.advanceX *= -1; + string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX; + string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX; + } + + return(&string_glyph); + } /* end of "if (rot_flag==0.0)" */ + + + /* fnt_ptr now points to the correct FontSizeDeps-struct => + lets now raster the character */ + mode=0; + kern_pairs=(int *)calloc(no_chars, sizeof(int)); + if ((modflag & T1_KERNING)) + for (i=0; i<no_chars -1; i++) + kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); + area=fontfcnB_string( FontID, modflag, Current_S, + fontarrayP->pFontEnc, + ustring, no_chars, &mode, + fontarrayP->pType1Data, + kern_pairs, spacewidth, + DO_RASTER, + strokewidth); + KillSpace (Current_S); + + /* In all cases, free memory for kerning pairs */ + free(kern_pairs); + + /* fill the string_glyph-structure */ + if (mode > 0) { + sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + /* make sure to get rid of area if it's there */ + if (area){ + KillRegion (area); + } + return(NULL); + } + if (area == NULL){ + T1_PrintLog( "T1_SetString()", "area=NULL returned by fontfcnB()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + + if (mode == FF_NOTDEF_SUBST) { + sprintf( err_warn_msg_buf, + "\".notdef\" substituted somewhere in string from font %d", + FontID); + T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); + mode=0; + } + + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + paddedW = PAD(w, T1_pad); + if (h > 0 && w > 0) { + memsize = h * paddedW / 8 + 1; + /* This is for the users copy of the character, for security-reasons + the original pointer to the cache area is not used. The entry string_glyph.bits + is free'ed every time this function is called: */ + string_glyph.bits = (char *)malloc(memsize*sizeof( char)); + if (string_glyph.bits == NULL) { + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to get rid of area if it's there */ + if (area){ + KillRegion (area); + } + /* it's safe to free this, since this is a rotated glyph and + therefore it's a copy of the original one */ + return(NULL); + } + } + else { + h = w = 0; + area->xmin = area->xmax = 0; + area->ymin = area->ymax = 0; + } + + string_glyph.metrics.leftSideBearing=area->xmin; + string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x); + string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y); + string_glyph.metrics.rightSideBearing=area->xmax; + string_glyph.metrics.descent=-area->ymax; + string_glyph.metrics.ascent=-area->ymin; + + if (h > 0 && w > 0) { + (void) memset(string_glyph.bits, 0, memsize); + fill(string_glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); + } + else { /* We have no black pixels */ + string_glyph.metrics.leftSideBearing=0; + string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x); + string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y); + string_glyph.metrics.rightSideBearing=0; + string_glyph.metrics.descent=0; + string_glyph.metrics.ascent=0; + } + + + /* make sure to get rid of area if it's there */ + if (area){ + KillRegion (area); + } + /* Check for writing direction and re-compute dimensions appropriately: */ + if (modflag & T1_RIGHT_TO_LEFT){ + string_glyph.metrics.advanceX *= -1; + string_glyph.metrics.advanceY *= -1; + string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX; + string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX; + string_glyph.metrics.descent += string_glyph.metrics.advanceY; + string_glyph.metrics.ascent += string_glyph.metrics.advanceY; + } + return(&string_glyph); +} + + + +void fill(dest, h, w, area, byte, bit, wordsize) + register char *dest; /* destination bitmap */ + int h,w; /* dimensions of 'dest', w padded */ + register struct region *area; /* region to write to 'dest' */ + int byte,bit; /* flags; LSBFirst or MSBFirst */ + int wordsize; /* number of bits per word for LSB/MSB purposes */ +{ + register struct edgelist *edge; /* for looping through edges */ + register char *p; /* current scan line in 'dest' */ + register int y; /* for looping through scans */ + register int wbytes = w / 8; /* number of bytes in width */ + register pel *leftP,*rightP; /* pointers to X values, left and right */ + int xmin = area->xmin; /* upper left X */ + int ymin = area->ymin; /* upper left Y */ + + for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) { + + p = dest + (edge->ymin - ymin) * wbytes; + leftP = edge->xvalues; + rightP = edge->link->xvalues; + + for (y = edge->ymin; y < edge->ymax; y++) { + fillrun(p, *leftP++ - xmin , *rightP++ - xmin, bit); + p += wbytes; + } + } + /* + Now, as an afterthought, we'll go reorganize if odd byte order requires + it: + */ + /* We do not reorganize since t1lib internally always uses LSBFirst */ + /* + if ( 0 && wordsize != 8) { + register int i; + printf("Reorganizing data ..\n"); + + switch (wordsize) { + case 16: + { + register unsigned short data,*p; + p = (unsigned short *) dest; + for (i = h * w /16; --i >= 0;) { + data = *p; + *p++ = (data << 8) + (data >> 8); + } + break; + } + case 64: + case 32: + { + register ULONG data,*p; + p = (ULONG *) dest; + for (i = h * w / 32; --i >= 0;) { + data = *p; + *p++ = (data << 24) + (data >> 24) + + (0xFF00 & (data >> 8)) + + (0xFF0000 & (data << 8)); + } + if (wordsize == 64) { + p = (ULONG *) dest; + for (i = h * w / 64; --i >= 0;) { + data = *p++; + p[-1] = p[0]; + *p++ = data; + } + } + break; + } + default: + abort("xiFill: unknown format"); + } + } + */ +} + +#define ALLONES 0xFF + +void fillrun(register char *p, pel x0, pel x1, int bit) +{ + register int startmask,endmask; /* bits to set in first and last char*/ + register int middle; /* number of chars between start and end + 1 */ + + if (x1 <= x0) + return; + middle = x1/8 - x0/8; + p += x0/8; + x0 &= 7; x1 &= 7; + if (bit == LSBFirst) { + startmask = ALLONES << x0; + endmask = ~(ALLONES << x1); + } + else { + startmask = ALLONES >> x0; + endmask = ~(ALLONES >> x1); + } + if (middle == 0) + *p++ |= startmask & endmask; + else { + *p++ |= startmask; + while (--middle > 0){ + *p++ = (unsigned char)ALLONES; + } + if (endmask) + *p |= endmask; + } +} + + +/* outline */ +#undef CHECK_OUTLINEFILL +#ifdef CHECK_OUTLINEFILL +void fill(dest, h, w, area, byte, bit, wordsize) + register char *dest; /* destination bitmap */ + int h,w; /* dimensions of 'dest', w padded */ + register struct region *area; /* region to write to 'dest' */ + int byte,bit; /* flags; LSBFirst or MSBFirst */ + int wordsize; /* number of bits per word for LSB/MSB purposes */ +{ + register struct edgelist *edge; /* for looping through edges */ + register char *p; /* current scan line in 'dest' */ + register int y; /* for looping through scans */ + register int wbytes = w / 8; /* number of bytes in width */ + register pel *leftP,*rightP; /* pointers to X values, left and right */ + int xmin = area->xmin; /* upper left X */ + int ymin = area->ymin; /* upper left Y */ + + for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) { + + p = dest + (edge->ymin - ymin) * wbytes; + leftP = edge->xvalues; + rightP = edge->link->xvalues; + + printf("leftP=%d, RightP=%d,\n", *leftP, *rightP); + + + for (y = edge->ymin; y < edge->ymax; y++) { + printf("leftP=%d, RightP=%d,y=%d\n", *leftP, *rightP, y); + + fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit); + p += wbytes; + } + } +} +#endif + + +/* T1_CopyGlyph(): Make a copy of an existent glyph-structure to save it + for later usage by the user. */ +GLYPH *T1_CopyGlyph( GLYPH *glyph) +{ + GLYPH *dest; + long size; + + + if (glyph==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + /* Assign padding value */ + T1_pad=pFontBase->bitmap_pad; + /* Allocate memory for struct: */ + if ((dest=(GLYPH *)malloc(sizeof(GLYPH)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + /* Copy the structure members: */ + *dest=*glyph; + /* Allocate memory for bitmap, initialize pointer to it and copy bitmap: */ + size=PAD((dest->metrics.rightSideBearing-dest->metrics.leftSideBearing)* + glyph->bpp, T1_pad) / 8; + size=size*(dest->metrics.ascent-dest->metrics.descent); + /* We must check whether there's actually a bits-pointer different from + NULL. If not omit the following step: */ + if (glyph->bits!=NULL){ + if ((dest->bits=(char *)malloc(size*sizeof(char)))==NULL){ + free(dest); + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + memcpy(dest->bits,glyph->bits,size); + } + return(dest); +} + +/* T1_DumpGlyph(): Dump a glyph-representation to stdout: */ +void T1_DumpGlyph( GLYPH *glyph) +{ + int i,j,h,w; /* i=line-index, j=column-index */ + long paddedW; + + + printf("Dataformat: T1_bit=%d, T1_byte=%d, T1_wordsize=%d, T1_pad=%d\n", + T1_bit, T1_byte, T1_pad, T1_pad); + + if (glyph==NULL){ + return; + } + + h=glyph->metrics.ascent-glyph->metrics.descent; + w=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing; + + paddedW=PAD(w,T1_pad); + + printf("GlyphInfo: h=%d, w=%d, paddedW=%ld\n", h, w, paddedW); + + for ( i=0; i<h; i++){ + if (T1_pad==8) + for (j=0; j<paddedW/T1_pad; j++) + bin_dump_c(glyph->bits[i*paddedW/T1_pad+j], 1); + else if (T1_pad==16) + for (j=0; j<paddedW/T1_pad; j++){ + bin_dump_s(((unsigned short *)glyph->bits)[i*paddedW/T1_pad+j], 1); + } + else + for (j=0; j<paddedW/T1_pad; j++){ + bin_dump_l(((unsigned long *)glyph->bits)[i*paddedW/T1_pad+j], 1); + } + printf("\n"); + } +} + + + +/* This function will essentially return the bounding box of the + line-rule */ +static void T1_ComputeLineParameters( int FontID, int mode, + int width, float size, + int *startx, int *endx, + int *starty, int *endy) +{ + float position=0.0, thickness=0.0; + int startx1, startx2, endx1, endx2; + + if (mode & T1_UNDERLINE){ + position=pFontBase->pFontArray[FontID].UndrLnPos + * DeviceSpecifics.scale_y; + thickness=pFontBase->pFontArray[FontID].UndrLnThick + * DeviceSpecifics.scale_y; + } + else if (mode & T1_OVERLINE){ + position=pFontBase->pFontArray[FontID].OvrLnPos + * DeviceSpecifics.scale_y; + thickness=pFontBase->pFontArray[FontID].OvrLnThick + * DeviceSpecifics.scale_y; + } + else if (mode & T1_OVERSTRIKE){ + position=pFontBase->pFontArray[FontID].OvrStrkPos + * DeviceSpecifics.scale_y; + thickness=pFontBase->pFontArray[FontID].OvrStrkThick + * DeviceSpecifics.scale_y; + } + + *starty=(int) floor((position+0.5*(thickness-DeviceSpecifics.y_resolution/1000.0)) + *size/1000.0 +0.5 ); + startx1=(int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5); + *endy =*starty - (int) floor(thickness/1000.0*size+0.5); + startx2=(int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5); + *startx=startx1 < startx2 ? startx1 : startx2; + endx1 = width + + (int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5); + endx2 = width + + (int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5); + *endx=endx1 < endx2 ? endx2 : endx1; + + /* We take care that at least one pixel is drawn */ + if (*starty==*endy) + *endy -=1; + + return; + +} + + + +/* The following function concatenates two glyphs. Optional offsets + x_off, y_off are respected. By the function. + If either glyph is NULL or the glyphs have distinct depth, NULL is + returned. */ +GLYPH *T1_ConcatGlyphs( GLYPH *glyph_1, GLYPH *glyph_2, + int x_off, int y_off, int modflag) +{ + + int lsb1, lsb2, rsb1, rsb2; + int advanceX1, advanceX2, advanceY1, advanceY2; + int ascent1, ascent2, descent1, descent2; + int rsb, lsb, ascent, descent, advanceX, advanceY; + int vanchor, w, h, wscanline, wscanline1, wscanline2, bpp; + int memsize, BitShift; + GLYPH *glyph1, *glyph2; + unsigned T1_AA_TYPE16 BitBuf_c; + unsigned T1_AA_TYPE32 BitBuf_s; + unsigned long BitBuf_l; /* This is only actually used if sizeof long = 8 */ + int i, j, k; + int ByteOffset; + + unsigned char *Target_c, *p_c; + unsigned T1_AA_TYPE16 *Target_s, *p_s; + unsigned T1_AA_TYPE32 *Target_l, *p_l; + + static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; + + + /* We handle the Right-To-Left concatenation the simple way: + 1) Change the order of the two glyphs + 2) Invert the sign of the y-part of the offset + 3) Recalculate the dimensions of the resulating glyph. + */ + /* Check for writing direction and reorganize appropriately: */ + if (modflag & T1_RIGHT_TO_LEFT){ + glyph1=glyph_2; + glyph2=glyph_1; + y_off=-y_off; + } + else { + glyph1=glyph_1; + glyph2=glyph_2; + } + + if (glyph1==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return( NULL); + } + if (glyph2==NULL){ + T1_errno=T1ERR_INVALID_PARAMETER; + return( NULL); + } + if (glyph1->bpp != glyph2->bpp){ + T1_errno=T1ERR_INVALID_PARAMETER; + return( NULL); + } + + /* We have two glyph different from NULL */ + /* Reset glyph, if necessary */ + if (glyph.bits!=NULL){ + free(glyph.bits); + glyph.bits=NULL; + } + glyph.metrics.leftSideBearing=0; + glyph.metrics.rightSideBearing=0; + glyph.metrics.advanceX=0; + glyph.metrics.advanceY=0; + glyph.metrics.ascent=0; + glyph.metrics.descent=0; + glyph.pFontCacheInfo=NULL; + glyph.bpp=1; + + /* Assign dimens */ + lsb1=glyph1->metrics.leftSideBearing; + rsb1=glyph1->metrics.rightSideBearing; + ascent1=glyph1->metrics.ascent; + descent1=glyph1->metrics.descent; + advanceX1=glyph1->metrics.advanceX + x_off; + advanceY1=glyph1->metrics.advanceY + y_off; + + lsb2=glyph2->metrics.leftSideBearing; + rsb2=glyph2->metrics.rightSideBearing; + ascent2=glyph2->metrics.ascent; + descent2=glyph2->metrics.descent; + advanceX2=glyph2->metrics.advanceX; + advanceY2=glyph2->metrics.advanceY; + + lsb=lsb1 < lsb2+advanceX1 ? lsb1 : lsb2+advanceX1; + rsb=rsb1 > rsb2+advanceX1 ? rsb1 : rsb2+advanceX1; + ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1; + descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1; + advanceX=advanceX1+advanceX2; + advanceY=advanceY1+advanceY2; + + bpp=glyph1->bpp; + w=rsb-lsb; + h=ascent-descent; + wscanline=PAD( w*bpp, T1_pad) / 8; + wscanline1=PAD( (rsb1-lsb1)*bpp, T1_pad) / 8; + wscanline2=PAD( (rsb2-lsb2)*bpp, T1_pad) / 8; + memsize=wscanline*h; + if ((glyph.bits=(char *)calloc( memsize + 1, sizeof(unsigned char)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + + if (bpp==1){ + if (T1_pad==32 && T1_byte==0 && sizeof(long)==8){ + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + BitShift=(lsb1-lsb) % 32; + ByteOffset=(lsb1-lsb)/32*4; + for ( i=0; i<ascent1-descent1; i++){ + Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i)); + if (BitShift == 0){ + for (k=wscanline1/4; k; k--) + *Target_l++ |= *p_l++; + } + else{ + for (k=wscanline1/4; k; k--){ + BitBuf_l = ((long)*p_l++) << BitShift; + *Target_l++ |= BitBuf_l; + *Target_l |= BitBuf_l>>l_shift; + } + } + } + /* The following loop steps through the lines of the second glyph: */ + vanchor=ascent-(ascent2+advanceY1); + BitShift=(lsb2+advanceX1-lsb) % 32; + ByteOffset=(lsb2+advanceX1-lsb)/32*4; + for ( i=0; i<ascent2-descent2; i++){ + Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i)); + if (BitShift == 0){ + for (k=wscanline2/4; k; k--) + *Target_l++ |= *p_l++; + } + else{ + for (k=wscanline2/4; k; k--){ + BitBuf_l = ((long)*p_l++) << BitShift; + *Target_l++ |= BitBuf_l; + *Target_l |= BitBuf_l>>l_shift; + } + } + } + } + else if(T1_pad==16 && T1_byte==0){ + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + BitShift=(lsb1-lsb) % 16; + ByteOffset=(lsb1-lsb)/16*2; + for ( i=0; i<ascent1-descent1; i++){ + Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i)); + if (BitShift == 0){ + for (k=wscanline1/2; k; k--) + *Target_s++ |= *p_s++; + } + else{ + for (k=wscanline1/2; k; k--){ + BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift; + *Target_s++ |= BitBuf_s; + *Target_s |= BitBuf_s>>s_shift; + } + } + } + /* The following loop steps through the lines of the second glyph: */ + vanchor=ascent-(ascent2+advanceY1); + BitShift=(lsb2+advanceX1-lsb) % 16; + ByteOffset=(lsb2+advanceX1-lsb)/16*2; + for ( i=0; i<ascent2-descent2; i++){ + Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i)); + if (BitShift == 0){ + for (k=wscanline2/2; k; k--) + *Target_s++ |= *p_s++; + } + else{ + for (k=wscanline2/2; k; k--){ + BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift; + *Target_s++ |= BitBuf_s; + *Target_s |= BitBuf_s>>s_shift; + } + } + } + } + else{ /* T1_pad==8 or Big Endian machine */ + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + BitShift=(lsb1-lsb) % 8; + ByteOffset=(lsb1-lsb) / 8; + for ( i=0; i<ascent1-descent1; i++){ + Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_c = (unsigned char *)(glyph1->bits+(wscanline1*i)); + if (BitShift == 0){ + for (k=wscanline1; k; k--) + *Target_c++ |= *p_c++; + } + else{ + for (k=wscanline1; k; k--){ + BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift; + *Target_c++ |= BitBuf_c; + *Target_c |= BitBuf_c>>c_shift; + } + } + } + /* The following loop steps through the lines of the second glyph: */ + vanchor=ascent-(ascent2+advanceY1); + BitShift=(lsb2+advanceX1-lsb) % 8; + ByteOffset=(lsb2+advanceX1-lsb) / 8; + for ( i=0; i<ascent2-descent2; i++){ + Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) + +ByteOffset); + p_c = (unsigned char *)(glyph2->bits+(wscanline2*i)); + if (BitShift == 0){ + for (k=wscanline2; k; k--) + *Target_c++ |= *p_c++; + } + else{ + for (k=wscanline2; k; k--){ + BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift; + *Target_c++ |= BitBuf_c; + *Target_c |= BitBuf_c>>c_shift; + } + } + } + } + } /* end of if (bpp==1) ... */ + else if (bpp==8){ + /* Set background */ + for ( i=0; i<memsize; i++) + ((char *)glyph.bits)[i]=(char) T1aa_bg; + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + for ( i=0; i<ascent1-descent1; i++){ + Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb1-lsb)); + p_c = (unsigned char *)(glyph1->bits+(wscanline1*i)); + memcpy( Target_c, p_c, (rsb1-lsb1)); + } + /* The following loop steps through the lines of the second glyph. + Note that we only set the pixel if it is not background! */ + vanchor=ascent-(ascent2+advanceY1); + for ( i=0; i<ascent2-descent2; i++){ + Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb2+advanceX1-lsb)); + p_c = (unsigned char *)(glyph2->bits+(wscanline2*i)); + for (j=0; j<(rsb2-lsb2); j++) + if (p_c[j] != (unsigned char) T1aa_bg) + Target_c[j]=p_c[j]; + } + } /* end of if (bpp==8) ... */ + else if (bpp==16){ + /* Set background */ + for ( i=0; i<memsize/2; i++) + ((T1_AA_TYPE16 *)glyph.bits)[i]=(T1_AA_TYPE16) T1aa_bg; + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + for ( i=0; i<ascent1-descent1; i++){ + Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb1-lsb)*2); + p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i)); + memcpy( Target_s, p_s, (rsb1-lsb1)*2); + } + /* The following loop steps through the lines of the second glyph. + Note that we only set the pixel if it is not background! */ + vanchor=ascent-(ascent2+advanceY1); + for ( i=0; i<ascent2-descent2; i++){ + Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb2+advanceX1-lsb)*2); + p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i)); + for (j=0; j<(rsb2-lsb2); j++) + if (p_s[j] != (unsigned T1_AA_TYPE16) T1aa_bg) + Target_s[j]=p_s[j]; + } + } /* end of if (bpp==16) ... */ + else if (bpp==32){ + /* Set background */ + for ( i=0; i<memsize/4; i++) + ((T1_AA_TYPE32 *)glyph.bits)[i]=(T1_AA_TYPE32) T1aa_bg; + /* The following loop steps through the lines of the first glyph: */ + vanchor=ascent-ascent1; + for ( i=0; i<ascent1-descent1; i++){ + Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb1-lsb)*4); + p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i)); + memcpy( Target_l, p_l, (rsb1-lsb1)*4); + } + /* The following loop steps through the lines of the second glyph. + Note that we only set the pixel if it is not background! */ + vanchor=ascent-(ascent2+advanceY1); + for ( i=0; i<ascent2-descent2; i++){ + Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) + +(lsb2+advanceX1-lsb)*4); + p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i)); + for (j=0; j<(rsb2-lsb2); j++) + if (p_l[j] != (unsigned T1_AA_TYPE32) T1aa_bg) + Target_l[j]=p_l[j]; + } + } /* end of if (bpp==32) ... */ + + + /* Check for writing direction and re-compute dimens appropriately: */ + if (modflag & T1_RIGHT_TO_LEFT){ + advanceX=-advanceX1-advanceX2; + advanceY=-advanceY1-advanceY2; + lsb=lsb1 < lsb2+advanceX1 ? advanceX+lsb1 : advanceX+lsb2+advanceX1; + rsb=rsb1 > rsb2+advanceX1 ? advanceX+rsb1 : advanceX+rsb2+advanceX1; + ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1; + descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1; + ascent += advanceY; + descent += advanceY; + } + + glyph.metrics.leftSideBearing=lsb; + glyph.metrics.rightSideBearing=rsb; + glyph.metrics.advanceX=advanceX; + glyph.metrics.advanceY=advanceY; + glyph.metrics.ascent=ascent; + glyph.metrics.descent=descent; + glyph.bpp=bpp; + + /* + printf("lsb=%d, rsb=%d, adX=%d, adY=%d asc=%d, desc=%d\n", + glyph.metrics.leftSideBearing, + glyph.metrics.rightSideBearing, + glyph.metrics.advanceX, + glyph.metrics.advanceY, + glyph.metrics.ascent, + glyph.metrics.descent ); + */ + + return( &glyph); + +} + + + +/* T1_FillOutline(): Create a filled glyph from an outline description */ +GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag) +{ + struct region *area=NULL; + + static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; + volatile int memsize=0; + int i; + LONG h,w; + LONG paddedW; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + /* Reset character glyph, if necessary */ + if (glyph.bits!=NULL){ + free(glyph.bits); + glyph.bits=NULL; + } + glyph.metrics.leftSideBearing=0; + glyph.metrics.rightSideBearing=0; + glyph.metrics.advanceX=0; + glyph.metrics.advanceY=0; + glyph.metrics.ascent=0; + glyph.metrics.descent=0; + glyph.pFontCacheInfo=NULL; + glyph.bpp=1; + + + /* Assign padding value */ + T1_pad=pFontBase->bitmap_pad; + if (pFontBase->endian) + T1_byte=1; + else + T1_byte=0; + T1_wordsize=T1_pad; + + /* Create a region from outline */ + area=(struct region *)Interior( (struct segment *)path, + WINDINGRULE+CONTINUITY); + + /* fill the glyph-structure */ + if (area == NULL){ + T1_PrintLog( "T1_FillOutline()", "area=NULL returned by Interior()", T1LOG_WARNING); + T1_errno=1000; + return(NULL); + } + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + + + paddedW = PAD(w, T1_pad); + if ( (area->xmin > area->xmax) || (area->ymin > area->ymax) ){ + /* There was a character like .notdef or space, that didn't + produce any black pixels on the bitmap! -> we return a glyph with + correct metrics and bitmap pointer set to NULL */ + sprintf( err_warn_msg_buf, + "No black pixels in outline %p", path); + T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf, T1LOG_WARNING); + + glyph.metrics.leftSideBearing = 0; + glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); + glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); + glyph.metrics.rightSideBearing = 0; + glyph.metrics.descent = 0; + glyph.metrics.ascent = 0; + /* make sure to get rid of 'area' before leaving! */ + KillRegion (area); + return( &glyph); + } + if (h > 0 && w > 0) { + memsize = h * paddedW / 8 + 1; + /* This is for the users copy of the character, for security-reasons + the original pointer to the cache area is not used. The entry glyph.bits + is free'ed every time this function is called: */ + glyph.bits = (char *)malloc(memsize*sizeof( char)); + if (glyph.bits == NULL){ + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to get rid of area if it's there */ + if (area){ + KillRegion (area); + } + return(NULL); + } + + } + else { + h = w = 0; + area->xmin = area->xmax = 0; + area->ymin = area->ymax = 0; + } + + glyph.metrics.leftSideBearing = area->xmin; + glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); + glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); + glyph.metrics.rightSideBearing = area->xmax; + glyph.metrics.descent = - area->ymax; + glyph.metrics.ascent = - area->ymin; + + + if (h > 0 && w > 0) { + (void) memset(glyph.bits, 0, memsize); + fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); + } + + /* Check for writing direction and re-compute dimensions appropriately: */ + if (modflag & T1_RIGHT_TO_LEFT){ + glyph.metrics.advanceX *= -1; + glyph.metrics.advanceY *= -1; + glyph.metrics.leftSideBearing += glyph.metrics.advanceX; + glyph.metrics.rightSideBearing += glyph.metrics.advanceX; + glyph.metrics.descent += glyph.metrics.advanceY; + glyph.metrics.ascent += glyph.metrics.advanceY; + } + + /* make sure to get rid of area if it's there */ + if (area){ + KillRegion (area); + } + return( &glyph); + + +} + + +/* T1_SetRect(): Raster a rectangle, whose size is given in charspace units. + The resulting glyph does not cause any escapement. */ +GLYPH* T1_SetRect( int FontID, float size, + float width, float height, T1_TMATRIX *transform) +{ + int i; + int mode; + struct region *area; + struct XYspace *Current_S; + float strokewidth = 0.0f; + + FONTSIZEDEPS *font_ptr; + FONTPRIVATE *fontarrayP; + + volatile int memsize=0; + LONG h,w; + LONG paddedW; + + static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; + + + /* We return to this if something goes wrong deep in the rasterizer */ + if ((i=setjmp( stck_state))!=0) { + T1_errno=T1ERR_TYPE1_ABORT; + sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", + t1_get_abort_message( i)); + T1_PrintLog( "T1_SetRect()", err_warn_msg_buf, + T1LOG_ERROR); + return( NULL); + } + + font_ptr = NULL; + + /* Reset character glyph, if necessary */ + if (glyph.bits!=NULL){ + free(glyph.bits); + glyph.bits=NULL; + } + glyph.metrics.leftSideBearing=0; + glyph.metrics.rightSideBearing=0; + glyph.metrics.advanceX=0; + glyph.metrics.advanceY=0; + glyph.metrics.ascent=0; + glyph.metrics.descent=0; + glyph.pFontCacheInfo=NULL; + glyph.bpp=1; + + /* First, check for a correct ID. */ + i=T1_CheckForFontID(FontID); + if ( i == -1 ) { + return NULL; + } + /* if necessary load font into memory */ + if ( i == 0 ) + if ( T1_LoadFont( FontID) ) + return NULL; + + /* Check for valid size */ + if (size<=0.0){ + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + /* Assign padding value */ + T1_pad=pFontBase->bitmap_pad; + if (pFontBase->endian) + T1_byte=1; + else + T1_byte=0; + T1_wordsize=T1_pad; + + if ( i > 0 ) { + /* FontID identifies a valid font */ + fontarrayP = &(pFontBase->pFontArray[FontID]); + + /* Check for size and create it if necessary */ + if ((font_ptr=T1int_QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ + font_ptr=T1int_CreateNewFontSize( FontID, size, NO_ANTIALIAS); + if (font_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + } + + /* handle stroking stuff */ + if ( fontarrayP->info_flags & RASTER_STROKED) { + strokewidth = pFontBase->pFontArray[FontID].StrokeWidth; + } + else { + strokewidth = 0.0f; + } + } + else { + fontarrayP = NULL; + strokewidth = 0.0f; + } + + + /* Setup an appropriate charspace matrix. Note that the rasterizer + assumes vertical values with inverted sign! Transformation should + create a copy of the local charspace matrix which then still has + to be made permanent. */ + if ( transform != NULL ) { + Current_S = (struct XYspace *) + Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, + transform->cxx, - transform->cxy, + transform->cyx, - transform->cyy), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + else{ + Current_S = (struct XYspace *) + Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, + 1.0, 0.0, 0.0, -1.0), + DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); + } + + mode=0; + area=fontfcnRect( width, + height, + Current_S, + &mode, + DO_RASTER, + strokewidth); + KillSpace (Current_S); + + /* fill the glyph-structure */ + if ( mode > 0 ) { + sprintf( err_warn_msg_buf, "fontfcnRect() set mode=%d", mode); + T1_PrintLog( "T1_SetRect()", err_warn_msg_buf, T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + if ( area == NULL ) { + T1_PrintLog( "T1_SetRect()", "area=NULL returned by fontfcnRect()", T1LOG_WARNING); + T1_errno=mode; + return(NULL); + } + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + + paddedW = PAD(w, T1_pad); + + if (h > 0 && w > 0) { + memsize = h * paddedW / 8 + 1; + /* This is for the users copy of the character, for security-reasons + the original pointer to the cache area is not used. The entry glyph.bits + is free'ed every time this function is called: */ + glyph.bits = (char *)malloc(memsize*sizeof( char)); + if ( glyph.bits == NULL ) { + T1_errno=T1ERR_ALLOC_MEM; + /* make sure to get rid of 'area' before leaving! */ + KillRegion (area); + return(NULL); + } + } + else { + h = w = 0; + area->xmin = area->xmax = 0; + area->ymin = area->ymax = 0; + } + + /* Assign metrics */ + glyph.metrics.leftSideBearing = area->xmin; + glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); + glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); + glyph.metrics.rightSideBearing = area->xmax; + glyph.metrics.descent = - area->ymax; + glyph.metrics.ascent = - area->ymin; + + + if (h > 0 && w > 0) { + (void) memset(glyph.bits, 0, memsize); + fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); + } + + /* make sure to get rid of 'area' before leaving! */ + KillRegion (area); + + return(&glyph); +} diff --git a/Build/source/libs/t1lib/t1set.h b/Build/source/libs/t1lib/t1set.h new file mode 100644 index 00000000000..e2fd80a0218 --- /dev/null +++ b/Build/source/libs/t1lib/t1set.h @@ -0,0 +1,98 @@ +/*-------------------------------------------------------------------------- + ----- File: t1set.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations for t1set.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1SET_C + +GLYPH *T1_SetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_SetString( int FontID, char *string, volatile int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +GLYPH* T1_SetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +void fill(char *dest, int h, int w, + struct region *area, int byte, int bit, + int wordsize); +void fillrun(char *p, pel x0, pel x1, int bit); +GLYPH *T1_CopyGlyph(GLYPH *glyph); +void T1_DumpGlyph( GLYPH *glyph); +GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2, + int x_off, int y_off, int modflag); +void T1_DumpGlyph( GLYPH *glyph); +GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag); + + +#else + +extern GLYPH *T1_SetChar( int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetString( int FontID, char *string, volatile int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH* T1_SetRect( int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern void fill(char *dest, int h, int w, + struct region *area, int byte, int bit, + int wordsize); +extern void fillrun(char *p, pel x0, pel x1, int bit); +extern GLYPH *T1_CopyGlyph(GLYPH *glyph); +extern void T1_DumpGlyph( GLYPH *glyph); +extern GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2, + int x_off, int y_off, int modflag); +extern void T1_DumpGlyph( GLYPH *glyph); +extern GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag); + +#endif + + +extern struct region *fontfcnB(int FontID, int modflag, + struct XYspace *S, char **ev, + unsigned char index, int *mode, + psfont *Font_Ptr, + int do_raster, + float strokewidth); +extern struct region *fontfcnB_string( int FontID, int modflag, + struct XYspace *S, char **ev, + unsigned char *string, int no_chars, + int *mode, psfont *Font_Ptr, + int *kern_pairs, long spacewidth, + int do_raster, + float strokewidth); +extern struct region *fontfcnB_ByName( int FontID, int modflag, + struct XYspace *S, + char *charname, + int *mode, psfont *Font_Ptr, + int do_raster); +extern struct region* fontfcnRect( float width, + float height, + struct XYspace* S, + int* mode, + int do_raster, + float strokewidth); + diff --git a/Build/source/libs/t1lib/t1subset.c b/Build/source/libs/t1lib/t1subset.c new file mode 100644 index 00000000000..59d30207d1f --- /dev/null +++ b/Build/source/libs/t1lib/t1subset.c @@ -0,0 +1,933 @@ +/*-------------------------------------------------------------------------- + ----- File: t1subset.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-12-08 + ----- Description: This file is part of the t1-library. It contains + functions for subsetting type 1 fonts. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1SUBSET_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1base.h" +#include "t1delete.h" +#include "t1subset.h" + +/* Segment header for pfb-files (reminder): + + Segment-header: + + Byte 1: always 128 (0x80) + + Byte 2: 1 = ASCII text + 2 = Binary text + 3 = End of file indicator (EOF) + + Byte 3: least significant byte \ + Byte 4: \ Length of + Byte 5: / data segment in bytes + Byte 6: most significant byte / + + */ +#define SEGMENT_ASCII 1 +#define SEGMENT_BINARY 2 +#define SEGMENT_EOF 3 + + + +static char *charstringP; +static int charstringL; + + +/* We define two lookup tables to make a fast conversion from + binary bytes to ASCII-hex bytes. */ +static unsigned char highHexByte[256]={ + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31, + 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, + 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37, + 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38, + 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45, + 0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46 +}; +static unsigned char lowHexByte[256]={ + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46 +}; + + +/* parameters for eexec encryption */ +static unsigned short int eexec_r; +static unsigned short int eexec_c1=52845; +static unsigned short int eexec_c2=22719; + +/* Eexec-encrption according to the Adobe Black Book */ +static unsigned char EexecEncrypt( unsigned char plain) +{ + + unsigned char cipher; + + cipher = (plain ^ (eexec_r>>8)); + eexec_r = (cipher + eexec_r) * eexec_c1 + eexec_c2; + return( cipher); +} + + + +static int locateCharString( int FontID, char *charname) +{ + + int namelen; + int dictlen; + int i; + psdict *CharStringsP; + + + namelen=strlen( charname); + + CharStringsP=pFontBase->pFontArray[FontID].pType1Data->CharStringsP; + + dictlen=CharStringsP[0].key.len; + for ( i=1; i<=dictlen; i++) { + if (namelen==CharStringsP[i].key.len) { + /* This could be the charstring in question */ + if (strncmp( charname, + CharStringsP[i].key.data.nameP, + namelen)==0) { + /* It is the the desired charstring */ + charstringP=CharStringsP[i].value.data.valueP; + charstringL=CharStringsP[i].value.len; + return( i); + } + } + } + /* charstring not found ??? */ + return( 0); + +} + + + +static int make_pfb_segment_header( char *ptr, int type, unsigned long size) +{ + ptr[0]=(char) 0x80; + ptr[1]=type; + if (type==3) + return( 2); + ptr[2]=(char)(size & 0xFF); + ptr[3]=(char)((size>>8) & 0xFF); + ptr[4]=(char)((size>>16) & 0xFF); + ptr[5]=(char)((size>>24) & 0xFF); + return( 6); +} + + + + +/* A function for reading a Type 1 font file. eexec-decryption + is done on the fly. */ +char *T1_SubsetFont( int FontID, + char *mask, + unsigned int flags, + int linewidth, + unsigned long maxblocksize, + unsigned long *bufsize) +{ + + FILE *ifp; + static char *filebuf=NULL; + unsigned long filesize=0; + int filesegs=0; + + char *outbuf=NULL; + unsigned long outsize=0; + char *encryptbuf=NULL; + unsigned long encryptsize=0; + int encryptsegs=0; + char *trailerbuf=NULL; + unsigned long trailersize=0; + int trailersegs=0; + char linebuf[1025]; + + char *csdone; /* stores which charstrings already have been written */ + int currstring_no=0; + char *charnameP; + unsigned char cipher; + char rdstring[3]; + char ndstring[3]; + + int retval=1; + + /* Indices. Could save a few but debugging becomes easier this way */ + int i=0; + int j=0; + int k=0; + int l=0; + int m=0; + int n=0; + int o=0; + int p=0; + + + int notdefencoded=0; + int stdenc=0; + int reencode=0; + int colcount=0; + int tr_len=-1; + int encrypt=1; /* 1=ASCII-hex, 2=Binary, 0=None (for debugging) */ + int dindex=0; + int nocharstrings=0; + char encmask[256]; /* Mask after resolving composite characters */ + T1_COMP_CHAR_INFO* cci = NULL; + + + /* Otherwise we would get invalid accesses later */ + if (T1_CheckForFontID(FontID)!=1) { + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + + /* Check parameters */ + if ( (mask==NULL) || (bufsize==NULL) || (linewidth < 8) || + (linewidth > 1024) || (maxblocksize < 4) ) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + + /* First, we check how many characters have to find their way into the + subsetted file. We take possibly existing composite character + definitions by the user into account. */ + for ( j=0; j<256; j++) { + if ( mask[j] != 0 ) { + /* check whether addressed character is an internal character of + the font */ + if ( cci != NULL ) + T1_FreeCompCharData( cci); + + cci = T1_GetCompCharData( FontID, j); + + if ( cci != NULL ) { + nocharstrings += cci->numPieces; + } + else { + ++nocharstrings; + } + } + } + + + /* adjust encrypting type according to flags. Default is ASCII-hex + encryption because the output may be verbatim inserted into a + PostScript-file. */ + if (flags & T1_SUBSET_ENCRYPT_BINARY) + encrypt=2; + else if (flags & T1_SUBSET_ENCRYPT_NONE) + encrypt=0; + + /* Open and initialize scanning machinery */ + T1io_reset(); + if ((ifp = (FILE *)T1Open(T1_GetFontFilePath( FontID), "rb"))==NULL) { + T1_errno=T1ERR_FILE_OPEN_ERR; + return(NULL); + } + + if (encrypt==0) + sprintf( err_warn_msg_buf, "Subsetting Font %d, flags=0x%X, non-encrypted debug output", + FontID, flags); + else if (encrypt==1) + sprintf( err_warn_msg_buf, "Subsetting Font %d, flags=0x%X, ASCII-hex output with linelength %d", + FontID, flags, linewidth); + else if (encrypt==2) + sprintf( err_warn_msg_buf, "Subsetting Font %d, flags=0x%X, Binary output with maximum blocksize %lu", + FontID, flags, maxblocksize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + + /* Get size of file */ + filesize=T1GetFileSize( ifp); + sprintf( err_warn_msg_buf, "Source file %s is %lu bytes long", + T1_GetFontFilePath( FontID), filesize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + if ((filebuf=(char *)calloc( filesize, sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + + while (retval>0) { + /* get a line from the file. We have to read enough characters to + ensure that "eexec" does not get split between two reads. + Otherwise, decryption would not be started. */ + retval=T1Gets(&(filebuf[i]), 1025, ifp); + + i+=retval; + if ( (dindex==0) && (T1GetDecrypt()>0) ) { + dindex=i-retval; /* from this point on we have decrypted bytes */ + sprintf( err_warn_msg_buf, "Human-readable header finished (%d data bytes)", + dindex); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + } + + /* Encoding handling */ + if (strstr( &(filebuf[i-retval]), "/Encoding")!=NULL) { + if (strstr( &(filebuf[i-retval]), "StandardEncoding")!=NULL) { + stdenc=1; + if ((flags & T1_SUBSET_FORCE_REENCODE)!=0) { + /* we ignore the current line ... */ + i-=retval; + /* and put the encoding header into the buffer */ + i+=sprintf( &(filebuf[i]), + "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n" + ); + reencode=1; + } + else { + T1_PrintLog( "T1_SubsetFont()", "Leaving StandardEncoding untouched", + T1LOG_DEBUG); + reencode=0; + } + } + else { + /* The encoding is explicitly defined in the font file. We skip the + whole definition unless reencoding should be skipped. */ + stdenc=0; + retval=T1Gets(&(filebuf[i]), 1025, ifp); + i+=retval; + while (retval>0) { + /* get a line and check for end of encoding definition. */ + retval=T1Gets(&(filebuf[i]), 1025, ifp); + if ((flags & T1_SUBSET_SKIP_REENCODE)!=0) { /* we store the encoding + defined here */ + i+=retval; + reencode=0; + } + else { + reencode=1; + } + if ( (dindex==0) && (T1GetDecrypt()>0) ) { + dindex=i; /* from this point we have decrypted bytes */ + } + if (strstr( &(filebuf[i-retval]), "readonly def")!=NULL) { + break; + } + } + if (reencode==0) + T1_PrintLog( "T1_SubsetFont()", "Preserving FontSpecific Encoding", + T1LOG_DEBUG); + } + + /* At this point, if required, the actual encoding definition + follows. */ + if ( reencode!=0) { + k=0; + + /* Reset resulting encoding mask */ + for ( j=0; j<256; j++) { + encmask[j] = 0; + } + + /* Resolve composite characters and their components */ + for ( j=0; j<256; j++) { + if (mask[j]!=0) { + if ( cci != NULL) + T1_FreeCompCharData( cci); + cci = T1_GetCompCharData( FontID, j); + if ( (cci != NULL) && (cci->numPieces > 1) ) { + /* Tag all components that are required to construct + the composite character j. */ + for ( p=0; p<cci->numPieces; p++) { + encmask[cci->pieces[p].piece] = 1; + } + } + /* Tag character j in encoding definition */ + encmask[j] = 1; + } + } + + /* Write actually required encoding slots */ + for ( j=0; j<256; j++) { + if (encmask[j]!=0) { + charnameP=T1_GetCharName( FontID, j); + i+=sprintf( &(filebuf[i]), "dup %d /%s put\n", j, + charnameP); + k++; + if (strcmp(charnameP, ".notdef")==0) + notdefencoded=1; + } + } + + /* finish encoding definition */ + i+=sprintf( &(filebuf[i]), "readonly def\n"); + sprintf( err_warn_msg_buf, "Encoded %d characters", + k); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + k=0; + } + + } /* end of if (...encoding handling...) */ + + /* Extract the names are used for the charstring definitions. + We will later need them! */ + if (strstr( &(filebuf[i-retval]), "/RD")!=NULL) { + sprintf( rdstring, "RD"); + } + if (strstr( &(filebuf[i-retval]), "/ND")!=NULL) { + sprintf( ndstring, "ND"); + } + if (strstr( &(filebuf[i-retval]), "/-|")!=NULL) { + sprintf( rdstring, "-|"); + } + if (strstr( &(filebuf[i-retval]), "/|-")!=NULL) { + sprintf( ndstring, "|-"); + } + + if (strstr( &(filebuf[i-retval]), "/CharStrings")!=NULL) { + /* replace dictionary with one of an appropriate size: */ + i -=retval; + sprintf( err_warn_msg_buf, "Private dictionary finished (%u data bytes)", + i-dindex); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + /* if .notdef is not in the encoding mask, we have to reserve + room for the additional charstring .notdef. Note that still + nocharstrings is an upper bound estimation, which is reached + in cases where no characters are encoded more than one time. */ + if (notdefencoded==0) + nocharstrings++; + + i+=sprintf( &(filebuf[i]), "2 index /CharStrings %d dict dup begin\n", + nocharstrings); + break; + } + } /* the portion until Charstrings-dict is now read in */ + + + /* We now have to write the CharStrings. + Each charstring must be written once, even if the respective + character appears more than once in the encoding. So we set up + table to remember which charstrings already have been written. + + Note: The indices returned by locateCharString() range from 1 to n, so that + we have to decrement the index when filling the csdone array! + */ + if (( csdone=(char *)calloc( pFontBase->pFontArray[FontID].pType1Data->CharStringsP[0].key.len, + sizeof(char)))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( filebuf); + T1Close( ifp); + return( NULL); + } + + /* The .notdef character is in force! */ + if ((currstring_no=locateCharString( FontID, ".notdef"))==0) { + T1_errno=T1ERR_UNSPECIFIED; + free( csdone); + T1Close( ifp); + return( NULL); + } + i+=sprintf( &(filebuf[i]), "/.notdef %d %s ", charstringL, rdstring); + memcpy(&(filebuf[i]), charstringP, charstringL); + i+=charstringL; + i+=sprintf( &(filebuf[i]), " %s\n", ndstring); + csdone[currstring_no-1]=1; + /* Now, step through the specifier matrix and write only the + necessary charstrings. */ + for ( j=0; j<256; j++) { + if (mask[j]!=0) { + charnameP=T1_GetCharName( FontID, j); + if ((currstring_no=locateCharString( FontID, charnameP))==0) { + /* This might be a composite character, check and handle this case ... */ + if ( cci != NULL ) + T1_FreeCompCharData( cci); + + cci = T1_GetCompCharData( FontID, j); + if ( (cci != NULL) && (cci->numPieces > 1) ) { + /* composite character, loop through pieces and look for the components */ + for ( p=0; p<cci->numPieces; p++) { + + charnameP=T1_GetCharName( FontID, cci->pieces[p].piece); + if ((currstring_no=locateCharString( FontID, charnameP))==0) { + /* Character component not found. Try next ... */ + T1_PrintLog( "T1_SubsetFont()", "Could not locate component CS ""%s"" for index %d", + T1LOG_WARNING, charnameP, cci->pieces[p].piece); + } + else { + /* Add component to subset and process charstring only if it has not + already been done */ + if (csdone[currstring_no-1]==0) { + k=i; + i+=sprintf( &(filebuf[i]), "/%s %d %s ", charnameP, charstringL, rdstring); + memcpy(&(filebuf[i]), charstringP, charstringL); + i+=charstringL; + i+=sprintf( &(filebuf[i]), " %s\n", ndstring); + csdone[currstring_no-1]=1; + T1_PrintLog( "T1_SubsetFont()", + "Processing of component CS ""%s"" for index %d successful (len=%d bytes, line=%d bytes)", + T1LOG_DEBUG, charnameP, cci->pieces[p].piece, charstringL, i-k); + } + else { + sprintf( err_warn_msg_buf, "Skipped multiple processing of component CS ""%s"" (index %d)", + charnameP, cci->pieces[p].piece); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + } + } + } + continue; + } + else { + /* Character not found and no composite. This is mysterious, but causes no harm + because .notdef will be substituted */ + sprintf( err_warn_msg_buf, "Could not locate CS ""%s"" for index %d", + charnameP, j); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_WARNING); + continue; + } + + } + /* Process charstring only if it has not already been done */ + if (csdone[currstring_no-1]==0) { + k=i; + i+=sprintf( &(filebuf[i]), "/%s %d %s ", charnameP, charstringL, rdstring); + memcpy(&(filebuf[i]), charstringP, charstringL); + i+=charstringL; + i+=sprintf( &(filebuf[i]), " %s\n", ndstring); + csdone[currstring_no-1]=1; + sprintf( err_warn_msg_buf, + "Processing of CS ""%s"" for index %d successful (len=%d bytes, line=%d bytes)", + charnameP, j, charstringL, i-k); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + } + else { + sprintf( err_warn_msg_buf, "Skipped multiple processing of CS ""%s"" (index %d)", + charnameP, j); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + } + } + } + + /* Get rid of temporary data */ + if (csdone!=NULL) { + free( csdone); + csdone = NULL; + } + if ( cci != NULL ) { + free( cci); + cci = NULL; + } + + /* All charstrings are written. Some PostScript code follows */ + i+=sprintf( &(filebuf[i]), + "end\nend\nreadonly put\nnoaccess put\ndup /FontName get exch definefont pop\nmark currentfile closefile\n"); + sprintf( err_warn_msg_buf, + "Charstrings and Font definition finished (%d data bytes, from which %d bytes will be encrypted)", + i, i-dindex); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + + /* we compute the size of the encrypted area. */ + if (encrypt==1) { + encryptsize=i-dindex; + encryptsize+=4; /* the four random bytes */ + encryptsize*=2; /* since we use ASCII-hex output */ + encryptsize+=(int)ceil((double)encryptsize/linewidth); /* we need a few newline characters + to adjust the output format */ + } + else if (encrypt==2) { /* binary encryption. The whole data is contiguous + and only at the end of the data a newline is + added. */ + encryptsize=i-dindex+1; + encryptsize+=4; /* the four random bytes */ + } + else { /*The case of no encryption does not produce + valid fonts, it is for debugging purposes only */ + encryptsize=i-dindex+1; + } + + + /* we add the size of the 512 zeros and the cleartomark */ + trailersize+=ZEROS; + trailersize+=(int)ceil((double)ZEROS/linewidth); + trailersize+=12; /* cleartomark */ + + /* Search for remaining PostScript code in the last 1024 bytes. This + should suffice for any font. */ + tr_len=T1GetTrailer( linebuf, 1025, ifp); + T1Close(ifp); /* we do not need the file any longer */ + + /* And we add the size of the trailer. A trailer only consisting of + a newline is ignored because the newline has already been included + in the cleartomark-string. */ + if ( !((tr_len==1) && ((linebuf[0]=='\n') || (linebuf[0]=='\r')) ) ) { + trailersize+=tr_len; + } + + + if ((encryptbuf=(char *)calloc( encryptsize, 1))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( filebuf); + return( NULL); + } + + /* Allocate one byte in orer to be able to use sprintf() (which appends + an ASCII-\0).*/ + if ((trailerbuf=(char *)calloc( trailersize+1, 1))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( filebuf); + free( encryptbuf); + return( NULL); + } + + k=0; + colcount=0; + + /* perform eexec-encryption */ + eexec_r=55665; + if (encrypt==0) { + for (j=dindex; j<i; j++) { + encryptbuf[k++]=filebuf[j]; + } + } + else if ( encrypt==1) { + /* consume four random bytes. We take the numbers '0', '1', '2' + and '3'. The first cipher then is 217-dec (0xD9-hex), i.e., it + is no white space character. The resulting font can thus be + converted to pfb-format without the risk violating the Adobe spec.*/ + for (j=0; j<4; j++) { + cipher=EexecEncrypt( (unsigned char) j); + encryptbuf[k++]=highHexByte[cipher]; + if (++colcount==linewidth) { + colcount=0; + encryptbuf[k++]='\n'; + } + encryptbuf[k++]=lowHexByte[cipher]; + if (++colcount==linewidth) { + colcount=0; + encryptbuf[k++]='\n'; + } + } + for (j=dindex; j<i; j++) { + cipher=EexecEncrypt( (unsigned char) filebuf[j]); + encryptbuf[k++]=highHexByte[cipher]; + if (++colcount==linewidth) { + colcount=0; + encryptbuf[k++]='\n'; + } + encryptbuf[k++]=lowHexByte[cipher]; + if (++colcount==linewidth) { + colcount=0; + encryptbuf[k++]='\n'; + } + } + /* If necessary, append newline char */ + if (encryptbuf[k-1]!='\n') { + encryptbuf[k++]='\n'; + } + } /* if encrypt==1 */ + else { /* four random bytes ... */ + for (j=0; j<4; j++) { + encryptbuf[k++]=EexecEncrypt( (unsigned char) j); + } + for (j=dindex; j<i; j++) { /* and encrypted charstrings */ + encryptbuf[k++]=EexecEncrypt( (unsigned char) filebuf[j]); + } + } /* encrypt == 2 */ + /* Encryption finished */ + + /* If necessary, append newline char */ + if (encryptbuf[k-1]!='\n') { + encryptbuf[k++]='\n'; + } + + colcount=0; + /* Append zeroes and cleartomark */ + for (j=0; j<ZEROS; j++) { + trailerbuf[l++]='0'; + if (++colcount==linewidth) { + colcount=0; + trailerbuf[l++]='\n'; + } + } + /* If necessary, append newline char */ + if (trailerbuf[l-1]!='\n') { + trailerbuf[l++]='\n'; + } + l+=sprintf( &(trailerbuf[l]), "cleartomark\n"); + if ( !((tr_len==1) && ((linebuf[0]=='\n') || (linebuf[0]=='\r')) ) ) { + sprintf( err_warn_msg_buf, + "Including additional PostScript trailer (%d bytes)", + tr_len); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + l+=sprintf( &(trailerbuf[l]), linebuf); /* contains the PostScript trailer */ + } + + /* compute size of output file */ + outsize=0; + if (encrypt==2) { /* binary encryption, take care about pfb-blocks */ + /* each segment requires 6 bytes for the header */ + filesegs=(int)(ceil((double)dindex/maxblocksize)); + encryptsegs=(int)(ceil((double)k/maxblocksize)); + trailersegs=(int)(ceil((double)l/maxblocksize)); + /* trainling ASCII-part: */ + outsize +=dindex; + /* binary encrypted data */ + outsize +=k; + /* leading ASCII-part: */ + outsize +=l; + /* segment headers */ + outsize +=6*(filesegs+encryptsegs+trailersegs); + outsize +=2; /* the EOF-marker segment */ + } + else { /* ASCII-hex encryption or no encryption: no segmentation */ + outsize=dindex+k+l; + } + + if ((outbuf=(char *)calloc( outsize, 1))==NULL) { + T1_errno=T1ERR_ALLOC_MEM; + free( filebuf); + free( encryptbuf); + free( trailerbuf); + return( NULL); + } + + + + /* The full bufsize is given as the unencrypted portion plus size + of encryptbuf (which also inccorporates an unencrypted trailer). + In addition, the segment headers have to be taken into account for + pfb-format. */ + i=0; + if (encrypt==2) { /* we have to add segment headers */ + T1_PrintLog( "T1_SubsetFont()", "Setting up segmented binary buffer (pfb-format)", + T1LOG_DEBUG); + /* Clear text header */ + m=0; + for ( j=0; j<filesegs; j++) { + if (j==filesegs-1) + n=dindex % maxblocksize; + else + n=maxblocksize; + i +=make_pfb_segment_header( &(outbuf[i]), SEGMENT_ASCII, n); + memcpy( &(outbuf[i]), &(filebuf[m]), n); + i +=n; + m +=n; + } + sprintf( err_warn_msg_buf, + " Readable header (%d bytes: %d data bytes in %d ASCII-segments of maximum size %lu bytes)", + i, dindex, filesegs, maxblocksize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + /* Binary data */ + m=0; + o=i; + for ( j=0; j<encryptsegs; j++) { + if (j==encryptsegs-1) + n=k % maxblocksize; + else + n=maxblocksize; + i +=make_pfb_segment_header( &(outbuf[i]), SEGMENT_BINARY, n); + memcpy( &(outbuf[i]), &(encryptbuf[m]), n); + i +=n; + m +=n; + } + sprintf( err_warn_msg_buf, + " Binary data (%d bytes: %d data bytes in %d binary segments of maximum size %lu bytes)", + i-o, k, encryptsegs, maxblocksize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + /* Readable ASCII-trailer */ + m=0; + o=i; + for ( j=0; j<trailersegs; j++) { + if (j==trailersegs-1) + n=l % maxblocksize; + else + n=maxblocksize; + i +=make_pfb_segment_header( &(outbuf[i]), SEGMENT_ASCII, n); + memcpy( &(outbuf[i]), &(trailerbuf[m]), n); + i +=n; + m +=n; + } + sprintf( err_warn_msg_buf, + " Readable trailer (%d bytes: %d data bytes in %d ASCII-segments of maximum size %lu bytes)", + i-o, l, trailersegs, maxblocksize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + i +=make_pfb_segment_header( &(outbuf[i]), SEGMENT_EOF, 0); + sprintf( err_warn_msg_buf, + " EOF-segment marker (2 bytes)"); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + *bufsize=i; + } /* end of pfb-setup */ + else { /* we continuously copy the data */ + if (encrypt==1) + sprintf( err_warn_msg_buf, + "Dumping output buffer (%d bytes: %d readable ASCII, %d ASCII-hex in lines of width %d, %d readable ASCII)", + dindex+k+l, dindex, k, linewidth, l); + else + sprintf( err_warn_msg_buf, + "Dumping output buffer (%d bytes: %d readable ASCII, %d non-encrypted binary, %d readable ASCII)", + dindex+k+l, dindex, k, l); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + memcpy( outbuf, filebuf, dindex); + memcpy( &(outbuf[dindex]), encryptbuf, k); + memcpy( &(outbuf[dindex+k]), trailerbuf, l); + *bufsize=dindex+k+l; + } + + sprintf( err_warn_msg_buf, + "Output buffer is %ld bytes, original file size is %lu bytes", + *bufsize, filesize); + T1_PrintLog( "T1_SubsetFont()", err_warn_msg_buf, + T1LOG_DEBUG); + + + if (encryptbuf!=NULL) + free(encryptbuf); + if (trailerbuf!=NULL) + free(trailerbuf); + if (filebuf!=NULL) + free( filebuf); + + return( outbuf); + +} + + + +/* This function returns the encrypted charstring of character + charname of font FontID. The length is saved at len */ +char *T1_GetCharString( int FontID, char *charname, int *len) +{ + + static char *charstring=NULL; + + if (T1_CheckForFontID(FontID)!=1) { + T1_errno=T1ERR_INVALID_FONTID; + return(NULL); + } + + if ( (charname==NULL) || (len==0) ) { + T1_errno=T1ERR_INVALID_PARAMETER; + return(NULL); + } + + if ((locateCharString( FontID, charname))==0) { + *len=0; + T1_errno=T1ERR_UNSPECIFIED; + return( NULL); + } + + if (charstring!=NULL) { + free( charstring); + charstring=NULL; + } + if ((charstring=(char *)malloc( charstringL))==NULL) { + *len=0; + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + + memcpy( charstring, charstringP, charstringL); + *len=charstringL; + return( charstring); + +} + + + +/* For those who really need it, this function returns the value + of lenIV from the Private dictionary. It specifies how many + random leading bytes are used in Charstring encryption in the + current font. */ +int T1_GetlenIV( int FontID) +{ + + if (T1_CheckForFontID(FontID)!=1) { + T1_errno=T1ERR_INVALID_FONTID; + return( -2); + } + return( pFontBase->pFontArray[FontID].pType1Data->Private[LENIV].value.data.integer); + +} diff --git a/Build/source/libs/t1lib/t1subset.h b/Build/source/libs/t1lib/t1subset.h new file mode 100644 index 00000000000..9ab7e716c0a --- /dev/null +++ b/Build/source/libs/t1lib/t1subset.h @@ -0,0 +1,76 @@ +/*-------------------------------------------------------------------------- + ----- File: t1subset.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-04-01 + ----- Description: This file is part of the t1-library. It contains + declarations and definitions for t1subset.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independ from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#ifdef T1SUBSET_C + + +#define T1_SUBSET_DEFAULT 0x00 +#define T1_SUBSET_FORCE_REENCODE 0x01 +#define T1_SUBSET_SKIP_REENCODE 0x02 +#define T1_SUBSET_ENCRYPT_BINARY 0x04 +/* This is only for debugging, it does not produce valid font-files! */ +#define T1_SUBSET_ENCRYPT_NONE 0x08 + + +/* Functions used from the t1io-module, partially written + and added for font-subsetting. We don't care about the + special F_FILE-type defined in that module because all + accesses are done via pointers. */ +extern unsigned long T1GetFileSize( FILE *f); +extern FILE *T1Open( char *fn, char *mode); +extern int T1Gets(char *string, int size, FILE *f); +extern int T1GetDecrypt( void); +extern int T1GetTrailer(char *string, int size, FILE *f); +extern int T1Close( FILE *f); +extern void T1io_reset( void); + +char *T1_SubsetFont( int FontID, + char *mask, + unsigned int flags, + int linewidth, + unsigned long maxblocksize, + unsigned long *bufsize); +char *T1_GetCharString( int FontID, char *charname, int *len); +int T1_GetlenIV( int FontID); + + +#define ZEROS 512 + +#else + +extern char *T1_SubsetFont( int FontID, + char *mask, + unsigned int flags, + int linewidth, + unsigned long maxblocksize, + unsigned long *bufsize); +extern char *T1_GetCharString( int FontID, char *charname, int *len); +extern int T1_GetlenIV( int FontID); + + +#endif diff --git a/Build/source/libs/t1lib/t1trans.c b/Build/source/libs/t1lib/t1trans.c new file mode 100644 index 00000000000..998c4bd16c5 --- /dev/null +++ b/Build/source/libs/t1lib/t1trans.c @@ -0,0 +1,702 @@ +/*-------------------------------------------------------------------------- + ----- File: t1trans.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-04 + ----- Description: This file is part of the t1-library. It contains + functions for transforming fonts and setting + line-parameters. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1TRANS_C + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include "../type1/ffilest.h" +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + + +#include "t1types.h" +#include "t1extern.h" +#include "t1trans.h" +#include "t1base.h" + + +/* T1_ExtendFont(): Extend the font referenced by FontID by the factor + extend. This is only allowed if no size dependent data exists. + Of course, the font must already have been loaded. + Returns 0 for success and -1 otherwise. + */ +int T1_ExtendFont( int FontID, double extend) +{ + + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + /* Second, check whether size-dependent data exists: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pFontBase->pFontArray[FontID].extend=extend; + pFontBase->pFontArray[FontID].FontTransform[0] = extend; + return(0); +} + + + +/* T1_GetExtend(): Return the current extension factor of the + font FontID + Return: 0.0 if font not loaded + current extent otherwise +*/ +double T1_GetExtend( int FontID) +{ + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return( pFontBase->pFontArray[FontID].extend); +} + + + + +/* T1_SlantFont(): Slant the font referenced by FontID by the factor + extend. This is only allowed if no size dependent data exists. + Of course, the font must already have been loaded. + Returns 0 for success and -1 otherwise. + */ +int T1_SlantFont( int FontID, double slant) +{ + + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + /* Second, check whether size-dependent data exists: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pFontBase->pFontArray[FontID].slant=slant; + pFontBase->pFontArray[FontID].FontTransform[2] = slant; + return(0); +} + + + +/* T1_GetSlant(): Return the current slanting factor of the + font FontID + Return: 0.0 if font not loaded + current slant otherwise (may also be 0.0!) +*/ +double T1_GetSlant( int FontID) +{ + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + return( pFontBase->pFontArray[FontID].slant); +} + + + +/* T1_TransformFont(): Transform the font referenced by FontID according + to the transform matrix. This is only allowed if no size dependent + data exists. Of course, the font must already have been loaded. + Returns 0 for success and -1 otherwise. + */ +int T1_TransformFont( int FontID, T1_TMATRIX *matrix) +{ + + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + /* Second, check whether size-dependent data exists: */ + if (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL){ + T1_errno=T1ERR_OP_NOT_PERMITTED; + return(-1); + } + + pFontBase->pFontArray[FontID].FontTransform[0] = matrix->cxx; + pFontBase->pFontArray[FontID].FontTransform[1] = matrix->cxy; + pFontBase->pFontArray[FontID].FontTransform[2] = matrix->cyx; + pFontBase->pFontArray[FontID].FontTransform[3] = matrix->cyy; + return(0); +} + + + +/* T1_GetTransform(): Return the current transformation matrix for the + font FontID + Return: [0.0, 0.0, 0.0, 0.0] if font not loaded + current tmatrix otherwise +*/ +T1_TMATRIX T1_GetTransform( int FontID) +{ + T1_TMATRIX tmatrix={0.0, 0.0, 0.0, 0.0}; + + /* First, check for font residing in memory: */ + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(tmatrix); + } + + tmatrix.cxx=pFontBase->pFontArray[FontID].FontTransform[0]; + tmatrix.cxy=pFontBase->pFontArray[FontID].FontTransform[1]; + tmatrix.cyx=pFontBase->pFontArray[FontID].FontTransform[2]; + tmatrix.cyy=pFontBase->pFontArray[FontID].FontTransform[3]; + + return( tmatrix); +} + + + +/* Functions for setting line-parameters: + linetypeis expected to be an OR'ed combination of + T1_UNDERLINE, T1_OVERLINE and T1_OVERSTRIKE. + */ +int T1_SetLinePosition( int FontID, int linetype, float value) +{ + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + if (linetype & T1_UNDERLINE){ + pFontBase->pFontArray[FontID].UndrLnPos=value; + return( 0); + } + if (linetype & T1_OVERLINE){ + pFontBase->pFontArray[FontID].OvrLnPos=value; + return( 0); + } + if (linetype & T1_OVERSTRIKE){ + pFontBase->pFontArray[FontID].OvrStrkPos=value; + return( 0); + } + + /* The linetype was bad */ + T1_errno=T1ERR_INVALID_PARAMETER; + return( -1); + +} + + + +int T1_SetLineThickness( int FontID, int linetype, float value) +{ + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(-1); + } + + if (linetype & T1_UNDERLINE){ + pFontBase->pFontArray[FontID].UndrLnThick=value; + return( 0); + } + if (linetype & T1_OVERLINE){ + pFontBase->pFontArray[FontID].OvrLnThick=value; + return( 0); + } + if (linetype & T1_OVERSTRIKE){ + pFontBase->pFontArray[FontID].OvrStrkThick=value; + return( 0); + } + + /* The linetype was bad */ + T1_errno=T1ERR_INVALID_PARAMETER; + return( -1); + +} + + +float T1_GetLinePosition( int FontID, int linetype) +{ + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + if (linetype & T1_UNDERLINE) + return( pFontBase->pFontArray[FontID].UndrLnPos); + if (linetype & T1_OVERLINE) + return( pFontBase->pFontArray[FontID].OvrLnPos); + if (linetype & T1_OVERSTRIKE) + return( pFontBase->pFontArray[FontID].OvrStrkPos); + + /* The linetype was bad */ + T1_errno=T1ERR_INVALID_PARAMETER; + return( 0.0); + +} + + + +float T1_GetLineThickness( int FontID, int linetype) +{ + + if (T1_CheckForFontID(FontID)!=1){ + T1_errno=T1ERR_INVALID_FONTID; + return(0.0); + } + + if (linetype & T1_UNDERLINE) + return( pFontBase->pFontArray[FontID].UndrLnThick); + if (linetype & T1_OVERLINE) + return( pFontBase->pFontArray[FontID].OvrLnThick); + if (linetype & T1_OVERSTRIKE) + return( pFontBase->pFontArray[FontID].OvrStrkThick); + + /* The linetype was bad */ + T1_errno=T1ERR_INVALID_PARAMETER; + return( 0.0); + +} + + +/* Functions for intuitively transforming matrices. All function operate on their + original objects. In case NULL is specified, a unity-matrix is allocated by + the function and then tranformed appropriately. Note that in order to concatenate + transformation in the sense of t1lib the current transformation matrix must be + left-multiplied by the trnasformation to be applied! */ +/* Rotation: + ( x11' x21' ) ( cos(a) -sin(a) ) ( x11 x21 ) + ( ) = ( ) * ( ) + ( x12' x22' ) ( sin(a) cos(a) ) ( x12 x22 ) +*/ +T1_TMATRIX *T1_RotateMatrix( T1_TMATRIX *matrix, double angle) +{ + T1_TMATRIX tmat; + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + memcpy( &tmat, matrix, sizeof(T1_TMATRIX)); + /* Convert angle to radians: */ + angle=angle*PI/180.0; + /* multiply matrices */ + matrix->cxx=cos((double)angle) * tmat.cxx - sin((double)angle) * tmat.cxy; + matrix->cyx=cos((double)angle) * tmat.cyx - sin((double)angle) * tmat.cyy; + matrix->cxy=sin((double)angle) * tmat.cxx + cos((double)angle) * tmat.cxy; + matrix->cyy=sin((double)angle) * tmat.cyx + cos((double)angle) * tmat.cyy; + return( matrix); +} + + +/* Horizontal mirroring */ +/* H-Mirror: + ( x11' x21' ) ( -1 0 ) ( x11 x21 ) ( -x11 -x21 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( 0 1 ) ( x12 x22 ) ( x12 x22 ) +*/ +T1_TMATRIX *T1_MirrorHMatrix( T1_TMATRIX *matrix) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxx *=-1.0; + matrix->cyx *=-1.0; + return( matrix); +} + + +/* Vertical mirroring */ +/* V-Mirror: + ( x11' x21' ) ( 1 0 ) ( x11 x21 ) ( x11 x21 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( 0 -1 ) ( x12 x22 ) ( -x12 -x22 ) +*/ +T1_TMATRIX *T1_MirrorVMatrix( T1_TMATRIX *matrix) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxy *=-1.0; + matrix->cyy *=-1.0; + return( matrix); + +} + + +/* Horizontal shearing */ +/* H-Shearing: + ( x11' x21' ) ( 1 f ) ( x11 x21 ) ( x11+f*x12 x21+f*x22 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( 0 1 ) ( x12 x22 ) ( x12 x22 ) +*/ +T1_TMATRIX *T1_ShearHMatrix( T1_TMATRIX *matrix, double shear) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxx +=shear*matrix->cxy; + matrix->cyx +=shear*matrix->cyy; + return( matrix); + +} + + +/* Vertical shearing */ +/* V-Shearing: + ( x11' x21' ) ( 1 0 ) ( x11 x21 ) ( x11 x21 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( f 1 ) ( x12 x22 ) ( x12+f*x11 x22+f*x21 ) +*/ +T1_TMATRIX *T1_ShearVMatrix( T1_TMATRIX *matrix, double shear) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxy +=shear*matrix->cxx; + matrix->cyy +=shear*matrix->cyx; + return( matrix); + +} + + +/* Horizontal extension */ +/* Horizontal-Extension: + ( x11' x21' ) ( f 0 ) ( x11 x21 ) ( f*x11 f*x21 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( 0 1 ) ( x12 x22 ) ( x12 x22 ) +*/ +T1_TMATRIX *T1_ExtendHMatrix( T1_TMATRIX *matrix, double extent) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxx *=extent; + matrix->cyx *=extent; + return( matrix); + +} + + +/* Vertical extension */ +/* Vertical-Extension: + ( x11' x21' ) ( 1 0 ) ( x11 x21 ) ( x11 x21 ) + ( ) = ( ) * ( ) = ( ) + ( x12' x22' ) ( 0 f ) ( x12 x22 ) ( f*x12 f*x22 ) +*/ +T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX *matrix, double extent) +{ + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + matrix->cxy *=extent; + matrix->cyy *=extent; + return( matrix); + +} + + +/* General transformation */ +/* + ( x11 x21 ) ( y11 y21 ) ( x11*y11+x21*y12 x11*y21+x21*y22 ) + ( ) * ( ) = ( ) + ( x12 x22 ) ( y12 y22 ) ( x12*y11+x22*y12 x12*y21+x22*y22 ) +*/ +T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix, + double cxx, double cyx, + double cxy, double cyy) +{ + T1_TMATRIX tmat; + + if (matrix==NULL){ + if ((matrix=(T1_TMATRIX *)malloc( sizeof(T1_TMATRIX)))==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return( NULL); + } + matrix->cxx=1.0; + matrix->cyx=0.0; + matrix->cxy=0.0; + matrix->cyy=1.0; + } + memcpy( &tmat, matrix, sizeof(T1_TMATRIX)); + matrix->cxx=cxx * tmat.cxx + cyx * tmat.cxy; + matrix->cyx=cxx * tmat.cyx + cyx * tmat.cyy; + matrix->cxy=cxy * tmat.cxx + cyy * tmat.cxy; + matrix->cyy=cxy * tmat.cyx + cyy * tmat.cyy; + + return( matrix); +} + + + +/* T1_StrokeFont(): Switch the font referenced by FontID to stroking + or filling. The stroked character will be cached and + filled characters are no longer cached and vice versa. + This is only allowed if no size dependent data exists. + Of course, the font must already have been loaded. + Returns 0 for success and -1 otherwise. + */ +int T1_StrokeFont( int FontID, int dostroke) +{ + + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID( FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return -1; + } + + /* Second, check whether size-dependent data exists: */ + if ( pFontBase->pFontArray[FontID].pFontSizeDeps != NULL ) { + T1_errno = T1ERR_OP_NOT_PERMITTED; + return -1; + } + + if ( dostroke != 0 ) { + pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED; + pFontBase->pFontArray[FontID].info_flags |= CACHE_STROKED; + } + else { + pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED; + pFontBase->pFontArray[FontID].info_flags &= ~CACHE_STROKED; + } + + + return 0; +} + + + +/* T1_SetStrokeFlag(): Return the stroke flag for font FontID. + Return: 0 flag has been set + -1 flag could not be set +*/ +int T1_SetStrokeFlag( int FontID) +{ + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID(FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return -1; + } + + /* Set stroke flag to true */ + pFontBase->pFontArray[FontID].info_flags |= RASTER_STROKED; + + return 0; + +} + + + +/* T1_ClearStrokeFlag(): Reset the stroke flag for font FontID. + Return: 0 flag has been reset + -1 flag could not be reset +*/ +int T1_ClearStrokeFlag( int FontID) +{ + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID(FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return -1; + } + + /* Reset stroke flag */ + pFontBase->pFontArray[FontID].info_flags &= ~RASTER_STROKED; + + return 0; + +} + + + +/* T1_GetStrokeMode(): Return the stroke flag for font FontID. + Return: -1 if font is not loaded. + 0 if flag is reset, + 1 if stroking is enabled for this font, + 2 if stroked characters are cached, + 3 if stroking is enabled and stroked + characters are cached. +*/ +int T1_GetStrokeMode( int FontID) +{ + int outval = 0; + + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID( FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return -1; + } + + if ( (pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0 ) + outval |= 0x02; + + if ( (pFontBase->pFontArray[FontID].info_flags & RASTER_STROKED) != 0 ) + outval |= 0x01; + + return outval; + +} + + + +/* T1_SetStrokeWidth(): Set the penwidth used when stroking font FontID. + Return -1 If width could not be set. + 0 if width has been set. + */ +int T1_SetStrokeWidth( int FontID, float strokewidth) +{ + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID( FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return -1; + } + + /* Second, check whether caching stroked characters is enabled + for this font and glyph data is already existing. In this case + the operation is forbidden, unless the previous non-zero value + is just restored! */ + if ( ((pFontBase->pFontArray[FontID].info_flags & CACHE_STROKED) != 0) && + (pFontBase->pFontArray[FontID].pFontSizeDeps != NULL) && + (pFontBase->pFontArray[FontID].SavedStrokeWidth != strokewidth) + ) { + T1_errno = T1ERR_OP_NOT_PERMITTED; + return -1; + } + + /* OK, accept stroke width after ensuring a numerically meaningful + value */ + if ( strokewidth < 0.0f ) { + T1_errno = T1ERR_INVALID_PARAMETER; + return -1; + } + + pFontBase->pFontArray[FontID].StrokeWidth = strokewidth; + + if ( strokewidth != 0.0f ) + pFontBase->pFontArray[FontID].SavedStrokeWidth = strokewidth; + + return 0; + +} + + + +/* T1_GetStrokeWidth(): Get the penwidth used when stroking font FontID. + If 0.0 is returned, it might also indicate that the font is not loaded. +*/ +float T1_GetStrokeWidth( int FontID) +{ + /* First, check for font residing in memory: */ + if ( T1_CheckForFontID( FontID) != 1 ) { + T1_errno = T1ERR_INVALID_FONTID; + return 0.0f; + } + + return pFontBase->pFontArray[FontID].StrokeWidth; +} + diff --git a/Build/source/libs/t1lib/t1trans.h b/Build/source/libs/t1lib/t1trans.h new file mode 100644 index 00000000000..1d8685b98a4 --- /dev/null +++ b/Build/source/libs/t1lib/t1trans.h @@ -0,0 +1,89 @@ +/*-------------------------------------------------------------------------- + ----- File: t1trans.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2002-10-19 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations fort t1trans.c + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#ifdef T1TRANS_C + +int T1_ExtendFont( int FontID, double extend); +int T1_SlantFont( int FontID, double slant); +int T1_TransformFont( int FontID, T1_TMATRIX *matrix); +double T1_GetExtend( int FontID); +double T1_GetSlant( int FontID); +T1_TMATRIX T1_GetTransform( int FontID); +int T1_SetLinePosition( int FontID, int linetype, float value); +int T1_SetLineThickness( int FontID, int linetype, float value); +float T1_GetLinePosition( int FontID, int linetype); +float T1_GetLineThickness( int FontID, int linetype); +T1_TMATRIX *T1_RotateMatrix( T1_TMATRIX *matrix, double angle); +T1_TMATRIX *T1_MirrorHMatrix( T1_TMATRIX *matrix); +T1_TMATRIX *T1_MirrorVMatrix( T1_TMATRIX *matrix); +T1_TMATRIX *T1_ShearHMatrix( T1_TMATRIX *matrix, double shear); +T1_TMATRIX *T1_ShearVMatrix( T1_TMATRIX *matrix, double shear); +T1_TMATRIX *T1_ExtendHMatrix( T1_TMATRIX *matrix, double extent); +T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX *matrix, double extent); +T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix, + double cxx, double cyx, + double cxy, double cyy); +int T1_StrokeFont( int FontID, int dostroke); +int T1_SetStrokeFlag( int FontID); +int T1_ClearStrokeFlag( int FontID); +int T1_GetStrokeMode( int FontID); +int T1_SetStrokeWidth( int FontID, float strokewidth); +float T1_GetStrokeWidth( int FontID); + + +#else + + +extern int T1_ExtendFont( int FontID, double extend); +extern int T1_SlantFont( int FontID, double slant); +extern int T1_TransformFont( int FontID, T1_TMATRIX *matrix); +extern double T1_GetExtend( int FontID); +extern double T1_GetSlant( int FontID); +extern T1_TMATRIX T1_GetTransform( int FontID); +extern int T1_SetLinePosition( int FontID, int linetype, float value); +extern int T1_SetLineThickness( int FontID, int linetype, float value); +extern float T1_GetLinePosition( int FontID, int linetype); +extern float T1_GetLineThickness( int FontID, int linetype); +extern T1_TMATRIX *T1_RotateMatrix( T1_TMATRIX *matrix, double angle); +extern T1_TMATRIX *T1_MirrorHMatrix( T1_TMATRIX *matrix); +extern T1_TMATRIX *T1_MirrorVMatrix( T1_TMATRIX *matrix); +extern T1_TMATRIX *T1_ShearHMatrix( T1_TMATRIX *matrix, double shear); +extern T1_TMATRIX *T1_ShearVMatrix( T1_TMATRIX *matrix, double shear); +extern T1_TMATRIX *T1_ExtendHMatrix( T1_TMATRIX *matrix, double extent); +extern T1_TMATRIX *T1_ExtendVMatrix( T1_TMATRIX *matrix, double extent); +extern T1_TMATRIX *T1_TransformMatrix( T1_TMATRIX *matrix, + double cxx, double cyx, + double cxy, double cyy); +extern int T1_StrokeFont( int FontID, int dostroke); +extern int T1_SetStrokeFlag( int FontID); +extern int T1_ClearStrokeFlag( int FontID); +extern int T1_GetStrokeMode( int FontID); +extern int T1_SetStrokeWidth( int FontID, float strokewidth); +extern float T1_GetStrokeWidth( int FontID); + +#endif + diff --git a/Build/source/libs/t1lib/t1types.h b/Build/source/libs/t1lib/t1types.h new file mode 100644 index 00000000000..156e702b58a --- /dev/null +++ b/Build/source/libs/t1lib/t1types.h @@ -0,0 +1,224 @@ +/*-------------------------------------------------------------------------- + ----- File: t1types.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2001-06-04 + ----- Description: This file is part of the t1-library. It contains + type definitions used by the t1-library. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + + +#define T1TYPES_H + + +typedef struct +{ + int flags; + int chars; + int hkern; +} METRICS_ENTRY; + + +typedef struct +{ + char *pFontFileName; /* Pointer to the font's filename */ + char *pAfmFileName; /* Pointer to the afm filename, IFF set explicitly */ + FontInfo *pAFMData; /* A pointer to a struct which gives access to all + the data contained in the .afm-file. If this + pointer is NULL, no .afm-file had been found. + => There's no advanced info on the font available. + */ + psfont *pType1Data; /* A pointer to a struct giving access to all + information contained in the .pfa/.pfb-file. This + is needed! */ + int *pEncMap; /* For fast mapping from charnames to encoding + indices */ + METRICS_ENTRY *pKernMap; /* dito */ + int KernMapSize; + char **pFontEnc; /* This is the pointer to the encoding array + associated with that particular font. If + FontEnc=NULL, it means the internal + (fontspecific) encoding is to be used. */ + char *vm_base; /* The base address of the virtual memory area for this + font. It must be stored in order to be able to realloc + and free those memory areas later. */ + void *pFontSizeDeps; /* This one points to a linked list of structures + which store all font size dependent data. */ + double FontMatrix[4]; /* Two matrices which store the font matrix and special + Transformation to be applied, such as slant and + extend or probably some rotation. */ + double FontTransform[4]; + float slant; /* A slant factor for the font */ + float extend; /* A extension factor for the font */ + float UndrLnPos; /* Parameters for ~lining rules */ + float UndrLnThick; + float OvrLnPos; + float OvrLnThick; + float OvrStrkPos; + float OvrStrkThick; + float StrokeWidth; + float SavedStrokeWidth; + + unsigned short physical; /* This entry is used to decide, whether a + font is associated with an own physical + fontfile, or whether it has been created + as a "logical" font by copying another + "physical" font. */ + unsigned short refcount; /* At load time this counter is set to 1. Every + time, a T1_CopyFont() is executed on this font, + this counter is incremented by 1. This gives + the possibility to decide whether a physical + font is used by some logical font. */ + short space_position; /* The position where "space" is encoded, is saved + in this entry. The space character needs special + treatment. Saving its position here yields faster + execution during rastering of strings with a + user-supplied space-offset! */ + short info_flags; /* Here some info may be stored */ +} FONTPRIVATE; + + +/* A structure representing a matrix */ +typedef struct +{ + double cxx; + double cyx; + double cxy; + double cyy; +} T1_TMATRIX; + + +/* Following struct is used for storing all information for a particular + rendered character glyph */ +typedef struct +{ + char *bits; /* A pointer to the characters local bitmap */ + struct /* A struct containing diverse metric information */ + { + int ascent; + int descent; + int leftSideBearing; + int rightSideBearing; + int advanceX; + int advanceY; + } metrics; + void *pFontCacheInfo; + unsigned long bpp; /* The number of bits that represent 1 pixel */ +} GLYPH; + + + +/* Next comes the struct declaration for FontSizeDeps, which stores size + specific data of a font */ +typedef struct +{ + GLYPH *pFontCache; /* Pointer to the cache area of this + font at this size */ + void *pNextFontSizeDeps; /* A pointer to the next size's + FontSizeDeps-structure. */ + void *pPrevFontSizeDeps; /* A pointer to the previous size's + FontSizeDeps-structure or NULL if + the current is the first. */ + struct XYspace *pCharSpaceLocal; /* This is a scaled version of the + global version for this font. */ + float size; /* The desired size, to be specified + in bp's. */ + int antialias; /* Switch for marking the current size + antialiased */ +} FONTSIZEDEPS; + + + +/* A data type that makes most important information available to user. */ +typedef struct +{ + int width; /* The glyph's width */ + BBox bbox; /* The glyph's bounding box */ + int numchars; /* The number of characters in the glyph (string) */ + int *charpos; /* A pointer to an integer array were the horizontal + positions in (afm units) of the individual + characters in the string are stored */ +} METRICSINFO; + + +/* Handling of outlines: These definitions decouple from the type 1 rasterizers + def's and make the necessary stuff available to end users */ + +#define FRACTBITS 16 /* number of fractional bits in 'fractpel' */ +/* From/to conversion of pels/fractpels */ +#define T1_TOPATHPOINT(p) (((long)p)<<FRACTBITS) +#define PPHALF (1<<(FRACTBITS-1)) +#define T1_NEARESTPOINT(fp) (((fp)+PPHALF)>>FRACTBITS) + +/* A fractional point */ +typedef struct { + long x; + long y; +} T1_PATHPOINT; + + +/* A straight outline segment, stroked or not stroked */ +typedef struct pathsegment { + char type; /* type of segment (line or move) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* size of the structure */ + unsigned char context; /* index to device context */ + struct pathsegment *link; /* pointer to next structure in linked list */ + struct pathsegment *last; /* pointer to last structure in list */ + T1_PATHPOINT dest; /* relative ending location of path segment */ +} T1_PATHSEGMENT; + +/* A third order bezier segment */ +typedef struct bezierpathsegment { + char type; /* type of segment (bezier) */ + unsigned char flag; /* type1 rasterizer internal stuff */ + short references; /* type1 rasterizer internal stuff */ + unsigned char size; /* as with any 'segment' type */ + unsigned char context; /* as with any 'segment' type */ + T1_PATHSEGMENT *link; /* as with any 'segment' type */ + T1_PATHSEGMENT *last; /* as with any 'segment' type */ + T1_PATHPOINT dest; /* ending point (D) */ + T1_PATHPOINT B; /* control point B */ + T1_PATHPOINT C; /* control point C */ +} T1_BEZIERSEGMENT; + +typedef T1_PATHSEGMENT T1_OUTLINE; + + +/* Two structures for handling composite character data */ +/* One structure for each symbol of the composite character */ +typedef struct +{ + int piece; /* the index of the current symbol */ + int deltax; /* horizontal displacement of current symbol in CS */ + int deltay; /* vertical displacement of current symbol in CS */ +} T1_COMP_PIECE; + +/* This one defines the composite character, the number of pieces and how to + access their data. */ +typedef struct +{ + int compchar; /* the base character in the current encoding */ + int numPieces; /* the number of defined pieces including the base char */ + T1_COMP_PIECE *pieces; /* a pointer to the pieces' information */ +} T1_COMP_CHAR_INFO; + diff --git a/Build/source/libs/t1lib/t1win32.c b/Build/source/libs/t1lib/t1win32.c new file mode 100644 index 00000000000..2e1608b96fe --- /dev/null +++ b/Build/source/libs/t1lib/t1win32.c @@ -0,0 +1,791 @@ +/*-------------------------------------------------------------------------- + ----- File: t1win32.c + ----- Author: Rainer Menzner (rmz@neuroinformatik.ruhr-uni-bochum.de) + modified for win32 by Fabrice Popineau (Fabrice.Popineau@supelec.fr) + ----- Date: 1999-06-24 + ----- Description: This file is part of the t1-library. It contains + functions for generating glyphs with data in + Win32 dib format. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-1998. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1WIN32_C + + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <math.h> + +#include <windows.h> + +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + +#include "t1types.h" +#include "t1extern.h" +#include "t1set.h" +#include "t1aaset.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1win32.h" +#include "t1base.h" + + + +#define T1GCMASK GCForeground | GCBackground + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + + +/* The three important X11 parameters t1lib has to deal with: */ +static HDC *T1_display=NULL; /* Must be accessible from t1delete.c */ +static Colormap T1_colormap; +static unsigned int T1_depth; +static int T1_byte_order; +static int lastlevel=0; +static unsigned long oldfg_n=0, oldbg_n=0, oldfg_l=0, oldbg_l=0; +static unsigned long oldfg_h=0, oldbg_h=0, oldfg=0, oldbg=0; + + +extern int T1aa_SmartOn; /* from t1aaset.c */ +extern float T1aa_smartlimit1; +extern float T1aa_smartlimit2; + + + +static XColor aacolors[AAMAXPLANES]; +static unsigned long aapixels[AAMAXPLANES]; + + +/* The following parameter determines whether t1lib will use logical + positioning of chars and string (place the origin at specified + destination-point) or absolute positioning with respect to the + origin (upper left corner) of the generated bitmap/pixmap. */ +static int T1_lposition=1; + + + +/* T1_SetX11Params(): Set X11-parameters which t1lib has to know in order + to properly generate pixmaps from characters */ +int T1_SetWin32Params( HDC hDc, + unsigned int depth, + Colormap colormap) +{ + + T1_display =display; + T1_visual =visual; + T1_depth =depth; + T1_colormap =colormap; + + if (T1_CheckEndian()==0) + T1_byte_order=0; + else + T1_byte_order=1; + + /* For bug hunting: */ + if (ImageByteOrder( T1_display)==0) + T1_PrintLog( "T1_SetX11Params()", + "X-Server uses Little Endian data representation", + T1LOG_DEBUG); + else + T1_PrintLog( "T1_SetX11Params()", + "X-Server uses Big Endian data representation", + T1LOG_DEBUG); + + return(0); +} + + + +/* T1_SetCharX(): Generate an object of type GLYPH, i.e, a glyph with + a pixmap ID instead of a pointer to a bitmap: */ + +GLYPH *T1_SetCharX( HDC hDc, int mode, int x_dest, int y_dest, + int FontID, char charcode, + float size, T1_TMATRIX *transform) +{ + GLYPH *pglyph; + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width; + Pixmap clipmask=0; + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + if ((pglyph=T1_SetChar( FontID, charcode, size, transform))==NULL){ + T1_PrintLog( "T1_SetCharX()", + "T1_SetChar() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)pglyph->bits, + PAD(width, pFontBase->bitmap_pad), + height + ); + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + } + + XCopyPlane( T1_display, clipmask, d, gc, 0, 0, + width, height, x_dest, y_dest, 0x01); + + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_SetStringX(...): Draw a string of characters into an X11 drawable */ +GLYPH *T1_SetStringX( HDC hDc, int mode, int x_dest, int y_dest, + int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + GLYPH *pglyph; + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width; + Pixmap clipmask=0; + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + if ((pglyph=T1_SetString( FontID, string, len, + spaceoff, modflag, size, + transform))==NULL){ + T1_PrintLog( "T1_SetStringX()", + "T1_SetString() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)pglyph->bits, + PAD(width, pFontBase->bitmap_pad), /* width */ + height + ); + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + } + + XCopyPlane( T1_display, clipmask, d, gc, 0, 0, + width, height, x_dest, y_dest, 0x01); + + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_AASetCharX(): Generate an object of type GLYPH, i.e, a glyph with + a pixmap ID instead of a pointer to a bitmap: */ + +GLYPH *T1_AASetCharX( HDC hDc, int mode, int x_dest, int y_dest, + int FontID, char charcode, + float size, T1_TMATRIX *transform) +{ + int j, k; + + GLYPH *pglyph; + XImage *ximage; + + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width, width_pad; + + XGCValues xgcvalues; + static unsigned long fg, bg, oldfg=0, oldbg=0; + static unsigned long oldfg_l=0, oldbg_l=0, oldfg_h=0, oldbg_h=0; + + Pixmap clipmask=0; + int clipmask_h, clipmask_v, line_off; + char *clipmask_ptr; + + int opaque; + + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + xglyph.bpp=T1_depth; + + /* In order to be able to contruct the pixmap we need to know + foreground and background color as well the copy function */ + XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues); + fg=xgcvalues.foreground; + bg=xgcvalues.background; + + + /* At this point we must compute the colors that are needed to do + antialiasing between fore- and background. The following function + fills the static aacolors */ + if (T1aa_SmartOn==0) + j=T1_AAGetLevel(); + else if (size>=T1aa_smartlimit2) + j=1; + else if (size>=T1aa_smartlimit1) + j=2; + else + j=4; + if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){ + switch ( j){ + case 1: + if ( fg!=oldfg_n || bg!=oldbg_n){ + oldfg_n=fg; + oldbg_n=bg; + /* computing colors is not necessary here */ + T1_AANSetGrayValues( bg, fg); + } + break; + case 2: + if ( fg!=oldfg_l || bg!=oldbg_l){ + oldfg_l=fg; + oldbg_l=bg; + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + T1_AASetGrayValues(aapixels[0], /* white */ + aapixels[4], + aapixels[8], + aapixels[12], + aapixels[16] ); /* black */ + } + break; + case 4: + if ( fg!=oldfg_h || bg!=oldbg_h){ + oldfg_h=fg; + oldbg_h=bg; + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + T1_AAHSetGrayValues( aapixels); + } + break; + } + lastlevel=j; + oldfg=fg; + oldbg=bg; + } + + if ((pglyph=T1_AASetChar( FontID, charcode, size, + transform))==NULL){ + T1_PrintLog( "T1_AASetCharX()", + "T1_AASetChar() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + clipmask_v=height; + clipmask_h=width; + width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp; + clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); + if (clipmask_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* Note: We pad the clipmask always to byte boundary */ + if (pglyph->bpp==8) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((char *)(pglyph->bits))[k*width_pad+j]!=bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else if (pglyph->bpp==16) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)clipmask_ptr, + width, + height + ); + free( clipmask_ptr); + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + + } + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + width, + height, + pFontBase->bitmap_pad, + 0 /*PAD(width,8)/8*/ /* number of bytes per line */ + ); + ximage->byte_order=T1_byte_order; + XPutImage(T1_display, + d, + gc, + ximage, + 0, + 0, + x_dest, + y_dest, + width, + height + ); + XDestroyImage(ximage); + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_AASetStringX(...): Draw a string of characters into an X11 drawable */ +GLYPH *T1_AASetStringX( HDC hDc, int mode, int x_dest, int y_dest, + int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + int j, k; + + GLYPH *pglyph; + XImage *ximage; + + + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width, width_pad; + + XGCValues xgcvalues; + static unsigned long fg, bg; + + + Pixmap clipmask=0; + int clipmask_h, clipmask_v, line_off; + char *clipmask_ptr; + + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + /* In order to be able to contruct the pixmap we need to know + foreground and background color as well the copy function */ + XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues); + fg=xgcvalues.foreground; + bg=xgcvalues.background; + + xglyph.bpp=T1_depth; + + /* At this point we must compute the colors that are needed to do + antialiasing between fore- and background. The following function + fills the static aacolors */ + if (T1aa_SmartOn==0) + j=T1_AAGetLevel(); + else if (size>=T1aa_smartlimit2) + j=1; + else if (size>=T1aa_smartlimit1) + j=2; + else + j=4; + if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){ + switch ( j){ + case 1: + if ( fg!=oldfg_n || bg!=oldbg_n){ + oldfg_n=fg; + oldbg_n=bg; + /* computing colors is not necessary here */ + T1_AANSetGrayValues( bg, fg); + } + break; + case 2: + if ( fg!=oldfg_l || bg!=oldbg_l){ + oldfg_l=fg; + oldbg_l=bg; + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + T1_AASetGrayValues(aapixels[0], /* white */ + aapixels[4], + aapixels[8], + aapixels[12], + aapixels[16] ); /* black */ + } + break; + case 4: + if ( fg!=oldfg_h || bg!=oldbg_h){ + oldfg_h=fg; + oldbg_h=bg; + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + T1_AAHSetGrayValues( aapixels); + } + break; + } + lastlevel=j; + oldfg=fg; + oldbg=bg; + } + + + if ((pglyph=T1_AASetString( FontID, string, len, + spaceoff, modflag, size, + transform))==NULL){ + T1_PrintLog( "T1_AASetStringX()", + "T1_AASetString() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + clipmask_v=height; + clipmask_h=width; + width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp; + clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); + if (clipmask_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* Note: We pad the clipmask always to byte boundary */ + if (pglyph->bpp==8) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((char *)(pglyph->bits))[k*width_pad+j]!=bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else if (pglyph->bpp==16) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)clipmask_ptr, + width, + height + ); + free( clipmask_ptr); + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + + } + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + width, + height, + pFontBase->bitmap_pad, /* lines padded to bytes */ + 0 /*PAD(width,8)/8*/ /* number of bytes per line */ + ); + ximage->byte_order=T1_byte_order; + XPutImage(T1_display, + d, + gc, + ximage, + 0, + 0, + x_dest, + y_dest, + width, + height + ); + XDestroyImage(ximage); + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_ComputeAAColorsX(): Compute the antialiasing colors in dependency + of foreground and background */ +int T1_ComputeAAColorsX( unsigned long fg, unsigned long bg, int nolevels) +{ + + static unsigned long last_fg; + static unsigned long last_bg; + unsigned long delta_red, delta_green, delta_blue; + int i; + int nocolors=0; + + + aacolors[0].pixel=bg; + aacolors[nolevels-1].pixel=fg; + + if ((fg==last_fg)&&(bg==last_bg)) + return(nocolors); + + /* Get RGB values for fore- and background */ + XQueryColor( T1_display, T1_colormap, &aacolors[0]); + XQueryColor( T1_display, T1_colormap, &aacolors[nolevels-1]); + delta_red = (aacolors[nolevels-1].red - aacolors[0].red)/(nolevels-1); + delta_green = (aacolors[nolevels-1].green - aacolors[0].green)/(nolevels-1); + delta_blue = (aacolors[nolevels-1].blue - aacolors[0].blue)/(nolevels-1); + aapixels[0]=aacolors[0].pixel; + aapixels[nolevels-1]=aacolors[nolevels-1].pixel; + + + for (i=1; i<nolevels-1; i++){ + aacolors[i].red = aacolors[i-1].red + delta_red; + aacolors[i].green = aacolors[i-1].green + delta_green; + aacolors[i].blue = aacolors[i-1].blue + delta_blue; + /* Allocate color in current palette */ + if (XAllocColor( T1_display, T1_colormap, &aacolors[i])!=0){ + aapixels[i]=aacolors[i].pixel; + nocolors++; + } + + } + + return(nocolors); + +} + + + +/* Set the positioning switch */ +void T1_LogicalPositionX( int pos_switch) +{ + if (pos_switch) + T1_lposition=1; + else + T1_lposition=0; + return; +} + diff --git a/Build/source/libs/t1lib/t1win32.h b/Build/source/libs/t1lib/t1win32.h new file mode 100644 index 00000000000..3aaa857b011 --- /dev/null +++ b/Build/source/libs/t1lib/t1win32.h @@ -0,0 +1,50 @@ +/*-------------------------------------------------------------------------- + ----- File: t1win32.h + ----- Author: Rainer Menzner (rmz@neuroinformatik.ruhr-uni-bochum.de) + ----- Date: 08/20/1998 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations for t1x11.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-1998. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#include <windows.h> + +int T1_SetWin32Params(HDC hDc); +GLYPH *T1_SetCharX( HDC hDc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_SetStringX( HDC hDc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +GLYPH *T1_AASetCharX( HDC hDc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_AASetStringX( HDC hDc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +int T1_ComputeAAColorsX( unsigned long fg, + unsigned long bg, + int nolevels); +int T1_GetDepthOfDrawable( HDC hDc ); +void T1_LogicalPositionX( int pos_switch); + diff --git a/Build/source/libs/t1lib/t1x11.c b/Build/source/libs/t1lib/t1x11.c new file mode 100644 index 00000000000..cda82ef986a --- /dev/null +++ b/Build/source/libs/t1lib/t1x11.c @@ -0,0 +1,1167 @@ +/*-------------------------------------------------------------------------- + ----- File: t1x11.c + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + functions for generating glyphs with data in + X11-Pixmap format. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#define T1X11_C + + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <math.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include "../type1/types.h" +#include "parseAFM.h" +#include "../type1/objects.h" +#include "../type1/spaces.h" +#include "../type1/util.h" +#include "../type1/fontfcn.h" +#include "../type1/regions.h" + +#include "t1types.h" +#include "t1extern.h" +#include "t1set.h" +#include "t1aaset.h" +#include "t1load.h" +#include "t1finfo.h" +#include "t1misc.h" +#include "t1x11.h" +#include "t1base.h" + + + +#define T1GCMASK GCForeground | GCBackground + +/* As a fall back */ +#ifndef T1_AA_TYPE16 +#define T1_AA_TYPE16 short +#endif +#ifndef T1_AA_TYPE32 +#define T1_AA_TYPE32 int +#endif + + + +/* The three important X11 parameters t1lib has to deal with: */ +static Display *T1_display=NULL; /* Must be accessible from t1delete.c */ +static Visual *T1_visual=NULL; +static Colormap T1_colormap; +static unsigned int T1_depth=0; +static int T1_byte_order; +static int lastlevel=0; +static unsigned long oldfg_n=0, oldbg_n=0, oldfg_l=0, oldbg_l=0; +static unsigned long oldfg_h=0, oldbg_h=0, oldfg=0, oldbg=0; + + +extern int T1aa_SmartOn; /* from t1aaset.c */ +extern float T1aa_smartlimit1; +extern float T1aa_smartlimit2; + + + +static XColor aacolors[AAMAXPLANES]; +static unsigned long aapixels[AAMAXPLANES]; + + +/* The following parameter determines whether t1lib will use logical + positioning of chars and string (place the origin at specified + destination-point) or absolute positioning with respect to the + origin (upper left corner) of the generated bitmap/pixmap. */ +static int T1_lposition=1; + + + +/* T1_SetX11Params(): Set X11-parameters which t1lib has to know in order + to properly generate pixmaps from characters */ +int T1_SetX11Params( Display *display, + Visual *visual, + unsigned int depth, + Colormap colormap) +{ + + T1_display =display; + T1_visual =visual; + T1_depth =depth; + T1_colormap =colormap; + + if (T1_CheckEndian()==0) + T1_byte_order=0; + else + T1_byte_order=1; + + /* For bug hunting: */ + if (ImageByteOrder( T1_display)==0) + T1_PrintLog( "T1_SetX11Params()", + "X-Server uses Little Endian data representation", + T1LOG_DEBUG); + else + T1_PrintLog( "T1_SetX11Params()", + "X-Server uses Big Endian data representation", + T1LOG_DEBUG); + + return(0); +} + + + +/* T1_SetCharX(): Generate an object of type GLYPH, i.e, a glyph with + a pixmap ID instead of a pointer to a bitmap: */ + +GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, char charcode, + float size, T1_TMATRIX *transform) +{ + GLYPH *pglyph; + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width; + Pixmap clipmask=0; + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + if ((pglyph=T1_SetChar( FontID, charcode, size, transform))==NULL){ + T1_PrintLog( "T1_SetCharX()", + "T1_SetChar() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)pglyph->bits, + PAD(width, pFontBase->bitmap_pad), + height + ); + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + } + + XCopyPlane( T1_display, clipmask, d, gc, 0, 0, + width, height, x_dest, y_dest, 0x01); + + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_SetStringX(...): Draw a string of characters into an X11 drawable */ +GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + GLYPH *pglyph; + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width; + Pixmap clipmask=0; + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + if ((pglyph=T1_SetString( FontID, string, len, + spaceoff, modflag, size, + transform))==NULL){ + T1_PrintLog( "T1_SetStringX()", + "T1_SetString() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)pglyph->bits, + PAD(width, pFontBase->bitmap_pad), /* width */ + height + ); + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + } + + XCopyPlane( T1_display, clipmask, d, gc, 0, 0, + width, height, x_dest, y_dest, 0x01); + + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + +/* T1_SetRectX(): Draw a rectangle into an x11 drawable */ + +GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float rwidth, float rheight, + T1_TMATRIX *transform) +{ + GLYPH *pglyph; + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width; + Pixmap clipmask=0; + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + if ((pglyph=T1_SetRect( FontID, size, rwidth, rheight, transform))==NULL){ + T1_PrintLog( "T1_SetRectrX()", + "T1_SetRect() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)pglyph->bits, + PAD(width, pFontBase->bitmap_pad), + height + ); + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + } + + XCopyPlane( T1_display, clipmask, d, gc, 0, 0, + width, height, x_dest, y_dest, 0x01); + + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_AASetCharX(): Generate an object of type GLYPH, i.e, a glyph with + a pixmap ID instead of a pointer to a bitmap: */ +GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, char charcode, + float size, T1_TMATRIX *transform) +{ + int j, k; + + GLYPH *pglyph; + XImage *ximage; + + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width, width_pad; + + XGCValues xgcvalues; + static unsigned long fg, bg; + + Pixmap clipmask=0; + int clipmask_h, clipmask_v, line_off; + char *clipmask_ptr; + + int opaque; + + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + xglyph.bpp=T1_depth; + + /* In order to be able to contruct the pixmap we need to know + foreground and background color as well the copy function */ + XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues); + fg=xgcvalues.foreground; + bg=xgcvalues.background; + + + /* At this point we must compute the colors that are needed to do + antialiasing between fore- and background. The following function + fills the static aacolors */ + if (T1aa_SmartOn==0) + j=T1_AAGetLevel(); + else if (size>=T1aa_smartlimit2) + j=1; + else if (size>=T1aa_smartlimit1) + j=2; + else + j=4; + if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){ + switch ( j){ + case 1: + if ( fg!=oldfg_n || bg!=oldbg_n){ + oldfg_n=fg; + oldbg_n=bg; + /* computing colors is not necessary here */ + T1_AANSetGrayValues( bg, fg); + } + break; + case 2: + if ( fg!=oldfg_l || bg!=oldbg_l){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_l=fg; + oldbg_l=bg; + T1_AASetGrayValues(aapixels[0], /* white */ + aapixels[4], + aapixels[8], + aapixels[12], + aapixels[16] ); /* black */ + } + break; + case 4: + if ( fg!=oldfg_h || bg!=oldbg_h){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_h=fg; + oldbg_h=bg; + T1_AAHSetGrayValues( aapixels); + } + break; + } + lastlevel=j; + oldfg=fg; + oldbg=bg; + } + + if ((pglyph=T1_AASetChar( FontID, charcode, size, + transform))==NULL){ + T1_PrintLog( "T1_AASetCharX()", + "T1_AASetChar() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + clipmask_v=height; + clipmask_h=width; + width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp; + clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); + if (clipmask_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* Note: We pad the clipmask always to byte boundary */ + if (pglyph->bpp==8) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((char *)(pglyph->bits))[k*width_pad+j]!=bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else if (pglyph->bpp==16) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)clipmask_ptr, + width, + height + ); + free( clipmask_ptr); + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + + } + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + width, + height, + pFontBase->bitmap_pad, + 0 /*PAD(width,8)/8*/ /* number of bytes per line */ + ); + ximage->byte_order=T1_byte_order; + XPutImage(T1_display, + d, + gc, + ximage, + 0, + 0, + x_dest, + y_dest, + width, + height + ); + XDestroyImage(ximage); + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_AASetStringX(...): Draw a string of characters into an X11 drawable */ +GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, char *string, int len, + long spaceoff, int modflag, float size, + T1_TMATRIX *transform) +{ + int j, k; + + GLYPH *pglyph; + XImage *ximage; + + + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width, width_pad; + + XGCValues xgcvalues; + static unsigned long fg, bg; + + + Pixmap clipmask=0; + int clipmask_h, clipmask_v, line_off; + char *clipmask_ptr; + + int opaque; + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + + /* In order to be able to contruct the pixmap we need to know + foreground and background color as well the copy function */ + XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues); + fg=xgcvalues.foreground; + bg=xgcvalues.background; + + xglyph.bpp=T1_depth; + + /* At this point we must compute the colors that are needed to do + antialiasing between fore- and background. The following function + fills the static aacolors */ + if (T1aa_SmartOn==0) + j=T1_AAGetLevel(); + else if (size>=T1aa_smartlimit2) + j=1; + else if (size>=T1aa_smartlimit1) + j=2; + else + j=4; + if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){ + switch ( j){ + case 1: + if ( fg!=oldfg_n || bg!=oldbg_n){ + oldfg_n=fg; + oldbg_n=bg; + /* computing colors is not necessary here */ + T1_AANSetGrayValues( bg, fg); + } + break; + case 2: + if ( fg!=oldfg_l || bg!=oldbg_l){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_l=fg; + oldbg_l=bg; + T1_AASetGrayValues(aapixels[0], /* white */ + aapixels[4], + aapixels[8], + aapixels[12], + aapixels[16] ); /* black */ + } + break; + case 4: + if ( fg!=oldfg_h || bg!=oldbg_h){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_h=fg; + oldbg_h=bg; + T1_AAHSetGrayValues( aapixels); + } + break; + } + lastlevel=j; + oldfg=fg; + oldbg=bg; + } + + + if ((pglyph=T1_AASetString( FontID, string, len, + spaceoff, modflag, size, + transform))==NULL){ + T1_PrintLog( "T1_AASetStringX()", + "T1_AASetString() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + clipmask_v=height; + clipmask_h=width; + width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp; + clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); + if (clipmask_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* Note: We pad the clipmask always to byte boundary */ + if (pglyph->bpp==8) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((char *)(pglyph->bits))[k*width_pad+j]!=bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else if (pglyph->bpp==16) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)clipmask_ptr, + width, + height + ); + free( clipmask_ptr); + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + + } + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + width, + height, + pFontBase->bitmap_pad, /* lines padded to bytes */ + 0 /*PAD(width,8)/8*/ /* number of bytes per line */ + ); + ximage->byte_order=T1_byte_order; + XPutImage(T1_display, + d, + gc, + ximage, + 0, + 0, + x_dest, + y_dest, + width, + height + ); + XDestroyImage(ximage); + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_AASetCharX(): Draw a rectangle into an x11 drawable */ +GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float rwidth, float rheight, + T1_TMATRIX *transform) +{ + int j, k; + + GLYPH *pglyph; + XImage *ximage; + + static GLYPH xglyph={NULL,{0,0,0,0,0,0},NULL,0}; + + int height, width, width_pad; + + XGCValues xgcvalues; + static unsigned long fg, bg; + + Pixmap clipmask=0; + int clipmask_h, clipmask_v, line_off; + char *clipmask_ptr; + + int opaque; + + + + xglyph.metrics.leftSideBearing=0; + xglyph.metrics.rightSideBearing=0; + xglyph.metrics.advanceX=0; + xglyph.metrics.advanceY=0; + xglyph.metrics.ascent=0; + xglyph.metrics.descent=0; + xglyph.pFontCacheInfo=NULL; + + + opaque=mode; + + xglyph.bpp=T1_depth; + + /* In order to be able to contruct the pixmap we need to know + foreground and background color as well the copy function */ + XGetGCValues( T1_display, gc, T1GCMASK, &xgcvalues); + fg=xgcvalues.foreground; + bg=xgcvalues.background; + + + /* At this point we must compute the colors that are needed to do + antialiasing between fore- and background. The following function + fills the static aacolors */ + if (T1aa_SmartOn==0) + j=T1_AAGetLevel(); + else if (size>=T1aa_smartlimit2) + j=1; + else if (size>=T1aa_smartlimit1) + j=2; + else + j=4; + if ( j!=lastlevel || fg!=oldfg || bg!=oldbg ){ + switch ( j){ + case 1: + if ( fg!=oldfg_n || bg!=oldbg_n){ + oldfg_n=fg; + oldbg_n=bg; + /* computing colors is not necessary here */ + T1_AANSetGrayValues( bg, fg); + } + break; + case 2: + if ( fg!=oldfg_l || bg!=oldbg_l){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_l=fg; + oldbg_l=bg; + T1_AASetGrayValues(aapixels[0], /* white */ + aapixels[4], + aapixels[8], + aapixels[12], + aapixels[16] ); /* black */ + } + break; + case 4: + if ( fg!=oldfg_h || bg!=oldbg_h){ + T1_ComputeAAColorsX( fg, bg, AAMAXPLANES); + /*~derekn*/ + /* If fg=bg, the clipmask will be messed up; in this case */ + /* we can arbitrarily change bg to get a correct clipmask. */ + if (opaque == 0 && fg == bg) + aapixels[0] = bg = (fg > 0) ? fg - 1 : fg + 1; + oldfg_h=fg; + oldbg_h=bg; + T1_AAHSetGrayValues( aapixels); + } + break; + } + lastlevel=j; + oldfg=fg; + oldbg=bg; + } + + if ((pglyph=T1_AASetRect( FontID, size, rwidth, rheight, transform))==NULL){ + T1_PrintLog( "T1_AASetRectX()", + "T1_AASetRect() returned NULL-pointer!", + T1LOG_WARNING); + return(NULL); + } + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + xglyph=*pglyph; + return( &xglyph); + } + + width=pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing; + height=pglyph->metrics.ascent-pglyph->metrics.descent; + + + /* Correct position */ + if (T1_lposition){ + x_dest += pglyph->metrics.leftSideBearing; + y_dest -= pglyph->metrics.ascent; + } + + if (opaque==0){ + clipmask_v=height; + clipmask_h=width; + width_pad=PAD(width*T1aa_bpp, pFontBase->bitmap_pad)/T1aa_bpp; + clipmask_ptr=(char *)calloc((PAD(clipmask_h, 8)>>3) * clipmask_v, sizeof( char)); + if (clipmask_ptr==NULL){ + T1_errno=T1ERR_ALLOC_MEM; + return(NULL); + } + /* Note: We pad the clipmask always to byte boundary */ + if (pglyph->bpp==8) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((char *)(pglyph->bits))[k*width_pad+j]!=bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else if (pglyph->bpp==16) + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE16 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE16)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + else + for ( k=0; k<clipmask_v; k++){ + line_off=k*(PAD(clipmask_h, 8)>>3); + for (j=0; j<clipmask_h; j++){ + if (((T1_AA_TYPE32 *)(pglyph->bits))[k*width_pad+j]!=(T1_AA_TYPE32)bg) + clipmask_ptr[line_off+(j>>3)] |= (0x01<<(j%8)); + } + } + + clipmask=XCreateBitmapFromData( T1_display, + d, + (char *)clipmask_ptr, + width, + height + ); + free( clipmask_ptr); + XSetClipMask(T1_display, gc, clipmask); + XSetClipOrigin(T1_display, gc, x_dest, y_dest); + + } + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + width, + height, + pFontBase->bitmap_pad, + 0 /*PAD(width,8)/8*/ /* number of bytes per line */ + ); + ximage->byte_order=T1_byte_order; + XPutImage(T1_display, + d, + gc, + ximage, + 0, + 0, + x_dest, + y_dest, + width, + height + ); + XDestroyImage(ximage); + if (clipmask){ + XFreePixmap( T1_display, clipmask); + clipmask=0; + XSetClipMask(T1_display, gc, None); + XSetClipOrigin(T1_display, gc, 0, 0); + } + + pglyph->bits=NULL; /* Since XDestroyImage() free's this also! */ + xglyph.metrics.leftSideBearing=pglyph->metrics.leftSideBearing; + xglyph.metrics.rightSideBearing=pglyph->metrics.rightSideBearing; + xglyph.metrics.advanceX=pglyph->metrics.advanceX; + xglyph.metrics.advanceY=pglyph->metrics.advanceY; + xglyph.metrics.ascent=pglyph->metrics.ascent; + xglyph.metrics.descent=pglyph->metrics.descent; + xglyph.bpp=pglyph->bpp; + + return( &xglyph); + + +} + + + +/* T1_ComputeAAColorsX(): Compute the antialiasing colors in dependency + of foreground and background */ +int T1_ComputeAAColorsX( unsigned long fg, unsigned long bg, int nolevels) +{ + + static unsigned long last_fg; + static unsigned long last_bg; + long delta_red, delta_green, delta_blue; + int i; + int nocolors=0; + + + aacolors[0].pixel=bg; + aacolors[nolevels-1].pixel=fg; + + if ((fg==last_fg)&&(bg==last_bg)) + return(nocolors); + + /* Get RGB values for fore- and background */ + XQueryColor( T1_display, T1_colormap, &aacolors[0]); + XQueryColor( T1_display, T1_colormap, &aacolors[nolevels-1]); + delta_red = (aacolors[nolevels-1].red - aacolors[0].red)/(nolevels-1); + delta_green = (aacolors[nolevels-1].green - aacolors[0].green)/(nolevels-1); + delta_blue = (aacolors[nolevels-1].blue - aacolors[0].blue)/(nolevels-1); + aapixels[0]=aacolors[0].pixel; + aapixels[nolevels-1]=aacolors[nolevels-1].pixel; + + for (i=1; i<nolevels-1; i++){ + aacolors[i].red = aacolors[0].red + i*delta_red; + aacolors[i].green = aacolors[0].green + i*delta_green; + aacolors[i].blue = aacolors[0].blue + i*delta_blue; + aacolors[i].flags = DoRed | DoGreen | DoBlue; + aacolors[i].pad = aacolors[0].pad; + /* Allocate color in current palette */ + if (XAllocColor( T1_display, T1_colormap, &aacolors[i])!=0){ + aapixels[i]=aacolors[i].pixel; + nocolors++; + } + } + + return(nocolors); + +} + + + +/* Set the positioning switch */ +void T1_LogicalPositionX( int pos_switch) +{ + if (pos_switch) + T1_lposition=1; + else + T1_lposition=0; + return; +} + + + +XImage *T1_XImageFromGlyph( GLYPH *pglyph) +{ + XImage *ximage; + + /* Check for empty bitmap */ + if (pglyph->bits==NULL) { + T1_errno=T1ERR_INVALID_PARAMETER; + return( NULL); + } + + if (pglyph->bpp==1) { /* we have a bitmap glyph */ + ximage=XCreateImage( T1_display, + T1_visual, + 1, + XYBitmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing, + pglyph->metrics.ascent-pglyph->metrics.descent, + pFontBase->bitmap_pad, + 0 /* number of bytes per line */ + ); + } + else { /* we have an anztialiased glyph */ + ximage=XCreateImage( T1_display, + T1_visual, + T1_depth, + ZPixmap, /* XYBitmap or XYPixmap */ + 0, /* No offset */ + (char *)pglyph->bits, + pglyph->metrics.rightSideBearing-pglyph->metrics.leftSideBearing, + pglyph->metrics.ascent-pglyph->metrics.descent, + pFontBase->bitmap_pad, + 0 /* number of bytes per line */ + ); + } + + if (ximage==NULL) { + T1_errno=T1ERR_X11; + return( NULL); + } + ximage->byte_order=T1_byte_order; /* Set t1libīs byteorder */ + + return( ximage); + +} + diff --git a/Build/source/libs/t1lib/t1x11.h b/Build/source/libs/t1lib/t1x11.h new file mode 100644 index 00000000000..e6413085c1e --- /dev/null +++ b/Build/source/libs/t1lib/t1x11.h @@ -0,0 +1,103 @@ +/*-------------------------------------------------------------------------- + ----- File: t1x11.h + ----- Author: Rainer Menzner (Rainer.Menzner@web.de) + ----- Date: 2003-01-02 + ----- Description: This file is part of the t1-library. It contains + definitions and declarations for t1x11.c. + ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2003. + As of version 0.5, t1lib is distributed under the + GNU General Public Library Lincense. The + conditions can be found in the files LICENSE and + LGPL, which should reside in the toplevel + directory of the distribution. Please note that + there are parts of t1lib that are subject to + other licenses: + The parseAFM-package is copyrighted by Adobe Systems + Inc. + The type1 rasterizer is copyrighted by IBM and the + X11-consortium. + ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) + ----- Credits: I want to thank IBM and the X11-consortium for making + their rasterizer freely available. + Also thanks to Piet Tutelaers for his ps2pk, from + which I took the rasterizer sources in a format + independent from X11. + Thanks to all people who make free software living! +--------------------------------------------------------------------------*/ + +#include <X11/Xlib.h> + +#ifdef T1X11_C + +int T1_SetX11Params( Display *display, + Visual *visual, + unsigned int depth, + Colormap colormap); +GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +int T1_ComputeAAColorsX( unsigned long fg, + unsigned long bg, + int nolevels); +int T1_GetDepthOfDrawable( Drawable drawable); +void T1_LogicalPositionX( int pos_switch); + + +#else + +extern Display *T1_display; + +extern int T1_SetX11Params( Display *display, + Visual *visual, + unsigned int depth, + Colormap colormap); +extern GLYPH *T1_SetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_SetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern GLYPH *T1_AASetCharX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char charcode, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetStringX( Drawable d, GC gc, int mode, int x, int y, + int FontID, char *string, int len, + long spaceoff, int modflag, + float size, T1_TMATRIX *transform); +extern GLYPH *T1_AASetRectX( Drawable d, GC gc, int mode, int x_dest, int y_dest, + int FontID, float size, + float width, float height, + T1_TMATRIX *transform); +extern int T1_ComputeAAColorsX( unsigned long fg, + unsigned long bg, + int nolevels); +extern int T1_GetDepthOfDrawable( Drawable drawable); +extern void T1_LogicalPositionX( int pos_switch); + + +#endif + diff --git a/Build/source/libs/t1lib/win32.mak b/Build/source/libs/t1lib/win32.mak new file mode 100644 index 00000000000..a4205380ac3 --- /dev/null +++ b/Build/source/libs/t1lib/win32.mak @@ -0,0 +1,76 @@ +################################################################################ +# +# Makefile : LibT1 +# Author : Fabrice Popineau <Fabrice.Popineau@supelec.fr> +# Platform : Win32, Microsoft VC++ 6.0, depends upon fpTeX 0.5 sources +# Time-stamp: <02/09/23 17:41:08 popineau> +# +################################################################################ +root_srcdir = ..\.. +!ifdef DEVELOPMENT +INCLUDE=$(INCLUDE);$(root_srcdir)\texk.development +!else +INCLUDE=$(INCLUDE);$(root_srcdir)\texk +!endif + +USE_GNUW32 = 1 +USE_T1 = 1 + +!include <msvc/common.mak> + +programs = $(t1dll) +libfiles = $(t1lib) +includefiles = +installdirs = $(bindir) $(includedir) $(libdir) + +objects = \ + $(objdir)\parseAFM.obj \ + $(objdir)\t1aaset.obj \ + $(objdir)\t1afmtool.obj \ + $(objdir)\t1base.obj \ + $(objdir)\t1delete.obj \ + $(objdir)\t1enc.obj \ + $(objdir)\t1env.obj \ + $(objdir)\t1finfo.obj \ + $(objdir)\t1load.obj \ + $(objdir)\t1outline.obj \ + $(objdir)\t1set.obj \ + $(objdir)\t1subset.obj \ + $(objdir)\t1trans.obj \ + $(objdir)\t1win32.obj \ + $(NULL) + +default: all + +all: $(objdir) $(t1) + +lib: $(objdir) $(t1lib) + +!ifdef T1_DLL +DEFS = $(DEFS) -DMAKE_T1_DLL + +$(t1lib): $(objdir) $(objects) + $(archive) /DEF $(objects) + +$(t1dll): $(objects) $(objdir)\libt1.res $(gnuw32lib) $(regexlib) $(zliblib) + $(link_dll) $(**) $(t1lib:.lib=.exp) wsock32.lib $(conlibs) +!else +$(t1lib): $(objdir) $(objects) $(gnuw32lib) $(regexlib) $(zliblib) + $(archive) $(**) wsock32.lib +!ENDIF + +!include <msvc/config.mak> + +!include <msvc/install.mak> + +install:: install-exec install-include install-lib + +!include <msvc/clean.mak> + +!include <msvc/rdepend.mak> +!include "./depend.mak" + +# +# Local Variables: +# mode: makefile +# End: diff --git a/Build/source/libs/t1lib/withenable.ac b/Build/source/libs/t1lib/withenable.ac new file mode 100644 index 00000000000..cc7076168d9 --- /dev/null +++ b/Build/source/libs/t1lib/withenable.ac @@ -0,0 +1,10 @@ +AC_ARG_WITH([system-t1lib], +[ --with-system-t1lib Use installed T1lib]) + +AC_ARG_WITH([t1lib_libdir], +[ --with-t1lib-libdir=DIR + Specify the location of T1lib library files (libt1.a)]) + +AC_ARG_WITH([t1lib_include], +[ --with-t1lib-include=DIR + Specify the location of T1lib header files]) |