void
gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
                                            bool aStdFile)
{
    FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(aFLE);
    if (fe) {
        fe->mStandardFace = aStdFile;
        nsAutoString name(aFLE.familyName());
        gfxFontFamily *family = mFontFamilies.GetWeak(name);
        if (!family) {
            family = new FT2FontFamily(name);
            mFontFamilies.Put(name, family);
            if (mBadUnderlineFamilyNames.Contains(name)) {
                family->SetBadUnderlineFamily();
            }
        }
        family->AddFontEntry(fe);

        fe->CheckForBrokenFont(family);
    }
}
예제 #2
0
// 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
    }
}
예제 #3
0
void
gfxFT2FontList::AppendFacesFromFontFile(nsCString& aFileName,
                                        bool aStdFile,
                                        FontNameCache *aCache)
{
    nsCString faceList;
    PRUint32 filesize = 0, timestamp = 0;
    if (aCache) {
        aCache->GetInfoForFile(aFileName, faceList, &timestamp, &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, &timestamp, &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);
        }
    }
}