diff options
-rw-r--r-- | gfx/thebes/gfxFT2Utils.cpp | 30 | ||||
-rw-r--r-- | gfx/thebes/gfxFcPlatformFontList.cpp | 29 | ||||
-rw-r--r-- | gfx/thebes/gfxFcPlatformFontList.h | 4 |
3 files changed, 49 insertions, 14 deletions
diff --git a/gfx/thebes/gfxFT2Utils.cpp b/gfx/thebes/gfxFT2Utils.cpp index a544a8cb4..77e1c9632 100644 --- a/gfx/thebes/gfxFT2Utils.cpp +++ b/gfx/thebes/gfxFT2Utils.cpp @@ -10,6 +10,10 @@ #include FT_TRUETYPE_TABLES_H #include <algorithm> +#ifndef FT_FACE_FLAG_COLOR +#define FT_FACE_FLAG_COLOR ( 1L << 14 ) +#endif + #ifdef HAVE_FONTCONFIG_FCFREETYPE_H #include <fontconfig/fcfreetype.h> #endif @@ -53,7 +57,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics, if (MOZ_UNLIKELY(!mFace)) { // No face. This unfortunate situation might happen if the font // file is (re)moved at the wrong time. - const gfxFloat emHeight = mGfxFont->GetStyle()->size; + const gfxFloat emHeight = mGfxFont->GetAdjustedSize(); aMetrics->emHeight = emHeight; aMetrics->maxAscent = aMetrics->emAscent = 0.8 * emHeight; aMetrics->maxDescent = aMetrics->emDescent = 0.2 * emHeight; @@ -80,6 +84,11 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics, const FT_Size_Metrics& ftMetrics = mFace->size->metrics; + aMetrics->maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender); + aMetrics->maxDescent = -FLOAT_FROM_26_6(ftMetrics.descender); + aMetrics->maxAdvance = FLOAT_FROM_26_6(ftMetrics.max_advance); + gfxFloat lineHeight = FLOAT_FROM_26_6(ftMetrics.height); + gfxFloat emHeight; // Scale for vertical design metric conversion: pixels per design unit. // If this remains at 0.0, we can't use metrics from OS/2 etc. @@ -103,6 +112,19 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics, const TT_Header* head = static_cast<TT_Header*>(FT_Get_Sfnt_Table(mFace, ft_sfnt_head)); if (head) { + // Even if the font is not explicitly scalable, if the face has + // color bitmaps, it should be treated as scalable and scaled to + // the desired size. Metrics based on y_ppem need to be rescaled + // for the adjusted size. This makes metrics agree with the + // scales we pass to Cairo for Fontconfig fonts. + if (mFace->face_flags & FT_FACE_FLAG_COLOR) { + emHeight = mGfxFont->GetAdjustedSize(); + gfxFloat adjustScale = emHeight / ftMetrics.y_ppem; + aMetrics->maxAscent *= adjustScale; + aMetrics->maxDescent *= adjustScale; + aMetrics->maxAdvance *= adjustScale; + lineHeight *= adjustScale; + } gfxFloat emUnit = head->Units_Per_EM; yScale = emHeight / emUnit; } @@ -111,11 +133,6 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics, TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(mFace, ft_sfnt_os2)); - aMetrics->maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender); - aMetrics->maxDescent = -FLOAT_FROM_26_6(ftMetrics.descender); - aMetrics->maxAdvance = FLOAT_FROM_26_6(ftMetrics.max_advance); - - gfxFloat lineHeight; if (os2 && os2->sTypoAscender && yScale > 0.0) { aMetrics->emAscent = os2->sTypoAscender * yScale; aMetrics->emDescent = -os2->sTypoDescender * yScale; @@ -142,7 +159,6 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics, } else { aMetrics->emAscent = aMetrics->maxAscent; aMetrics->emDescent = aMetrics->maxDescent; - lineHeight = FLOAT_FROM_26_6(ftMetrics.height); } cairo_text_extents_t extents; diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 601e7a90c..75e8fb76a 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -811,6 +811,15 @@ ChooseFontSize(gfxFontconfigFontEntry* aEntry, bestSize = size; } } + // If the font has bitmaps but wants to be scaled, then let it scale. + if (bestSize >= 0.0) { + FcBool scalable; + if (FcPatternGetBool(aEntry->GetPattern(), + FC_SCALABLE, 0, &scalable) == FcResultMatch && + scalable) { + return requestedSize; + } + } return bestSize; } @@ -946,10 +955,16 @@ gfxFontconfigFontFamily::AddFontPattern(FcPattern* aFontPattern) NS_ASSERTION(!mHasStyles, "font patterns must not be added to already enumerated families"); - FcBool scalable; - if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) != FcResultMatch || - !scalable) { + FcBool outline; + if (FcPatternGetBool(aFontPattern, FC_OUTLINE, 0, &outline) != FcResultMatch || + !outline) { mHasNonScalableFaces = true; + + FcBool scalable; + if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) == FcResultMatch && + scalable) { + mForceScalable = true; + } } nsCountedRef<FcPattern> pattern(aFontPattern); @@ -961,7 +976,9 @@ static const double kRejectDistance = 10000.0; // Calculate a distance score representing the size disparity between the // requested style's size and the font entry's size. static double -SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle) +SizeDistance(gfxFontconfigFontEntry* aEntry, + const gfxFontStyle& aStyle, + bool aForceScalable) { double requestedSize = SizeForStyle(aEntry, aStyle); double bestDist = -1.0; @@ -978,7 +995,7 @@ SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle) if (bestDist < 0.0) { // No size means scalable return -1.0; - } else if (5.0 * bestDist < requestedSize) { + } else if (aForceScalable || 5.0 * bestDist < requestedSize) { // fontconfig prefers a matching family or lang to pixelsize of bitmap // fonts. CSS suggests a tolerance of 20% on pixelsize. return bestDist; @@ -1012,7 +1029,7 @@ gfxFontconfigFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle, for (size_t i = 0; i < aFontEntryList.Length(); i++) { gfxFontconfigFontEntry* entry = static_cast<gfxFontconfigFontEntry*>(aFontEntryList[i]); - double dist = SizeDistance(entry, aFontStyle); + double dist = SizeDistance(entry, aFontStyle, mForceScalable); // If the entry is scalable or has a style that does not match // the group of unscalable fonts, then start a new group. if (dist < 0.0 || diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h index 1bc35021e..aa8f614a9 100644 --- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -175,7 +175,8 @@ public: explicit gfxFontconfigFontFamily(const nsAString& aName) : gfxFontFamily(aName), mContainsAppFonts(false), - mHasNonScalableFaces(false) + mHasNonScalableFaces(false), + mForceScalable(false) { } void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override; @@ -201,6 +202,7 @@ protected: bool mContainsAppFonts; bool mHasNonScalableFaces; + bool mForceScalable; }; class gfxFontconfigFont : public gfxFontconfigFontBase { |