ftifi.c

来自「字体缩放显示」· C语言 代码 · 共 1,682 行 · 第 1/5 页

C
1,682
字号
/* A simple function for comparing strings without case sensitivity. Just   *//* returns zero if strings match, one otherwise. I wrote this because       *//* stricmp is not available in the subsystem run-time library (probably     *//* because it uses locales). toupper() is unfortunately unavailable too.    *//*                                                                          */#define toupper( c ) ( ((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c) )staticint mystricmp(const char *s1, const char *s2) {   int i = 0;   int match = 0;   int len = strlen(s1);   if (len != strlen(s2))      return 1;   /* no match */   while (i < len) {      if (toupper(s1[i]) != toupper(s2[i])) {         match = 1;         break;      }      i++;   }   return match;}/* DBCS enabled strrchr (only looks for SBCS chars though) */staticchar *mystrrchr(char *s, char c) {   int i = 0;   int lastfound = -1;   int len = strlen(s);   while (i <= len) {      if (IsDBCSChar(s[i])) {         i += 2;         continue;      }      if (s[i] == c)         lastfound = i;      i++;   }   if (lastfound == -1)      return NULL;   else      return s + lastfound;}/* -------------------------------------------------------------------------*//* here begin the exported functions                                        *//* -------------------------------------------------------------------------*//****************************************************************************//*                                                                          *//* ConvertFontFile :                                                        *//*                                                                          *//*  Install/delete font file                                                *//*                                                                          */LONG _System ConvertFontFile( PSZ  source,                              PSZ  dest_dir,                              PSZ  new_name ){   PSZ  source_name;   COPY("ConvertFontFile: Src = "); CAT(source);   if (dest_dir) {      CAT(", DestDir = "); CAT(dest_dir);   }   CAT("\r\n"); WRITE;   if (dest_dir && new_name)   {     /* install the font file */     source_name = mystrrchr( source, '\\' );  /* find the last backslash */     if (!source_name)       ERRRET(-1);     source_name++;     strcpy( new_name, source_name );     /* check if file is to be copied onto itself */     if (strncmp(source, dest_dir, strlen(dest_dir)) == 0)        return OK;  /* do nothing */     if ( DosCopy( source, dest_dir, DCPY_EXISTING) )  /* overwrite file */       ERRRET(-1);  /* XXX : we should probably set the error condition */      COPY(" -> Name: "); CAT(new_name); CAT("\r\n"); WRITE;   }   else   {      COPY("Delete file "); CAT(source); CAT("\r\n"); WRITE;      DosDelete(source);  /* fail quietly */   }   return OK;}/****************************************************************************//*                                                                          *//* LoadFontFile :                                                           *//*                                                                          *//*  open a font file and return a handle for it                             *//*                                                                          */HFF _System LoadFontFile( PSZ file_name ){   PSZ           extension;   PFontFile     cur_file;   PListElement  element;   COPY( "LoadFontFile " ); CAT( file_name ); CAT( "\r\n" ); WRITE;   /* first check if the file extension is supported */   extension = mystrrchr( file_name, '.' );  /* find the last dot */   if ( extension == NULL ||        (mystricmp(extension, ".TTF") &&         mystricmp(extension, ".TTC")) )     return ((HFF)-1);   /* now actually open the file */   cur_file = New_FontFile( file_name );   if (cur_file)     return  cur_file->hff;   else     return (HFF)-1;}/****************************************************************************//*                                                                          *//* UnloadFontFile :                                                         *//*                                                                          *//*  destroy resources associated with a given HFF                           *//*                                                                          */LONG _System UnloadFontFile( HFF hff ){   PListElement  element;   COPY("UnloadFontFile: hff = "); CATI((int) hff); CAT("\r\n"); WRITE;   /* look in the live list first */   for (element = liveFiles.head; element; element = element->next)   {     if (element->key == (long)hff)     {       PFontFile  file = (PFontFile)element->data;       if (--file->ref_count > 0)  /* don't really close, return OK */         return 0;       List_Remove( &liveFiles, element );       Done_Element( element );       Done_FontFile( &file );       return 0;     }   }   /* now look in sleep list */   for (element = idleFiles.head; element; element = element->next)   {     if (element->key == (long)hff)     {       PFontFile  file = (PFontFile)element->data;       if (--file->ref_count > 0)  /* don't really close, return OK */         return 0;       List_Remove( &idleFiles, element );       Done_Element( element );       Done_FontFile( &file );       return 0;     }   }   /* didn't find the file */   return -1;}/****************************************************************************//*                                                                          *//* QueryFaces :                                                             *//*                                                                          *//*   Return font metrics. This routine has to do a lot of not very          *//*   hard work.                                                             *//*                                                                          */LONG _System QueryFaces( HFF          hff,                         PIFIMETRICS  pifiMetrics,                         ULONG        cMetricLen,                         ULONG        cFontCount,                         ULONG        cStart){   static TT_Face_Properties   properties;   static IFIMETRICS           ifi;   /* temporary structure */          PFontFace            pface;          TT_Header            *phead;          TT_Horizontal_Header *phhea;          TT_OS2               *pOS2;          TT_Postscript        *ppost;          PIFIMETRICS          pifi2;          PFontFile            file;          LONG                 index, faceIndex, ifiCount = 0;          char                 *name;   COPY( "QueryFaces: hff = " ); CATI( hff );   CAT(  ", cFontCount = " );    CATI( cFontCount );   CAT(  ", cStart = " );        CATI( cStart );   CAT(  ", cMetricLen = " );    CATI( cMetricLen );   CAT( "\r\n");   WRITE;   file = getFontFile(hff);   if (!file)      ERRRET(-1) /* error, invalid handle */   if (cMetricLen == 0) {   /* only number of faces is requested */      #ifdef  FAKE_TNR      /* create an alias for Times New Roman */      pface = &(file->faces[0]);      name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY);      if (!strcmp(name, "Times New Roman")) {         file->flags |= FL_FLAG_FAKE_ROMAN;         return 2;      }      #endif      if (file->flags & FL_FLAG_DBCS_FILE)         return file->numFaces * 2;      else         return file->numFaces;   }   for (faceIndex = 0; faceIndex < file->numFaces; faceIndex++) {      /* get pointer to this face's data */      pface = &(file->faces[faceIndex]);      TT_Get_Face_Properties( pface->face, &properties );      pOS2  = properties.os2;      phead = properties.header;      phhea = properties.horizontal;      ppost = properties.postscript;      /* get font name and check it's really found */      name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY);      if (name == NULL)         ERET1(Fail);      strncpy(ifi.szFamilyname, name, FACESIZE);      ifi.szFamilyname[FACESIZE - 1] = '\0';      name = LookupName(pface->face, TT_NAME_ID_FULL_NAME);      if (name == NULL) {         ERET1(Fail);      }      strncpy(ifi.szFacename, name, FACESIZE);      ifi.szFacename[FACESIZE - 1] = '\0';      /* If Unicode cmap exists in font and it contains more than 1024 glyphs,   */      /* then do not translate from UGL to Unicode and use straight Unicode.     */      /* But first check if it's a DBCS font and handle it properly              */      if ((pface->charMode == TRANSLATE_UGL) && (properties.num_Glyphs > 1024))      {         LONG  specEnc;         BOOL  UDCflag = FALSE;   /* !!!!TODO: UDC support */         specEnc = interfaceSEId(pface->face, UDCflag, PSEID_UNICODE);         switch (specEnc) {            case PSEID_SHIFTJIS:               strcpy( ifi.szGlyphlistName, "PMJPN" );               pface->charMode = TRANSLATE_UNI_SJIS;               break;            case PSEID_BIG5:               strcpy( ifi.szGlyphlistName, "PMCHT" );               pface->charMode = TRANSLATE_UNI_BIG5;               break;            default:  /* do use straight Unicode */               strcpy( ifi.szGlyphlistName, "UNICODE" );               pface->charMode = TRANSLATE_UNICODE; /* straight Unicode */         }#if 0         strcpy( ifi.szGlyphlistName, "PMJPN" );         pface->charMode = TRANSLATE_UNI_SJIS;#endif      }      else         if (pface->charMode == TRANSLATE_SYMBOL)  /* symbol encoding    */            strcpy(ifi.szGlyphlistName, "SYMBOL");      else         if (pface->charMode == TRANSLATE_BIG5)    /* Big5 encoding      */            strcpy(ifi.szGlyphlistName, "PMCHT");      else         if (pface->charMode == TRANSLATE_SJIS)            strcpy(ifi.szGlyphlistName, "PMJPN");  /* ShiftJIS encoding  */      else         strcpy(ifi.szGlyphlistName, "PM383");      ifi.idRegistry         = 0;      ifi.lCapEmHeight       = phead->Units_Per_EM; /* ??? probably correct  */      ifi.lXHeight           = phead->yMax /2;      /* IBM TRUETYPE.DLL does */      ifi.lMaxAscender       = pOS2->usWinAscent;      if ((LONG)pOS2->usWinDescent >= 0)         ifi.lMaxDescender   = pOS2->usWinDescent;      else         ifi.lMaxDescender   = -pOS2->usWinDescent;      ifi.lLowerCaseAscent   = phhea->Ascender;      ifi.lLowerCaseDescent  = -phhea->Descender;      ifi.lInternalLeading   = ifi.lMaxAscender + ifi.lMaxDescender                               - ifi.lCapEmHeight;      ifi.lExternalLeading    = 0;      ifi.lAveCharWidth       = pOS2->xAvgCharWidth;      ifi.lMaxCharInc         = phhea->advance_Width_Max;      ifi.lEmInc              = phead->Units_Per_EM;      ifi.lMaxBaselineExt     = ifi.lMaxAscender + ifi.lMaxDescender;      ifi.fxCharSlope         = -ppost->italicAngle;    /* is this correct ?  */      ifi.fxInlineDir         = 0;      ifi.fxCharRot           = 0;      ifi.usWeightClass       = pOS2->usWeightClass;    /* hopefully OK       */      ifi.usWidthClass        = pOS2->usWidthClass;      ifi.lEmSquareSizeX      = phead->Units_Per_EM;      ifi.lEmSquareSizeY      = phead->Units_Per_EM;    /* probably correct   */      ifi.giFirstChar         = 0;            /* following values should work */      ifi.giLastChar          = 503;          /* either 383 or 503            */      ifi.giDefaultChar       = 0;      ifi.giBreakChar         = 32;      ifi.usNominalPointSize  = 120;   /*    these are simply constants       */      ifi.usMinimumPointSize  = 10;      ifi.usMaximumPointSize  = 10000; /* limit to 1000 pt (like the ATM fonts) */      ifi.fsType              = pOS2->fsType & IFIMETRICS_LICENSED; /* ???    */      ifi.fsDefn              = 

⌨️ 快捷键说明

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