merge backout of 7e3e4c91c0f7, a=backout

This commit is contained in:
Jonathan Kew 2010-11-11 12:18:56 +00:00
Родитель 703420faca 8f44149b52
Коммит 5a0aec7ce6
6 изменённых файлов: 62 добавлений и 91 удалений

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

@ -1300,96 +1300,34 @@ gfxFont::Measure(gfxTextRun *aTextRun,
return metrics; return metrics;
} }
#define MAX_SHAPING_LENGTH 32760 // slightly less than 32K, trying to avoid
// over-stressing platform shapers
#define BACKTRACK_LIMIT 1024 // If we can't find a space or a cluster start
// within 1K chars, just chop arbitrarily.
// Limiting backtrack here avoids pathological
// behavior on long runs with no whitespace.
PRBool PRBool
gfxFont::InitTextRun(gfxContext *aContext, gfxFont::InitTextRun(gfxContext *aContext,
gfxTextRun *aTextRun, gfxTextRun *aTextRun,
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript)
PRBool aPreferPlatformShaping)
{ {
PRBool ok; PRBool ok = PR_FALSE;
do { if (mHarfBuzzShaper) {
// Because various shaping backends struggle with very long runs, if (gfxPlatform::GetPlatform()->UseHarfBuzzLevel() >=
// we look for appropriate break locations (preferring whitespace), gfxUnicodeProperties::ScriptShapingLevel(aRunScript)) {
// and shape sub-runs of no more than 32K characters at a time. ok = mHarfBuzzShaper->InitTextRun(aContext, aTextRun, aString,
// See bug 606714 (CoreText), and similar Uniscribe issues. aRunStart, aRunLength, aRunScript);
// This loop always executes at least once, and "processes" up to
// MAX_RUN_LENGTH_FOR_SHAPING characters, updating aRunStart and
// aRunLength accordingly. It terminates when the entire run has
// been processed, or when shaping fails.
PRUint32 thisRunLength;
ok = PR_FALSE;
if (aRunLength <= MAX_SHAPING_LENGTH) {
thisRunLength = aRunLength;
} else {
// We're splitting this font run because it's very long
PRUint32 offset = aRunStart + MAX_SHAPING_LENGTH;
PRUint32 clusterStart = 0;
while (offset > aRunStart + MAX_SHAPING_LENGTH - BACKTRACK_LIMIT) {
if (aTextRun->IsClusterStart(offset)) {
if (!clusterStart) {
clusterStart = offset;
}
if (aString[offset] == ' ' || aString[offset - 1] == ' ') {
break;
}
}
--offset;
}
if (offset > MAX_SHAPING_LENGTH - BACKTRACK_LIMIT) {
// we found a space, so break the run there
thisRunLength = offset - aRunStart;
} else if (clusterStart != 0) {
// didn't find a space, but we found a cluster start
thisRunLength = clusterStart - aRunStart;
} else {
// otherwise we'll simply break at MAX_SHAPING_LENGTH chars,
// which may interfere with shaping behavior (but in practice
// only pathological cases will lack ANY whitespace or cluster
// boundaries, so we don't really care; it won't affect any
// "real" text)
thisRunLength = MAX_SHAPING_LENGTH;
}
} }
}
if (mHarfBuzzShaper && !aPreferPlatformShaping) { if (!ok) {
if (gfxPlatform::GetPlatform()->UseHarfBuzzLevel() >= if (!mPlatformShaper) {
gfxUnicodeProperties::ScriptShapingLevel(aRunScript)) { CreatePlatformShaper();
ok = mHarfBuzzShaper->InitTextRun(aContext, aTextRun, aString, NS_ASSERTION(mPlatformShaper, "no platform shaper available!");
aRunStart, thisRunLength,
aRunScript);
}
} }
if (mPlatformShaper) {
if (!ok) { ok = mPlatformShaper->InitTextRun(aContext, aTextRun, aString,
if (!mPlatformShaper) { aRunStart, aRunLength, aRunScript);
CreatePlatformShaper();
NS_ASSERTION(mPlatformShaper, "no platform shaper available!");
}
if (mPlatformShaper) {
ok = mPlatformShaper->InitTextRun(aContext, aTextRun, aString,
aRunStart, thisRunLength,
aRunScript);
}
} }
}
aRunStart += thisRunLength;
aRunLength -= thisRunLength;
} while (ok && aRunLength > 0);
NS_WARN_IF_FALSE(ok, "shaper failed, expect scrambled or missing text"); NS_WARN_IF_FALSE(ok, "shaper failed, expect scrambled or missing text");
return ok; return ok;

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

@ -1136,8 +1136,7 @@ public:
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript);
PRBool aPreferPlatformShaping = PR_FALSE);
protected: protected:
nsRefPtr<gfxFontEntry> mFontEntry; nsRefPtr<gfxFontEntry> mFontEntry;

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

@ -142,8 +142,7 @@ gfxGDIFont::InitTextRun(gfxContext *aContext,
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript)
PRBool aPreferPlatformShaping)
{ {
if (!mMetrics) { if (!mMetrics) {
Initialize(); Initialize();

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

@ -82,8 +82,7 @@ public:
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript);
PRBool aPreferPlatformShaping = PR_FALSE);
virtual PRBool ProvidesHintedWidths() const { return PR_TRUE; } virtual PRBool ProvidesHintedWidths() const { return PR_TRUE; }

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

@ -159,17 +159,54 @@ gfxMacFont::InitTextRun(gfxContext *aContext,
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript)
PRBool aPreferPlatformShaping)
{ {
if (!mIsValid) { if (!mIsValid) {
NS_WARNING("invalid font! expect incorrect text rendering"); NS_WARNING("invalid font! expect incorrect text rendering");
return PR_FALSE; return PR_FALSE;
} }
PRBool ok = gfxFont::InitTextRun(aContext, aTextRun, aString, PRBool ok = PR_FALSE;
aRunStart, aRunLength, aRunScript,
static_cast<MacOSFontEntry*>(GetFontEntry())->RequiresAATLayout()); 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
}
aTextRun->AdjustAdvancesForSyntheticBold(aRunStart, aRunLength); aTextRun->AdjustAdvancesForSyntheticBold(aRunStart, aRunLength);

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

@ -62,8 +62,7 @@ public:
const PRUnichar *aString, const PRUnichar *aString,
PRUint32 aRunStart, PRUint32 aRunStart,
PRUint32 aRunLength, PRUint32 aRunLength,
PRInt32 aRunScript, PRInt32 aRunScript);
PRBool aPreferPlatformShaping = PR_FALSE);
/* overrides for the pure virtual methods in gfxFont */ /* overrides for the pure virtual methods in gfxFont */
virtual const gfxFont::Metrics& GetMetrics() { virtual const gfxFont::Metrics& GetMetrics() {