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

📄 ftmac.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    return noErr;  }#endif /* HAVE_FSSPEC && !HAVE_FSREF */  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, no 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, no support for dfont format without FSRef */    /* (see above), try original resource-fork font          */    *res = FSpOpenResFile( &spec, fsRdPerm );    err  = ResError();#endif /* HAVE_FSREF */    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 ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )      return ( OSType ) 0;    if ( noErr != FSpGetFInfo( &spec, &finfo ) )      return ( OSType ) 0;    return finfo.fdType;#endif /* HAVE_FSREF */  }  /* 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++;    }  }  static short  count_faces_sfnt( char*  fond_data )  {    /* The count is 1 greater than the value in the FOND.  */    /* Isn't that cute? :-)                                */    return EndianS16_BtoN( *( (short*)( fond_data +                                        sizeof ( FamRec ) ) ) ) + 1;  }  static short  count_faces_scalable( char*  fond_data )  {    AsscEntry*  assoc;    FamRec*     fond;    short       i, face, face_all;    fond     = (FamRec*)fond_data;    face_all = EndianS16_BtoN( *( (short *)( fond_data +                                             sizeof ( FamRec ) ) ) ) + 1;    assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );    face     = 0;    for ( i = 0; i < face_all; i++ )    {      if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )        face++;    }    return face;  }  /* 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 ( EndianS16_BtoN( assoc->fontSize ) == 0 )      {        *have_sfnt = 1;        *sfnt_id   = EndianS16_BtoN( assoc->fontID );      }      else if ( base_assoc->fontSize == 0 )      {        *have_sfnt = 1;        *sfnt_id   = EndianS16_BtoN( base_assoc->fontID );      }    }    if ( EndianS32_BtoN( 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 += EndianS32_BtoN( fond->ffStylOff );      style = (StyleTable*)p;      p += sizeof ( StyleTable );      string_count = EndianS16_BtoN( *(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++ )          {            unsigned char*  s;            size_t          j = suffixes[i] - 1;            if ( j < string_count && ( s = names[j] ) != NULL )            {              size_t  s_len = (size_t)s[0];              if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )              {                ft_memcpy( ps_name + ps_name_len, s + 1, s_len );                ps_name_len += s_len;                ps_name[ps_name_len] = 0;              }            }          }        }      }      create_lwfn_name( ps_name, lwfn_file_name );    }  }  static  FT_Error  lookup_lwfn_by_fond( const UInt8*     path_fond,                       const StringPtr  base_lwfn,                       UInt8*           path_lwfn,                       int              path_size )  {#if HAVE_FSREF    FSRef  ref, par_ref;    int    dirname_len;    /* Pathname for FSRef can be in various formats: 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 /* HAVE_FSREF */  }  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;    short     num_faces;    have_sfnt = have_lwfn = 0;    HLock( fond );    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );    if ( lwfn_file_name[0] )    {      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 ) )      num_faces = 1;    else      num_faces = count_faces_scalable( *fond );    HUnlock( fond );    return num_faces;  }  /* Read Type 1 data from the POST resources inside the LWFN file,     return a PFB buffer.  This is somewhat convoluted because the FT2     PFB parser wants the ASCII header as one chunk, and the LWFN     chunks are often not organized that way, so we glue chunks     of the same type together. */  static FT_Error  read_lwfn( FT_Memory  memory,             short      res,             FT_Byte**  pfb_data,             FT_ULong*  size )  {    FT_Error       error = FT_Err_Ok;    short          res_id;    unsigned char  *buffer, *p, *size_p = NULL;    FT_ULong       total_size = 0;    FT_ULong       old_total_size = 0;    FT_ULong       post_size, pfb_chunk_size;    Handle         post_data;    char           code, last_code;    UseResFile( res );    /* First pass: load all POST resources, and determine the size of */    /* the output buffer.                                             */    res_id    = 501;    last_code = -1;    for (;;)    {      post_data = Get1Resource( 'POST', res_id++ );      if ( post_data == NULL )        break;  /* we are done */      code = (*post_data)[0];      if ( code != last_code )      {        if ( code == 5 )          total_size += 2; /* just the end code */        else          total_size += 6; /* code + 4 bytes chunk length */      }      total_size += GetHandleSize( post_data ) - 2;      last_code = code;      /* detect integer overflows */      if ( total_size < old_total_size )      {        error = FT_Err_Array_Too_Large;        goto Error;      }      old_total_size = total_size;    }    if ( FT_ALLOC( buffer, (FT_Long)total_size ) )      goto Error;    /* Second pass: append all POST data to the buffer, add PFB fields. */    /* Glue all consecutive chunks of the same type together.           */    p              = buffer;    res_id         = 501;    last_code      = -1;    pfb_chunk_size = 0;    for (;;)    {      post_data = Get1Resource( 'POST', res_id++ );      if ( post_data == NULL )        break;  /* we are done */      post_size = (FT_ULong)GetHandleSize( post_data ) - 2;      code = (*post_data)[0];      if ( code != last_code )      {        if ( last_code != -1 )        {          /* we are done adding a chunk, fill in the size field */          if ( size_p != NULL )          {            *size_p++ = (FT_Byte)(   pfb_chunk_size         & 0xFF );            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8  ) & 0xFF );            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );          }          pfb_chunk_size = 0;        }        *p++ = 0x80;        if ( code == 5 )          *p++ = 0x03;  /* the end */        else if ( code == 2 )          *p++ = 0x02;  /* binary segment */        else          *p++ = 0x01;  /* ASCII segment */        if ( code != 5 )        {          size_p = p;   /* save for later */          p += 4;       /* make space for size field */        }      }      ft_memcpy( p, *post_data + 2, post_size );      pfb_chunk_size += post_size;      p += post_size;      last_code = code;    }    *pfb_data = buffer;    *size = total_size;  Error:    CloseResFile( res );    return error;  }  /* Finalizer for a memory stream; gets called by FT_Done_Face().     It frees the memory it uses. */  static void  memory_stream_close( FT_Stream  stream )  {    FT_Memory  memory = stream->memory;

⌨️ 快捷键说明

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