From 563598d45d14f318321f825623579ca77478cb33 Mon Sep 17 00:00:00 2001 From: Ian Pilcher Date: Wed, 16 May 2001 20:56:05 +0000 Subject: [PATCH] Read metrics from TrueType fonts. --- configure | 385 ++++++++++++++++--------- configure.in | 33 +++ dlls/wineps/Makefile.in | 6 +- dlls/wineps/afm.c | 19 +- dlls/wineps/psdrv.h | 1 + dlls/wineps/truetype.c | 610 ++++++++++++++++++++++++++++++++++++++++ include/acconfig.h | 3 + include/config.h.in | 3 + 8 files changed, 915 insertions(+), 145 deletions(-) create mode 100644 dlls/wineps/truetype.c diff --git a/configure b/configure index f4480f2127c..856d4f09009 100755 --- a/configure +++ b/configure @@ -4646,13 +4646,108 @@ fi +echo $ac_n "checking for FT_Init_FreeType in -lfreetype""... $ac_c" 1>&6 +echo "configure:4651: checking for FT_Init_FreeType in -lfreetype" >&5 +ac_lib_var=`echo freetype'_'FT_Init_FreeType | 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="-lfreetype $LIBS" +cat > conftest.$ac_ext <&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 + ft_lib=yes +else + echo "$ac_t""no" 1>&6 +ft_lib=no +fi + +if test "$ft_lib" = "no" +then + FREETYPELIBS="" + FREETYPEINCL="" + wine_cv_msg_freetype=no +else + # Extract the first word of "freetype-config", so it can be a program name with args. +set dummy freetype-config; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:4700: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_ft_devel'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$ft_devel"; then + ac_cv_prog_ft_devel="$ft_devel" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_ft_devel="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_ft_devel" && ac_cv_prog_ft_devel="no" +fi +fi +ft_devel="$ac_cv_prog_ft_devel" +if test -n "$ft_devel"; then + echo "$ac_t""$ft_devel" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$ft_devel" = "no" + then + FREETYPELIBS="" + FREETYPEINCL="" + wine_cv_msg_freetype=yes + else + cat >> confdefs.h <<\EOF +#define HAVE_FREETYPE 1 +EOF + + FREETYPELIBS=`freetype-config --libs` + FREETYPEINCL=`freetype-config --cflags` + wine_cv_msg_freetype=no + fi +fi + + + echo $ac_n "checking "for GNU style IPX support"""... $ac_c" 1>&6 -echo "configure:4651: checking "for GNU style IPX support"" >&5 +echo "configure:4746: checking "for GNU style IPX support"" >&5 if eval "test \"`echo '$''{'ac_cv_c_ipx_gnu'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4660,7 +4755,7 @@ int main() { ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX ; return 0; } EOF -if { (eval echo configure:4664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_ipx_gnu="yes" else @@ -4685,12 +4780,12 @@ fi if test "$ac_cv_c_ipx_gnu" = "no" then echo $ac_n "checking "for linux style IPX support"""... $ac_c" 1>&6 -echo "configure:4689: checking "for linux style IPX support"" >&5 +echo "configure:4784: checking "for linux style IPX support"" >&5 if eval "test \"`echo '$''{'ac_cv_c_ipx_linux'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4699,7 +4794,7 @@ int main() { ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX ; return 0; } EOF -if { (eval echo configure:4703: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4798: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_ipx_linux="yes" else @@ -4726,17 +4821,17 @@ for ac_hdr in sys/soundcard.h machine/soundcard.h soundcard.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4730: checking for $ac_hdr" >&5 +echo "configure:4825: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4835: \"$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* @@ -4764,12 +4859,12 @@ done echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6 -echo "configure:4768: checking "for Open Sound System"" >&5 +echo "configure:4863: checking "for Open Sound System"" >&5 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4889: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_opensoundsystem="yes" else @@ -4813,12 +4908,12 @@ EOF fi echo $ac_n "checking "for Open Sound System/MIDI interface"""... $ac_c" 1>&6 -echo "configure:4817: checking "for Open Sound System/MIDI interface"" >&5 +echo "configure:4912: checking "for Open Sound System/MIDI interface"" >&5 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem_midi'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4938: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_opensoundsystem_midi="yes" else @@ -4868,7 +4963,7 @@ if test "x${GCC}" = "xyes" then CFLAGS="$CFLAGS -Wall" echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6 -echo "configure:4872: checking "for gcc strength-reduce bug"" >&5 +echo "configure:4967: 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 @@ -4876,7 +4971,7 @@ else ac_cv_c_gcc_strength_bug="yes" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4990: \"$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 @@ -4912,21 +5007,21 @@ echo "$ac_t""$ac_cv_c_gcc_strength_bug" 1>&6 fi echo $ac_n "checking "for gcc -mpreferred-stack-boundary=2 support"""... $ac_c" 1>&6 -echo "configure:4916: checking "for gcc -mpreferred-stack-boundary=2 support"" >&5 +echo "configure:5011: checking "for gcc -mpreferred-stack-boundary=2 support"" >&5 if eval "test \"`echo '$''{'ac_cv_c_gcc_stack_boundary'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -mpreferred-stack-boundary=2" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5025: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_gcc_stack_boundary="yes" else @@ -4949,7 +5044,7 @@ fi echo $ac_n "checking "whether .type must sit inside a .def directive"""... $ac_c" 1>&6 -echo "configure:4953: checking "whether .type must sit inside a .def directive"" >&5 +echo "configure:5048: checking "whether .type must sit inside a .def directive"" >&5 if eval "test \"`echo '$''{'ac_cv_c_type_in_def'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4962,14 +5057,14 @@ _ac_test: .long 0 EOF cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_type_in_def="yes" else @@ -4993,7 +5088,7 @@ fi echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6 -echo "configure:4997: checking "whether external symbols need an underscore prefix"" >&5 +echo "configure:5092: 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 @@ -5005,14 +5100,14 @@ _ac_test: .long 0 EOF cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5111: \"$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 @@ -5036,7 +5131,7 @@ fi echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6 -echo "configure:5040: checking "whether assembler accepts .string"" >&5 +echo "configure:5135: checking "whether assembler accepts .string"" >&5 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5046,14 +5141,14 @@ cat > conftest_asm.s < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5152: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_asm_string="yes" else @@ -5081,21 +5176,21 @@ LDDLLFLAGS="" if test "$LIBEXT" = "so" then echo $ac_n "checking "whether we can build a Linux dll"""... $ac_c" 1>&6 -echo "configure:5085: checking "whether we can build a Linux dll"" >&5 +echo "configure:5180: checking "whether we can build a Linux dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll_linux'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0,-Bsymbolic" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5194: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_dll_linux="yes" else @@ -5116,21 +5211,21 @@ echo "$ac_t""$ac_cv_c_dll_linux" 1>&6 LDDLLFLAGS="-Wl,-Bsymbolic" else echo $ac_n "checking whether we can build a UnixWare (Solaris) dll""... $ac_c" 1>&6 -echo "configure:5120: checking whether we can build a UnixWare (Solaris) dll" >&5 +echo "configure:5215: checking whether we can build a UnixWare (Solaris) dll" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll_unixware'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -Wl,-G,-h,conftest.so.1.0,-B,symbolic" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_dll_unixware="yes" else @@ -5151,21 +5246,21 @@ echo "$ac_t""$ac_cv_c_dll_unixware" 1>&6 LDDLLFLAGS="-Wl,-B,symbolic" else echo $ac_n "checking "whether we can build a NetBSD a.out dll"""... $ac_c" 1>&6 -echo "configure:5155: checking "whether we can build a NetBSD a.out dll"" >&5 +echo "configure:5250: checking "whether we can build a NetBSD a.out dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll_netbsd'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -Wl,-Bshareable,-Bforcearchive" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_dll_netbsd="yes" else @@ -5221,21 +5316,21 @@ elif test "$LIBEXT" = "dll"; then else DLL_LINK="-L\$(DLLDIR) \$(DLLS:%=-l%) \$(LIBWINE) \$(LIBUNICODE) \$(X_LIBS) \$(XLIB)" echo $ac_n "checking whether the linker supports --[no]-whole-archive (Linux)""... $ac_c" 1>&6 -echo "configure:5225: checking whether the linker supports --[no]-whole-archive (Linux)" >&5 +echo "configure:5320: checking whether the linker supports --[no]-whole-archive (Linux)" >&5 if eval "test \"`echo '$''{'ac_cv_c_whole_archive'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -Wl,--whole-archive -Wl,--no-whole-archive" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_whole_archive="yes" else @@ -5255,21 +5350,21 @@ echo "$ac_t""$ac_cv_c_whole_archive" 1>&6 DLL_LINK="-Wl,--whole-archive $DLL_LINK -Wl,--no-whole-archive" else echo $ac_n "checking whether the linker supports -z {all,default}extract (Linux)""... $ac_c" 1>&6 -echo "configure:5259: checking whether the linker supports -z {all,default}extract (Linux)" >&5 +echo "configure:5354: checking whether the linker supports -z {all,default}extract (Linux)" >&5 if eval "test \"`echo '$''{'ac_cv_c_allextract'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -Wl,-z,allextract -Wl,-z,defaultextract" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_c_allextract="yes" else @@ -5304,7 +5399,7 @@ fi wine_cv_libc_reentrant=no echo $ac_n "checking for reentrant libc: __errno_location""... $ac_c" 1>&6 -echo "configure:5308: checking for reentrant libc: __errno_location" >&5 +echo "configure:5403: checking for reentrant libc: __errno_location" >&5 if eval "test \"`echo '$''{'wine_cv_libc_r___errno_location'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5312,14 +5407,14 @@ else wine_cv_libc_r___errno_location=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then wine_cv_libc_r___errno_location=yes else @@ -5342,7 +5437,7 @@ fi echo $ac_n "checking for reentrant libc: __error""... $ac_c" 1>&6 -echo "configure:5346: checking for reentrant libc: __error" >&5 +echo "configure:5441: checking for reentrant libc: __error" >&5 if eval "test \"`echo '$''{'wine_cv_libc_r___error'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5350,14 +5445,14 @@ else wine_cv_libc_r___error=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then wine_cv_libc_r___error=yes else @@ -5380,7 +5475,7 @@ fi echo $ac_n "checking for reentrant libc: ___errno""... $ac_c" 1>&6 -echo "configure:5384: checking for reentrant libc: ___errno" >&5 +echo "configure:5479: checking for reentrant libc: ___errno" >&5 if eval "test \"`echo '$''{'wine_cv_libc_r____errno'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5388,14 +5483,14 @@ else wine_cv_libc_r____errno=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then wine_cv_libc_r____errno=yes else @@ -5418,7 +5513,7 @@ fi echo $ac_n "checking for reentrant libc: __thr_errno""... $ac_c" 1>&6 -echo "configure:5422: checking for reentrant libc: __thr_errno" >&5 +echo "configure:5517: checking for reentrant libc: __thr_errno" >&5 if eval "test \"`echo '$''{'wine_cv_libc_r___thr_errno'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5426,14 +5521,14 @@ else wine_cv_libc_r___thr_errno=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then wine_cv_libc_r___thr_errno=yes else @@ -5456,7 +5551,7 @@ fi echo $ac_n "checking for reentrant libc: __errno""... $ac_c" 1>&6 -echo "configure:5460: checking for reentrant libc: __errno" >&5 +echo "configure:5555: checking for reentrant libc: __errno" >&5 if eval "test \"`echo '$''{'wine_cv_libc_r___errno'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5464,14 +5559,14 @@ else wine_cv_libc_r___errno=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then wine_cv_libc_r___errno=yes else @@ -5505,7 +5600,7 @@ fi if test "$have_x" = "yes" -a "$wine_cv_libc_reentrant" != "no" then echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6 -echo "configure:5509: checking "for reentrant X libraries"" >&5 +echo "configure:5604: checking "for reentrant X libraries"" >&5 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5554,19 +5649,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:5558: checking for working alloca.h" >&5 +echo "configure:5653: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { void *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:5570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -5587,12 +5682,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:5591: checking for alloca" >&5 +echo "configure:5686: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5719: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -5652,12 +5747,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:5656: checking whether alloca needs Cray hooks" >&5 +echo "configure:5751: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5686: checking for $ac_func" >&5 +echo "configure:5781: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5737,7 +5832,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:5741: checking stack direction for C alloca" >&5 +echo "configure:5836: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5745,7 +5840,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -5827,12 +5922,12 @@ for ac_func in \ do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5831: checking for $ac_func" >&5 +echo "configure:5926: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5937,17 +6032,17 @@ for ac_hdr in \ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5941: checking for $ac_hdr" >&5 +echo "configure:6036: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5951: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6046: \"$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* @@ -5974,12 +6069,12 @@ fi done echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:5978: checking whether stat file-mode macros are broken" >&5 +echo "configure:6073: 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 < #include @@ -6032,12 +6127,12 @@ fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:6036: checking for working const" >&5 +echo "configure:6131: 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 <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -6107,21 +6202,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:6111: checking for inline" >&5 +echo "configure:6206: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6220: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -6147,12 +6242,12 @@ EOF esac echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:6151: checking for ANSI C header files" >&5 +echo "configure:6246: 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 < #include @@ -6160,7 +6255,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6259: \"$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* @@ -6177,7 +6272,7 @@ 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 @@ -6195,7 +6290,7 @@ 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 @@ -6216,7 +6311,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -6227,7 +6322,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:6231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -6251,12 +6346,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:6255: checking for size_t" >&5 +echo "configure:6350: 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 < #if STDC_HEADERS @@ -6284,7 +6379,7 @@ EOF fi echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:6288: checking size of long long" >&5 +echo "configure:6383: 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 @@ -6292,7 +6387,7 @@ else ac_cv_sizeof_long_long=0 else cat > conftest.$ac_ext < main() @@ -6303,7 +6398,7 @@ main() exit(0); } EOF -if { (eval echo configure:6307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6402: \"$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 @@ -6324,12 +6419,12 @@ EOF echo $ac_n "checking "for off64_t"""... $ac_c" 1>&6 -echo "configure:6328: checking "for off64_t"" >&5 +echo "configure:6423: checking "for off64_t"" >&5 if eval "test \"`echo '$''{'wine_cv_off64_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6440: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_off64_t="yes" else @@ -6364,12 +6459,12 @@ EOF fi echo $ac_n "checking "for struct stat64"""... $ac_c" 1>&6 -echo "configure:6368: checking "for struct stat64"" >&5 +echo "configure:6463: checking "for struct stat64"" >&5 if eval "test \"`echo '$''{'wine_cv_struct_stat64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_struct_stat64="yes" else @@ -6405,12 +6500,12 @@ EOF fi echo $ac_n "checking "whether linux/input.h is for real"""... $ac_c" 1>&6 -echo "configure:6409: checking "whether linux/input.h is for real"" >&5 +echo "configure:6504: checking "whether linux/input.h is for real"" >&5 if eval "test \"`echo '$''{'wine_cv_linux_input_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6423,7 +6518,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6427: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6522: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_linux_input_h=yes else @@ -6447,12 +6542,12 @@ EOF echo $ac_n "checking "whether we can use re-entrant gethostbyname_r Linux style"""... $ac_c" 1>&6 -echo "configure:6451: checking "whether we can use re-entrant gethostbyname_r Linux style"" >&5 +echo "configure:6546: checking "whether we can use re-entrant gethostbyname_r Linux style"" >&5 if eval "test \"`echo '$''{'wine_cv_linux_gethostbyname_r_6'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6473,7 +6568,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_linux_gethostbyname_r_6=yes else @@ -6499,12 +6594,12 @@ EOF if test "$ac_cv_header_linux_joystick_h" = "yes" then echo $ac_n "checking "whether linux/joystick.h uses the Linux 2.2+ API"""... $ac_c" 1>&6 -echo "configure:6503: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5 +echo "configure:6598: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5 if eval "test \"`echo '$''{'wine_cv_linux_joystick_22_api'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6519,7 +6614,7 @@ int main() { /*empty*/ ; return 0; } EOF -if { (eval echo configure:6523: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_linux_joystick_22_api=yes else @@ -6546,12 +6641,12 @@ fi if test "$ac_cv_header_sys_vfs_h" = "yes" then echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:6550: checking "whether sys/vfs.h defines statfs"" >&5 +echo "configure:6645: checking "whether sys/vfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6568,7 +6663,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_vfs_has_statfs=yes else @@ -6595,12 +6690,12 @@ fi if test "$ac_cv_header_sys_statfs_h" = "yes" then echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6 -echo "configure:6599: checking "whether sys/statfs.h defines statfs"" >&5 +echo "configure:6694: checking "whether sys/statfs.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6615,7 +6710,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6619: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6714: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_statfs_has_statfs=yes else @@ -6642,12 +6737,12 @@ fi if test "$ac_cv_header_sys_mount_h" = "yes" then echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6 -echo "configure:6646: checking "whether sys/mount.h defines statfs"" >&5 +echo "configure:6741: checking "whether sys/mount.h defines statfs"" >&5 if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -6662,7 +6757,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6666: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_sys_mount_has_statfs=yes else @@ -6688,7 +6783,7 @@ fi echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6 -echo "configure:6692: checking "for statfs.f_bfree"" >&5 +echo "configure:6787: checking "for statfs.f_bfree"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6697,7 +6792,7 @@ else wine_cv_statfs_bfree=no else cat > conftest.$ac_ext < @@ -6724,7 +6819,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6823: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bfree=yes else @@ -6748,7 +6843,7 @@ EOF fi echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6 -echo "configure:6752: checking "for statfs.f_bavail"" >&5 +echo "configure:6847: checking "for statfs.f_bavail"" >&5 if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6757,7 +6852,7 @@ else wine_cv_statfs_bavail=no else cat > conftest.$ac_ext < @@ -6784,7 +6879,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:6788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wine_cv_statfs_bavail=yes else @@ -6809,12 +6904,12 @@ fi echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6 -echo "configure:6813: checking "for msg_accrights in struct msghdr"" >&5 +echo "configure:6908: checking "for msg_accrights in struct msghdr"" >&5 if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -6822,7 +6917,7 @@ int main() { struct msghdr hdr; hdr.msg_accrights=0 ; return 0; } EOF -if { (eval echo configure:6826: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6921: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_msg_accrights="yes" else @@ -6845,12 +6940,12 @@ fi echo $ac_n "checking "for sun_len in struct sockaddr_un"""... $ac_c" 1>&6 -echo "configure:6849: checking "for sun_len in struct sockaddr_un"" >&5 +echo "configure:6944: checking "for sun_len in struct sockaddr_un"" >&5 if eval "test \"`echo '$''{'ac_cv_c_sun_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -6859,7 +6954,7 @@ int main() { static struct sockaddr_un addr; addr.sun_len = 1 ; return 0; } EOF -if { (eval echo configure:6863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6958: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_sun_len="yes" else @@ -6882,12 +6977,12 @@ fi echo $ac_n "checking "whether we need to define __i386__"""... $ac_c" 1>&6 -echo "configure:6886: checking "whether we need to define __i386__"" >&5 +echo "configure:6981: checking "whether we need to define __i386__"" >&5 if eval "test \"`echo '$''{'ac_cv_cpp_def_i386'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <afm->FontName, - afmle->afm->NumofMetrics); + TRACE("\tFontName '%s' (%i glyphs) - '%s' encoding:\n", + afmle->afm->FontName, afmle->afm->NumofMetrics, + afmle->afm->EncodingScheme); for (i = 0; i < afmle->afm->NumofMetrics; ++i) { @@ -671,7 +672,10 @@ static void PSDRV_DumpFontList(void) * SortFontMetrics * * Initializes the UV member of each glyph's AFMMETRICS and sorts each font's - * Metrics by Unicode Value. + * Metrics by Unicode Value. If the font has a standard encoding (i.e. it is + * using the Adobe Glyph List encoding vector), look up each glyph's Unicode + * Value based on it's glyph name. If the font has a font-specific encoding, + * map the default PostScript encodings into the Unicode private use area. * */ static int UnicodeGlyphByNameIndex(const UNICODEGLYPH *a, const UNICODEGLYPH *b) @@ -965,10 +969,17 @@ BOOL PSDRV_GetFontMetrics(void) if (PSDRV_ReadAFMDir (value) == FALSE) return FALSE; - PSDRV_IndexGlyphList(); + PSDRV_IndexGlyphList(); /* So SortFontMetrics will work */ if (SortFontMetrics() == FALSE) return FALSE; CalcWindowsMetrics(); + +#ifdef HAVE_FREETYPE + if (PSDRV_GetTrueTypeMetrics() == FALSE) + return FALSE; + PSDRV_IndexGlyphList(); +#endif + PSDRV_DumpFontList(); return TRUE; } diff --git a/dlls/wineps/psdrv.h b/dlls/wineps/psdrv.h index 614273d8b66..75903d4af94 100644 --- a/dlls/wineps/psdrv.h +++ b/dlls/wineps/psdrv.h @@ -418,6 +418,7 @@ VOID PSDRV_DrawLine( DC *dc ); INT PSDRV_GlyphListInit(); GLYPHNAME *PSDRV_GlyphName(LPCSTR szName); VOID PSDRV_IndexGlyphList(); +BOOL PSDRV_GetTrueTypeMetrics(); #endif diff --git a/dlls/wineps/truetype.c b/dlls/wineps/truetype.c new file mode 100644 index 00000000000..715901e9f24 --- /dev/null +++ b/dlls/wineps/truetype.c @@ -0,0 +1,610 @@ +/******************************************************************************* + * TrueType font-related functions for Wine PostScript driver. Currently just + * uses FreeType to read font metrics. + * + * Copyright 2001 Ian Pilcher + * + */ +#include "config.h" + +#ifdef HAVE_FREETYPE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "winnt.h" +#include "options.h" +#include "psdrv.h" +#include "debugtools.h" +#include "heap.h" + +DEFAULT_DEBUG_CHANNEL(psdrv); + + +#define REQUIRED_FACE_FLAGS ( FT_FACE_FLAG_SCALABLE | \ + FT_FACE_FLAG_HORIZONTAL | \ + FT_FACE_FLAG_SFNT | \ + FT_FACE_FLAG_GLYPH_NAMES ) + +static FT_Library library; +static FT_Face face; +static FT_CharMap charmap; +static TT_Header *head; +static TT_Postscript *post; +static TT_OS2 *os2; +static TT_HoriHeader *hhea; + +/******************************************************************************* + * + * FindCharMap + * + * Sets charmap and points afm->EncodingScheme to encoding name (in driver + * heap). Leaves both uninitialized if font contains no Windows encoding. + * + * Returns FALSE to indicate memory allocation error. + * + */ +static const char *encoding_names[7] = +{ + "WindowsSymbol", /* TT_MS_ID_SYMBOL_CS */ + "WindowsUnicode", /* TT_MS_ID_UNICODE_CS */ + "WindowsShiftJIS", /* TT_MS_ID_SJIS */ + "WindowsPRC", /* TT_MS_ID_GB2312 */ + "WindowsBig5", /* TT_MS_ID_BIG_5 */ + "WindowsWansung", /* TT_MS_ID_WANSUNG */ + "WindowsJohab" /* TT_MS_ID_JOHAB */ +}; + +static BOOL FindCharMap(AFM *afm) +{ + FT_Int i; + FT_Error error; + + charmap = NULL; + + for (i = 0; i < face->num_charmaps; ++i) + { + if (face->charmaps[i]->platform_id != TT_PLATFORM_MICROSOFT) + continue; + + if (face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS) + { + charmap = face->charmaps[i]; + break; + } + + if (charmap == NULL) + charmap = face->charmaps[i]; + } + + if (charmap == NULL) + return TRUE; + + error = FT_Set_Charmap(face, charmap); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Set_CharMap", error); + return FALSE; + } + + if (charmap->encoding_id < 7) + { + afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, + encoding_names[charmap->encoding_id]); + if (afm->EncodingScheme == NULL) + return FALSE; + } + else + { + afm->EncodingScheme = HeapAlloc(PSDRV_Heap, 0, + sizeof("WindowsUnknown") + 1 + charmap->encoding_id / 10); + if (afm->EncodingScheme == NULL) + return FALSE; + + sprintf(afm->EncodingScheme, "%s%u", "WindowsUnknown", + charmap->encoding_id); + } + + return TRUE; +} + +/******************************************************************************* + * NameTableString + * + * Converts a name table string to a null-terminated character string. The + * space for the character string is allocated from the driver heap. + * + * This function handles only platform_id = 3 (TT_PLATFORM_MICROSOFT) -- 16-bit + * big-endian strings. It also only handles ASCII character codes (< 128). + * + * This function will set *sz to NULL if it cannot parse the string, but it + * will only return FALSE in the event of an unexpected error (memory + * allocation failure). + * + */ +static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name) +{ + FT_UShort i, len, *ws; + LPSTR s; + + if (name->platform_id != TT_PLATFORM_MICROSOFT) + { + ERR("Unsupported encoding %i\n", name->platform_id); + return FALSE; /* should never get here */ + } + + len = name->string_len / 2; + s = *sz = HeapAlloc(PSDRV_Heap, 0, len + 1); + if (s == NULL) + return FALSE; + ws = (FT_UShort *)(name->string); + + for (i = 0; i < len; ++i, ++s, ++ws) + { + FT_UShort wc = *ws; + +#ifndef WORDS_BIGENDIAN + wc = (wc >> 8) | (wc << 8); +#endif + + if (wc > 127) + { + WARN("Non-ASCII character 0x%.4x\n", wc); + HeapFree(PSDRV_Heap, 0, *sz); + *sz = NULL; + return TRUE; + } + + *s = (CHAR)wc; + } + + *s = '\0'; + return TRUE; +} + +/******************************************************************************* + * ReadNameTable + * + * Reads various font names from the TrueType 'NAME' table. Currently looks + * for U.S. English names only, + * + * May leave a pointer uninitialized if the desired string is not present; + * returns FALSE only in the event of an unexpected error. + * + */ +static BOOL ReadNameTable(AFM *afm) +{ + FT_UInt numStrings, stringIndex; + FT_SfntName name; + FT_Error error; + + numStrings = FT_Get_Sfnt_Name_Count(face); + + for (stringIndex = 0; stringIndex < numStrings; ++stringIndex) + { + error = FT_Get_Sfnt_Name(face, stringIndex, &name); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Get_Sfnt_Name", error); + return FALSE; + } + + /* FIXME - Handle other languages? */ + + if (name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES || + name.platform_id != charmap->platform_id || + name.encoding_id != charmap->encoding_id) + continue; + + switch (name.name_id) + { + case TT_NAME_ID_FONT_FAMILY: + + if (NameTableString(&(afm->FamilyName), &name) == FALSE) + return FALSE; + break; + + case TT_NAME_ID_FULL_NAME: + + if (NameTableString(&(afm->FullName), &name) == FALSE) + return FALSE; + break; + + case TT_NAME_ID_PS_NAME: + + if (NameTableString(&(afm->FontName), &name) == FALSE) + return FALSE; + break; + } + } + + return TRUE; +} + +/******************************************************************************* + * FreeAFM + * + * Frees an AFM and all subsidiary objects. For this function to work + * properly, the AFM must have been allocated with HEAP_ZERO_MEMORY, and the + * UNICODEVECTOR and it's associated array of UNICODEGLYPHs must have been + * allocated as a single object. + */ +static void FreeAFM(AFM *afm) +{ + if (afm->FontName != NULL) + HeapFree(PSDRV_Heap, 0, afm->FontName); + if (afm->FullName != NULL) + HeapFree(PSDRV_Heap, 0, afm->FullName); + if (afm->FamilyName != NULL) + HeapFree(PSDRV_Heap, 0, afm->FamilyName); + if (afm->EncodingScheme != NULL) + HeapFree(PSDRV_Heap, 0, afm->EncodingScheme); + if (afm->Metrics != NULL) + HeapFree(PSDRV_Heap, 0, afm->Metrics); + if (afm->Encoding != NULL) + HeapFree(PSDRV_Heap, 0, afm->Encoding); + + HeapFree(PSDRV_Heap, 0, afm); +} + +/******************************************************************************* + * PSUnits + * + * Convert TrueType font units (relative to font em square) to PostScript + * units. This is defined as a macro, so it can handle different TrueType + * data types as inputs. + * + */ +#define PSUnits(x) (((float)(x)) * 1000.0 / ((float)(head->Units_Per_EM))) + +/******************************************************************************* + * ReadMetricsTables + * + * Reads basic font metrics from the 'head', 'post', and 'OS/2' tables. + * Returns FALSE if any table is missing. + * + */ +static BOOL ReadMetricsTables(AFM *afm) +{ + head = FT_Get_Sfnt_Table(face, ft_sfnt_head); + post = FT_Get_Sfnt_Table(face, ft_sfnt_post); + hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); + os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + + if (head == NULL || post == NULL || hhea == NULL || os2 == NULL) + return FALSE; + + if (os2->version == 0xffff) /* Old Macintosh font */ + return FALSE; + + afm->Weight = os2->usWeightClass; + afm->ItalicAngle = ((float)(post->italicAngle)) / 65536.0; + afm->IsFixedPitch = (post->isFixedPitch == 0) ? FALSE : TRUE; + afm->UnderlinePosition = PSUnits(post->underlinePosition); + afm->UnderlineThickness = PSUnits(post->underlineThickness); + + afm->FontBBox.llx = PSUnits(head->xMin); + afm->FontBBox.lly = PSUnits(head->yMin); + afm->FontBBox.urx = PSUnits(head->xMax); + afm->FontBBox.ury = PSUnits(head->yMax); + + /* CapHeight & XHeight set by ReadCharMetrics */ + + afm->Ascender = PSUnits(os2->sTypoAscender); + afm->Descender = PSUnits(os2->sTypoDescender); + afm->FullAscender = afm->FontBBox.ury; /* get rid of this */ + + afm->WinMetrics.usUnitsPerEm = head->Units_Per_EM; + afm->WinMetrics.sAscender = hhea->Ascender; + afm->WinMetrics.sDescender = hhea->Descender; + afm->WinMetrics.sLineGap = hhea->Line_Gap; + afm->WinMetrics.sTypoAscender = os2->sTypoAscender; + afm->WinMetrics.sTypoDescender = os2->sTypoDescender; + afm->WinMetrics.sTypoLineGap = os2->sTypoLineGap; + afm->WinMetrics.usWinAscent = os2->usWinAscent; + afm->WinMetrics.usWinDescent = os2->usWinDescent; + + return TRUE; +} + +/******************************************************************************* + * ReadCharMetrics + * + * Reads metrics for each glyph in a TrueType font. Since FreeAFM will try to + * free afm->Metrics and afm->Encoding if they are non-NULL, don't free them + * in the event of an error. (FreeAFM depends on the fact that afm->Encoding + * and its associated array of UNICODEGLYPHs are allocated as a single object.) + * + */ +static BOOL ReadCharMetrics(AFM *afm) +{ + FT_ULong charcode, index; + UNICODEGLYPH *glyphs; + + /* + * There does not seem to be an easy way to get the number of characters + * in an encoding out of a TrueType font. + */ + for (charcode = 0, index = 0; charcode < 65536; ++charcode) + { + if (FT_Get_Char_Index(face, charcode) != 0) + ++index; + } + + afm->NumofMetrics = index; + + afm->Metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS)); + afm->Encoding = HeapAlloc(PSDRV_Heap, 0, sizeof(UNICODEVECTOR) + + index * sizeof(UNICODEGLYPH)); + if (afm->Metrics == NULL || afm->Encoding == NULL) + return FALSE; + + glyphs = (UNICODEGLYPH *)(afm->Encoding + 1); + afm->Encoding->size = index; + afm->Encoding->glyphs = glyphs; + + for (charcode = 0, index = 0; charcode <= 65536; ++charcode) + { + FT_UInt glyph_index = FT_Get_Char_Index(face, charcode); + FT_Error error; + FT_Glyph glyph; + FT_BBox bbox; + char buffer[256]; + + if (glyph_index == 0) + continue; + + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | + FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_LINEAR_DESIGN); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Load_Glyph", error); + return FALSE; + } + + error = FT_Get_Glyph(face->glyph, &glyph); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Get_Glyph", error); + return FALSE; + } + + FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox); + + error = FT_Get_Glyph_Name(face, glyph_index, buffer, 255); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Get_Glyph_Name", error); + return FALSE; + } + + afm->Metrics[index].N = PSDRV_GlyphName(buffer); + if (afm->Metrics[index].N == NULL) + return FALSE; + + afm->Metrics[index].C = charcode; + afm->Metrics[index].UV = charcode; + afm->Metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance); + afm->Metrics[index].B.llx = PSUnits(bbox.xMin); + afm->Metrics[index].B.lly = PSUnits(bbox.yMin); + afm->Metrics[index].B.urx = PSUnits(bbox.xMax); + afm->Metrics[index].B.ury = PSUnits(bbox.yMax); + afm->Metrics[index].L = NULL; + + TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n", + afm->Metrics[index].N->sz, afm->Metrics[index].WX, + afm->Metrics[index].B.llx, afm->Metrics[index].B.lly, + afm->Metrics[index].B.urx, afm->Metrics[index].B.ury); + + glyphs[index].UV = charcode; + glyphs[index].name = afm->Metrics[index].N; + + if (charcode == 0x0048) /* 'H' */ + afm->CapHeight = PSUnits(bbox.yMax); + if (charcode == 0x0078) /* 'x' */ + afm->XHeight = PSUnits(bbox.yMax); + + ++index; + } + + return TRUE; +} + +/******************************************************************************* + * ReadTrueTypeAFM + * + * Fills in AFM structure for opened TrueType font file. Returns FALSE only on + * an unexpected error (memory allocation failure or FreeType error); otherwise + * returns TRUE. Leaves it to the caller (ReadTrueTypeFile) to clean up. + * + */ +static BOOL ReadTrueTypeAFM(AFM *afm) +{ + + if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS) + { + WARN("Font flags do not match requirements\n"); + return TRUE; + } + + if (FindCharMap(afm) == FALSE) + return FALSE; + + if (charmap == NULL) + { + WARN("No Windows encodings in font\n"); + return TRUE; + } + + TRACE("Using encoding '%s'\n", afm->EncodingScheme); + + if (ReadNameTable(afm) == FALSE) + return FALSE; + + if (afm->FamilyName == NULL || afm->FullName == NULL || + afm->FontName == NULL) + { + WARN("Required strings missing from font\n"); + return TRUE; + } + + if (ReadMetricsTables(afm) == FALSE) /* Non-fatal */ + { + WARN("Required metrics tables missing from font\n"); + return TRUE; + } + + if (ReadCharMetrics(afm) == FALSE) + return FALSE; + + return TRUE; +} + +/******************************************************************************* + * ReadTrueTypeFile + * + * Reads PostScript-style font metrics from a TrueType font file. Only returns + * FALSE for unexpected errors (memory allocation, etc.); returns TRUE if it's + * just a bad font file. + * + */ +static BOOL ReadTrueTypeFile(LPCSTR filename) +{ + FT_Error error; + AFM *afm; + + TRACE("'%s'\n", filename); + + afm = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(AFM)); + if (afm == NULL) + return FALSE; + + error = FT_New_Face(library, filename, 0, &face); + + if (error != FT_Err_Ok) + { + WARN("FreeType error %i opening '%s'\n", error, filename); + HeapFree(PSDRV_Heap, 0, afm); + return TRUE; + } + + if (ReadTrueTypeAFM(afm) == FALSE) + { + FreeAFM(afm); + FT_Done_Face(face); + return FALSE; + } + + error = FT_Done_Face(face); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Done_Face", error); + FreeAFM(afm); + return FALSE; + } + + if (afm->Encoding == NULL) /* last element to be set */ + { + FreeAFM(afm); + return TRUE; + } + + if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) + { + FreeAFM(afm); + return FALSE; + } + + return TRUE; +} + + + +/******************************************************************************* + * PSDRV_GetTrueTypeMetrics + * + * Reads PostScript-stype font metrics from TrueType font files in directories + * listed in the [TrueType Font Directories] section of the Wine configuration + * file. + * + * If this function fails, the driver will fail to initialize and the driver + * heap will be destroyed, so it's not necessary to HeapFree everything in + * that event. + * + */ +BOOL PSDRV_GetTrueTypeMetrics() +{ + CHAR keybuf[256], namebuf[256]; + INT i = 0; + FT_Error error; + + error = FT_Init_FreeType(&library); + if (error != FT_Err_Ok) + { + ERR("%s returned %i\n", "FT_Init_FreeType", error); + return FALSE; + } + + while (PROFILE_EnumWineIniString("TrueType Font Directories", i++, keybuf, + sizeof(keybuf), namebuf, sizeof(namebuf))) + { + struct dirent *dent; + DIR *dir; + INT dnlen; /* directory name length */ + + namebuf[sizeof(namebuf) - 1] = '\0'; + dir = opendir(namebuf); + if (dir == NULL) + { + WARN("Error opening directory '%s'\n", namebuf); + continue; + } + + dnlen = strlen(namebuf); + namebuf[dnlen] = '/'; /* 2 slashes is OK, 0 is not */ + ++dnlen; + + while ((dent = readdir(dir)) != NULL) + { + INT fnlen; /* file name length */ + + fnlen = strlen(dent->d_name); + + if (fnlen < 5 || strcasecmp(dent->d_name + fnlen - 4, ".ttf") != 0) + { + TRACE("Skipping filename '%s'\n", dent->d_name); + continue; + } + + if (dnlen + fnlen + 1 > sizeof(namebuf)) /* allow for '\0' */ + { + WARN("Path '%s/%s' is too long\n", namebuf, dent->d_name); + continue; + } + + memcpy(namebuf + dnlen, dent->d_name, fnlen + 1); + + if (ReadTrueTypeFile(namebuf) == FALSE) + { + ERR("Error reading '%s'\n", namebuf); + closedir(dir); + FT_Done_FreeType(library); + return FALSE; + } + } + + closedir(dir); + } + + FT_Done_FreeType(library); + return TRUE; +} + +#endif /* HAVE_FREETYPE */ diff --git a/include/acconfig.h b/include/acconfig.h index c17452b5cb4..ad7b1f0a401 100644 --- a/include/acconfig.h +++ b/include/acconfig.h @@ -123,6 +123,9 @@ /* Define if we have CUPS */ #undef HAVE_CUPS +/* Define if FreeType 2 is installed */ +#undef HAVE_FREETYPE + /* Define if we have 64 bit file offsets */ #undef HAVE_OFF64_T diff --git a/include/config.h.in b/include/config.h.in index eee0c58a18b..efadfc69893 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -154,6 +154,9 @@ /* Define if we have CUPS */ #undef HAVE_CUPS +/* Define if FreeType 2 is installed */ +#undef HAVE_FREETYPE + /* Define if we have 64 bit file offsets */ #undef HAVE_OFF64_T