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

📄 ftmac.c

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************//*                                                                         *//*  ftmac.c                                                                *//*                                                                         *//*    Mac FOND support.  Written by just@letterror.com.                    *//*                                                                         *//*  Copyright 1996-2001, 2002, 2003, 2004 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: Although the FOND driver sets face->num_faces field to the    number of available fonts, but the Type 1 driver sets it to 1 anyway.    So this field is currently not reliable, and I don't see a clean way    to  resolve that.  The face_index argument translates to      Get1IndResource( 'FOND', face_index + 1 );    so clients should figure out the resource index of the FOND.    (I'll try to provide some example code for this at some point.)    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().  */#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.                         */#define OS_INLINE  static __inline__#include <Carbon/Carbon.h>#else#include <Resources.h>#include <Fonts.h>#include <Errors.h>#include <Files.h>#include <TextUtils.h>#endif#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#include <FSp_fopen.h>#endif#include FT_MAC_H  /* 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 defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#define STREAM_FILE( stream )  ( (FILE*)stream->descriptor.pointer )  FT_CALLBACK_DEF( void )  ft_FSp_stream_close( FT_Stream  stream )  {    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 )  {    FILE*  file;    file = STREAM_FILE( stream );    fseek( file, offset, SEEK_SET );    return (unsigned long)fread( buffer, 1, count, file );  }#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 !TARGET_API_MAC_OS8 && \    !( defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO )    OSErr  e;    FSRef  ref;    e = FSPathMakeRef( (UInt8 *)pathname, &ref, false /* not a directory */ );    if ( e == noErr )      e = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, spec, NULL );    return ( e == noErr ) ? 0 : (-1);#else    Str255    p_path;    FT_ULong  path_len;    /* 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 );    if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr )      return -1;    else      return 0;#endif  }  /* Return the file type of the file specified by spec. */  static OSType  get_file_type( const FSSpec*  spec )  {    FInfo  finfo;    if ( FSpGetFInfo( spec, &finfo ) != noErr )      return 0;  /* file might not exist */    return finfo.fdType;  }  /* Given a PostScript font name, create the Macintosh LWFN file name. */  static void  create_lwfn_name( char*   ps_name,                    Str255  lwfn_file_name )  {    int       max = 5, count = 0;    FT_Byte*  p = lwfn_file_name;    FT_Byte*  q = (FT_Byte*)ps_name;    lwfn_file_name[0] = 0;    while ( *q )    {      if ( ft_isupper( *q ) )      {        if ( count )          max = 3;        count = 0;      }      if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) )      {        *++p = *q;        lwfn_file_name[0]++;        count++;      }      q++;    }  }  /* 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;  }  static short  count_faces_sfnt( char *fond_data )  {    /* The count is 1 greater than the value in the FOND.  */    /* Isn't that cute? :-)                                */    return 1 + *( (short *)( fond_data + sizeof ( FamRec ) ) );  }  /* Look inside the FOND data, answer whether there should be an SFNT     resource, and answer the name of a possible LWFN Type 1 file.     Thanks to Paul Miller (paulm@profoundeffects.com) for the fix     to load a face OTHER than the first one in the FOND!  */  static void  parse_fond( char*   fond_data,              short*  have_sfnt,              short*  sfnt_id,              Str255  lwfn_file_name,              short   face_index )  {    AsscEntry*  assoc;    AsscEntry*  base_assoc;    FamRec*     fond;    *sfnt_id          = 0;    *have_sfnt        = 0;    lwfn_file_name[0] = 0;    fond       = (FamRec*)fond_data;    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );    base_assoc = assoc;    /* Let's do a little range checking before we get too excited here */    if ( face_index < count_faces_sfnt( fond_data ) )    {      assoc += face_index;        /* add on the face_index! */      /* if the face at this index is not scalable,         fall back to the first one (old behavior) */      if ( assoc->fontSize == 0 )      {        *have_sfnt = 1;        *sfnt_id   = assoc->fontID;      }      else if ( base_assoc->fontSize == 0 )      {        *have_sfnt = 1;        *sfnt_id   = base_assoc->fontID;      }    }    if ( fond->ffStylOff )    {      unsigned char*  p = (unsigned char*)fond_data;      StyleTable*     style;      unsigned short  string_count;      char            ps_name[256];      unsigned char*  names[64];      int             i;      p += fond->ffStylOff;      style = (StyleTable*)p;      p += sizeof ( StyleTable );      string_count = *(unsigned short*)(p);      p += sizeof ( short );      for ( i = 0 ; i < string_count && i < 64; i++ )      {        names[i] = p;        p += names[i][0];        p++;      }      {        size_t  ps_name_len = (size_t)names[0][0];        if ( ps_name_len != 0 )        {          ft_memcpy(ps_name, names[0] + 1, ps_name_len);          ps_name[ps_name_len] = 0;        }        if ( style->indexes[0] > 1 )        {          unsigned char*  suffixes = names[style->indexes[0] - 1];          for ( i = 1; i <= suffixes[0]; i++ )

⌨️ 快捷键说明

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