зеркало из https://github.com/mozilla/pjs.git
bug 577380 - use Core Text shaping for fonts requiring AAT layout on Mac OS X. r=jdaggett
This commit is contained in:
Родитель
cb8fa3b5ba
Коммит
ed2ddf2315
|
@ -43,6 +43,7 @@
|
|||
#include "gfxHarfBuzzShaper.h"
|
||||
#include "gfxPlatformMac.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxUnicodeProperties.h"
|
||||
|
||||
#include "cairo-quartz.h"
|
||||
|
||||
|
@ -149,6 +150,64 @@ gfxMacFont::~gfxMacFont()
|
|||
::CGFontRelease(mCGFont);
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxMacFont::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
if (!mIsValid) {
|
||||
NS_WARNING("invalid font! expect incorrect text rendering");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool ok = PR_FALSE;
|
||||
|
||||
if (mHarfBuzzShaper &&
|
||||
!static_cast<MacOSFontEntry*>(GetFontEntry())->RequiresAATLayout())
|
||||
{
|
||||
if (gfxPlatform::GetPlatform()->UseHarfBuzzLevel() >=
|
||||
gfxUnicodeProperties::ScriptShapingLevel(aRunScript)) {
|
||||
ok = mHarfBuzzShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength,
|
||||
aRunScript);
|
||||
#if DEBUG
|
||||
if (!ok) {
|
||||
NS_ConvertUTF16toUTF8 name(GetName());
|
||||
char msg[256];
|
||||
sprintf(msg, "HarfBuzz shaping failed for font: %s",
|
||||
name.get());
|
||||
NS_WARNING(msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
// fallback to Core Text shaping
|
||||
if (!mPlatformShaper) {
|
||||
CreatePlatformShaper();
|
||||
}
|
||||
|
||||
ok = mPlatformShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength,
|
||||
aRunScript);
|
||||
#if DEBUG
|
||||
if (!ok) {
|
||||
NS_ConvertUTF16toUTF8 name(GetName());
|
||||
char msg[256];
|
||||
sprintf(msg, "Core Text shaping failed for font: %s",
|
||||
name.get());
|
||||
NS_WARNING(msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::CreatePlatformShaper()
|
||||
{
|
||||
|
|
|
@ -57,6 +57,13 @@ public:
|
|||
ATSFontRef GetATSFontRef() const { return mATSFont; }
|
||||
CGFontRef GetCGFontRef() const { return mCGFont; }
|
||||
|
||||
virtual PRBool InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
/* overrides for the pure virtual methods in gfxFont */
|
||||
virtual const gfxFont::Metrics& GetMetrics() {
|
||||
return mMetrics;
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
ATSFontRef GetFontRef();
|
||||
nsresult ReadCMAP();
|
||||
|
||||
PRBool RequiresAATLayout() const { return mRequiresAAT; }
|
||||
|
||||
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
||||
|
||||
protected:
|
||||
|
@ -78,6 +80,7 @@ protected:
|
|||
|
||||
ATSFontRef mATSFontRef;
|
||||
PRPackedBool mATSFontRefInitialized;
|
||||
PRPackedBool mRequiresAAT;
|
||||
};
|
||||
|
||||
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
||||
|
|
|
@ -136,7 +136,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
|||
PRBool aIsStandardFace)
|
||||
: gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
|
||||
mATSFontRef(0),
|
||||
mATSFontRefInitialized(PR_FALSE)
|
||||
mATSFontRefInitialized(PR_FALSE),
|
||||
mRequiresAAT(PR_FALSE)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
}
|
||||
|
@ -146,7 +147,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon
|
|||
gfxUserFontData *aUserFontData)
|
||||
: gfxFontEntry(aPostscriptName),
|
||||
mATSFontRef(aFontRef),
|
||||
mATSFontRefInitialized(PR_TRUE)
|
||||
mATSFontRefInitialized(PR_TRUE),
|
||||
mRequiresAAT(PR_FALSE)
|
||||
{
|
||||
// xxx - stretch is basically ignored for now
|
||||
|
||||
|
@ -198,7 +200,6 @@ const ScriptRange gScriptsThatRequireShaping[] = {
|
|||
nsresult
|
||||
MacOSFontEntry::ReadCMAP()
|
||||
{
|
||||
OSStatus status;
|
||||
ByteCount size;
|
||||
|
||||
// attempt this once, if errors occur leave a blank cmap
|
||||
|
@ -214,20 +215,37 @@ MacOSFontEntry::ReadCMAP()
|
|||
|
||||
PRPackedBool unicodeFont, symbolFont; // currently ignored
|
||||
nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
|
||||
mCharacterMap, mUVSOffset, unicodeFont, symbolFont);
|
||||
mCharacterMap, mUVSOffset,
|
||||
unicodeFont, symbolFont);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCharacterMap.reset();
|
||||
return rv;
|
||||
}
|
||||
mHasCmapTable = PR_TRUE;
|
||||
|
||||
// for complex scripts, check for the presence of mort/morx
|
||||
PRBool checkedForMorphTable = PR_FALSE, hasMorphTable = PR_FALSE;
|
||||
|
||||
ATSFontRef fontRef = GetFontRef();
|
||||
PRUint32 s, numScripts = sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
|
||||
|
||||
for (s = 0; s < numScripts; s++) {
|
||||
// for layout support, check for the presence of mort/morx and GSUB/GPOS
|
||||
PRBool hasAATLayout =
|
||||
(::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','x'),
|
||||
0, 0, 0, &size) == noErr) ||
|
||||
(::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','t'),
|
||||
0, 0, 0, &size) == noErr);
|
||||
|
||||
PRBool hasOTLayout =
|
||||
(::ATSFontGetTable(fontRef, TRUETYPE_TAG('G','S','U','B'),
|
||||
0, 0, 0, &size) == noErr) ||
|
||||
(::ATSFontGetTable(fontRef, TRUETYPE_TAG('G','P','O','S'),
|
||||
0, 0, 0, &size) == noErr);
|
||||
|
||||
if (hasAATLayout && !hasOTLayout) {
|
||||
mRequiresAAT = PR_TRUE;
|
||||
}
|
||||
|
||||
PRUint32 numScripts =
|
||||
sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
|
||||
|
||||
for (PRUint32 s = 0; s < numScripts; s++) {
|
||||
eComplexScript whichScript = gScriptsThatRequireShaping[s].script;
|
||||
|
||||
// check to see if the cmap includes complex script codepoints
|
||||
|
@ -235,42 +253,17 @@ MacOSFontEntry::ReadCMAP()
|
|||
gScriptsThatRequireShaping[s].rangeEnd)) {
|
||||
PRBool omitRange = PR_TRUE;
|
||||
|
||||
// check for mort/morx table, if haven't already
|
||||
if (!checkedForMorphTable) {
|
||||
status = ::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','x'), 0, 0, 0, &size);
|
||||
if (status == noErr) {
|
||||
checkedForMorphTable = PR_TRUE;
|
||||
hasMorphTable = PR_TRUE;
|
||||
} else {
|
||||
// check for a mort table
|
||||
status = ::ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','t'), 0, 0, 0, &size);
|
||||
checkedForMorphTable = PR_TRUE;
|
||||
if (status == noErr) {
|
||||
hasMorphTable = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMorphTable) {
|
||||
if (hasAATLayout) {
|
||||
omitRange = PR_FALSE;
|
||||
}
|
||||
|
||||
// special-cases for Arabic:
|
||||
if (whichScript == eComplexScriptArabic) {
|
||||
} else if (whichScript == eComplexScriptArabic) {
|
||||
// special-case for Arabic:
|
||||
// even if there's no morph table, CoreText can shape Arabic
|
||||
// if there's GSUB support
|
||||
status = ::ATSFontGetTable(fontRef, TRUETYPE_TAG('G','S','U','B'), 0, 0, 0, &size);
|
||||
if (status == noErr) {
|
||||
// TODO: to be really thorough, we could check that the GSUB table
|
||||
// actually supports the 'arab' script tag.
|
||||
// using OpenType layout
|
||||
if (hasOTLayout) {
|
||||
// TODO: to be really thorough, we could check that the
|
||||
// GSUB table actually supports the 'arab' script tag.
|
||||
omitRange = PR_FALSE;
|
||||
}
|
||||
|
||||
// rude hack - the Chinese STxxx fonts on 10.4 contain morx tables and Arabic glyphs but
|
||||
// lack the proper info for shaping Arabic, so exclude explicitly, ick
|
||||
if (mName.CharAt(0) == 'S' && mName.CharAt(1) == 'T') {
|
||||
omitRange = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (omitRange) {
|
||||
|
@ -281,7 +274,8 @@ MacOSFontEntry::ReadCMAP()
|
|||
}
|
||||
|
||||
PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n",
|
||||
NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
|
||||
NS_ConvertUTF16toUTF8(mName).get(),
|
||||
mCharacterMap.GetSize()));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Times; /* this test is only for OS X, we know Times will be there */
|
||||
font-size: 40px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
fi
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Times; /* this test is only for OS X, we know Times will be there */
|
||||
font-size: 40px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
fi
|
||||
</body>
|
||||
</html>
|
|
@ -57,3 +57,5 @@ random HTTP(..) == 475092-pos.html 475092-sub.html # bug 482596
|
|||
== 476378-soft-hyphen-fallback.html 476378-soft-hyphen-fallback-ref.html
|
||||
# Test for bug 484954
|
||||
== rgba-text.html rgba-text-ref.html
|
||||
# Test for bug 577380, support for AAT layout (on OS X only)
|
||||
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 577380.html 577380-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче