зеркало из https://github.com/mozilla/pjs.git
merge backout of 7e3e4c91c0f7, a=backout
This commit is contained in:
Коммит
5a0aec7ce6
|
@ -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() {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче