зеркало из https://github.com/mozilla/pjs.git
Bug 375662. Fix ATSUI issues with cluster detection. Also fix extraction of glyphs when trailing whitespace doesn't get the dominant text direction; remove the current workaround and replace it with a simpler workaround. r=vlad
This commit is contained in:
Родитель
59edcd91ad
Коммит
5bb822a577
|
@ -101,11 +101,14 @@ public:
|
||||||
Parameters* aParams);
|
Parameters* aParams);
|
||||||
virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength,
|
virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength,
|
||||||
Parameters* aParams);
|
Parameters* aParams);
|
||||||
// Here, aString is actually aLength + aHeaderChars*2 chars long; the first char
|
// When aWrapped is true, the string includes bidi control
|
||||||
// may be a LRO or RLO bidi control character to force setting the direction
|
// characters. The first character will be LRO or LRO to force setting the
|
||||||
// for all characters, and if so the last character will be a PDF
|
// direction for all characters, the last character is PDF, and the
|
||||||
|
// second to last character is a non-whitespace character --- to ensure
|
||||||
|
// that there is no "trailing whitespace" in the string, see
|
||||||
|
// http://weblogs.mozillazine.org/roc/archives/2007/02/superlaser_targ.html#comments
|
||||||
gfxTextRun *MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
gfxTextRun *MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
||||||
Parameters *aParams, PRUint32 aheaderChars);
|
PRBool aWrapped, Parameters *aParams);
|
||||||
|
|
||||||
ATSUFontFallbacks *GetATSUFontFallbacksPtr() { return &mFallbacks; }
|
ATSUFontFallbacks *GetATSUFontFallbacksPtr() { return &mFallbacks; }
|
||||||
|
|
||||||
|
@ -121,7 +124,7 @@ protected:
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
void InitTextRun(gfxTextRun *aRun, const PRUnichar *aString, PRUint32 aLength,
|
void InitTextRun(gfxTextRun *aRun, const PRUnichar *aString, PRUint32 aLength,
|
||||||
PRUint32 aHeaderChars);
|
PRBool aWrapped);
|
||||||
|
|
||||||
ATSUFontFallbacks mFallbacks;
|
ATSUFontFallbacks mFallbacks;
|
||||||
};
|
};
|
||||||
|
|
|
@ -349,7 +349,7 @@ gfxAtsuiFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString, PRUint32 aLength)
|
SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString)
|
||||||
{
|
{
|
||||||
TextBreakLocatorRef locator;
|
TextBreakLocatorRef locator;
|
||||||
OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakClusterMask,
|
OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakClusterMask,
|
||||||
|
@ -357,50 +357,51 @@ SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString, PRUint32
|
||||||
if (status != noErr)
|
if (status != noErr)
|
||||||
return;
|
return;
|
||||||
UniCharArrayOffset breakOffset;
|
UniCharArrayOffset breakOffset;
|
||||||
status = UCFindTextBreak(locator, kUCTextBreakClusterMask, 0, aString, aLength,
|
PRUint32 length = aTextRun->GetLength();
|
||||||
0, &breakOffset);
|
status = UCFindTextBreak(locator, kUCTextBreakClusterMask,
|
||||||
|
kUCTextBreakLeadingEdgeMask, aString, length, 0, &breakOffset);
|
||||||
if (status != noErr) {
|
if (status != noErr) {
|
||||||
UCDisposeTextBreakLocator(&locator);
|
UCDisposeTextBreakLocator(&locator);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NS_ASSERTION(breakOffset == 0, "Cluster should start at offset zero");
|
|
||||||
gfxTextRun::CompressedGlyph g;
|
gfxTextRun::CompressedGlyph g;
|
||||||
while (breakOffset < aLength) {
|
PRUint32 lastBreak = 1;
|
||||||
PRUint32 curOffset = breakOffset;
|
do {
|
||||||
|
while (lastBreak < breakOffset) {
|
||||||
|
aTextRun->SetCharacterGlyph(lastBreak, g.SetClusterContinuation());
|
||||||
|
++lastBreak;
|
||||||
|
}
|
||||||
status = UCFindTextBreak(locator, kUCTextBreakClusterMask,
|
status = UCFindTextBreak(locator, kUCTextBreakClusterMask,
|
||||||
kUCTextBreakIterateMask,
|
kUCTextBreakIterateMask|kUCTextBreakLeadingEdgeMask,
|
||||||
aString, aLength, curOffset, &breakOffset);
|
aString, length, breakOffset, &breakOffset);
|
||||||
if (status != noErr) {
|
if (status != noErr) {
|
||||||
UCDisposeTextBreakLocator(&locator);
|
UCDisposeTextBreakLocator(&locator);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PRUint32 j;
|
++lastBreak;
|
||||||
for (j = curOffset + 1; j < breakOffset; ++j) {
|
} while (breakOffset < length);
|
||||||
aTextRun->SetCharacterGlyph(j, g.SetClusterContinuation());
|
NS_ASSERTION(breakOffset == length, "Should have found a final break");
|
||||||
}
|
|
||||||
}
|
|
||||||
NS_ASSERTION(breakOffset == aLength, "Should have found a final break");
|
|
||||||
UCDisposeTextBreakLocator(&locator);
|
UCDisposeTextBreakLocator(&locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
gfxAtsuiFontGroup::MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
gfxAtsuiFontGroup::MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
||||||
Parameters *aParams, PRUint32 aHeaderChars)
|
PRBool aWrapped, Parameters *aParams)
|
||||||
{
|
{
|
||||||
// NS_ASSERTION(!(aParams->mFlags & TEXT_NEED_BOUNDING_BOX),
|
// NS_ASSERTION(!(aParams->mFlags & TEXT_NEED_BOUNDING_BOX),
|
||||||
// "Glyph extents not yet supported");
|
// "Glyph extents not yet supported");
|
||||||
|
|
||||||
gfxTextRun *textRun = new gfxTextRun(aParams, aLength);
|
gfxTextRun *textRun = new gfxTextRun(aParams, aLength - (aWrapped ? 3 : 0));
|
||||||
if (!textRun)
|
if (!textRun)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
// There's a one-char header in the string and a one-char trailer
|
const PRUnichar *realString = aString + (aWrapped ? 1 : 0);
|
||||||
textRun->RecordSurrogates(aString + aHeaderChars);
|
textRun->RecordSurrogates(realString);
|
||||||
if (!(aParams->mFlags & TEXT_IS_8BIT)) {
|
if (!(aParams->mFlags & TEXT_IS_8BIT)) {
|
||||||
SetupClusterBoundaries(textRun, aString + aHeaderChars, aLength);
|
SetupClusterBoundaries(textRun, realString);
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTextRun(textRun, aString, aLength, aHeaderChars);
|
InitTextRun(textRun, aString, aLength, aWrapped);
|
||||||
return textRun;
|
return textRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,8 +423,11 @@ gfxAtsuiFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
||||||
nsAutoString utf16;
|
nsAutoString utf16;
|
||||||
AppendDirectionalIndicator(aParams->mFlags, utf16);
|
AppendDirectionalIndicator(aParams->mFlags, utf16);
|
||||||
utf16.Append(aString, aLength);
|
utf16.Append(aString, aLength);
|
||||||
|
// Ensure that none of the whitespace in the run is considered "trailing"
|
||||||
|
// by ATSUI's bidi algorithm
|
||||||
|
utf16.Append('.');
|
||||||
utf16.Append(UNICODE_PDF);
|
utf16.Append(UNICODE_PDF);
|
||||||
return MakeTextRunInternal(utf16.get(), aLength, aParams, 1);
|
return MakeTextRunInternal(utf16.get(), utf16.Length(), PR_TRUE, aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
|
@ -434,16 +438,16 @@ gfxAtsuiFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
||||||
nsDependentCSubstring cString(reinterpret_cast<const char*>(aString),
|
nsDependentCSubstring cString(reinterpret_cast<const char*>(aString),
|
||||||
reinterpret_cast<const char*>(aString + aLength));
|
reinterpret_cast<const char*>(aString + aLength));
|
||||||
nsAutoString utf16;
|
nsAutoString utf16;
|
||||||
PRUint32 headerChars = 0;
|
PRBool wrapBidi = (aParams->mFlags & TEXT_IS_RTL) != 0;
|
||||||
if (aParams->mFlags & TEXT_IS_RTL) {
|
if (wrapBidi) {
|
||||||
AppendDirectionalIndicator(aParams->mFlags, utf16);
|
AppendDirectionalIndicator(aParams->mFlags, utf16);
|
||||||
headerChars = 1;
|
|
||||||
}
|
}
|
||||||
AppendASCIItoUTF16(cString, utf16);
|
AppendASCIItoUTF16(cString, utf16);
|
||||||
if (aParams->mFlags & TEXT_IS_RTL) {
|
if (wrapBidi) {
|
||||||
|
utf16.Append('.');
|
||||||
utf16.Append(UNICODE_PDF);
|
utf16.Append(UNICODE_PDF);
|
||||||
}
|
}
|
||||||
return MakeTextRunInternal(utf16.get(), aLength, aParams, headerChars);
|
return MakeTextRunInternal(utf16.get(), utf16.Length(), wrapBidi, aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxAtsuiFont*
|
gfxAtsuiFont*
|
||||||
|
@ -616,7 +620,8 @@ SetGlyphsForCharacterGroup(ATSLayoutRecord *aGlyphs, PRUint32 aGlyphCount,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PostLayoutCallback(ATSULineRef aLine, gfxTextRun *aRun,
|
PostLayoutCallback(ATSULineRef aLine, gfxTextRun *aRun,
|
||||||
const PRUnichar *aString, const PRPackedBool *aUnmatched)
|
const PRUnichar *aString, PRBool aWrapped,
|
||||||
|
const PRPackedBool *aUnmatched)
|
||||||
{
|
{
|
||||||
// AutoLayoutDataArrayPtr advanceDeltasArray(aLine, kATSUDirectDataAdvanceDeltaFixedArray);
|
// AutoLayoutDataArrayPtr advanceDeltasArray(aLine, kATSUDirectDataAdvanceDeltaFixedArray);
|
||||||
// Fixed *advanceDeltas = NS_STATIC_CAST(Fixed *, advanceDeltasArray.mArray);
|
// Fixed *advanceDeltas = NS_STATIC_CAST(Fixed *, advanceDeltasArray.mArray);
|
||||||
|
@ -640,50 +645,25 @@ PostLayoutCallback(ATSULineRef aLine, gfxTextRun *aRun,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PRUint32 appUnitsPerDevUnit = aRun->GetAppUnitsPerDevUnit();
|
PRUint32 appUnitsPerDevUnit = aRun->GetAppUnitsPerDevUnit();
|
||||||
|
|
||||||
// ATSUI seems to have a bug where trailing whitespace in a run,
|
|
||||||
// even after we've forced the direction with LRO/RLO/PDF, does not
|
|
||||||
// necessarily get the required direction.
|
|
||||||
// A specific testcase is "RLO space space PDF"; we get
|
|
||||||
// glyphRecords[0] = { originalOffset:0, realPos:0; }
|
|
||||||
// glyphRecords[1] = { originalOffset:2, realPos:>0 }
|
|
||||||
// We count the number of glyphs that appear to be this sort of erroneous
|
|
||||||
// whitespace.
|
|
||||||
// In RTL situations, the bug manifests as the trailing whitespace characters
|
|
||||||
// being rendered in LTR order at the end of the glyph array.
|
|
||||||
// In LTR situations, the bug manifests as the trailing whitespace characters
|
|
||||||
// being rendered in RTL order at the start of the glyph array.
|
|
||||||
// Compensate for this bug now by detecting those characters, setting up
|
|
||||||
// the glyphs for those characters, and then chopping those glyphs off
|
|
||||||
// the glyph array we need to look at.
|
|
||||||
PRUint32 stringTailOffset = aRun->GetLength() - 1;
|
|
||||||
PRBool isRTL = aRun->IsRightToLeft();
|
PRBool isRTL = aRun->IsRightToLeft();
|
||||||
if (isRTL) {
|
|
||||||
while (numGlyphs > 0 &&
|
if (aWrapped) {
|
||||||
glyphRecords[numGlyphs - 1].originalOffset == stringTailOffset*2 &&
|
// The glyph array includes a glyph for the artificial trailing
|
||||||
aString[stringTailOffset] == ' ') {
|
// non-whitespace character. Strip that glyph from the array now.
|
||||||
SetGlyphsForCharacterGroup(glyphRecords + numGlyphs - 1, 1,
|
if (isRTL) {
|
||||||
baselineDeltas ? baselineDeltas + numGlyphs - 1 : nsnull,
|
NS_ASSERTION(glyphRecords[0].originalOffset == aRun->GetLength()*2,
|
||||||
appUnitsPerDevUnit, aRun, aUnmatched,
|
"Couldn't find glyph for trailing marker");
|
||||||
aString);
|
glyphRecords++;
|
||||||
--stringTailOffset;
|
} else {
|
||||||
--numGlyphs;
|
NS_ASSERTION(glyphRecords[numGlyphs - 1].originalOffset == aRun->GetLength()*2,
|
||||||
}
|
"Couldn't find glyph for trailing marker");
|
||||||
} else {
|
|
||||||
while (numGlyphs > 0 &&
|
|
||||||
glyphRecords[0].originalOffset == stringTailOffset*2 &&
|
|
||||||
aString[stringTailOffset] == ' ') {
|
|
||||||
SetGlyphsForCharacterGroup(glyphRecords, 1,
|
|
||||||
baselineDeltas,
|
|
||||||
appUnitsPerDevUnit, aRun, aUnmatched,
|
|
||||||
aString);
|
|
||||||
--stringTailOffset;
|
|
||||||
--numGlyphs;
|
|
||||||
++glyphRecords;
|
|
||||||
}
|
}
|
||||||
|
--numGlyphs;
|
||||||
|
if (numGlyphs == 0)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now process the rest of the glyphs, which should basically be in
|
// Now process the glyphs, which should basically be in
|
||||||
// the textrun's desired order, so process them in textrun order
|
// the textrun's desired order, so process them in textrun order
|
||||||
PRInt32 direction = PRInt32(aRun->GetDirection());
|
PRInt32 direction = PRInt32(aRun->GetDirection());
|
||||||
while (numGlyphs > 0) {
|
while (numGlyphs > 0) {
|
||||||
|
@ -703,6 +683,12 @@ PostLayoutCallback(ATSULineRef aLine, gfxTextRun *aRun,
|
||||||
// In this case we need to make sure the glyph for the consonant
|
// In this case we need to make sure the glyph for the consonant
|
||||||
// is added to the group containing the vowel.
|
// is added to the group containing the vowel.
|
||||||
if (lastOffset < glyphOffset) {
|
if (lastOffset < glyphOffset) {
|
||||||
|
if (!aRun->IsClusterStart(glyphOffset/2)) {
|
||||||
|
// next character is a cluster continuation,
|
||||||
|
// add it to the current group
|
||||||
|
lastOffset = glyphOffset;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// We could be at the end of a character group
|
// We could be at the end of a character group
|
||||||
if (glyph->glyphID != ATSUI_SPECIAL_GLYPH_ID) {
|
if (glyph->glyphID != ATSUI_SPECIAL_GLYPH_ID) {
|
||||||
// Next character is a normal character, stop the group here
|
// Next character is a normal character, stop the group here
|
||||||
|
@ -741,6 +727,9 @@ PostLayoutCallback(ATSULineRef aLine, gfxTextRun *aRun,
|
||||||
struct PostLayoutCallbackClosure {
|
struct PostLayoutCallbackClosure {
|
||||||
gfxTextRun *mTextRun;
|
gfxTextRun *mTextRun;
|
||||||
const PRUnichar *mString;
|
const PRUnichar *mString;
|
||||||
|
// This is true when we inserted an artifical trailing character at the
|
||||||
|
// end of the string when computing the ATSUI layout.
|
||||||
|
PRPackedBool mWrapped;
|
||||||
// Either null or an array of stringlength booleans set to true for
|
// Either null or an array of stringlength booleans set to true for
|
||||||
// each character that did not match any fonts
|
// each character that did not match any fonts
|
||||||
nsAutoArrayPtr<PRPackedBool> mUnmatchedChars;
|
nsAutoArrayPtr<PRPackedBool> mUnmatchedChars;
|
||||||
|
@ -757,7 +746,8 @@ PostLayoutOperationCallback(ATSULayoutOperationSelector iCurrentOperation,
|
||||||
ATSULayoutOperationCallbackStatus *oCallbackStatus)
|
ATSULayoutOperationCallbackStatus *oCallbackStatus)
|
||||||
{
|
{
|
||||||
PostLayoutCallback(iLineRef, gCallbackClosure->mTextRun,
|
PostLayoutCallback(iLineRef, gCallbackClosure->mTextRun,
|
||||||
gCallbackClosure->mString, gCallbackClosure->mUnmatchedChars);
|
gCallbackClosure->mString, gCallbackClosure->mWrapped,
|
||||||
|
gCallbackClosure->mUnmatchedChars);
|
||||||
*oCallbackStatus = kATSULayoutOperationCallbackStatusContinue;
|
*oCallbackStatus = kATSULayoutOperationCallbackStatusContinue;
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
@ -765,30 +755,35 @@ PostLayoutOperationCallback(ATSULayoutOperationSelector iCurrentOperation,
|
||||||
void
|
void
|
||||||
gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
const PRUnichar *aString, PRUint32 aLength,
|
const PRUnichar *aString, PRUint32 aLength,
|
||||||
PRUint32 aHeaderChars)
|
PRBool aWrapped)
|
||||||
{
|
{
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
gfxAtsuiFont *atsuiFont = GetFontAt(0);
|
gfxAtsuiFont *atsuiFont = GetFontAt(0);
|
||||||
ATSUStyle mainStyle = atsuiFont->GetATSUStyle();
|
ATSUStyle mainStyle = atsuiFont->GetATSUStyle();
|
||||||
nsTArray<ATSUStyle> stylesToDispose;
|
nsTArray<ATSUStyle> stylesToDispose;
|
||||||
|
PRUint32 headerChars = aWrapped ? 1 : 0;
|
||||||
|
const PRUnichar *realString = aString + headerChars;
|
||||||
|
PRUint32 realLength = aRun->GetLength();
|
||||||
|
NS_ASSERTION(realLength == aLength - (aWrapped ? 3 : 0),
|
||||||
|
"Length mismatch");
|
||||||
|
|
||||||
#ifdef DUMP_TEXT_RUNS
|
#ifdef DUMP_TEXT_RUNS
|
||||||
NS_ConvertUTF16toUTF8 str(aString + 1, aLength);
|
NS_ConvertUTF16toUTF8 str(realString, realLength);
|
||||||
NS_ConvertUTF16toUTF8 families(mFamilies);
|
NS_ConvertUTF16toUTF8 families(mFamilies);
|
||||||
printf("%p(%s) TEXTRUN \"%s\" ENDTEXTRUN\n", this, families.get(), str.get());
|
printf("%p(%s) TEXTRUN \"%s\" ENDTEXTRUN\n", this, families.get(), str.get());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UniCharCount runLengths = aLength;
|
UniCharCount runLengths = realLength;
|
||||||
ATSUTextLayout layout;
|
ATSUTextLayout layout;
|
||||||
// The string is actually aLength + 2*aHeaderChars chars, with optionally
|
// Create the text layout for the whole string, but only produce glyphs
|
||||||
// a header char to set the direction and a trailer char to pop it. So
|
// for the text inside LRO/RLO - PDF, if present. For wrapped strings
|
||||||
// create the text layout giving the whole string as context, although we
|
// we do need to produce glyphs for the trailing non-whitespace
|
||||||
// only want glyphs for the inner substring.
|
// character to ensure that ATSUI treats all whitespace as non-trailing.
|
||||||
status = ATSUCreateTextLayoutWithTextPtr
|
status = ATSUCreateTextLayoutWithTextPtr
|
||||||
(aString,
|
(aString,
|
||||||
aHeaderChars,
|
headerChars,
|
||||||
|
realLength + (aWrapped ? 1 : 0),
|
||||||
aLength,
|
aLength,
|
||||||
aLength + aHeaderChars*2,
|
|
||||||
1,
|
1,
|
||||||
&runLengths,
|
&runLengths,
|
||||||
&mainStyle,
|
&mainStyle,
|
||||||
|
@ -797,8 +792,8 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
|
|
||||||
PostLayoutCallbackClosure closure;
|
PostLayoutCallbackClosure closure;
|
||||||
closure.mTextRun = aRun;
|
closure.mTextRun = aRun;
|
||||||
// Pass the real string to the closure, ignoring the header
|
closure.mString = realString;
|
||||||
closure.mString = aString + aHeaderChars;
|
closure.mWrapped = aWrapped;
|
||||||
NS_ASSERTION(!gCallbackClosure, "Reentering InitTextRun? Expect disaster!");
|
NS_ASSERTION(!gCallbackClosure, "Reentering InitTextRun? Expect disaster!");
|
||||||
gCallbackClosure = &closure;
|
gCallbackClosure = &closure;
|
||||||
|
|
||||||
|
@ -833,9 +828,9 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
|
|
||||||
/* Now go through and update the styles for the text, based on font matching. */
|
/* Now go through and update the styles for the text, based on font matching. */
|
||||||
|
|
||||||
UniCharArrayOffset runStart = aHeaderChars;
|
UniCharArrayOffset runStart = headerChars;
|
||||||
UniCharCount totalLength = aLength + aHeaderChars;
|
UniCharCount totalLength = runStart + realLength;
|
||||||
UniCharCount runLength = aLength;
|
UniCharCount runLength = realLength;
|
||||||
|
|
||||||
//fprintf (stderr, "==== Starting font maching [string length: %d]\n", totalLength);
|
//fprintf (stderr, "==== Starting font maching [string length: %d]\n", totalLength);
|
||||||
while (runStart < totalLength) {
|
while (runStart < totalLength) {
|
||||||
|
@ -848,7 +843,7 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
if (status == noErr) {
|
if (status == noErr) {
|
||||||
//fprintf (stderr, "ATSUMatchFontsToText returned noErr\n");
|
//fprintf (stderr, "ATSUMatchFontsToText returned noErr\n");
|
||||||
// everything's good, finish up
|
// everything's good, finish up
|
||||||
aRun->AddGlyphRun(atsuiFont, runStart - aHeaderChars);
|
aRun->AddGlyphRun(atsuiFont, runStart - headerChars);
|
||||||
break;
|
break;
|
||||||
} else if (status == kATSUFontsMatched) {
|
} else if (status == kATSUFontsMatched) {
|
||||||
//fprintf (stderr, "ATSUMatchFontsToText returned kATSUFontsMatched: FID %d\n", substituteFontID);
|
//fprintf (stderr, "ATSUMatchFontsToText returned kATSUFontsMatched: FID %d\n", substituteFontID);
|
||||||
|
@ -864,14 +859,14 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
ATSUSetAttributes (subStyle, 1, fontTags, fontArgSizes, fontArgs);
|
ATSUSetAttributes (subStyle, 1, fontTags, fontArgSizes, fontArgs);
|
||||||
|
|
||||||
if (changedOffset > runStart) {
|
if (changedOffset > runStart) {
|
||||||
aRun->AddGlyphRun(atsuiFont, runStart - aHeaderChars);
|
aRun->AddGlyphRun(atsuiFont, runStart - headerChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATSUSetRunStyle (layout, subStyle, changedOffset, changedLength);
|
ATSUSetRunStyle (layout, subStyle, changedOffset, changedLength);
|
||||||
|
|
||||||
gfxAtsuiFont *font = FindFontFor(substituteFontID);
|
gfxAtsuiFont *font = FindFontFor(substituteFontID);
|
||||||
if (font) {
|
if (font) {
|
||||||
aRun->AddGlyphRun(font, changedOffset - aHeaderChars);
|
aRun->AddGlyphRun(font, changedOffset - headerChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
stylesToDispose.AppendElement(subStyle);
|
stylesToDispose.AppendElement(subStyle);
|
||||||
|
@ -879,7 +874,7 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
//fprintf (stderr, "ATSUMatchFontsToText returned kATSUFontsNotMatched\n");
|
//fprintf (stderr, "ATSUMatchFontsToText returned kATSUFontsNotMatched\n");
|
||||||
/* I need to select the last resort font; how the heck do I do that? */
|
/* I need to select the last resort font; how the heck do I do that? */
|
||||||
// Record which font is associated with these glyphs, anyway
|
// Record which font is associated with these glyphs, anyway
|
||||||
aRun->AddGlyphRun(atsuiFont, runStart - aHeaderChars);
|
aRun->AddGlyphRun(atsuiFont, runStart - headerChars);
|
||||||
|
|
||||||
if (!closure.mUnmatchedChars) {
|
if (!closure.mUnmatchedChars) {
|
||||||
closure.mUnmatchedChars = new PRPackedBool[aLength];
|
closure.mUnmatchedChars = new PRPackedBool[aLength];
|
||||||
|
@ -888,7 +883,7 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closure.mUnmatchedChars) {
|
if (closure.mUnmatchedChars) {
|
||||||
memset(closure.mUnmatchedChars.get() + changedOffset - aHeaderChars,
|
memset(closure.mUnmatchedChars.get() + changedOffset - headerChars,
|
||||||
PR_TRUE, changedLength);
|
PR_TRUE, changedLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -903,7 +898,7 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
// the result of this call.
|
// the result of this call.
|
||||||
ATSTrapezoid trap;
|
ATSTrapezoid trap;
|
||||||
ItemCount trapCount;
|
ItemCount trapCount;
|
||||||
ATSUGetGlyphBounds(layout, 0, 0, aHeaderChars, aLength,
|
ATSUGetGlyphBounds(layout, 0, 0, headerChars, realLength,
|
||||||
kATSUseFractionalOrigins, 1, &trap, &trapCount);
|
kATSUseFractionalOrigins, 1, &trap, &trapCount);
|
||||||
|
|
||||||
ATSUDisposeTextLayout(layout);
|
ATSUDisposeTextLayout(layout);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче