зеркало из https://github.com/mozilla/pjs.git
Bug 407761. Don't try to get/use extents for missing glyphs, and tolerate glyph extents that might be missing due to OOM. r=vlad
This commit is contained in:
Родитель
d64ce5e03c
Коммит
bdc1c51761
|
@ -272,7 +272,10 @@ public:
|
|||
}
|
||||
|
||||
// Get glyph extents; a rectangle relative to the left baseline origin
|
||||
gfxRect GetTightGlyphExtentsAppUnits(gfxFont *aFont, gfxContext *aContext, PRUint32 aGlyphID);
|
||||
// Returns true on success. Can fail on OOM or when aContext is null
|
||||
// and extents were not (successfully) prefetched.
|
||||
PRBool GetTightGlyphExtentsAppUnits(gfxFont *aFont, gfxContext *aContext,
|
||||
PRUint32 aGlyphID, gfxRect *aExtents);
|
||||
|
||||
void SetContainedGlyphWidthAppUnits(PRUint32 aGlyphID, PRUint16 aWidth) {
|
||||
mContainedGlyphWidths.Set(aGlyphID, aWidth);
|
||||
|
@ -488,6 +491,8 @@ public:
|
|||
* the advance width for the character run,y=-(font ascent), and height=
|
||||
* font ascent + font descent). Otherwise, we must return as tight as possible
|
||||
* an approximation to the area actually painted by glyphs.
|
||||
* @param aContextForTightBoundingBox when aTight is true, this must
|
||||
* be non-null.
|
||||
* @param aSpacing spacing to insert before and after glyphs. The bounding box
|
||||
* need not include the spacing itself, but the spacing affects the glyph
|
||||
* positions. null if there is no spacing.
|
||||
|
@ -1203,6 +1208,12 @@ public:
|
|||
void SetMissingGlyph(PRUint32 aCharIndex, PRUint32 aUnicodeChar);
|
||||
void SetSpaceGlyph(gfxFont *aFont, gfxContext *aContext, PRUint32 aCharIndex);
|
||||
|
||||
/**
|
||||
* Prefetch all the glyph extents needed to ensure that Measure calls
|
||||
* on this textrun with aTightBoundingBox false will succeed. Note
|
||||
* that some glyph extents might not be fetched due to OOM or other
|
||||
* errors.
|
||||
*/
|
||||
void FetchGlyphExtents(gfxContext *aRefContext);
|
||||
|
||||
// API for access to the raw glyph data, needed by gfxFont::Draw
|
||||
|
@ -1402,6 +1413,7 @@ public:
|
|||
* Make a textrun for a given string.
|
||||
* If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the
|
||||
* textrun will copy it.
|
||||
* This calls FetchGlyphExtents on the textrun.
|
||||
*/
|
||||
virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags) = 0;
|
||||
|
@ -1409,6 +1421,7 @@ public:
|
|||
* Make a textrun for a given string.
|
||||
* If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the
|
||||
* textrun will copy it.
|
||||
* This calls FetchGlyphExtents on the textrun.
|
||||
*/
|
||||
virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags) = 0;
|
||||
|
|
|
@ -405,14 +405,18 @@ gfxFont::Measure(gfxTextRun *aTextRun,
|
|||
double advance = glyphData->GetSimpleAdvance();
|
||||
// Only get the real glyph horizontal extent if we were asked
|
||||
// for the tight bounding box or we're in quality mode
|
||||
if (aTightBoundingBox || NeedsGlyphExtents(aTextRun)) {
|
||||
if ((aTightBoundingBox || NeedsGlyphExtents(aTextRun)) && extents) {
|
||||
PRUint32 glyphIndex = glyphData->GetSimpleGlyph();
|
||||
PRUint16 extentsWidth = extents->GetContainedGlyphWidthAppUnits(glyphIndex);
|
||||
if (extentsWidth != gfxGlyphExtents::INVALID_WIDTH && !aTightBoundingBox) {
|
||||
UnionWithXPoint(&metrics.mBoundingBox, x + direction*extentsWidth);
|
||||
} else {
|
||||
gfxRect glyphRect =
|
||||
extents->GetTightGlyphExtentsAppUnits(this, aRefContext, glyphIndex);
|
||||
gfxRect glyphRect;
|
||||
if (!extents->GetTightGlyphExtentsAppUnits(this,
|
||||
aRefContext, glyphIndex, &glyphRect)) {
|
||||
glyphRect = gfxRect(0, metrics.mBoundingBox.Y(),
|
||||
advance, metrics.mBoundingBox.Height());
|
||||
}
|
||||
if (isRTL) {
|
||||
glyphRect.pos.x -= advance;
|
||||
}
|
||||
|
@ -429,8 +433,15 @@ gfxFont::Measure(gfxTextRun *aTextRun,
|
|||
PRUint32 glyphIndex = details->mGlyphID;
|
||||
gfxPoint glyphPt(x + details->mXOffset, details->mYOffset);
|
||||
double advance = details->mAdvance;
|
||||
gfxRect glyphRect =
|
||||
extents->GetTightGlyphExtentsAppUnits(this, aRefContext, glyphIndex);
|
||||
gfxRect glyphRect;
|
||||
if (glyphData->IsMissing() || !extents ||
|
||||
!extents->GetTightGlyphExtentsAppUnits(this,
|
||||
aRefContext, glyphIndex, &glyphRect)) {
|
||||
// We might have failed to get glyph extents due to
|
||||
// OOM or something
|
||||
glyphRect = gfxRect(0, metrics.mBoundingBox.Y(),
|
||||
advance, metrics.mBoundingBox.Height());
|
||||
}
|
||||
if (isRTL) {
|
||||
glyphRect.pos.x -= advance;
|
||||
}
|
||||
|
@ -522,12 +533,17 @@ gfxGlyphExtents::~gfxGlyphExtents()
|
|||
MOZ_COUNT_DTOR(gfxGlyphExtents);
|
||||
}
|
||||
|
||||
gfxRect
|
||||
PRBool
|
||||
gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
|
||||
gfxContext *aContext, PRUint32 aGlyphID)
|
||||
gfxContext *aContext, PRUint32 aGlyphID, gfxRect *aExtents)
|
||||
{
|
||||
HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID);
|
||||
if (!entry) {
|
||||
if (!aContext) {
|
||||
NS_WARNING("Could not get glyph extents (no aContext)");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
aFont->SetupCairoFont(aContext);
|
||||
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
|
||||
++gGlyphExtentsSetupLazyTight;
|
||||
|
@ -536,11 +552,12 @@ gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
|
|||
entry = mTightGlyphExtents.GetEntry(aGlyphID);
|
||||
if (!entry) {
|
||||
NS_WARNING("Could not get glyph extents");
|
||||
return gfxRect(0,0,0,0);
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return gfxRect(entry->x, entry->y, entry->width, entry->height);
|
||||
*aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gfxGlyphExtents::GlyphWidths::~GlyphWidths()
|
||||
|
@ -1931,7 +1948,7 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
|
|||
font->SetupGlyphExtents(aRefContext, glyphIndex, PR_FALSE, extents);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (!glyphData->IsMissing()) {
|
||||
PRUint32 k;
|
||||
PRUint32 glyphCount = glyphData->GetGlyphCount();
|
||||
const gfxTextRun::DetailedGlyph *details = GetDetailedGlyphs(j);
|
||||
|
|
Загрузка…
Ссылка в новой задаче