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:
Jonathan Kew 2010-10-07 08:59:16 +01:00
Родитель 339859c3b4
Коммит 76279ccf05
4 изменённых файлов: 56 добавлений и 12 удалений

Просмотреть файл

@ -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-