зеркало из https://github.com/mozilla/pjs.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:
Родитель
caa84d02a4
Коммит
e72058c4cc
|
@ -268,6 +268,16 @@ gfxMacFont::InitMetrics()
|
||||||
mAdjustedSize = PR_MAX(mStyle.size, 1.0f);
|
mAdjustedSize = PR_MAX(mStyle.size, 1.0f);
|
||||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
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
|
// Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
|
||||||
// platform APIs. The InitMetrics...() functions will set mIsValid on success.
|
// platform APIs. The InitMetrics...() functions will set mIsValid on success.
|
||||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||||
|
@ -279,7 +289,7 @@ gfxMacFont::InitMetrics()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMetrics.xHeight == 0.0) {
|
if (mMetrics.xHeight == 0.0) {
|
||||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
|
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
|
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
|
||||||
|
@ -288,6 +298,11 @@ gfxMacFont::InitMetrics()
|
||||||
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
|
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
|
||||||
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
|
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
|
||||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
mFUnitsConvFactor = mAdjustedSize / upem;
|
||||||
|
if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
|
||||||
|
cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
|
||||||
|
} else {
|
||||||
|
cgConvFactor = mFUnitsConvFactor;
|
||||||
|
}
|
||||||
mMetrics.xHeight = 0.0;
|
mMetrics.xHeight = 0.0;
|
||||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||||
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
|
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
|
||||||
|
@ -299,7 +314,7 @@ gfxMacFont::InitMetrics()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mMetrics.xHeight == 0.0) {
|
if (mMetrics.xHeight == 0.0) {
|
||||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
|
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +332,8 @@ gfxMacFont::InitMetrics()
|
||||||
|
|
||||||
PRUint32 glyphID;
|
PRUint32 glyphID;
|
||||||
if (mMetrics.aveCharWidth <= 0) {
|
if (mMetrics.aveCharWidth <= 0) {
|
||||||
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID);
|
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID,
|
||||||
|
cgConvFactor);
|
||||||
if (glyphID == 0) {
|
if (glyphID == 0) {
|
||||||
// we didn't find 'x', so use maxAdvance rather than zero
|
// we didn't find 'x', so use maxAdvance rather than zero
|
||||||
mMetrics.aveCharWidth = mMetrics.maxAdvance;
|
mMetrics.aveCharWidth = mMetrics.maxAdvance;
|
||||||
|
@ -326,14 +342,15 @@ gfxMacFont::InitMetrics()
|
||||||
mMetrics.aveCharWidth += mSyntheticBoldOffset;
|
mMetrics.aveCharWidth += mSyntheticBoldOffset;
|
||||||
mMetrics.maxAdvance += mSyntheticBoldOffset;
|
mMetrics.maxAdvance += mSyntheticBoldOffset;
|
||||||
|
|
||||||
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID);
|
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID, cgConvFactor);
|
||||||
if (glyphID == 0) {
|
if (glyphID == 0) {
|
||||||
// no space glyph?!
|
// no space glyph?!
|
||||||
mMetrics.spaceWidth = mMetrics.aveCharWidth;
|
mMetrics.spaceWidth = mMetrics.aveCharWidth;
|
||||||
}
|
}
|
||||||
mSpaceGlyph = glyphID;
|
mSpaceGlyph = glyphID;
|
||||||
|
|
||||||
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID);
|
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID,
|
||||||
|
cgConvFactor);
|
||||||
if (glyphID == 0) {
|
if (glyphID == 0) {
|
||||||
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +377,7 @@ gfxMacFont::InitMetrics()
|
||||||
|
|
||||||
gfxFloat
|
gfxFloat
|
||||||
gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
||||||
PRUint32 *aGlyphID)
|
PRUint32 *aGlyphID, gfxFloat aConvFactor)
|
||||||
{
|
{
|
||||||
CGGlyph glyph = 0;
|
CGGlyph glyph = 0;
|
||||||
|
|
||||||
|
@ -377,7 +394,7 @@ gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
||||||
if (glyph) {
|
if (glyph) {
|
||||||
int advance;
|
int advance;
|
||||||
if (::CGFontGetGlyphAdvances(mCGFont, &glyph, 1, &advance)) {
|
if (::CGFontGetGlyphAdvances(mCGFont, &glyph, 1, &advance)) {
|
||||||
return advance * mFUnitsConvFactor;
|
return advance * aConvFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,10 @@ protected:
|
||||||
void InitMetrics();
|
void InitMetrics();
|
||||||
void InitMetricsFromATSMetrics();
|
void InitMetricsFromATSMetrics();
|
||||||
|
|
||||||
// Get width and glyph ID for a character; requires that
|
// Get width and glyph ID for a character; uses aConvFactor
|
||||||
// mFUnitsConvFactor has been set before this is called
|
// to convert font units as returned by CG to actual dimensions
|
||||||
gfxFloat GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
gfxFloat GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
|
||||||
PRUint32 *aGlyphID);
|
PRUint32 *aGlyphID, gfxFloat aConvFactor);
|
||||||
|
|
||||||
static void DestroyBlobFunc(void* aUserData);
|
static void DestroyBlobFunc(void* aUserData);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,8 @@ public:
|
||||||
|
|
||||||
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
||||||
|
|
||||||
|
PRBool IsCFF();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// for use with data fonts
|
// for use with data fonts
|
||||||
MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
|
MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
|
||||||
|
@ -81,6 +83,8 @@ protected:
|
||||||
ATSFontRef mATSFontRef;
|
ATSFontRef mATSFontRef;
|
||||||
PRPackedBool mATSFontRefInitialized;
|
PRPackedBool mATSFontRefInitialized;
|
||||||
PRPackedBool mRequiresAAT;
|
PRPackedBool mRequiresAAT;
|
||||||
|
PRPackedBool mIsCFF;
|
||||||
|
PRPackedBool mIsCFFInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
||||||
|
|
|
@ -137,7 +137,9 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
||||||
: gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
|
: gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
|
||||||
mATSFontRef(0),
|
mATSFontRef(0),
|
||||||
mATSFontRefInitialized(PR_FALSE),
|
mATSFontRefInitialized(PR_FALSE),
|
||||||
mRequiresAAT(PR_FALSE)
|
mRequiresAAT(PR_FALSE),
|
||||||
|
mIsCFF(PR_FALSE),
|
||||||
|
mIsCFFInitialized(PR_FALSE)
|
||||||
{
|
{
|
||||||
mWeight = aWeight;
|
mWeight = aWeight;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +150,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon
|
||||||
: gfxFontEntry(aPostscriptName),
|
: gfxFontEntry(aPostscriptName),
|
||||||
mATSFontRef(aFontRef),
|
mATSFontRef(aFontRef),
|
||||||
mATSFontRefInitialized(PR_TRUE),
|
mATSFontRefInitialized(PR_TRUE),
|
||||||
mRequiresAAT(PR_FALSE)
|
mRequiresAAT(PR_FALSE),
|
||||||
|
mIsCFFInitialized(PR_FALSE)
|
||||||
{
|
{
|
||||||
// xxx - stretch is basically ignored for now
|
// xxx - stretch is basically ignored for now
|
||||||
|
|
||||||
|
@ -313,6 +316,26 @@ MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeeds
|
||||||
return new gfxMacFont(this, aFontStyle, aNeedsBold);
|
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 */
|
/* gfxMacFontFamily */
|
||||||
#pragma mark-
|
#pragma mark-
|
||||||
|
|
Загрузка…
Ссылка в новой задаче