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

📄 ftifi.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 5 页
字号:
/*                                                                          *//* Wake_FontFile :                                                          *//*                                                                          *//*   awakes a font file, and reloads important data from disk.              *//*                                                                          */static  int  Wake_FontFile( PFontFile  cur_file ){  static TT_Face              face;  static TT_Glyph             glyph;  static TT_CharMap           cmap;  static TT_Face_Properties   props;  static PFontFace            cur_face;  ULONG                       encoding, i;  if (cur_file->flags & FL_FLAG_LIVE_FACE)    ERRRET(-1);  /* already awoken !! */  /* OK, try to activate the FreeType objects */  error = TT_Open_Face(engine, cur_file->filename, &face);  if (error)  {     COPY( "Error while opening " ); CAT( cur_file->filename );     CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE;     return -1; /* error, can't open file                 */                /* XXX : should set error condition here! */  }  /* Create a glyph container for it */  error = TT_New_Glyph( face, &glyph );  if (error)  {     COPY( "Error while creating container for " ); CAT( cur_file->filename );     CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE;     goto Fail_Face;  }  /*  now get suitable charmap for this font */  encoding = GetCharmap(face);  error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap);  if (error)  {     COPY( "Error: No char map in " ); CAT(  cur_file->filename );     CAT(  "\r\n" ); WRITE;     goto Fail_Glyph;  }  /* Get face properties. Necessary to find out number of fonts for TTCs */  TT_Get_Face_Properties(face, &props);  /* all right, now remove the face from the sleep list */  if (List_Remove( &idleFiles, cur_file->element ))    ERET1( Fail_Glyph );  /* add it to the live list */  if (List_Insert( &liveFiles, cur_file->element ))    ERET1( Fail_Glyph );  /* If the file is a TTC, the first face is now opened successfully.     */  cur_file->numFaces = props.num_Faces;  /* Now allocate memory for face data (one struct for each face in TTC). */  if (cur_file->faces == NULL) {     if (ALLOC(cur_face, sizeof(TFontFace) * cur_file->numFaces))        ERET1( Fail_Glyph );     cur_file->faces  = cur_face;  }  else     cur_face = cur_file->faces;  cur_face->face      = face;  /* possibly first face in a TTC */  cur_face->glyph     = glyph;  cur_face->charMap   = cmap;  cur_file->flags    |= FL_FLAG_LIVE_FACE;  if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) {     cur_face->charMode  = encoding >> 16;  /* Unicode, Symbol, ... */     cur_face->em_size   = props.header->Units_Per_EM;     /* if a face contains over 1024 glyphs, assume it's a DBCS font - */     /* VERY probable                                                  */     TT_Get_Face_Properties(cur_face->face, &props);     if (props.num_Glyphs > 1024) {        cur_file->flags |= FL_FLAG_DBCS_FILE;        cur_face->flags |= FC_FLAG_DBCS_FACE;     }     cur_face->widths    = NULL;     cur_face->kernIndices = NULL;  }  /* load kerning directory, if any */  error = TT_Get_Kerning_Directory(face, &(cur_face->directory));  if (error)     cur_face->directory.nTables = 0; /* indicates no kerning in font */  TT_Flush_Face(face);    /* this is important !  */  /* open remaining faces if this font is a TTC */  for (i = 1; i < cur_file->numFaces; i++) {     error = TT_Open_Collection(engine, cur_file->filename,                                i, &face);     if (error)        return -1;   /* TODO: handle bad TTCs more tolerantly */     error = TT_New_Glyph( face, &glyph );     if (error)        ERET1(Fail_Face);     encoding = GetCharmap(face);     error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap);     if (error)        ERET1(Fail_Glyph);     cur_face = &(cur_file->faces[i]);     cur_face->face     = face;     cur_face->glyph    = glyph;     cur_face->charMap  = cmap;     if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) {        cur_face->em_size  = props.header->Units_Per_EM;        cur_face->charMode = encoding >> 16;  /* 0 - Unicode; 1 - Symbol */        if (cur_file->flags & FL_FLAG_DBCS_FILE)           cur_face->flags |= FC_FLAG_DBCS_FACE;        cur_face->widths    = NULL;        cur_face->kernIndices = NULL;     }     /* load kerning directory, if any */     error = TT_Get_Kerning_Directory(face, &(cur_face->directory));     if (error)        cur_face->directory.nTables = 0; /* indicates no kerning in font */  }  cur_file->flags    |= FL_FLAG_ALREADY_USED; /* indicates some fields need no re-init */  error = TT_Flush_Face(face);    /* this is important !           */  if (error) {     COPY("Error flushing face\r\n"); WRITE;  }  return 0;    /* everything is in order, return 0 == success */Fail_Glyph:  /* This line isn't really necessary, because the glyph container */  /* would be destroyed by the following TT_Close_Face anyway. We  */  /* however use it for the sake of orthodoxy                      */  TT_Done_Glyph( glyph );Fail_Face:  TT_Close_Face(face);  /* note that in case of error (e.g. out of memory), the face stays */  /* on the sleeping list                                            */  return -1;}/****************************************************************************//*                                                                          *//* Done_FontFile :                                                          *//*                                                                          *//*   destroys a given font file object. This will also destroy all of its   *//*   live child font sizes (which in turn will destroy the glyph caches).   *//*   This is done for all faces if the file is a collection.                *//*                                                                          *//* WARNING : The font face must be removed from its list by the caller      *//*           before this function is called.                                *//*                                                                          */static  void  Done_FontFile( PFontFile  *file ){  static PListElement  element;  static PListElement  next;         ULONG         i;#if 0    /* this part isn't really used and maybe it never will */  /* destroy its font sizes */  element = (*face)->sizes.head;  while (element)  {    next = element->next;    /* XXX : right now, we simply free the font size object, */    /*       because the instance is destroyed automatically */    /*       by FreeType.                                    */    FREE( element->data );    /* Done_FontSize( (PFontSize)element->data ); - later */    Done_Element( element );    element = next;  }#endif  /* now discard the font face itself */  if ((*file)->flags & FL_FLAG_LIVE_FACE)  {     for (i = 0; i < (*file)->numFaces; i++) {        TT_Done_Glyph( (*file)->faces[i].glyph );        TT_Close_Face( (*file)->faces[i].face );        if ((*file)->faces[i].widths)           FREE((*file)->faces[i].widths);        if ((*file)->faces[i].kernIndices)           FREE((*file)->faces[i].kernIndices);     }  }  FREE( (*file)->faces );  FREE( *file );}/****************************************************************************//*                                                                          *//* New_FontFile :                                                           *//*                                                                          *//*   return the address of the TFontFile corresponding to a given           *//*   HFF. Note that in our implementation, we could simply to a             *//*   typecast like '(PFontFile)hff'. However, for safety reasons, we        *//*   look up the handle in the list.                                        *//*                                                                          */static  PFontFile  New_FontFile( char*  file_name ){   static PListElement  element;   static PFontFile     cur_file;   static TT_CharMap    cmap;   /* first, check if it's already open - in the live list */   for ( element = liveFiles.head; element; element = element->next )   {     cur_file = (PFontFile)element->data;     if (strcmp( cur_file->filename, file_name ) == 0)       goto Exit_Same;   }   /* check in the idle list */   for ( element = idleFiles.head; element; element = element->next )   {     cur_file = (PFontFile)element->data;     if (strcmp( cur_file->filename, file_name ) == 0)       goto Exit_Same;   }   /* OK, this file isn't opened yet. Create a new font face object     */   /* then try to wake it up. This will fail if the file can't be found */   /* or if we lack memory..                                            */   element = New_Element();   if (!element)     ERRRET(NULL);   if ( ALLOC( cur_file, sizeof(TFontFile) ) )     ERET1( Fail_Element );   element->data        = cur_file;   element->key         = (long)cur_file;         /* use the HFF as cur key */   cur_file->element    = element;   cur_file->ref_count  = 1;   cur_file->hff        = (HFF)cur_file;   strcpy( cur_file->filename, file_name);   cur_file->flags      = 0;   cur_file->faces      = NULL;#if 0  /* not used */   cur_face->sizes.head = NULL;   cur_face->sizes.tail = NULL;   cur_face->sizes.count= 0;#endif   /* add new font face to sleep list */   if (List_Insert( &idleFiles, element ))     ERET1( Fail_File );   /* Make enough room in the live list */   if ( liveFiles.count >= max_open_files)   {     COPY( "rolling...\n" ); WRITE;     if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) ))       ERET1( Fail_File );   }   /* wake new font file */   if ( Wake_FontFile( cur_file ) )   {     COPY( "could not open/wake " ); CAT( file_name ); CAT( "\r\n" ); WRITE;     if (List_Remove( &idleFiles, element ))       ERET1( Fail_File );     ERET1( Fail_File );   }   return cur_file;      /* everything is in order */Fail_File:   FREE( cur_file );Fail_Element:   Done_Element( element );   return  NULL;Exit_Same:   cur_file->ref_count++;  /* increment reference count */   COPY( " -> (duplicate) hff = " ); CATI( cur_file->hff );   CAT( "\r\n" ); WRITE;   return cur_file;        /* no sense going on */}/****************************************************************************//*                                                                          *//* getFontFile :                                                            *//*                                                                          *//*   return the address of the TFontFile corresponding to a given           *//*   HFF. If asleep, the file and its face object(s) is awoken.             *//*                                                                          */PFontFile  getFontFile( HFF  hff ){  static PListElement  element;  /* look in the live list first */  element = List_Find( &liveFiles, (long)hff );  if (element)  {    /* move it to the front of the live list - if it isn't already */    if ( liveFiles.head != element )    {      if ( List_Remove( &liveFiles, element ) )        ERRRET( NULL );      if ( List_Insert( &liveFiles, element ) )        ERRRET( NULL );    }

⌨️ 快捷键说明

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