// Given the freetype face corresponding to an entryName and face index, // add the face to the available font list and to the faceList string void gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, bool aStdFile, FT_Face aFace, nsCString& aFaceList) { if (FT_Err_Ok != FT_Select_Charmap(aFace, FT_ENCODING_UNICODE)) { // ignore faces that don't support a Unicode charmap return; } // build the font entry name and create an FT2FontEntry, // but do -not- keep a reference to the FT_Face FT2FontEntry* fe = CreateNamedFontEntry(aFace, aEntryName.get(), aIndex); if (fe) { NS_ConvertUTF8toUTF16 name(aFace->family_name); BuildKeyNameFromFontName(name); gfxFontFamily *family = mFontFamilies.GetWeak(name); if (!family) { family = new FT2FontFamily(name); mFontFamilies.Put(name, family); if (mSkipSpaceLookupCheckFamilies.Contains(name)) { family->SetSkipSpaceFeatureCheck(true); } if (mBadUnderlineFamilyNames.Contains(name)) { family->SetBadUnderlineFamily(); } } fe->mStandardFace = aStdFile; family->AddFontEntry(fe); fe->CheckForBrokenFont(family); AppendToFaceList(aFaceList, name, fe); #ifdef PR_LOGGING if (LOG_ENABLED()) { LOG(("(fontinit) added (%s) to family (%s)" " with style: %s weight: %d stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", fe->Weight(), fe->Stretch())); } #endif } }
void gfxFT2FontList::AppendFacesFromFontFile(nsCString& aFileName, bool aStdFile, FontNameCache *aCache) { nsCString faceList; PRUint32 filesize = 0, timestamp = 0; if (aCache) { aCache->GetInfoForFile(aFileName, faceList, ×tamp, &filesize); } struct stat s; int statRetval = stat(aFileName.get(), &s); if (!faceList.IsEmpty() && 0 == statRetval && s.st_mtime == timestamp && s.st_size == filesize) { LOG(("using cached font info for %s", aFileName.get())); AppendFacesFromCachedFaceList(aFileName, aStdFile, faceList); return; } #ifdef XP_WIN FT_Library ftLibrary = gfxWindowsPlatform::GetPlatform()->GetFTLibrary(); #elif defined(ANDROID) FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary(); #endif FT_Face dummy; if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName.get(), -1, &dummy)) { LOG(("reading font info via FreeType for %s", aFileName.get())); nsCString faceList; timestamp = s.st_mtime; filesize = s.st_size; for (FT_Long i = 0; i < dummy->num_faces; i++) { FT_Face face; if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName.get(), i, &face)) { continue; } FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, aFileName.get(), i); if (fe) { NS_ConvertUTF8toUTF16 name(face->family_name); BuildKeyNameFromFontName(name); gfxFontFamily *family = mFontFamilies.GetWeak(name); if (!family) { family = new FT2FontFamily(name); mFontFamilies.Put(name, family); if (mBadUnderlineFamilyNames.Contains(name)) { family->SetBadUnderlineFamily(); } } fe->mStandardFace = aStdFile; family->AddFontEntry(fe); if (family->IsBadUnderlineFamily()) { fe->mIsBadUnderlineFont = true; } // bug 721719 - set the IgnoreGSUB flag on entries for Roboto // because of unwanted on-by-default "ae" ligature. // (See also AppendFaceFromFontListEntry.) if (name.EqualsLiteral("roboto")) { fe->mIgnoreGSUB = true; } // bug 706888 - set the IgnoreGSUB flag on the broken version of // Droid Sans Arabic from certain phones, as identified by the // font checksum in the 'head' table else if (name.EqualsLiteral("droid sans arabic")) { const TT_Header *head = static_cast<const TT_Header*> (FT_Get_Sfnt_Table(face, ft_sfnt_head)); if (head && head->CheckSum_Adjust == 0xe445242) { fe->mIgnoreGSUB = true; } } AppendToFaceList(faceList, name, fe); #ifdef PR_LOGGING if (LOG_ENABLED()) { LOG(("(fontinit) added (%s) to family (%s)" " with style: %s weight: %d stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", fe->Weight(), fe->Stretch())); } #endif } } FT_Done_Face(dummy); if (aCache && 0 == statRetval && !faceList.IsEmpty()) { aCache->CacheFileInfo(aFileName, faceList, timestamp, filesize); } } }
void gfxFT2FontList::AppendFacesFromFontFile(nsCString& aFileName, bool aStdFile, FontNameCache *aCache) { nsCString faceList; uint32_t filesize = 0, timestamp = 0; if (aCache) { aCache->GetInfoForFile(aFileName, faceList, ×tamp, &filesize); } struct stat s; int statRetval = stat(aFileName.get(), &s); if (!faceList.IsEmpty() && 0 == statRetval && s.st_mtime == timestamp && s.st_size == filesize) { LOG(("using cached font info for %s", aFileName.get())); AppendFacesFromCachedFaceList(aFileName, aStdFile, faceList); return; } #ifdef XP_WIN FT_Library ftLibrary = gfxWindowsPlatform::GetPlatform()->GetFTLibrary(); #elif defined(ANDROID) FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary(); #endif FT_Face dummy; if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName.get(), -1, &dummy)) { LOG(("reading font info via FreeType for %s", aFileName.get())); nsCString faceList; timestamp = s.st_mtime; filesize = s.st_size; for (FT_Long i = 0; i < dummy->num_faces; i++) { FT_Face face; if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName.get(), i, &face)) { continue; } if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE)) { FT_Done_Face(face); continue; } FT2FontEntry* fe = CreateNamedFontEntry(face, aFileName.get(), i); if (fe) { NS_ConvertUTF8toUTF16 name(face->family_name); BuildKeyNameFromFontName(name); gfxFontFamily *family = mFontFamilies.GetWeak(name); if (!family) { family = new FT2FontFamily(name); mFontFamilies.Put(name, family); if (mBadUnderlineFamilyNames.Contains(name)) { family->SetBadUnderlineFamily(); } } fe->mStandardFace = aStdFile; family->AddFontEntry(fe); fe->CheckForBrokenFont(family); AppendToFaceList(faceList, name, fe); #ifdef PR_LOGGING if (LOG_ENABLED()) { LOG(("(fontinit) added (%s) to family (%s)" " with style: %s weight: %d stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", fe->Weight(), fe->Stretch())); } #endif } } FT_Done_Face(dummy); if (aCache && 0 == statRetval && !faceList.IsEmpty()) { aCache->CacheFileInfo(aFileName, faceList, timestamp, filesize); } } }