summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gfx/thebes/gfxFT2Utils.cpp30
-rw-r--r--gfx/thebes/gfxFcPlatformFontList.cpp29
-rw-r--r--gfx/thebes/gfxFcPlatformFontList.h4
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 {