⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftmac.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************//*                                                                         *//*  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, 2006, 2007 by             *//*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     *//*                                                                         *//*  This file is part of the FreeType project, and may only be used,       *//*  modified, and distributed under the terms of the FreeType project      *//*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//***************************************************************************/  /*    Notes    Mac suitcase files can (and often do!) contain multiple fonts.  To    support this I use the face_index argument of FT_(Open|New)_Face()    functions, and pretend the suitcase file is a collection.    Warning: fbit and NFNT bitmap resources are not supported yet.  In old    sfnt fonts, bitmap glyph data for each size is stored in each `NFNT'    resources instead of the `bdat' table in the sfnt resource.  Therefore,    face->num_fixed_sizes is set to 0, because bitmap data in `NFNT'    resource is unavailable at present.    The Mac FOND support works roughly like this:    - Check whether the offered stream points to a Mac suitcase file.  This      is done by checking the file type: it has to be 'FFIL' or 'tfil'.  The      stream that gets passed to our init_face() routine is a stdio stream,      which isn't usable for us, since the FOND resources live in the      resource fork.  So we just grab the stream->pathname field.    - Read the FOND resource into memory, then check whether there is a      TrueType font and/or(!) a Type 1 font available.    - If there is a Type 1 font available (as a separate `LWFN' file), read      its data into memory, massage it slightly so it becomes PFB data, wrap      it into a memory stream, load the Type 1 driver and delegate the rest      of the work to it by calling FT_Open_Face().  (XXX TODO: after this      has been done, the kerning data from the FOND resource should be      appended to the face: On the Mac there are usually no AFM files      available.  However, this is tricky since we need to map Mac char      codes to ps glyph names to glyph ID's...)    - If there is a TrueType font (an `sfnt' resource), read it into memory,      wrap it into a memory stream, load the TrueType driver and delegate      the rest of the work to it, by calling FT_Open_Face().    - Some suitcase fonts (notably Onyx) might point the `LWFN' file to      itself, even though it doesn't contains `POST' resources.  To handle      this special case without opening the file an extra time, we just      ignore errors from the `LWFN' and fallback to the `sfnt' if both are      available.  */#include <ft2build.h>#include FT_FREETYPE_H#include FT_INTERNAL_STREAM_H#if defined( __GNUC__ ) || defined( __IBMC__ )  /* This is for Mac OS X.  Without redefinition, OS_INLINE */  /* expands to `static inline' which doesn't survive the   */  /* -ansi compilation flag of GCC.                         */#if !HAVE_ANSI_OS_INLINE#undef  OS_INLINE#define OS_INLINE   static __inline__#endif#include <Carbon/Carbon.h>#else#include <Resources.h>#include <Fonts.h>#include <Endian.h>#include <Errors.h>#include <Files.h>#include <TextUtils.h>#endif#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#include <FSp_fopen.h>#endif#define FT_DEPRECATED_ATTRIBUTE#include FT_MAC_H#undef FT_GetFile_From_Mac_Name#undef FT_GetFile_From_Mac_ATS_Name#undef FT_New_Face_From_FSSpec  /* FSSpec functions are deprecated 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 deprecated 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). */#ifndef PREFER_LWFN#define PREFER_LWFN  1#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 )              ft_strcat( fullName, " Bold" );            if ( style & italic )              ft_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 /* HAVE_QUICKDRAW_CARBON */#if HAVE_ATS  /* Private function.                                         */  /* The FSSpec type has been discouraged for a long time,     */  /* but for some reason, there is no FSRef version of         */  /* ATSFontGetFileSpecification(), so we made our own.        */  /* Apple will provide one eventually.                        */  static OSStatus  FT_ATSFontGetFileReference( ATSFontRef  ats_font_id,                              FSRef*      ats_font_ref )  {    OSStatus  err;    FSSpec    spec;    err = ATSFontGetFileSpecification( ats_font_id, &spec );    if ( noErr == err )      err = FSpMakeFSRef( &spec, ats_font_ref );    return err;  }  static FT_Error  FT_GetFileRef_From_Mac_ATS_Name( const char*  fontName,                                   FSRef*       ats_font_ref,                                   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 );    CFRelease( cf_fontName );    if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )      return FT_Err_Unknown_File_Format;    if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) )      return FT_Err_Unknown_File_Format;    /* face_index calculation by searching preceding fontIDs */    /* with same FSRef                                       */    {      ATSFontRef  id2 = ats_font_id - 1;      FSRef       ref2;      while ( id2 > 0 )      {        if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) )          break;        if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) )          break;        id2--;      }      *face_index = ats_font_id - ( id2 + 1 );    }    return FT_Err_Ok;  }#endif#if !HAVE_ATS  FT_EXPORT_DEF( FT_Error )  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,                                    UInt8*       path,                                    UInt32       maxPathSize,                                    FT_Long*     face_index )  {    return FT_Err_Unimplemented_Feature;  }#else  FT_EXPORT_DEF( FT_Error )  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,                                    UInt8*       path,                                    UInt32       maxPathSize,                                    FT_Long*     face_index )  {    FSRef     ref;    FT_Error  err;    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );    if ( FT_Err_Ok != err )      return err;    if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) )      return FT_Err_Unknown_File_Format;    return FT_Err_Ok;  }#endif /* HAVE_ATS */#if !HAVE_FSSPEC  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  /* This function is deprecated because FSSpec is deprecated in Mac OS X. */  FT_EXPORT_DEF( FT_Error )  FT_GetFile_From_Mac_ATS_Name( const char*  fontName,                                FSSpec*      pathSpec,                                FT_Long*     face_index )  {    FSRef     ref;    FT_Error  err;    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );    if ( FT_Err_Ok != err )      return err;    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL,                                    pathSpec, NULL ) )      return FT_Err_Unknown_File_Format;    return FT_Err_Ok;  }#endif#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#define STREAM_FILE( stream )  ( (FT_FILE*)stream->descriptor.pointer )  FT_CALLBACK_DEF( void )  ft_FSp_stream_close( FT_Stream  stream )  {    ft_fclose( STREAM_FILE( stream ) );    stream->descriptor.pointer = NULL;    stream->size               = 0;    stream->base               = 0;  }  FT_CALLBACK_DEF( unsigned long )  ft_FSp_stream_io( FT_Stream       stream,                    unsigned long   offset,                    unsigned char*  buffer,                    unsigned long   count )  {    FT_FILE*  file;    file = STREAM_FILE( stream );    ft_fseek( file, offset, SEEK_SET );    return (unsigned long)ft_fread( buffer, 1, count, file );  }#endif  /* __MWERKS__ && !TARGET_RT_MAC_MACHO */#if HAVE_FSSPEC && !HAVE_FSREF  static OSErr  FT_FSPathMakeSpec( const UInt8*  pathname,                     FSSpec*       spec_p,                     Boolean       isDirectory )  {    const char  *p, *q;    short       vRefNum;    long        dirID;    Str255      nodeName;    OSErr       err;    p = q = (const char *)pathname;    dirID   = 0;    vRefNum = 0;    while ( 1 )    {      int  len = ft_strlen( p );      if ( len > 255 )        len = 255;      q = p + len;      if ( q == p )        return 0;      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;      ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName );      err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p );      if ( err || '\0' == *q )        return err;      vRefNum = spec_p->vRefNum;      dirID   = spec_p->parID;      p = q;    }  }  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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -