/* ttf_name.c */ #include #include #include #include "ttffmt.h" /* 各種文字列の定義(スペルミスがあるかもしれない) */ static char *Platform_IDstr[] = { "Apple Unicode", "Macintosh", "ISO", "Microsoft" }; static char *Platform_MSSpecificstr[] = { "Symbol/Undefined character set", "Unicode/UGL character set", "ShiftJIS", "Big5", "PRC", "Wansung", "Johab" }; static char *Platform_MacScriptMgrstr[] = { "Roman", "Japanese", "Chinese", "Korean", "Arabic", "Hebrew", "Greek", "Russian", "RSymbol", "Devanagari", "Gurmukhi", "Gujarati", "Oriya", "Benegali", "Tamil", "Telugu", "Kannada", "Malayalam", "Sinhalese", "Burmese", "Khmer", "Thai", "Laotian", "Georgian", "Armenian", "Maldivian", "Tibetan", "Mongolian", "Geez", "Slavic", "Vietnamese", "Sindhi", "Uninterp" }; static char *Name_MacLanguageIDstr[] = { "English", "French", "German", "Italian", "Dutch", "Swedish", "Spanish", "Danish", "Portuguese", "Norwegian", "Hebrew", "Japanese", "Arabic", "Finnish", "Greek", "Icelandic", "Maltese", "Turkish", "Yugoslavian", "Chinese", "Urdu", "Hindi", "Thai" }; static char *Platform_ISOSpecificstr[] = { "7-bit ASCII", "ISO 10646", "ISO 8859-1" }; static char *Name_IDstr[] = { "Copyright notice", "Font family name", "Font subfamily name", "Unique font identifier", "Full font name", "Version string", "Postscript name", "Trademark" }; /* エンディアン変換 (unsigned short) */ static unsigned short eUW(unsigned short input) { unsigned short output = 0; unsigned short template = 0xff; int i; for (i = 0; i < 2; i++) { output <<= 8; output |= input & template; input >>= 8; } return output; } /* エンディアン変換(unsigned long) */ static unsigned long eUL(unsigned long input) { unsigned long output = 0; unsigned long template = 0xff; int i; for (i = 0; i < 4; i++) { output <<= 8; output |= input & template; input >>= 8; } return output; } /* 任意のテーブルを読み込む(使用後は読み込んだテーブルをfreeすること)*/ static void *load_anytable(FILE *fp, TTF_TBLDIR tbl[], unsigned short numTables, unsigned long target_tag, unsigned long *readsize) { int i; void *buf; for (i = 0; i < numTables; i++) { if (eUL(tbl[i].tag) == target_tag) break; } if (i == numTables) { buf = NULL; goto fin0; } buf = malloc(eUL(tbl[i].length)); if (buf == NULL) { goto fin0; } fseek(fp, eUL(tbl[i].offset), SEEK_SET); fread(buf, eUL(tbl[i].length), 1, fp); if (readsize != NULL) *readsize = eUL(tbl[i].length); fin0: return buf; } /* TrueTypeヘッダの読み込み(使用後は読み込んだテーブルをfreeすること) */ static TTF_TBLDIR *load_TTFHeader(FILE *fp, TTF_HEADER *hdr) { TTF_TBLDIR *tbl; fread(hdr, sizeof(TTF_HEADER), 1, fp); tbl = malloc(sizeof(TTF_TBLDIR) * eUW(hdr->numTables)); if (tbl != NULL) { fread(tbl, sizeof(TTF_TBLDIR), eUW(hdr->numTables), fp); } return tbl; } static void disp_platformID(unsigned short pid, unsigned short spid) { printf("PlatformId : (%d) %s\n", pid, Platform_IDstr[pid]); printf("PlatformSpID : "); switch (pid) { case Platform_Macintosh: printf("(%d) %s\n", spid, Platform_MacScriptMgrstr[spid]); break; case Platform_ISO: printf("(%d) %s\n", spid, Platform_ISOSpecificstr[spid]); break; case Platform_Microsoft: printf("(%d) %s\n", spid, Platform_MSSpecificstr[spid]); break; default: printf("(%d)\n", spid); break; } } /* nameテーブルの内容を表示(一部手抜き) */ void disp_nameTable(NAME_INDEX *tbl) { int i; char *buf; printf("* name table\n"); printf("format : %d\n", eUW(tbl->format)); printf("numTables : %d\n", eUW(tbl->numTables)); printf("offset : %d\n", eUW(tbl->offset)); for (i = 0; i < eUW(tbl->numTables); i++) { disp_platformID(eUW(tbl->NameRecord[i].PlatformId), eUW(tbl->NameRecord[i].PlatformSpecificId)); switch (eUW(tbl->NameRecord[i].PlatformId)) { case Platform_Macintosh: if (eUW(tbl->NameRecord[i].LanguageId) > 22) { printf("LanguageID : (%x) ???\n", eUW(tbl->NameRecord[i].LanguageId)); } else { printf("LanguageID : (%x) %s\n", eUW(tbl->NameRecord[i].LanguageId), Name_MacLanguageIDstr[eUW(tbl->NameRecord[i].LanguageId)]); } break; case Platform_ISO: printf("LanguageID : (%x)\n", eUW(tbl->NameRecord[i].LanguageId)); break; case Platform_Microsoft: printf("LanguageID : (%x)\n", eUW(tbl->NameRecord[i].LanguageId)); break; default: printf("LanguageID : (%x)\n", eUW(tbl->NameRecord[i].LanguageId)); break; } printf("NameId : %s\n", Name_IDstr[eUW(tbl->NameRecord[i].NameId)]); printf("length : %d\n", eUW(tbl->NameRecord[i].length)); printf("offset : %d\n", eUW(tbl->NameRecord[i].offset)); buf = malloc(eUW(tbl->NameRecord[i].length) + 1); if(buf != NULL) { memcpy(buf, ((char *)tbl + eUW(tbl->offset) + eUW(tbl->NameRecord[i].offset)), eUW(tbl->NameRecord[i].length)); buf[eUW(tbl->NameRecord[i].length)] = '\0'; printf("namedata : %s\n", buf); free(buf); } } } /* nameテーブルからnameidで指定した内容を得る(手抜きver.) */ char *get_nameTable(NAME_INDEX *tbl, unsigned short nameid, unsigned short *name_len) { int i; for (i = 0; i < eUW(tbl->numTables); i++) { if (eUW(tbl->NameRecord[i].PlatformId) == Platform_Macintosh && eUW(tbl->NameRecord[i].NameId) == nameid) { if (name_len != NULL) { *name_len = eUW(tbl->NameRecord[i].length); } return ((char *)tbl + eUW(tbl->offset) + eUW(tbl->NameRecord[i].offset)); } } if (name_len != NULL) *name_len = 0; return NULL; } /* メイン */ int main(int argc, char *argv[]) { int i, result; unsigned short len; unsigned long readsize, filesize; char *p; FILE *fp; TTF_HEADER hdr; TTF_TBLDIR *tbl; NAME_INDEX *nametbl; if (argc < 2) { printf("%s [filename]\n", argv[0]); result = EXIT_FAILURE; goto fin0; } fp = fopen(argv[1], "rb"); if (fp == NULL) { printf("file open error\n"); result = EXIT_FAILURE; goto fin0; } fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, 0, SEEK_SET); tbl = load_TTFHeader(fp, &hdr); if (tbl == NULL) { printf("load_TTFHeader failed\n"); result = EXIT_FAILURE; goto fin1; } nametbl = load_anytable(fp, tbl, eUW(hdr.numTables), NAME, &readsize); if (nametbl == NULL) { printf("load_anytable failed\n"); result = EXIT_FAILURE; goto fin2; } // disp_nameTable(nametbl); printf("%-30s %8d ", argv[1], filesize); p = get_nameTable(nametbl, 4, &len); if (p != NULL) { for (i = 0; i < len; i++) printf("%c", p[i]); } printf("\n"); result = EXIT_SUCCESS; /*fin3:*/ free(nametbl); fin2: free(tbl); fin1: fclose(fp); fin0: return result; }