KernFeature::KernFeature ( FT_Face face ) :m_valid ( true ) { FontName = QString ( face->family_name ) + " " + QString ( face->style_name ) ; // qDebug() <<"KF"<<FontName; // QTime t; // t.start(); FT_ULong length = 0; if ( !FT_Load_Sfnt_Table ( face, TTAG_GPOS , 0, NULL, &length ) ) { // qDebug() <<"\t"<<"GPOS table len"<<length; if ( length > 32 ) { GPOSTableRaw.resize ( length ); FT_Load_Sfnt_Table ( face, TTAG_GPOS, 0, reinterpret_cast<FT_Byte*> ( GPOSTableRaw.data() ), &length ); makeCoverage(); } else m_valid = false; GPOSTableRaw.clear(); // coverages.clear(); } else m_valid = false; if ( !m_valid ) pairs.clear(); // qDebug() <<"\t"<<m_valid; // qDebug() <<"\t"<<t.elapsed(); }
PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const { FT_Face freeTypeFace = cairo_ft_scaled_font_lock_face(m_scaledFont); if (!freeTypeFace) return 0; FT_ULong tableSize = 0; // Tag bytes need to be reversed because OT_MAKE_TAG uses big-endian order. uint32_t tag = FT_MAKE_TAG((table & 0xff), (table & 0xff00) >> 8, (table & 0xff0000) >> 16, table >> 24); if (FT_Load_Sfnt_Table(freeTypeFace, tag, 0, 0, &tableSize)) return 0; RefPtr<SharedBuffer> buffer = SharedBuffer::create(tableSize); FT_ULong expectedTableSize = tableSize; if (buffer->size() != tableSize) return 0; FT_Error error = FT_Load_Sfnt_Table(freeTypeFace, tag, 0, reinterpret_cast<FT_Byte*>(const_cast<char*>(buffer->data())), &tableSize); if (error || tableSize != expectedTableSize) return 0; cairo_ft_scaled_font_unlock_face(m_scaledFont); return buffer.release(); }
/** * Checks face, which must be sfnt based, for the subtype. * Possible values: TTF, CFF, OTF */ void getSFontType(FT_Face face, ScFace::FontType & type) { if (FT_IS_SFNT(face)) { FT_ULong ret = 0; bool hasGlyph = ! FT_Load_Sfnt_Table(face, TTAG_glyf, 0, NULL, &ret); hasGlyph &= ret > 0; bool hasCFF = ! FT_Load_Sfnt_Table(face, TTAG_CFF, 0, NULL, &ret); hasCFF &= ret > 0; if (hasGlyph) type = ScFace::TTF; else if (hasCFF) type = ScFace::OTF; // TODO: CID or no } }
bool MinikinFontFreeType::GetTable(uint32_t tag, uint8_t *buf, size_t *size) { FT_ULong ftsize = *size; FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize); if (error != 0) { return false; } *size = ftsize; return true; }
static char* getTable(char* t, FT_Face face) { FT_ULong tag = FT_MAKE_TAG(t[0], t[1], t[2], t[3]); FT_ULong length = 0; int error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &length); if (error) { qDebug("genft: cannot load table LILC"); exit(-3); } FT_Byte* buffer = (FT_Byte*)malloc(length + 1); error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &length); buffer[length] = 0; if (error) { qDebug("genft: cannot load font table LILC"); exit(4); } return (char*)buffer; }
void * XeTeXFontInst::getFontTable(OTTag tag) const { FT_ULong tmpLength = 0; FT_Error error = FT_Load_Sfnt_Table(m_ftFace, tag, 0, NULL, &tmpLength); if (error) return NULL; void* table = xmalloc(tmpLength * sizeof(char)); if (table != NULL) { error = FT_Load_Sfnt_Table(m_ftFace, tag, 0, (FT_Byte*)table, &tmpLength); if (error) { free((void *) table); return NULL; } } return table; }
const void *XeTeXFontInst_FT2::readTable(LETag tag, le_uint32 *length) const { *length = 0; FT_ULong tmpLength = 0; FT_Error err = FT_Load_Sfnt_Table(face, tag, 0, NULL, &tmpLength); if (err != 0) return NULL; void* table = LE_NEW_ARRAY(char, tmpLength); if (table != NULL) { err = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &tmpLength); if (err != 0) { LE_DELETE_ARRAY(table); return NULL; } *length = tmpLength; } return table; }
HB_Error hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB_UInt *len) { FT_Face face = (FT_Face) voidface; FT_ULong ftlen = *len; if (!FT_IS_SFNT(face)) return HB_Err_Invalid_Argument; const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen); *len = ftlen; return (HB_Error) error; }
static hb_blob_t* referenceTable(hb_face_t*, hb_tag_t tag, void *userData) { FT_Face ftFace = reinterpret_cast<FT_Face>(userData); FT_Byte *buffer; FT_ULong length = 0; if (FT_Load_Sfnt_Table(ftFace, tag, 0, NULL, &length)) return NULL; buffer = reinterpret_cast<FT_Byte*>(malloc(length)); if (buffer == NULL) return NULL; if (FT_Load_Sfnt_Table(ftFace, tag, 0, buffer, &length)) { free(buffer); return NULL; } return hb_blob_create((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free); }
static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length) { FT_Face face = (FT_Face)font; FT_ULong ftlen = *length; FT_Error error = 0; if (!FT_IS_SFNT(face)) return HB_Err_Invalid_Argument; error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen); *length = ftlen; return (HB_Error)error; }
const void *FreeTypeFontCache::GetFontTable(uint32 tag, size_t &length) { const FontTable::iterator iter = this->font_tables.Find(tag); if (iter != this->font_tables.End()) { length = iter->second.first; return iter->second.second; } FT_ULong len = 0; FT_Byte *result = NULL; FT_Load_Sfnt_Table(this->face, tag, 0, NULL, &len); if (len > 0) { result = MallocT<FT_Byte>(len); FT_Load_Sfnt_Table(this->face, tag, 0, result, &len); } length = len; this->font_tables.Insert(tag, SmallPair<size_t, const void *>(length, result)); return result; }
static void readGPOSTable(SFFontRef sfFont) { FT_ULong length = 0; FT_Tag tag; FT_Byte *buffer; FT_Error error; tag = FT_MAKE_TAG('G', 'P', 'O', 'S'); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, NULL, &length); if (error) return; buffer = malloc(length); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, buffer, &length); if (!error) { SFReadGPOS(buffer, &sfFont->_gpos); sfFont->_availableFontTables |= itGPOS; } free(buffer); }
static void readCMAPTable(SFFontRef sfFont) { FT_ULong length = 0; FT_Tag tag; FT_Byte *buffer; FT_Error error; tag = FT_MAKE_TAG('c', 'm', 'a', 'p'); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, NULL, &length); if (error) return; buffer = malloc(length); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, buffer, &length); if (!error) { SFReadCMAP(buffer, &sfFont->_cmap, length); sfFont->_availableFontTables |= itCMAP; } free(buffer); }
static void readGSUBTable(SFFontRef sfFont) { FT_ULong length = 0; FT_Tag tag; FT_Byte *buffer; FT_Error error; tag = FT_MAKE_TAG('G', 'S', 'U', 'B'); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, NULL, &length); if (error) return; buffer = malloc(length); error = FT_Load_Sfnt_Table(sfFont->_ftFace, tag, 0, buffer, &length); if (!error) { SFReadGSUB(buffer, &sfFont->_tables->_gsub); sfFont->_tables->_availableTables |= itGSUB; } free(buffer); }
PRBool gfxFT2LockedFace::GetFontTable(PRUint32 aTag, FallibleTArray<PRUint8>& aBuffer) { if (!mFace || !FT_IS_SFNT(mFace)) return PR_FALSE; FT_ULong length = 0; // TRUETYPE_TAG is defined equivalent to FT_MAKE_TAG FT_Error error = FT_Load_Sfnt_Table(mFace, aTag, 0, NULL, &length); if (error != 0) return PR_FALSE; if (NS_UNLIKELY(length > static_cast<FallibleTArray<PRUint8>::size_type>(-1)) || NS_UNLIKELY(!aBuffer.SetLength(length))) return PR_FALSE; error = FT_Load_Sfnt_Table(mFace, aTag, 0, aBuffer.Elements(), &length); if (NS_UNLIKELY(error != 0)) { aBuffer.Clear(); return PR_FALSE; } return PR_TRUE; }
static FT_Error otv_load_table( FT_Face face, FT_Tag tag, FT_Byte* volatile* table, FT_ULong* table_len ) { FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); if ( error == OTV_Err_Table_Missing ) return OTV_Err_Ok; if ( error ) goto Exit; if ( FT_ALLOC( *table, *table_len ) ) goto Exit; error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); Exit: return error; }
bool gfxFT2LockedFace::GetFontTable(uint32_t aTag, FallibleTArray<uint8_t>& aBuffer) { if (!mFace || !FT_IS_SFNT(mFace)) return false; FT_ULong length = 0; // TRUETYPE_TAG is defined equivalent to FT_MAKE_TAG FT_Error error = FT_Load_Sfnt_Table(mFace, aTag, 0, NULL, &length); if (error != 0) return false; if (MOZ_UNLIKELY(length > static_cast<FallibleTArray<uint8_t>::size_type>(-1)) || MOZ_UNLIKELY(!aBuffer.SetLength(length))) return false; error = FT_Load_Sfnt_Table(mFace, aTag, 0, aBuffer.Elements(), &length); if (MOZ_UNLIKELY(error != 0)) { aBuffer.Clear(); return false; } return true; }
static hb_blob_t * _get_table(hb_face_t *, hb_tag_t tag, void *user_data) { FT_Face face = (FT_Face) user_data; FT_ULong length = 0; FT_Byte *table; FT_Error error; hb_blob_t* blob = NULL; error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &length); if (!error) { table = (FT_Byte *) xmalloc(length * sizeof(char)); if (table != NULL) { error = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &length); if (!error) { blob = hb_blob_create((const char*) table, length, HB_MEMORY_MODE_WRITABLE, table, free); } else { free(table); } } } return blob; }
static hb_blob_t * _get_table (hb_tag_t tag, void *user_data) { PangoOTInfo *info = (PangoOTInfo *) user_data; FT_Byte *buffer; FT_ULong length = 0; FT_Error error; error = FT_Load_Sfnt_Table (info->face, tag, 0, NULL, &length); if (error) return hb_blob_create_empty (); buffer = g_malloc (length); if (buffer == NULL) return hb_blob_create_empty (); error = FT_Load_Sfnt_Table (info->face, tag, 0, buffer, &length); if (error) return hb_blob_create_empty (); return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, g_free, buffer); }
static hb_blob_t *reference_table(hb_face_t * face HB_UNUSED, hb_tag_t tag, void *user_data) { FT_Face ft_face; FT_Byte *buffer; FT_ULong length; FT_Error error; ft_face = (FT_Face) user_data; length = 0; /*Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ error = FT_Load_Sfnt_Table(ft_face, tag, 0, NULL, &length); if (error) return NULL; buffer = (FT_Byte *) malloc(length); if (buffer == NULL) return NULL; error = FT_Load_Sfnt_Table(ft_face, tag, 0, buffer, &length); if (error) return NULL; return hb_blob_create((const char *)buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free); }
bool FreeTypeSysFontData::Init(LPCTSTR name, int weight, bool italic) { const CGdippSettings* pSettings = CGdippSettings::GetInstance(); void* pNameFromGDI = NULL; // Windows 偐傜庢摼偟偨 name 僞僌偺撪梕 void* pNameFromFreeType = NULL; // FreeType 偐傜庢摼偟偨 name 僞僌偺撪梕 HFONT hf = NULL; DWORD cbNameTable; DWORD cbFontData; int index; DWORD buf; FT_StreamRec& fsr = m_ftStream; m_name.assign(name); m_hdc = CreateCompatibleDC(NULL); if(m_hdc == NULL) { return false; } // 柤慜埲奜揔摉 if (pSettings->FontSubstitutes() < SETTING_FONTSUBSTITUTE_ALL) { hf = CreateFont( 12, 0, 0, 0, weight, italic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, FONT_MAGIC_NUMBER, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name); } else hf = CreateFont( 12, 0, 0, 0, weight, italic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name); if(hf == NULL){ return false; } m_hOldFont = SelectFont(m_hdc, hf); // 僼僅儞僩僨乕僞偑摼傜傟偦偆偐僠僃僢僋 cbNameTable = ::GetFontData(m_hdc, TVP_TT_TABLE_name, 0, NULL, 0); if(cbNameTable == GDI_ERROR){ goto ERROR_Init; } pNameFromGDI = malloc(cbNameTable); if (!pNameFromGDI) { goto ERROR_Init; } pNameFromFreeType = malloc(cbNameTable); if (!pNameFromFreeType) { goto ERROR_Init; } //- name 僞僌偺撪梕傪儊儌儕偵撉傒崬傓 if(GetFontData(m_hdc, TVP_TT_TABLE_name, 0, pNameFromGDI, cbNameTable) == GDI_ERROR){ goto ERROR_Init; } // 僼僅儞僩僒僀僘庢摼張棟 cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, &buf, 1); if(cbFontData == 1){ // TTC 僼傽僀儖偩偲巚傢傟傞 cbFontData = ::GetFontData(m_hdc, TVP_TT_TABLE_ttcf, 0, NULL, 0); m_isTTC = true; } else{ cbFontData = ::GetFontData(m_hdc, 0, 0, NULL, 0); } if(cbFontData == GDI_ERROR){ // 僄儔乕; GetFontData 偱偼埖偊側偐偭偨 goto ERROR_Init; } if (pSettings->UseMapping()) { HANDLE hmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT | SEC_NOCACHE, 0, cbFontData, NULL); if (!hmap) { goto ERROR_Init; } m_pMapping = MapViewOfFile(hmap, FILE_MAP_ALL_ACCESS, 0, 0, cbFontData); m_dwSize = cbFontData; CloseHandle(hmap); if (m_pMapping) { ::GetFontData(m_hdc, m_isTTC ? TVP_TT_TABLE_ttcf : 0, 0, m_pMapping, cbFontData); } } // FT_StreamRec 偺奺僼傿乕儖僪傪杽傔傞 fsr.base = 0; fsr.size = cbFontData; fsr.pos = 0; fsr.descriptor.pointer = this; fsr.pathname.pointer = NULL; fsr.read = IoFunc; fsr.close = CloseFunc; index = 0; m_locked = true; if(!OpenFaceByIndex(index)){ goto ERROR_Init; } for(;;) { // FreeType 偐傜丄name 僞僌偺僒僀僘傪庢摼偡傞 FT_ULong length = 0; FT_Error err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, NULL, &length); if(err){ goto ERROR_Init; } // FreeType 偐傜摼偨 name 僞僌偺挿偝傪 Windows 偐傜摼偨挿偝偲斾妑 if(length == cbNameTable){ // FreeType 偐傜 name 僞僌傪庢摼 err = FT_Load_Sfnt_Table(m_ftFace, TTAG_name, 0, (unsigned char*)pNameFromFreeType, &length); if(err){ goto ERROR_Init; } // FreeType 偐傜撉傒崬傫偩 name 僞僌偺撪梕偲丄Windows 偐傜撉傒崬傫偩 // name 僞僌偺撪梕傪斾妑偡傞丅 // 堦抳偟偰偄傟偽偦偺 index 偺僼僅儞僩傪巊偆丅 if(!memcmp(pNameFromGDI, pNameFromFreeType, cbNameTable)){ // 堦抳偟偨 // face 偼奐偄偨傑傑 break; // 儖乕僾傪敳偗傞 } } // 堦抳偟側偐偭偨 // 僀儞僨僢僋僗傪堦偮憹傗偟丄偦偺 face 傪奐偔 index ++; if(!OpenFaceByIndex(index)){ // 堦抳偡傞 face 偑側偄傑傑 僀儞僨僢僋僗偑斖埻傪挻偊偨偲尒傜傟傞 // index 傪 0 偵愝掕偟偰偦偺 index 傪奐偒丄儖乕僾傪敳偗傞 index = 0; if(!OpenFaceByIndex(index)){ goto ERROR_Init; } break; } } free(pNameFromGDI); free(pNameFromFreeType); m_locked = false; return true; ERROR_Init: m_locked = false; if (hf) { SelectFont(m_hdc, m_hOldFont); DeleteFont(hf); m_hOldFont = NULL; } free(pNameFromGDI); free(pNameFromFreeType); return false; }
static inline void fetch_GSUB (void) { FT_Error error; int i, j; FT_ULong Script_List_ptr, Feature_List_ptr, Lookup_List_ptr; /* * Fetch GSUB table */ if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, NULL, &GSUB_length))) { #ifdef DEBUG warning("No GSUB data available for vertical glyph presentation forms."); #endif return; } GSUB_table = mymalloc(GSUB_length); if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, GSUB_table, &GSUB_length))) { warning("Cannot load GSUB table (error code = 0x%x).", error); return; } /* * Read GSUB header */ need(10); if (get_ULong() != 0x00010000) oops("GSUB: Bad version."); Script_List_ptr = get_UShort(); Feature_List_ptr = get_UShort(); Lookup_List_ptr = get_UShort(); /* * Read Script_List */ GSUB_ptr = Script_List_ptr; need(2); Script_Count = get_UShort(); #ifdef DEBUG warning("GSUB: Script List with %d entries at 0x%04x.", Script_Count, Script_List_ptr); #endif Script_List = mycalloc (Script_Count, sizeof(Script_Record)); need (6 * Script_Count); for (i = 0; i < Script_Count; i++) { FT_Tag tag = get_ULong(); FT_ULong ptr = Script_List_ptr + get_UShort(); for (j = 0; j < num_Script_Lang; j++) if (tag == Script_Lang[j].script) { Script_List[i].tag = tag; Script_List[i].ltag = Script_Lang[j].language; Script_List[i].ptr = ptr; } } /* * Read Feature_List */ GSUB_ptr = Feature_List_ptr; need(2); Feature_Count = get_UShort(); #ifdef DEBUG warning("GSUB: Feature List with %d entries at 0x%04x.", Feature_Count, Feature_List_ptr); #endif Feature_List = mycalloc (Feature_Count, sizeof(Feature_Record)); need (6 * Feature_Count); for (i = 0; i < Feature_Count; i++) { FT_Tag tag = get_ULong(); FT_ULong ptr = Feature_List_ptr + get_UShort(); if (tag == FEATURE_vert || tag == FEATURE_vrt2) { Feature_List[i].tag = tag; Feature_List[i].ptr = ptr; } } /* * Read Lookup_List */ GSUB_ptr = Lookup_List_ptr; need(2); Lookup_Count = get_UShort(); #ifdef DEBUG warning("GSUB: Lookup List with %d entries at 0x%04x.", Lookup_Count, Lookup_List_ptr); #endif Lookup_List = mycalloc (Lookup_Count, sizeof(Lookup_Record)); need (2 * Lookup_Count); for (i = 0; i < Lookup_Count; i++) Lookup_List[i].ptr = Lookup_List_ptr + get_UShort(); /* * Read Script_List entries */ for (i = 0; i < Script_Count && !has_gsub; i++) fetch_Script (i); }
/** * コンストラクタ * @param fontname フォント名 * @param options オプション */ tNativeFreeTypeFace::tNativeFreeTypeFace(const std::wstring &fontname, tjs_uint32 options) { // フィールドのクリア FaceName = fontname; Face = NULL; memset(&Stream, 0, sizeof(Stream)); DC = NULL; OldFont = NULL; IsTTC = false; unsigned char *name_content = NULL; // Windows から取得した name タグの内容 unsigned char *name_content_ft = NULL; // FreeType から取得した name タグの内容 tjs_int name_content_size; // TrueType ライブラリをフック try { // 指定のフォントを持ったデバイスコンテキストを作成する // TODO: Italic, Bold handling DC = GetDC(0); LOGFONT l; l.lfHeight = -12; l.lfWidth = 0; l.lfEscapement = 0; l.lfOrientation = 0; l.lfWeight = 400; l.lfItalic = FALSE; l.lfUnderline = FALSE; l.lfStrikeOut = FALSE; l.lfCharSet = DEFAULT_CHARSET; l.lfOutPrecision = OUT_DEFAULT_PRECIS; l.lfQuality = DEFAULT_QUALITY; l.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; _tcscpy( l.lfFaceName, fontname.c_str() ); l.lfFaceName[LF_FACESIZE-1] = TJS_W('\0'); HFONT newfont = CreateFontIndirect(&l); OldFont = static_cast<HFONT>(SelectObject(DC, newfont)); // このフォントが GetFontData API で扱えるかどうかを // 'name' タグの内容を取得しようとすることでチェックする // (name タグは GetFontData が扱うような TrueType/OpenType フォントには // 必ず入っている) DWORD result = GetFontData(DC, TVP_TT_TABLE_name, 0, NULL, 0); if(result == GDI_ERROR) { // エラー; GetFontData では扱えなかった TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } //- この時点で result は name タグの内容が入るのに必要なバイト数 name_content_size = result; name_content = new unsigned char [name_content_size]; // メモリを確保 name_content_ft = new unsigned char [name_content_size]; // メモリを確保 //- name タグの内容をメモリに読み込む result = GetFontData(DC, TVP_TT_TABLE_name, 0, name_content, name_content_size); if(result == GDI_ERROR) { // エラー; メモリに読み込むことが出来なかった TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } // フォントファイルのサイズを取得する tjs_int fontsize; //- TTC (True Type Collection) ファイルのチェック //- GetFontData API の仕様では、TTC ファイルに対しては、現在選択されている //- フォントに対する情報しか返さない。しかし FreeType は TTC ファイル全体の //- 情報を必要とする。この場合、GetFontData に 'ttcf' を得るように指示すると //- ファイル全体の情報を得ることが出来る。 //- 参照 : microsoft.public.win32.programmer.gdi GetFontData and TTC fonts unsigned char buf[4]; result = GetFontData(DC, TVP_TT_TABLE_ttcf, 0, &buf, 1); if(result == 1) { // TTC ファイルだと思われる result = GetFontData(DC, TVP_TT_TABLE_ttcf, 0, NULL, 0); IsTTC = true; } else { result = GetFontData(DC, 0, 0, NULL, 0); } if(result == GDI_ERROR) { // エラー; GetFontData では扱えなかった TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } fontsize = result; // FT_StreamRec の各フィールドを埋める FT_StreamRec * fsr = &Stream; fsr->base = 0; fsr->size = fontsize; fsr->pos = 0; fsr->descriptor.pointer = this; fsr->pathname.pointer = NULL; fsr->read = IoFunc; fsr->close = CloseFunc; // FreeType で開く // 試しに 0 番の Face を開く // (この時点で開くことが出来なければ例外を発生させる) int index = 0; if(!OpenFaceByIndex(index)) { TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } // GDIが現在選択しているファイルとFreeTypeがアクセスしているファイルが // 実際に合致しているかどうかを、name タグの一致で見る。 // とくに TTC ファイルの場合は、name タグの一致を見ながら、face のインデッ // クスを一つずつ増やしながら、対象とするフォントを探さなければならない。 while(true) { // FreeType から、name タグのサイズを取得する FT_ULong length = 0; FT_Error err = FT_Load_Sfnt_Table(Face, TTAG_name, 0, NULL, &length); if(err) { TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } // FreeType から得た name タグの長さを Windows から得た長さと比較 if(length == name_content_size) { // FreeType から name タグを取得 err = FT_Load_Sfnt_Table(Face, TTAG_name, 0, name_content_ft, &length); if(err) { TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } // FreeType から読み込んだ name タグの内容と、Windows から読み込んだ // name タグの内容を比較する。 // 一致していればその index のフォントを使う。 if(!memcmp(name_content, name_content_ft, name_content_size)) { // 一致した // face は開いたまま break; // ループを抜ける } } // 一致しなかった // インデックスを一つ増やし、その face を開く index ++; if(!OpenFaceByIndex(index)) { // 一致する face がないまま インデックスが範囲を超えたと見られる // index を 0 に設定してその index を開き、ループを抜ける index = 0; if(!OpenFaceByIndex(index)) { TVPThrowExceptionMessage( TJS_W("Font '%1$s' cannot be used"), fontname ); } break; } } } catch(...) { Clear(); if(name_content) delete [] name_content; if(name_content_ft) delete [] name_content_ft; throw; } delete [] name_content; delete [] name_content_ft; }