From f8d16cc540f1fcb6a466ec25176cc869d08bb18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Suzuki=2C=20Toshiya=20=28=E9=88=B4=E6=9C=A8=E4=BF=8A?= =?UTF-8?q?=E5=93=89=29?= Date: Wed, 11 Jan 2006 09:28:38 +0000 Subject: [PATCH] * Fix 'deprecated' warnings in building for MacOS --- ChangeLog | 24 + builds/mac/FreeType.m68k_cfm.make.txt | 13 +- builds/mac/FreeType.m68k_far.make.txt | 17 +- builds/mac/FreeType.ppc_carbon.make.txt | 8 +- builds/mac/FreeType.ppc_classic.make.txt | 8 +- builds/mac/README | 188 ++++- builds/mac/ascii2mpw.py | 2 + builds/unix/configure.ac | 209 +++++ docs/CHANGES | 15 + src/base/ftmac.c | 938 +++++++++++++++-------- 10 files changed, 1074 insertions(+), 348 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05dc9c654..ba03a7d9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2006-01-11 suzuki toshiya + + Jumbo patch to fix "deprecated" warning to cross-build for + Tiger on Intel, the issue is reported by Sean McBride + on 2005-08-24. + + * src/base/ftmac.c: Heavy change to build without deprecated + Carbon functions on Tiger. + + * builds/unix/configure.ac: Add options and autochecks for + Carbon functions availabilities, for MacOS X. + + * builds/mac/ascii2mpw.py: Add convertor for character "\305". + * builds/mac/FreeType.m68k_{far|cfm}.make.txt: Add conditional + macros to avoid unavailable functions. And ftmac.c must be + compiled without "-strict ansi", because it disables cpp macro + to use ToolBox system call. + * builds/mac/FreeType.ppc_{classic|carbon}.make.txt: Add + conditional macros to avoid unavailable functions. + + * builds/mac/README: Detailed notes on function availabilities. + + * docs/CHANGES: Notes about (possible) incompatibilities. + 2006-01-08 Werner Lemberg * docs/CHANGES: Updated. diff --git a/builds/mac/FreeType.m68k_cfm.make.txt b/builds/mac/FreeType.m68k_cfm.make.txt index abcf517ec..de43b672c 100644 --- a/builds/mac/FreeType.m68k_cfm.make.txt +++ b/builds/mac/FreeType.m68k_cfm.make.txt @@ -15,7 +15,13 @@ Includes = \xB6 Sym-68K = -sym off -COptions = {Includes} {Sym-68K} -model cfmseg +COptions = \xB6 + -d HAVE_FSSPEC=1 \xB6 + -d HAVE_FSREF=0 \xB6 + -d HAVE_QUICKDRAW_TOOLBOX=1 \xB6 + -d HAVE_QUICKDRAW_CARBON=0 \xB6 + -d HAVE_ATS=0 \xB6 + {Includes} {Sym-68K} -model cfmseg ### Source Files ### @@ -119,6 +125,9 @@ LibFiles-68K = ### Build Rules ### +"{ObjDir}ftmac.c.o" \xC4\xC4 :src:base:ftmac.c + {C} :src:base:ftmac.c -o "{ObjDir}ftmac.c.o" {COptions} + FreeType.m68k_cfm \xC4\xC4 FreeType.m68k_cfm.o FreeType.m68k_cfm.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5} @@ -142,7 +151,7 @@ FreeType.m68k_cfm.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5 "{ObjDir}ftglyph.c.o" \xC4 :src:base:ftglyph.c "{ObjDir}ftgxval.c.o" \xC4 :src:base:ftgxval.c "{ObjDir}ftinit.c.o" \xC4 :src:base:ftinit.c -"{ObjDir}ftmac.c.o" \xC4 :src:base:ftmac.c +# "{ObjDir}ftmac.c.o" \xC4 :src:base:ftmac.c "{ObjDir}ftmm.c.o" \xC4 :src:base:ftmm.c "{ObjDir}ftotval.c.o" \xC4 :src:base:ftotval.c "{ObjDir}ftpfr.c.o" \xC4 :src:base:ftpfr.c diff --git a/builds/mac/FreeType.m68k_far.make.txt b/builds/mac/FreeType.m68k_far.make.txt index 83e515c3e..dd997b3e4 100644 --- a/builds/mac/FreeType.m68k_far.make.txt +++ b/builds/mac/FreeType.m68k_far.make.txt @@ -8,14 +8,19 @@ MAKEFILE = FreeType.m68k_far.make ObjDir = :objs: Includes = \xB6 - -ansi strict \xB6 -includes unix \xB6 -i :include: \xB6 -i :src: Sym-68K = -sym off -COptions = {Includes} {Sym-68K} -model far +COptions = \xB6 + -d HAVE_FSSPEC=1 \xB6 + -d HAVE_FSREF=0 \xB6 + -d HAVE_QUICKDRAW_TOOLBOX=1 \xB6 + -d HAVE_QUICKDRAW_CARBON=0 \xB6 + -d HAVE_ATS=0 \xB6 + {Includes} {Sym-68K} -model far ### Source Files ### @@ -114,10 +119,14 @@ LibFiles-68K = ### Default Rules ### .c.o \xC4 .c {\xA5MondoBuild\xA5} - {C} {depDir}{default}.c -o {targDir}{default}.c.o {COptions} + {C} {depDir}{default}.c -o {targDir}{default}.c.o {COptions} \xB6 + -ansi strict ### Build Rules ### +"{ObjDir}ftmac.c.o" \xC4\xC4 :src:base:ftmac.c + {C} :src:base:ftmac.c -o "{ObjDir}ftmac.c.o" {COptions} + FreeType.m68k_far \xC4\xC4 FreeType.m68k_far.o FreeType.m68k_far.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5} @@ -141,7 +150,7 @@ FreeType.m68k_far.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5 "{ObjDir}ftglyph.c.o" \xC4 :src:base:ftglyph.c "{ObjDir}ftgxval.c.o" \xC4 :src:base:ftgxval.c "{ObjDir}ftinit.c.o" \xC4 :src:base:ftinit.c -"{ObjDir}ftmac.c.o" \xC4 :src:base:ftmac.c +# "{ObjDir}ftmac.c.o" \xC4 :src:base:ftmac.c "{ObjDir}ftmm.c.o" \xC4 :src:base:ftmm.c "{ObjDir}ftotval.c.o" \xC4 :src:base:ftotval.c "{ObjDir}ftpfr.c.o" \xC4 :src:base:ftpfr.c diff --git a/builds/mac/FreeType.ppc_carbon.make.txt b/builds/mac/FreeType.ppc_carbon.make.txt index ad302ef93..3cfe3da26 100644 --- a/builds/mac/FreeType.ppc_carbon.make.txt +++ b/builds/mac/FreeType.ppc_carbon.make.txt @@ -15,7 +15,13 @@ Includes = \xB6 Sym-PPC = -sym off -PPCCOptions = {Includes} {Sym-PPC} -d TARGET_API_MAC_CARBON=1 +PPCCOptions = \xB6 + -d HAVE_FSSPEC=1 \xB6 + -d HAVE_FSREF=1 \xB6 + -d HAVE_QUICKDRAW_TOOLBOX=1 \xB6 + -d HAVE_QUICKDRAW_CARBON=1 \xB6 + -d HAVE_ATS=0 \xB6 + {Includes} {Sym-PPC} -d TARGET_API_MAC_CARBON=1 ### Source Files ### diff --git a/builds/mac/FreeType.ppc_classic.make.txt b/builds/mac/FreeType.ppc_classic.make.txt index 8943025cc..f589f75ec 100644 --- a/builds/mac/FreeType.ppc_classic.make.txt +++ b/builds/mac/FreeType.ppc_classic.make.txt @@ -15,7 +15,13 @@ Includes = \xB6 Sym-PPC = -sym off -PPCCOptions = {Includes} {Sym-PPC} +PPCCOptions = \xB6 + -d HAVE_FSSPEC=1 \xB6 + -d HAVE_FSREF=0 \xB6 + -d HAVE_QUICKDRAW_TOOLBOX=1 \xB6 + -d HAVE_QUICKDRAW_CARBON=0 \xB6 + -d HAVE_ATS=0 \xB6 + {Includes} {Sym-PPC} ### Source Files ### diff --git a/builds/mac/README b/builds/mac/README index 67e272b2f..8d9278232 100644 --- a/builds/mac/README +++ b/builds/mac/README @@ -18,6 +18,9 @@ Mac OS X, build as the system is UNIX. However, Mac OS X is most useful to manipulate files in vanilla FreeType to fit classic MacOS. +The information about MacOS specific API is written in +appendix of this document. + 2. Requirement -------------- @@ -205,8 +208,191 @@ environment by Metrowerks. GCC for MPW and Symantec to MPW. To update classic MacOS support easily, building by Jam is expected on MPW. + +APPENDIX I +---------- + + A-1. Framework dependencies + --------------------------- + + src/base/ftmac.c adds two Mac-specific features to + FreeType. These features are based on MacOS libraries. + + * accessing resource-fork font + The fonts for classic MacOS store their graphical data + in resource forks which cannot be accessed via ANSI C + functions. FreeType2 provides functions to handle such + resource fork fonts, they are based on File Manager + framework of MacOS. In addition, HFS and HFS+ file + system driver of Linux is supported. Following + functions are for this purpose. + + FT_New_Face_From_Resource() + FT_New_Face_From_FSSpec() + FT_New_Face_From_FSRef() + + * resolving font name to font file + The font menu of MacOS application prefers font name + written in FOND resource than sfnt resoure. FreeType2 + provides functions to find font file by name in MacOS + application, they are based on QuickDraw Font Manager + and Apple Type Service framework of MacOS. + + FT_GetFile_From_Mac_Name() + FT_GetFile_From_Mac_ATS_Name() + + Working functions for each MacOS are summarized as + following. + + upto MacOS 6: + not tested (you have to obtain MPW 2.x) + + MacOS 7.x, 8.x, 9.x (without CarbonLib): + FT_GetFile_From_Mac_Name() + FT_New_Face_From_Resource() + FT_New_Face_From_FSSpec() + + MacOS 9.x (with CarbonLib): + FT_GetFile_From_Mac_Name() + FT_New_Face_From_Resource() + FT_New_Face_From_FSSpec() + FT_New_Face_From_FSRef() + + Mac OS X upto 10.4.x: + FT_GetFile_From_Mac_Name() deprecated + FT_New_Face_From_FSSpec() deprecated + FT_GetFile_From_Mac_ATS_Name() deprecated? + FT_New_Face_From_FSRef() + + A-2. Deprecated Functions + ------------------------- + + A-2-1. FileManager + ------------------ + + For convenience to write MacOS application, ftmac.c + provides functions to specify a file by FSSpec and FSRef, + because the file identification pathname had ever been + unrecommended method in MacOS programming. + + Toward to MacOS X 10.4 & 5, Carbon functions using FSSpec + datatype is noticed as deprecated, and recommended to + migrate to FSRef datatype. The big differences of FSRef + against FSSpec are explained in Apple TechNotes 2078. + + http://developer.apple.com/technotes/tn2002/tn2078.html + + - filename length: the max length of file + name of FSRef is 255 chars (it is limit of HFS+), + that of FSSpec is 31 chars (it is limit of HFS). + + - filename encoding: FSSpec is localized by + legacy encoding for each language system, + FSRef is Unicode enabled. + + A-2-2. FontManager + ------------------ + + Following functions receive QuickDraw fontname: + + FT_GetFile_From_Mac_Name() + + QuickDraw is deprecated and replaced by Quartz + since Mac OS X 10.4. They are still kept for + backward compatibility. By undefinition of + HAVE_QUICKDRAW in building, you can change these + functions to return FT_Err_Unimplemented always. + + Replacement functions are added for migration. + + FT_GetFile_From_Mac_ATS_Name() + + They are usable on Mac OS X only. On older systems, + these functions return FT_Err_Unimplemented always. + + The detailed incompatibilities and possibility + of FontManager emulation without QuickDraw is + explained in + + http://www.gyve.org/~mpsuzuki/ats_benchmark.html + + A-3. Framework Availabilities + ----------------------------- + + The framework of MacOS are often revised, especially + when new format of binary executable is introduced. + Following table is the minimum version of frameworks + to use functions used in FreeType2. The table is + extracted from MPW header files for assembly language. + + *** NOTE *** + The conditional definition of available data type + in MPW compiler is insufficient. You can compile + program using FSRef data type for older systems + (MacOS 7, 8) that don't know FSRef data type. + + + +-------------------+-----------------------------+ + CPU | mc680x0 | PowerPC | + +---------+---------+---------+---------+---------+ + Binary Executable Format | Classic | 68K-CFM | CFM | CFM | Mach-O | + +---------+---------+---------+---------+---------+ + Framework API | Toolbox | Toolbox | Toolbox | Carbon | Carbon | + +---------+---------+---------+---------+---------+ + + +---------+---------+---------+---------+---------+ + | ?(*) |Interface|Interface|CarbonLib|Mac OS X | + | |Lib |Lib | | | +* Files.h +---------+---------+---------+---------+---------+ +PBGetFCBInfoSync() | o | 7.1- | 7.1- | 1.0- | o | +FSMakeFSSpec() | o | 7.1- | 7.1- | 1.0- | o | +FSGetForkCBInfo() | o | (**) | 9.0- | 1.0- | o | +FSpMakeFSRef() | o | (**) | 9.0- | 1.0- | o | +FSGetCatalogInfo() | o | (**) | 9.0- | 1.0- | -10.3 | +FSPathMakeRef() | x | x | x | 1.1- | -10.3 | + +---------+---------+---------+---------+---------+ + + +---------+---------+---------+---------+---------+ + | ?(*) |Font |Font |CarbonLib|Mac OS X | + | |Manager |Manager | | | +* Fonts.h +---------+---------+---------+---------+---------+ +FMCreateFontFamilyIterator() | x | x | 9.0- | 1.0- | -10.3 | +FMDisposeFontFamilyIterator() | x | x | 9.0- | 1.0- | -10.3 | +FMGetNextFontFamily() | x | x | 9.0- | 1.0- | -10.3 | +FMGetFontFamilyName() | x | x | 9.0- | 1.0- | -10.3 | +FMCreateFontFamilyInstanceIterator() | x | x | 9.0- | 1.0- | -10.3 | +FMDisposeFontFamilyInstanceIterator() | x | x | 9.0- | 1.0- | -10.3 | +FMGetNextFontFamilyInstance() | x | x | 9.0- | 1.0- | -10.3 | + +---------+---------+---------+---------+---------+ + + +---------+---------+---------+---------+---------+ + | - | - | - |CarbonLib|Mac OS X | +* ATSFont.h (***) +---------+---------+---------+---------+---------+ +ATSFontFindFromName() | x | x | x | x | o | +ATSFontGetFileSpecification() | x | x | x | x | o | + +---------+---------+---------+---------+---------+ + + (*) + In the "Classic": the original binary executable + format, these framework functions are directly + transformed to MacOS system call. Therefore, the + exact availabilitly should be checked by running + system. + + (**) + InterfaceLib is bundled to MacOS and its version + is usually equal to MacOS. There's no separate + update for InterfaceLib. It is supposed that + there's no InterfaceLib 9.x for m68k platforms. + In fact, these functions are FSRef dependent. + + (***) + ATSUI framework is available on ATSUnicode 8.5 on + ppc Toolbox CFM, CarbonLib 1.0 too. But its base: + ATS font manager is not published in these versions. + ------------------------------------------------------------ -Last update: 2005/10/28, by suzuki toshiya +Last update: 2006/01/10, by suzuki toshiya Currently maintained by suzuki toshiya, diff --git a/builds/mac/ascii2mpw.py b/builds/mac/ascii2mpw.py index 6033b39d7..ad32b2197 100755 --- a/builds/mac/ascii2mpw.py +++ b/builds/mac/ascii2mpw.py @@ -7,6 +7,7 @@ if len( sys.argv ) == 1 : mpw_line = string.replace(asc_line, "\\xA5", "\245") mpw_line = string.replace(mpw_line, "\\xB6", "\266") mpw_line = string.replace(mpw_line, "\\xC4", "\304") + mpw_line = string.replace(mpw_line, "\\xC5", "\305") mpw_line = string.replace(mpw_line, "\\xFF", "\377") mpw_line = string.replace(mpw_line, "\n", "\r") mpw_line = string.replace(mpw_line, "\\n", "\n") @@ -18,5 +19,6 @@ elif sys.argv[1] == "-r" : asc_line = string.replace(asc_line, "\245", "\\xA5") asc_line = string.replace(asc_line, "\266", "\\xB6") asc_line = string.replace(asc_line, "\304", "\\xC4") + asc_line = string.replace(asc_line, "\305", "\\xC5") asc_line = string.replace(asc_line, "\377", "\\xFF") sys.stdout.write(asc_line) diff --git a/builds/unix/configure.ac b/builds/unix/configure.ac index 393bd0846..a1dab41ae 100644 --- a/builds/unix/configure.ac +++ b/builds/unix/configure.ac @@ -147,6 +147,215 @@ else fi +# Whether to use FileManager which is deprecated since Mac OS X 10.4 + +AC_ARG_WITH([fsspec], + AS_HELP_STRING([--with-fsspec], + [use obsolete FSSpec API of MacOS, if available (default=yes)])) +if test x$with_fsspec = xno; then + CFLAGS="$CFLAGS -DHAVE_FSSPEC=0" +elif test x$with_old_mac_fonts = xyes; then + AC_MSG_CHECKING([FSSpec-based FileManager]) + AC_TRY_LINK([ +#if defined(__GNUC__) && defined(__APPLE_CC__) +# include +# include +#else +# include +# include +#endif + ], [ + FCBPBPtr paramBlock; + short vRefNum; + long dirID; + ConstStr255Param fileName; + FSSpec* spec; + + /* FSSpec functions: deprecated sicne Mac OS X 10.4 */ + PBGetFCBInfoSync( paramBlock ); + FSMakeFSSpec( vRefNum, dirID, fileName, spec ); + + ], [ + AC_MSG_RESULT([ok]) + CFLAGS="$CFLAGS -DHAVE_FSSPEC=1" + ], [ + AC_MSG_RESULT([not found]) + CFLAGS="$CFLAGS -DHAVE_FSSPEC=0" + ]) +fi + +# Whether to use FileManager in Carbon since MacOS 9.x + +AC_ARG_WITH([fsref], + AS_HELP_STRING([--with-fsref], + [use Carbon FSRef API of MacOS, if available (default=yes)])) +if test x$with_fsref = xno; then + AC_MSG_WARN([ +*** WARNING + FreeType2 built without FSRef API cannot load + data-fork fonts on MacOS, except of XXX.dfont. +]) + CFLAGS="$CFLAGS -DHAVE_FSREF=0" +elif test x$with_old_mac_fonts = xyes; then + AC_MSG_CHECKING([FSRef-based FileManager]) + AC_TRY_LINK([ +#if defined(__GNUC__) && defined(__APPLE_CC__) +# include +# include +#else +# include +# include +#endif + ], [ + FCBPBPtr paramBlock; + short vRefNum; + long dirID; + ConstStr255Param fileName; + FSSpec* spec; + + Boolean* isDirectory; + UInt8* path; + SInt16 desiredRefNum; + SInt16* iterator; + SInt16* actualRefNum; + HFSUniStr255* outForkName; + FSVolumeRefNum volume; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo* catalogInfo; + FSForkInfo* forkInfo; + FSRef* ref; + + + /* FSRef functions: no need to check? */ + FSGetForkCBInfo( desiredRefNum, volume, iterator, + actualRefNum, forkInfo, ref, + outForkName ); + FSpMakeFSRef ( spec, ref ); + FSGetCatalogInfo( ref, whichInfo, catalogInfo, + outForkName, spec, ref ); + FSPathMakeRef( path, ref, isDirectory ); + + ], [ + AC_MSG_RESULT([ok]) + CFLAGS="$CFLAGS -DHAVE_FSREF=1" + ], [ + AC_MSG_RESULT([not found]) + CFLAGS="$CFLAGS -DHAVE_FSREF=0" + ]) +fi + +# Whether to use QuickDraw API in ToolBox which is deprecated since Mac OS X 10.4 + +AC_ARG_WITH([quickdraw-toolbox], + AS_HELP_STRING([--with-quickdraw-toolbox], + [use MacOS QuickDraw in ToolBox, if available (default=yes)])) +if test x$with_quickdraw_toolbox = xno; then + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_TOOLBOX=0" +elif test x$with_old_mac_fonts = xyes; then + AC_MSG_CHECKING([QuickDraw FontManager functions in ToolBox]) + AC_TRY_LINK([ +#if defined(__GNUC__) && defined(__APPLE_CC__) +# include +# include +#else +# include +# include +#endif + ], [ + Str255 familyName; + SInt16 familyID = 0; + FMInput* fmIn = NULL; + FMOutput* fmOut = NULL; + + + GetFontName( familyID, familyName ); + GetFNum( familyName, &familyID ); + fmOut = FMSwapFont( fmIn ); + + ], [ + AC_MSG_RESULT([ok]) + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_TOOLBOX=1" + ], [ + AC_MSG_RESULT([not found]) + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_TOOLBOX=0" + ]) +fi + + +# Whether to use QuickDraw API in Carbon which is deprecated since Mac OS X 10.4 + +AC_ARG_WITH([quickdraw-carbon], + AS_HELP_STRING([--with-quickdraw-carbon], + [use MacOS QuickDraw in Carbon, if available (default=yes)])) +if test x$with_quickdraw_carbon = xno; then + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_CARBON=0" +elif test x$with_old_mac_fonts = xyes; then + AC_MSG_CHECKING([QuickDraw FontManager functions in Carbon]) + AC_TRY_LINK([ +#if defined(__GNUC__) && defined(__APPLE_CC__) +# include +# include +#else +# include +# include +#endif + ], [ + FMFontFamilyIterator famIter; + FMFontFamily family; + Str255 famNameStr; + FMFontFamilyInstanceIterator instIter; + FMFontStyle style; + FMFontSize size; + FMFont font; + FSSpec* pathSpec; + + + FMCreateFontFamilyIterator( NULL, NULL, kFMUseGlobalScopeOption, &famIter ); + FMGetNextFontFamily( &famIter, &family ); + FMGetFontFamilyName( family, famNameStr ); + FMCreateFontFamilyInstanceIterator( family, &instIter ); + FMGetNextFontFamilyInstance( &instIter, &font, &style, &size ); + FMDisposeFontFamilyInstanceIterator( &instIter ); + FMDisposeFontFamilyIterator( &famIter ); + FMGetFontContainer( font, pathSpec ); + ], [ + AC_MSG_RESULT([ok]) + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_CARBON=1" + ], [ + AC_MSG_RESULT([not found]) + CFLAGS="$CFLAGS -DHAVE_QUICKDRAW_CARBON=0" + ]) +fi + + +# Whether to use AppleTypeService since Mac OS X +AC_ARG_WITH([ats], + dnl don't quote AS_HELP_STRING! + AS_HELP_STRING([--with-ats], + [use AppleTypeService, if available (default=yes)])) +if test x$with_ats = xno; then + CFLAGS="$CFLAGS -DHAVE_ATS=0" +elif test x$with_old_mac_fonts = xyes; then + AC_MSG_CHECKING([AppleTypeService functions]) + AC_TRY_LINK([ +#include + ], [ + FSSpec* pathSpec; + + + ATSFontFindFromName( NULL, kATSOptionFlagsUnRestrictedScope ); + ATSFontGetFileSpecification( 0, pathSpec ); + ], [ + AC_MSG_RESULT([ok]) + CFLAGS="$CFLAGS -DHAVE_ATS=1" + ], [ + AC_MSG_RESULT([not found]) + CFLAGS="$CFLAGS -DHAVE_ATS=0" + ]) +fi + + + AC_SUBST([LIBZ]) AC_SUBST([CFLAGS]) AC_SUBST([LDFLAGS]) diff --git a/docs/CHANGES b/docs/CHANGES index 79e07aa2b..7a55d7787 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -45,6 +45,12 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10 Note that this doesn't affect binary backwards compatibility. + - On MacOS, new APIs are added as replacements for legacy APIs: + `FT_New_Face_From_FSRef' for FT_New_Face_From_FSSpec, and + `FT_GetFile_From_Mac_ATS_Name' for FT_GetFile_From_Mac_Name. + Legacy APIs are still available, if FreeType is built without + disabling them. + III. MISCELLANEOUS - The documentation for FT_LOAD_TARGET_XXX and FT_RENDER_MODE_XXX @@ -57,6 +63,15 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10 returns the number of available faces via face->num_faces. Unsupported bitmap faces (fbit, NFNT) are ignored. + - builds/unix/configure is improved for MacOS X. It automatically + checks available functions in Carbon library, and prepare to use + newest functions by default. Also options to specify dependency + of each Carbon APIs (FSSpec, FSRef, old/new QuickDraw, ATS) are + available. By manual disabling of all QuickDraw, FreeType can be + built without "deprecated function" warning on MacOS 10.4.x, but + FT_GetFile_Mac_Name in ftmac.c is changed to dummy function, and + returns unimplemented error. For detail, see builds/mac/README. + - SFNT cmap handling has been improved, mainly to run faster. - A new face flag `FT_FACE_FLAG_HINTER' has been added which is diff --git a/src/base/ftmac.c b/src/base/ftmac.c index c8f55730e..8506377a4 100644 --- a/src/base/ftmac.c +++ b/src/base/ftmac.c @@ -3,6 +3,7 @@ /* ftmac.c */ /* */ /* Mac FOND support. Written by just@letterror.com. */ +/* Heavily Fixed by mpsuzuki, George Williams and Sean McBride */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ @@ -80,6 +81,47 @@ #include FT_MAC_H + /* FSSpec functions are depricated since Mac OS X 10.4 */ +#ifndef HAVE_FSSPEC +#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON +#define HAVE_FSSPEC 1 +#else +#define HAVE_FSSPEC 0 +#endif +#endif + + /* most FSRef functions were introduced since Mac OS 9 */ +#ifndef HAVE_FSREF +#if TARGET_API_MAC_OSX +#define HAVE_FSREF 1 +#else +#define HAVE_FSREF 0 +#endif +#endif + +#ifndef HFS_MAXPATHLEN +#define HFS_MAXPATHLEN 1024 +#endif + + + /* QuickDraw is depricated since Mac OS X 10.4 */ +#ifndef HAVE_QUICKDRAW_CARBON +#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON +#define HAVE_QUICKDRAW_CARBON 1 +#else +#define HAVE_QUICKDRAW_CARBON 0 +#endif +#endif + + /* AppleTypeService is available since Mac OS X */ +#ifndef HAVE_ATS +#if TARGET_API_MAC_OSX +#define HAVE_ATS 1 +#else +#define HAVE_ATS 0 +#endif +#endif + /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over TrueType in case *both* are available (this is not common, but it *is* possible). */ @@ -88,6 +130,153 @@ #endif +#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + return FT_Err_Unimplemented_Feature; + } +#else + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + OptionBits options = kFMUseGlobalScopeOption; + + FMFontFamilyIterator famIter; + OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, + options, + &famIter ); + FMFont the_font = 0; + FMFontFamily family = 0; + + + *face_index = 0; + while ( status == 0 && !the_font ) + { + status = FMGetNextFontFamily( &famIter, &family ); + if ( status == 0 ) + { + int stat2; + FMFontFamilyInstanceIterator instIter; + Str255 famNameStr; + char famName[256]; + + + /* get the family name */ + FMGetFontFamilyName( family, famNameStr ); + CopyPascalStringToC( famNameStr, famName ); + + /* iterate through the styles */ + FMCreateFontFamilyInstanceIterator( family, &instIter ); + + *face_index = 0; + stat2 = 0; + while ( stat2 == 0 && !the_font ) + { + FMFontStyle style; + FMFontSize size; + FMFont font; + + + stat2 = FMGetNextFontFamilyInstance( &instIter, &font, + &style, &size ); + if ( stat2 == 0 && size == 0 ) + { + char fullName[256]; + + + /* build up a complete face name */ + ft_strcpy( fullName, famName ); + if ( style & bold ) + strcat( fullName, " Bold" ); + if ( style & italic ) + strcat( fullName, " Italic" ); + + /* compare with the name we are looking for */ + if ( ft_strcmp( fullName, fontName ) == 0 ) + { + /* found it! */ + the_font = font; + } + else + ++(*face_index); + } + } + + FMDisposeFontFamilyInstanceIterator( &instIter ); + } + } + + FMDisposeFontFamilyIterator( &famIter ); + + if ( the_font ) + { + FMGetFontContainer( the_font, pathSpec ); + return FT_Err_Ok; + } + else + return FT_Err_Unknown_File_Format; + } +#endif + + +#if !HAVE_ATS + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + return FT_Err_Unimplemented_Feature; + } +#else + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + CFStringRef cf_fontName; + ATSFontRef ats_font_id; + + *face_index = 0; + + cf_fontName = CFStringCreateWithCString( NULL, fontName, kCFStringEncodingMacRoman ); + ats_font_id = ATSFontFindFromName( cf_fontName, kATSOptionFlagsUnRestrictedScope ); + + if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFF ) + return FT_Err_Unknown_File_Format; + + if ( 0 != ATSFontGetFileSpecification( ats_font_id, pathSpec )) + return FT_Err_Unknown_File_Format; + + /* face_index calculation by searching preceding fontIDs with same FSRef */ + { + int i; + FSSpec f; + + + for ( i = 1; i < ats_font_id; i++ ) + { + if ( 0 != ATSFontGetFileSpecification( ats_font_id - i, + &f ) || + f.vRefNum != pathSpec->vRefNum || + f.parID != pathSpec->parID || + f.name[0] != pathSpec->name[0] || + 0 != ft_strncmp( (char *)f.name + 1, + (char *)pathSpec->name + 1, + f.name[0] ) ) + break; + } + *face_index = ( i - 1 ); + } + return FT_Err_Ok; + } +#endif + + #if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO #define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) @@ -123,59 +312,161 @@ #endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */ - /* Given a pathname, fill in a file spec. */ - static int - file_spec_from_path( const char* pathname, - FSSpec* spec ) +#if HAVE_FSSPEC && !HAVE_FSREF + static OSErr + FT_FSPathMakeSpec( const UInt8* pathname, + FSSpec* spec_p, + Boolean isDirectory ) { - -#if !TARGET_API_MAC_OS8 && \ - !( defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO ) - - OSErr e; - FSRef ref; + const char *p, *q; + short vRefNum; + long dirID; + Str255 nodeName; + OSErr err; - e = FSPathMakeRef( (UInt8 *)pathname, &ref, false /* not a directory */ ); - if ( e == noErr ) - e = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, spec, NULL ); + p = q = (const char *)pathname; + dirID = 0; + vRefNum = 0; - return ( e == noErr ) ? 0 : (-1); + while ( 1 ) + { + q = p + FT_MIN( 255, ft_strlen( p ) ); -#else + if ( q == p ) + return 0; - Str255 p_path; - FT_ULong path_len; + if ( 255 < ft_strlen( (char *)pathname ) ) + { + while ( p < q && *q != ':' ) + q--; + } + if ( p < q ) + *(char *)nodeName = q - p; + else if ( ft_strlen( p ) < 256 ) + *(char *)nodeName = ft_strlen( p ); + else + return errFSNameTooLong; - /* convert path to a pascal string */ - path_len = ft_strlen( pathname ); - if ( path_len > 255 ) - return -1; - p_path[0] = (unsigned char)path_len; - ft_strncpy( (char*)p_path + 1, pathname, path_len ); + ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName ); + err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p ); + if ( err || '\0' == *q ) + return err; - if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr ) - return -1; - else - return 0; - -#endif + vRefNum = spec_p->vRefNum; + dirID = spec_p->parID; + p = q; + } } - /* Return the file type of the file specified by spec. */ - static OSType - get_file_type( const FSSpec* spec ) + static OSErr + FT_FSpMakePath( const FSSpec* spec_p, + UInt8* path, + UInt32 maxPathSize ) { + OSErr err; + FSSpec spec = *spec_p; + short vRefNum; + long dirID; + Str255 parDir_name; + + + FT_MEM_SET( path, 0, maxPathSize ); + while ( 1 ) + { + int child_namelen = ft_strlen( (char *)path ); + unsigned char node_namelen = spec.name[0]; + unsigned char* node_name = spec.name + 1; + + + if ( node_namelen + child_namelen > maxPathSize ) + return errFSNameTooLong; + + FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen ); + FT_MEM_COPY( path, node_name, node_namelen ); + if ( child_namelen > 0 ) + path[ node_namelen ] = ':'; + + vRefNum = spec.vRefNum; + dirID = spec.parID; + parDir_name[0] = '\0'; + err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec ); + if ( noErr != err || dirID == spec.parID ) + break; + } + return noErr; + } +#endif + + + static OSErr + FT_FSPathMakeRes( const UInt8* pathname, + short* res ) + { +#if HAVE_FSREF + OSErr err; + FSRef ref; + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + /* at present, so support for dfont format */ + err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); + if ( noErr == err ) + return err; + + /* fallback to original resource-fork font */ + *res = FSOpenResFile( &ref, fsRdPerm ); + err = ResError(); +#else + OSErr err; + FSSpec spec; + + if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + /* at present, so support for dfont format without FSRef */ + /* (see above), try original resource-fork font */ + *res = FSpOpenResFile( &spec, fsRdPerm ); + err = ResError(); +#endif + return err; + } + + + /* Return the file type for given pathname */ + static OSType + get_file_type_from_path( const UInt8* pathname ) + { +#if HAVE_FSREF + FSRef ref; + FSCatalogInfo info; + + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return ( OSType ) 0; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, + NULL, NULL, NULL ) ) + return ( OSType ) 0; + + return ((FInfo *) (info.finderInfo))->fdType; +#else + FSSpec spec; FInfo finfo; - if ( FSpGetFInfo( spec, &finfo ) != noErr ) - return 0; /* file might not exist */ + if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) + return ( OSType ) 0; + + if ( noErr != FSpGetFInfo( &spec, &finfo ) ) + return ( OSType ) 0; return finfo.fdType; +#endif } @@ -210,61 +501,6 @@ } - /* Given a file reference, answer its location as a vRefNum - and a dirID. */ - static FT_Error - get_file_location( short ref_num, - short* v_ref_num, - long* dir_id, - unsigned char* file_name ) - { - FCBPBRec pb; - OSErr error; - - - pb.ioNamePtr = file_name; - pb.ioVRefNum = 0; - pb.ioRefNum = ref_num; - pb.ioFCBIndx = 0; - - error = PBGetFCBInfoSync( &pb ); - if ( error == noErr ) - { - *v_ref_num = pb.ioFCBVRefNum; - *dir_id = pb.ioFCBParID; - } - return error; - } - - - /* Make a file spec for an LWFN file from a FOND resource and - a file name. */ - static FT_Error - make_lwfn_spec( Handle fond, - const unsigned char* file_name, - FSSpec* spec ) - { - FT_Error error; - short ref_num, v_ref_num; - long dir_id; - Str255 fond_file_name; - - - ref_num = HomeResFile( fond ); - - error = ResError(); - if ( !error ) - error = get_file_location( ref_num, &v_ref_num, - &dir_id, fond_file_name ); - if ( !error ) - error = FSMakeFSSpec( v_ref_num, dir_id, file_name, spec ); - - return error; - } - - - /* count_faces_sfnt() counts both of sfnt & NFNT refered by FOND */ - /* count_faces_scalable() counts sfnt only refered by FOND */ static short count_faces_sfnt( char* fond_data ) { @@ -408,24 +644,113 @@ } - static short - count_faces( Handle fond ) + static FT_Error + lookup_lwfn_by_fond( const UInt8* path_fond, + const StringPtr base_lwfn, + UInt8* path_lwfn, + int path_size ) { - short sfnt_id, have_sfnt, have_lwfn = 0; - Str255 lwfn_file_name; - FSSpec lwfn_spec; +#if HAVE_FSREF + FSRef ref, par_ref; + int dirname_len; + /* pathname for FSRef can be various format: HFS, HFS+ and POSIX. */ + /* we should not extract parent directory by string manipulation */ + + if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) ) + return FT_Err_Invalid_Argument; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, &par_ref ) ) + return FT_Err_Invalid_Argument; + + if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) ) + return FT_Err_Invalid_Argument; + + if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) + return FT_Err_Invalid_Argument; + + /* now we have absolute dirname in lookup_path */ + if ( path_lwfn[0] == '/' ) + ft_strcat( (char *)path_lwfn, "/" ); + else + ft_strcat( (char *)path_lwfn, ":" ); + + dirname_len = ft_strlen( (char *)path_lwfn ); + ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 ); + path_lwfn[ dirname_len + base_lwfn[0] ] = '\0'; + + + if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, NULL ) ) + return FT_Err_Cannot_Open_Resource; + + return FT_Err_Ok; +#else + int i; + FSSpec spec; + + + /* pathname for FSSpec is always HFS format */ + if ( ft_strlen( (char *)path_fond ) > path_size ) + return FT_Err_Invalid_Argument; + + ft_strcpy( (char *)path_lwfn, (char *)path_fond ); + + i = ft_strlen( (char *)path_lwfn ) - 1; + while ( i > 0 && ':' != path_lwfn[i] ) + i-- ; + + if ( i + 1 + base_lwfn[0] > path_size ) + return FT_Err_Invalid_Argument; + + if ( ':' == path_lwfn[i] ) + { + ft_strcpy( (char *)path_lwfn + i + 1, (char *)base_lwfn + 1 ); + path_lwfn[ i + 1 + base_lwfn[0] ] = '\0'; + } + else + { + ft_strcpy( (char *)path_lwfn, (char *)base_lwfn + 1 ); + path_lwfn[ base_lwfn[0] ] = '\0'; + } + + + if ( noErr != FT_FSPathMakeSpec( path_lwfn, &spec, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + return FT_Err_Ok; +#endif + } + + + static short + count_faces( Handle fond, + const UInt8* pathname ) + { + short sfnt_id; + short have_sfnt, have_lwfn; + Str255 lwfn_file_name; + UInt8 buff[HFS_MAXPATHLEN]; + FT_Error err; + + + have_sfnt = have_lwfn = 0; + HLock( fond ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); HUnlock( fond ); if ( lwfn_file_name[0] ) { - if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) - have_lwfn = 1; /* yeah, we got one! */ - else - have_lwfn = 0; /* no LWFN file found */ + err = lookup_lwfn_by_fond( pathname, lwfn_file_name, + buff, sizeof( buff ) ); + if ( FT_Err_Ok == err ) + have_lwfn = 1; } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) @@ -442,7 +767,7 @@ of the same type together. */ static FT_Error read_lwfn( FT_Memory memory, - short res_ref, + short res, FT_Byte** pfb_data, FT_ULong* size ) { @@ -455,7 +780,7 @@ char code, last_code; - UseResFile( res_ref ); + UseResFile( res ); /* First pass: load all POST resources, and determine the size of */ /* the output buffer. */ @@ -541,7 +866,7 @@ *size = total_size; Error: - CloseResFile( res_ref ); + CloseResFile( res ); return error; } @@ -568,7 +893,7 @@ FT_Byte* base, FT_ULong size, FT_Stream_CloseFunc close, - FT_Stream *astream ) + FT_Stream* astream ) { FT_Error error; FT_Memory memory; @@ -604,7 +929,7 @@ FT_ULong size, FT_Long face_index, char* driver_name, - FT_Face *aface ) + FT_Face* aface ) { FT_Open_Args args; FT_Error error; @@ -647,59 +972,26 @@ } - static FT_Error - OpenFileAsResource( const FSSpec* spec, - short *p_res_ref ) - { - FT_Error error; - -#if !TARGET_API_MAC_OS8 - - FSRef hostContainerRef; - - - error = FSpMakeFSRef( spec, &hostContainerRef ); - if ( error == noErr ) - error = FSOpenResourceFile( &hostContainerRef, - 0, NULL, fsRdPerm, p_res_ref ); - - /* If the above fails, then it is probably not a resource file */ - /* However, it has been reported that FSOpenResourceFile() sometimes */ - /* fails on some old resource-fork files, which FSpOpenResFile() can */ - /* open. So, just try again with FSpOpenResFile() and see what */ - /* happens :-) */ - - if ( error != noErr ) - -#endif /* !TARGET_API_MAC_OS8 */ - - { - *p_res_ref = FSpOpenResFile( spec, fsRdPerm ); - error = ResError(); - } - - return error ? FT_Err_Cannot_Open_Resource : FT_Err_Ok; - } - - /* Create a new FT_Face from a file spec to an LWFN file. */ static FT_Error FT_New_Face_From_LWFN( FT_Library library, - const FSSpec* lwfn_spec, + const UInt8* pathname, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { FT_Byte* pfb_data; FT_ULong pfb_size; FT_Error error; - short res_ref; + short res; - error = OpenFileAsResource( lwfn_spec, &res_ref ); - if ( error ) - return error; + if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) + return FT_Err_Cannot_Open_Resource; - error = read_lwfn( library->memory, res_ref, &pfb_data, &pfb_size ); + pfb_data = NULL; + pfb_size = 0; + error = read_lwfn( library->memory, res, &pfb_data, &pfb_size ); + CloseResFile( res ); /* PFB is already loaded, useless anymore */ if ( error ) return error; @@ -717,7 +1009,7 @@ FT_New_Face_From_SFNT( FT_Library library, short sfnt_id, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { Handle sfnt = NULL; FT_Byte* sfnt_data; @@ -760,17 +1052,22 @@ /* Create a new FT_Face from a file spec to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, - short res_ref, + const UInt8* pathname, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { FT_Error error = FT_Err_Cannot_Open_Resource; - short res_index; + short res_ref, res_index; Handle fond; short num_faces_in_res, num_faces_in_fond; + if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) + return FT_Err_Cannot_Open_Resource; + UseResFile( res_ref ); + if ( ResError() ) + return FT_Err_Cannot_Open_Resource; num_faces_in_res = 0; for ( res_index = 1; ; ++res_index ) @@ -779,7 +1076,7 @@ if ( ResError() ) break; - num_faces_in_fond = count_faces( fond ); + num_faces_in_fond = count_faces( fond, pathname ); num_faces_in_res += num_faces_in_fond; if ( 0 <= face_index && face_index < num_faces_in_fond && error ) @@ -801,14 +1098,16 @@ FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { short sfnt_id, have_sfnt, have_lwfn = 0; - Str255 lwfn_file_name; short fond_id; OSType fond_type; Str255 fond_name; - FSSpec lwfn_spec; + Str255 lwfn_file_name; + UInt8 path_lwfn[HFS_MAXPATHLEN]; + OSErr err; + FT_Error error; GetResInfo( fond, &fond_id, &fond_type, fond_name ); @@ -821,148 +1120,108 @@ if ( lwfn_file_name[0] ) { - if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) - have_lwfn = 1; /* yeah, we got one! */ - else - have_lwfn = 0; /* no LWFN file found */ - } + short res; + + + res = HomeResFile( fond ); + if ( noErr != ResError() ) + goto found_no_lwfn_file; + +#if HAVE_FSREF + { + UInt8 path_fond[HFS_MAXPATHLEN]; + FSRef ref; + + err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum, + NULL, NULL, NULL, &ref, NULL ); + if ( noErr != err ) + goto found_no_lwfn_file; + + err = FSRefMakePath( &ref, path_fond, sizeof( path_fond ) ); + if ( noErr != err ) + goto found_no_lwfn_file; + + error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, + path_lwfn, sizeof( path_lwfn ) ); + if ( FT_Err_Ok == error ) + have_lwfn = 1; + } +#elif HAVE_FSSPEC + { + UInt8 path_fond[HFS_MAXPATHLEN]; + FCBPBRec pb; + Str255 fond_file_name; + FSSpec spec; + + + FT_MEM_SET( &spec, 0, sizeof( FSSpec ) ); + FT_MEM_SET( &pb, 0, sizeof( FCBPBRec ) ); + pb.ioNamePtr = fond_file_name; + pb.ioVRefNum = 0; + pb.ioRefNum = res; + pb.ioFCBIndx = 0; + + err = PBGetFCBInfoSync( &pb ); + if ( noErr != err ) + goto found_no_lwfn_file; + + err = FSMakeFSSpec( pb.ioFCBVRefNum, pb.ioFCBParID, fond_file_name, &spec ); + if ( noErr != err ) + goto found_no_lwfn_file; + + err = FT_FSpMakePath( &spec, path_fond, sizeof( path_fond ) ); + if ( noErr != err ) + goto found_no_lwfn_file; + + error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, + path_lwfn, sizeof( path_lwfn ) ); + if ( FT_Err_Ok == error ) + have_lwfn = 1; + } +#endif + } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) return FT_New_Face_From_LWFN( library, - &lwfn_spec, + path_lwfn, face_index, aface ); - else if ( have_sfnt ) + +found_no_lwfn_file: + if ( have_sfnt ) return FT_New_Face_From_SFNT( library, sfnt_id, face_index, aface ); - return FT_Err_Unknown_File_Format; - } - - - /* documentation is in ftmac.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( const char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) - { - OptionBits options = kFMUseGlobalScopeOption; - - FMFontFamilyIterator famIter; - OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, - options, - &famIter ); - FMFont the_font = 0; - FMFontFamily family = 0; - - - *face_index = 0; - while ( status == 0 && !the_font ) - { - status = FMGetNextFontFamily( &famIter, &family ); - if ( status == 0 ) - { - int stat2; - FMFontFamilyInstanceIterator instIter; - Str255 famNameStr; - char famName[256]; - - - /* get the family name */ - FMGetFontFamilyName( family, famNameStr ); - CopyPascalStringToC( famNameStr, famName ); - - /* iterate through the styles */ - FMCreateFontFamilyInstanceIterator( family, &instIter ); - - *face_index = 0; - stat2 = 0; - while ( stat2 == 0 && !the_font ) - { - FMFontStyle style; - FMFontSize size; - FMFont font; - - - stat2 = FMGetNextFontFamilyInstance( &instIter, &font, - &style, &size ); - if ( stat2 == 0 && size == 0 ) - { - char fullName[256]; - - - /* build up a complete face name */ - ft_strcpy( fullName, famName ); - if ( style & bold ) - strcat( fullName, " Bold" ); - if ( style & italic ) - strcat( fullName, " Italic" ); - - /* compare with the name we are looking for */ - if ( ft_strcmp( fullName, fontName ) == 0 ) - { - /* found it! */ - the_font = font; - } - else - ++(*face_index); - } - } - - FMDisposeFontFamilyInstanceIterator( &instIter ); - } - } - - FMDisposeFontFamilyIterator( &famIter ); - - if ( the_font ) - { - FMGetFontContainer( the_font, pathSpec ); - return FT_Err_Ok; - } - else return FT_Err_Unknown_File_Format; } - /* Common function to load a new FT_Face from a resource file. */ + /* Common function to load a new FT_Face from a resource file. */ static FT_Error FT_New_Face_From_Resource( FT_Library library, - const FSSpec *spec, + const UInt8* pathname, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { OSType file_type; - short res_ref; FT_Error error; - if ( OpenFileAsResource( spec, &res_ref ) == FT_Err_Ok ) - { /* LWFN is a (very) specific file format, check for it explicitly */ - - file_type = get_file_type( spec ); + file_type = get_file_type_from_path( pathname ); if ( file_type == 'LWFN' ) - return FT_New_Face_From_LWFN( library, spec, face_index, aface ); + return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); /* Otherwise the file type doesn't matter (there are more than */ /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ /* if it works, fine. */ - error = FT_New_Face_From_Suitcase( library, res_ref, - face_index, aface ); + error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); if ( error == 0 ) return error; - /* else forget about the resource fork and fall through to */ - /* data fork formats */ - - CloseResFile( res_ref ); - } - /* let it fall through to normal loader (.ttf, .otf, etc.); */ /* we signal this by returning no error and no FT_Face */ *aface = NULL; @@ -985,10 +1244,9 @@ FT_New_Face( FT_Library library, const char* pathname, FT_Long face_index, - FT_Face *aface ) + FT_Face* aface ) { FT_Open_Args args; - FSSpec spec; FT_Error error; @@ -996,10 +1254,11 @@ if ( !pathname ) return FT_Err_Invalid_Argument; - if ( file_spec_from_path( pathname, &spec ) ) - return FT_Err_Invalid_Argument; + error = 0; + *aface = NULL; - error = FT_New_Face_From_Resource( library, &spec, face_index, aface ); + /* try resourcefork based font: LWFN, FFIL */ + error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, face_index, aface ); if ( error != 0 || *aface != NULL ) return error; @@ -1010,6 +1269,49 @@ } + /*************************************************************************/ + /* */ + /* */ + /* FT_New_Face_From_FSRef */ + /* */ + /* */ + /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ + /* accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef* ref, + FT_Long face_index, + FT_Face* aface ) + { +#if !HAVE_FSREF + return FT_Err_Unimplemented_Feature; +#else + FT_Error error; + FT_Open_Args args; + OSErr err; + UInt8 pathname[HFS_MAXPATHLEN]; + + + if ( !ref ) + return FT_Err_Invalid_Argument; + + err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); + if ( err ) + error = FT_Err_Cannot_Open_Resource; + + error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; + + /* fallback to datafork font */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); +#endif + } + + /*************************************************************************/ /* */ /* */ @@ -1020,87 +1322,45 @@ /* accepts an FSSpec instead of a path. */ /* */ FT_EXPORT_DEF( FT_Error ) - FT_New_Face_From_FSSpec( FT_Library library, - const FSSpec *spec, - FT_Long face_index, - FT_Face *aface ) - { -#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO - FT_Open_Args args; - FT_Stream stream; - FILE* file; - FT_Memory memory; -#endif + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec* spec, + FT_Long face_index, + FT_Face* aface ) + { +#if HAVE_FSREF + FSRef ref; + + + if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) + return FT_Err_Invalid_Argument; + else + return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); +#elif HAVE_FSSPEC FT_Error error; + FT_Open_Args args; + OSErr err; + UInt8 pathname[HFS_MAXPATHLEN]; - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ if ( !spec ) return FT_Err_Invalid_Argument; - error = FT_New_Face_From_Resource( library, spec, face_index, aface ); - if ( error != 0 || *aface != NULL ) - return error; - - /* let it fall through to normal loader (.ttf, .otf, etc.) */ - -#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO - - /* Codewarrior's C library can open a FILE from a FSSpec */ - /* but we must compile with FSp_fopen.c in addition to */ - /* runtime libraries. */ - - memory = library->memory; - - if ( FT_NEW( stream ) ) - return error; - stream->memory = memory; - - file = FSp_fopen( spec, "rb" ); - if ( !file ) - return FT_Err_Cannot_Open_Resource; - - fseek( file, 0, SEEK_END ); - stream->size = ftell( file ); - fseek( file, 0, SEEK_SET ); - - stream->descriptor.pointer = file; - stream->pathname.pointer = NULL; - stream->pos = 0; - - stream->read = ft_FSp_stream_io; - stream->close = ft_FSp_stream_close; - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - - error = FT_Open_Face( library, &args, face_index, aface ); - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - -#else /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ - - { - FSRef ref; - UInt8 path[256]; - OSErr err; - - - err = FSpMakeFSRef(spec, &ref); - if ( !err ) - { - err = FSRefMakePath( &ref, path, sizeof ( path ) ); - if ( !err ) - error = FT_New_Face( library, (const char*)path, - face_index, aface ); - } + err = FT_FSpMakePath( spec, pathname, sizeof ( pathname ) ); if ( err ) error = FT_Err_Cannot_Open_Resource; - } - -#endif /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ + error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); + if ( error != 0 || *aface != NULL ) return error; + + + /* fallback to datafork font */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); +#else + return FT_Err_Unimplemented_Feature; +#endif }