mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 12:55:46 +00:00
bug 449292 - part 5 - break text into script runs before font-matching and shaping. r=jdaggett sr=roc
This commit is contained in:
parent
5754ac6b39
commit
37f3b9fe59
@ -675,7 +675,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength) = 0;
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript) = 0;
|
||||
|
||||
protected:
|
||||
// the font this shaper is working with
|
||||
@ -949,7 +950,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
@ -1946,11 +1948,22 @@ protected:
|
||||
// you should call this with the *first* bad font.
|
||||
void InitMetricsForBadFont(gfxFont* aBadFont);
|
||||
|
||||
// Set up the textrun glyphs, by finding script and font ranges
|
||||
// and calling each font's InitTextRun() as appropriate
|
||||
void InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength);
|
||||
|
||||
// InitTextRun helper to handle a single script run
|
||||
void InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
/* If aResolveGeneric is true, then CSS/Gecko generic family names are
|
||||
* replaced with preferred fonts.
|
||||
*
|
||||
|
@ -107,7 +107,8 @@ gfxCoreTextShaper::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
// aRunStart and aRunLength define the section of the textRun and of aString
|
||||
// that is to be drawn with this particular font
|
||||
|
@ -61,7 +61,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
// clean up static objects that may have been cached
|
||||
static void Shutdown();
|
||||
|
@ -50,7 +50,8 @@ gfxDWriteShaper::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
HRESULT hr;
|
||||
// TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES
|
||||
|
@ -61,7 +61,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
};
|
||||
|
||||
#endif /* GFX_DWRITESHAPER_H */
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "gfxFontMissingGlyphs.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "gfxPlatformFontList.h"
|
||||
#include "gfxScriptItemizer.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsBidiUtils.h"
|
||||
#include "nsUnicodeRange.h"
|
||||
@ -1250,7 +1251,8 @@ gfxFont::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
NS_ASSERTION(mShaper != nsnull, "no shaper?!");
|
||||
if (!mShaper) {
|
||||
@ -1258,7 +1260,7 @@ gfxFont::InitTextRun(gfxContext *aContext,
|
||||
}
|
||||
|
||||
PRBool ok = mShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength);
|
||||
aRunStart, aRunLength, aRunScript);
|
||||
NS_WARN_IF_FALSE(ok, "shaper failed, expect scrambled or missing text");
|
||||
}
|
||||
|
||||
@ -1965,17 +1967,35 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
// split into script runs so that script can potentially influence
|
||||
// the font matching process below
|
||||
gfxScriptItemizer scriptRuns(aString, aLength);
|
||||
|
||||
PRUint32 runStart = 0, runLimit = aLength;
|
||||
PRInt32 runScript = HB_SCRIPT_LATIN;
|
||||
while (scriptRuns.Next(runStart, runLimit, runScript)) {
|
||||
InitTextRun(aContext, aTextRun, aString, aLength,
|
||||
runStart, runLimit, runScript);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aScriptRunStart,
|
||||
PRUint32 aScriptRunEnd,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
gfxFont *mainFont = mFonts[0].get();
|
||||
|
||||
PRUint32 runStart = 0;
|
||||
PRUint32 runStart = aScriptRunStart;
|
||||
nsAutoTArray<gfxTextRange,3> fontRanges;
|
||||
ComputeRanges(fontRanges, aString, 0, aLength);
|
||||
ComputeRanges(fontRanges, aString, aScriptRunStart, aScriptRunEnd);
|
||||
PRUint32 numRanges = fontRanges.Length();
|
||||
|
||||
nsAutoTArray<PRPackedBool,SMALL_GLYPH_RUN> unmatchedArray;
|
||||
PRPackedBool *unmatched = NULL;
|
||||
|
||||
for (PRUint32 r = 0; r < numRanges; r++) {
|
||||
const gfxTextRange& range = fontRanges[r];
|
||||
PRUint32 matchedLength = range.Length();
|
||||
@ -1987,23 +2007,15 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
|
||||
// do glyph layout and record the resulting positioned glyphs
|
||||
matchedFont->InitTextRun(aContext, aTextRun, aString,
|
||||
runStart, matchedLength);
|
||||
runStart, matchedLength, aRunScript);
|
||||
} else {
|
||||
// no font available, so record missing glyph info instead
|
||||
if (unmatched == NULL) {
|
||||
if (unmatchedArray.SetLength(aLength)) {
|
||||
unmatched = unmatchedArray.Elements();
|
||||
::memset(unmatched, PR_FALSE, aLength*sizeof(PRPackedBool));
|
||||
}
|
||||
}
|
||||
|
||||
// create the glyph run before calling SetMissing Glyph
|
||||
aTextRun->AddGlyphRun(mainFont, runStart, matchedLength);
|
||||
|
||||
for (PRUint32 index = runStart; index < runStart + matchedLength; index++) {
|
||||
// Record the char code so we can draw a box with the Unicode value
|
||||
if (NS_IS_HIGH_SURROGATE(aString[index]) &&
|
||||
index + 1 < aLength &&
|
||||
index + 1 < aScriptRunEnd &&
|
||||
NS_IS_LOW_SURROGATE(aString[index+1])) {
|
||||
aTextRun->SetMissingGlyph(index,
|
||||
SURROGATE_TO_UCS4(aString[index],
|
||||
@ -2013,12 +2025,6 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||
aTextRun->SetMissingGlyph(index, aString[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// We have to remember the indices of unmatched chars to avoid overwriting
|
||||
// their glyph (actually char code) data with the space glyph later,
|
||||
// while we're retrieving actual glyph data from CoreText runs.
|
||||
if (unmatched)
|
||||
::memset(unmatched + runStart, PR_TRUE, matchedLength);
|
||||
}
|
||||
|
||||
runStart += matchedLength;
|
||||
|
@ -111,7 +111,8 @@ gfxGDIFont::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
if (!mMetrics) {
|
||||
Initialize();
|
||||
@ -121,7 +122,7 @@ gfxGDIFont::InitTextRun(gfxContext *aContext,
|
||||
return;
|
||||
}
|
||||
PRBool ok = mShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength);
|
||||
aRunStart, aRunLength, aRunScript);
|
||||
if (!ok) {
|
||||
// shaping failed; if we were using uniscribe, fall back to GDI
|
||||
GDIFontEntry *fe = static_cast<GDIFontEntry*>(GetFontEntry());
|
||||
@ -130,7 +131,7 @@ gfxGDIFont::InitTextRun(gfxContext *aContext,
|
||||
fe->mForceGDI = PR_TRUE;
|
||||
mShaper = new gfxGDIShaper(this);
|
||||
ok = mShaper->InitTextRun(aContext, aTextRun, aString,
|
||||
aRunStart, aRunLength);
|
||||
aRunStart, aRunLength, aRunScript);
|
||||
}
|
||||
}
|
||||
NS_WARN_IF_FALSE(ok, "shaper failed, expect broken or missing text");
|
||||
|
@ -78,7 +78,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
protected:
|
||||
void Initialize(); // creates metrics and Cairo fonts
|
||||
|
@ -54,7 +54,8 @@ gfxGDIShaper::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
gfxGDIFont *f = static_cast<gfxGDIFont*>(mFont);
|
||||
DCFromContext dc(aContext);
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
};
|
||||
|
||||
#endif /* GFX_GDISHAPER_H */
|
||||
|
@ -551,7 +551,8 @@ gfxUniscribeShaper::InitTextRun(gfxContext *aContext,
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript)
|
||||
{
|
||||
DCFromContext aDC(aContext);
|
||||
|
||||
|
@ -68,7 +68,8 @@ public:
|
||||
gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
PRUint32 aRunLength,
|
||||
PRInt32 aRunScript);
|
||||
|
||||
SCRIPT_CACHE *ScriptCache() { return &mScriptCache; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user