зеркало из https://github.com/mozilla/gecko-dev.git
bug 580863 part 2 - scale glyph metrics correctly when initializing CFF fonts on OS X 10.6. r=jdaggett a=blocking-betaN
This commit is contained in:
Родитель
339859c3b4
Коммит
76279ccf05
|
@ -268,6 +268,16 @@ gfxMacFont::InitMetrics()
|
|||
mAdjustedSize = PR_MAX(mStyle.size, 1.0f);
|
||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
||||
|
||||
// For CFF fonts, when scaling values read from CGFont* APIs, we need to
|
||||
// use CG's idea of unitsPerEm, which may differ from the "true" value in
|
||||
// the head table of the font (see bug 580863)
|
||||
gfxFloat cgConvFactor;
|
||||
if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
|
||||
cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
|
||||
} else {
|
||||
cgConvFactor = mFUnitsConvFactor;
|
||||
}
|
||||
|
||||
// Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
|
||||
// platform APIs. The InitMetrics...() functions will set mIsValid on success.
|
||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||
|
@ -279,7 +289,7 @@ gfxMacFont::InitMetrics()
|
|||
}
|
||||
|
||||
if (mMetrics.xHeight == 0.0) {
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
|
||||
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
|
||||
|
@ -288,6 +298,11 @@ gfxMacFont::InitMetrics()
|
|||
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
|
||||
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
|
||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
||||
if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
|
||||
cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
|
||||
} else {
|
||||
cgConvFactor = mFUnitsConvFactor;
|
||||
}
|
||||
mMetrics.xHeight = 0.0;
|
||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
|
||||
|
@ -299,7 +314,7 @@ gfxMacFont::InitMetrics()
|
|||
return;
|
||||
}
|
||||
if (mMetrics.xHeight == 0.0) {
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +332,8 @@ gfxMacFont::InitMetrics()
|
|||
|
||||
PRUint32 glyphID;
|
||||
if (mMetrics.aveCharWidth <= 0) {
|
||||
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID);
|
||||
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID,
|
||||
cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
// we didn't find 'x', so use maxAdvance rather than zero
|
||||
mMetrics.aveCharWidth = mMetrics.maxAdvance;
|
||||
|
@ -326,14 +342,15 @@ gfxMacFont::InitMetrics()
|
|||
mMetrics.aveCharWidth += mSyntheticBoldOffset;
|
||||
mMetrics.maxAdvance += mSyntheticBoldOffset;
|
||||
|
||||
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID);
|
||||
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID, cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
// no space glyph?!
|
||||
mMetrics.spaceWidth = mMetrics.aveCharWidth;
|
||||
}
|
||||
mSpaceGlyph = glyphID;
|
||||
|
||||
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID);
|
||||
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID,
|
||||
cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
||||
}
|
||||
|
@ -360,7 +377,7 @@ gfxMacFont::InitMetrics()
|
|||
|
||||
gfxFloat
|
||||
gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
||||
PRUint32 *aGlyphID)
|
||||
PRUint32 *aGlyphID, gfxFloat aConvFactor)
|
||||
{
|
||||
CGGlyph glyph = 0;
|
||||
|
||||
|
@ -377,7 +394,7 @@ gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
|||
if (glyph) {
|
||||
int advance;
|
||||
if (::CGFontGetGlyphAdvances(mCGFont, &glyph, 1, &advance)) {
|
||||
return advance * mFUnitsConvFactor;
|
||||
return advance * aConvFactor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,10 +85,10 @@ protected:
|
|||
void InitMetrics();
|
||||
void InitMetricsFromATSMetrics();
|
||||
|
||||
// Get width and glyph ID for a character; requires that
|
||||
// mFUnitsConvFactor has been set before this is called
|
||||
// Get width and glyph ID for a character; uses aConvFactor
|
||||
// to convert font units as returned by CG to actual dimensions
|
||||
gfxFloat GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
||||
PRUint32 *aGlyphID);
|
||||
PRUint32 *aGlyphID, gfxFloat aConvFactor);
|
||||
|
||||
static void DestroyBlobFunc(void* aUserData);
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ public:
|
|||
|
||||
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
||||
|
||||
PRBool IsCFF();
|
||||
|
||||
protected:
|
||||
// for use with data fonts
|
||||
MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
|
||||
|
@ -81,6 +83,8 @@ protected:
|
|||
ATSFontRef mATSFontRef;
|
||||
PRPackedBool mATSFontRefInitialized;
|
||||
PRPackedBool mRequiresAAT;
|
||||
PRPackedBool mIsCFF;
|
||||
PRPackedBool mIsCFFInitialized;
|
||||
};
|
||||
|
||||
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
||||
|
|
|
@ -137,7 +137,9 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
|||
: gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
|
||||
mATSFontRef(0),
|
||||
mATSFontRefInitialized(PR_FALSE),
|
||||
mRequiresAAT(PR_FALSE)
|
||||
mRequiresAAT(PR_FALSE),
|
||||
mIsCFF(PR_FALSE),
|
||||
mIsCFFInitialized(PR_FALSE)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
}
|
||||
|
@ -148,7 +150,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon
|
|||
: gfxFontEntry(aPostscriptName),
|
||||
mATSFontRef(aFontRef),
|
||||
mATSFontRefInitialized(PR_TRUE),
|
||||
mRequiresAAT(PR_FALSE)
|
||||
mRequiresAAT(PR_FALSE),
|
||||
mIsCFFInitialized(PR_FALSE)
|
||||
{
|
||||
// xxx - stretch is basically ignored for now
|
||||
|
||||
|
@ -313,6 +316,26 @@ MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeeds
|
|||
return new gfxMacFont(this, aFontStyle, aNeedsBold);
|
||||
}
|
||||
|
||||
PRBool
|
||||
MacOSFontEntry::IsCFF()
|
||||
{
|
||||
if (!mIsCFFInitialized) {
|
||||
mIsCFFInitialized = PR_TRUE;
|
||||
ATSFontRef fontRef = GetFontRef();
|
||||
if (fontRef != (ATSFontRef)kATSUInvalidFontID) {
|
||||
ByteCount dataLength;
|
||||
OSStatus status = ::ATSFontGetTable(fontRef,
|
||||
TRUETYPE_TAG('C','F','F',' '),
|
||||
0, 0, 0, &dataLength);
|
||||
if (status == noErr && dataLength > 0) {
|
||||
mIsCFF = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mIsCFF;
|
||||
}
|
||||
|
||||
|
||||
/* gfxMacFontFamily */
|
||||
#pragma mark-
|
||||
|
|
Загрузка…
Ссылка в новой задаче