从ttf原始文件解析出字体名称时遇到的字节序的问题是big endian

本文介绍了一个用于从TrueType字体文件中提取字体名称的C/C++函数实现。该函数能够处理Big Endian编码,并从字体文件中正确读取中文和英文名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上搜到的代码转换不过来,因为读出来的信息是big endian的unicode类型。高低字节是颠倒的,必须首先转换过来。

LPCSTR GetFontNameFromFile(LPSTR lpszFilePath, LPSTR chinesename, LPSTR englishname)
{

 USES_CONVERSION;
 FILE* f;
 static char csRetVal[128];

 memset(csRetVal, 0, sizeof(csRetVal));
 int nPos;
 //char tmp[256];
 //char tmp2[256];

 strcpy(chinesename, "");
 strcpy(englishname, "");


 f = fopen(lpszFilePath, "rb");

 if (f == NULL)
 {
  return csRetVal;
 }

 TT_OFFSET_TABLE ttOffsetTable;

 fread(&ttOffsetTable, sizeof(TT_OFFSET_TABLE),1,f);
 ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
 ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
 ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);

 //checkisthisisatruetypefontandtheversionis1.0
 if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
 {
  fclose(f);
  return csRetVal;
 }

 TT_TABLE_DIRECTORY tblDir;
 BOOL bFound = FALSE;
 char csTemp[64];



 for (int i = 0; i<ttOffsetTable.uNumOfTables; i++)
 {
  fread(&tblDir, sizeof(TT_TABLE_DIRECTORY),1,f);
  memset(csTemp, 0, sizeof(csTemp));
  strncpy(csTemp,tblDir.szTag, 4);

  if (stricmp(csTemp,"name") == 0)
  {
   bFound = TRUE;
   tblDir.uLength = SWAPLONG(tblDir.uLength);
   tblDir.uOffset = SWAPLONG(tblDir.uOffset);
   break;
  }
 }

 if (bFound)
 {
  fseek(f, tblDir.uOffset, SEEK_SET);

  TT_NAME_TABLE_HEADER ttNTHeader;
  fread(&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), 1, f);
  ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
  ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
  TT_NAME_RECORD ttRecord;
  bFound = FALSE;

  for (int i = 0; i < ttNTHeader.uNRCount; i++)
  {
   fread(&ttRecord, sizeof(TT_NAME_RECORD), 1, f);
   ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
   if ((ttRecord.uNameID == 1) && (ttRecord.uEncodingID == 256))
   {
    ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
    ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
    nPos = ftell(f);
    fseek(f, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, SEEK_SET);
    if (ttRecord.uStringLength > 0)
    {
     memset(csRetVal, 0, sizeof(csRetVal));
     fread(csRetVal, 1, ttRecord.uStringLength, f);

      {
       for (int i = 1; i < ttRecord.uStringLength; i += 2)
       {
        swap(csRetVal[i], csRetVal[i-1]);
       }

//中文名

       if (ttRecord.uLanguageID == 1032)
       {
        strcpy(chinesename, W2A((LPWSTR)csRetVal));
       }
       else if (ttRecord.uLanguageID == 2308)
       {

//英文名
        strcpy(englishname, W2A((LPWSTR)csRetVal));
       }
      }

    }
    fseek(f, nPos, SEEK_SET);
   }
  }
 }

 fclose(f);
 return csRetVal;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值