Bug 1781177 - Refactor gfxFont::GetShapedWord to use lambdas. r=jfkthame

Differential Revision: https://phabricator.services.mozilla.com/D153634
This commit is contained in:
Andrew Osmond 2022-08-04 10:42:45 +00:00
parent 5b42f788fb
commit f229ed975f
3 changed files with 69 additions and 54 deletions

View File

@ -2849,12 +2849,13 @@ static char16_t IsBoundarySpace(char16_t aChar, char16_t aNextChar) {
# define GFX_MAYBE_UNUSED
#endif
template <typename T>
gfxShapedWord* gfxFont::GetShapedWord(
template <typename T, typename Func>
bool gfxFont::ProcessShapedWordInternal(
DrawTarget* aDrawTarget, const T* aText, uint32_t aLength, uint32_t aHash,
Script aRunScript, nsAtom* aLanguage, bool aVertical,
int32_t aAppUnitsPerDevUnit, gfx::ShapedTextFlags aFlags,
RoundingFlags aRounding, gfxTextPerfMetrics* aTextPerf GFX_MAYBE_UNUSED) {
RoundingFlags aRounding, gfxTextPerfMetrics* aTextPerf GFX_MAYBE_UNUSED,
Func aCallback) {
CacheHashKey key(aText, aLength, aHash, aRunScript, aLanguage,
aAppUnitsPerDevUnit, aFlags, aRounding);
{
@ -2871,7 +2872,8 @@ gfxShapedWord* gfxFont::GetShapedWord(
aTextPerf->current.wordCacheHit++;
}
#endif
return sw;
aCallback(sw);
return true;
}
}
}
@ -2885,7 +2887,7 @@ gfxShapedWord* gfxFont::GetShapedWord(
aAppUnitsPerDevUnit, aFlags, aRounding);
if (!sw) {
NS_WARNING("failed to create gfxShapedWord - expect missing text");
return nullptr;
return false;
}
DebugOnly<bool> ok = ShapeText(aDrawTarget, aText, 0, aLength, aRunScript,
aLanguage, aVertical, aRounding, sw);
@ -2910,7 +2912,7 @@ gfxShapedWord* gfxFont::GetShapedWord(
if (!entry) {
NS_WARNING("failed to create word cache entry - expect missing text");
delete sw;
return nullptr;
return false;
}
// It's unlikely, but maybe another thread got there before us...
@ -2924,7 +2926,8 @@ gfxShapedWord* gfxFont::GetShapedWord(
aTextPerf->current.wordCacheHit++;
}
#endif
return sw;
aCallback(sw);
return true;
}
entry->mShapedWord.reset(sw);
@ -2934,19 +2937,13 @@ gfxShapedWord* gfxFont::GetShapedWord(
aTextPerf->current.wordCacheMiss++;
}
#endif
aCallback(sw);
}
gfxFontCache::GetCache()->RunWordCacheExpirationTimer();
return sw;
return true;
}
template gfxShapedWord* gfxFont::GetShapedWord(
DrawTarget* aDrawTarget, const uint8_t* aText, uint32_t aLength,
uint32_t aHash, Script aRunScript, nsAtom* aLanguage, bool aVertical,
int32_t aAppUnitsPerDevUnit, gfx::ShapedTextFlags aFlags,
RoundingFlags aRounding, gfxTextPerfMetrics* aTextPerf);
bool gfxFont::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const {
const gfxShapedWord* sw = mShapedWord.get();
if (!sw) {
@ -2984,6 +2981,17 @@ bool gfxFont::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const {
aKey->mLength * sizeof(char16_t)));
}
bool gfxFont::ProcessSingleSpaceShapedWord(
DrawTarget* aDrawTarget, bool aVertical, int32_t aAppUnitsPerDevUnit,
gfx::ShapedTextFlags aFlags, RoundingFlags aRounding,
const std::function<void(gfxShapedWord*)>& aCallback) {
static const uint8_t space = ' ';
return ProcessShapedWordInternal(
aDrawTarget, &space, 1, gfxShapedWord::HashMix(0, ' '), Script::LATIN,
/* aLanguage = */ nullptr, aVertical, aAppUnitsPerDevUnit, aFlags,
aRounding, nullptr, aCallback);
}
bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const uint8_t* aText,
uint32_t aOffset, uint32_t aLength, Script aScript,
nsAtom* aLanguage, bool aVertical,
@ -3325,12 +3333,13 @@ bool gfxFont::SplitAndInitTextRun(
wordFlags |= gfx::ShapedTextFlags::TEXT_IS_8BIT;
}
}
gfxShapedWord* sw = GetShapedWord(
bool processed = ProcessShapedWordInternal(
aDrawTarget, aString + wordStart, length, hash, aRunScript, aLanguage,
vertical, appUnitsPerDevUnit, wordFlags, rounding, tp);
if (sw) {
aTextRun->CopyGlyphDataFrom(sw, aRunStart + wordStart);
} else {
vertical, appUnitsPerDevUnit, wordFlags, rounding, tp,
[&](gfxShapedWord* aShapedWord) {
aTextRun->CopyGlyphDataFrom(aShapedWord, aRunStart + wordStart);
});
if (!processed) {
return false; // failed, presumably out of memory?
}
}
@ -3348,16 +3357,17 @@ bool gfxFont::SplitAndInitTextRun(
// Avoid tautological-constant-out-of-range-compare in 8-bit:
DebugOnly<char16_t> boundary16 = boundary;
NS_ASSERTION(boundary16 < 256, "unexpected boundary!");
gfxShapedWord* sw = GetShapedWord(
bool processed = ProcessShapedWordInternal(
aDrawTarget, &boundary, 1, gfxShapedWord::HashMix(0, boundary),
aRunScript, aLanguage, vertical, appUnitsPerDevUnit,
flags | gfx::ShapedTextFlags::TEXT_IS_8BIT, rounding, tp);
if (sw) {
aTextRun->CopyGlyphDataFrom(sw, aRunStart + i);
if (boundary == ' ') {
aTextRun->GetCharacterGlyphs()[aRunStart + i].SetIsSpace();
}
} else {
flags | gfx::ShapedTextFlags::TEXT_IS_8BIT, rounding, tp,
[&](gfxShapedWord* aShapedWord) {
aTextRun->CopyGlyphDataFrom(aShapedWord, aRunStart + i);
if (boundary == ' ') {
aTextRun->GetCharacterGlyphs()[aRunStart + i].SetIsSpace();
}
});
if (!processed) {
return false;
}
}

View File

@ -9,6 +9,7 @@
#include <new>
#include <utility>
#include <functional>
#include "PLDHashTable.h"
#include "ThebesRLBoxTypes.h"
#include "gfxFontVariations.h"
@ -1803,16 +1804,12 @@ class gfxFont {
nsAtom* aLanguage,
mozilla::gfx::ShapedTextFlags aOrientation);
// Get a ShapedWord representing the given text (either 8- or 16-bit)
// for use in setting up a gfxTextRun.
template <typename T>
gfxShapedWord* GetShapedWord(DrawTarget* aDrawTarget, const T* aText,
uint32_t aLength, uint32_t aHash,
Script aRunScript, nsAtom* aLanguage,
bool aVertical, int32_t aAppUnitsPerDevUnit,
mozilla::gfx::ShapedTextFlags aFlags,
RoundingFlags aRounding,
gfxTextPerfMetrics* aTextPerf);
// Get a ShapedWord representing a single space for use in setting up a
// gfxTextRun.
bool ProcessSingleSpaceShapedWord(
DrawTarget* aDrawTarget, bool aVertical, int32_t aAppUnitsPerDevUnit,
mozilla::gfx::ShapedTextFlags aFlags, RoundingFlags aRounding,
const std::function<void(gfxShapedWord*)>& aCallback);
// Called by the gfxFontCache timer to increment the age of all the words,
// so that they'll expire after a sufficient period of non-use.
@ -2049,6 +2046,17 @@ class gfxFont {
void CheckForFeaturesInvolvingSpace() const;
// Get a ShapedWord representing the given text (either 8- or 16-bit)
// for use in setting up a gfxTextRun.
template <typename T, typename Func>
bool ProcessShapedWordInternal(DrawTarget* aDrawTarget, const T* aText,
uint32_t aLength, uint32_t aHash,
Script aRunScript, nsAtom* aLanguage,
bool aVertical, int32_t aAppUnitsPerDevUnit,
mozilla::gfx::ShapedTextFlags aFlags,
RoundingFlags aRounding,
gfxTextPerfMetrics* aTextPerf, Func aCallback);
// whether a given feature is included in feature settings from both the
// font and the style. aFeatureOn set if resolved feature value is non-zero
bool HasFeatureSet(uint32_t aFeature, bool& aFeatureOn);

View File

@ -1582,28 +1582,25 @@ void gfxTextRun::SetSpaceGlyph(gfxFont* aFont, DrawTarget* aDrawTarget,
return;
}
static const uint8_t space = ' ';
gfx::ShapedTextFlags flags =
gfx::ShapedTextFlags::TEXT_IS_8BIT | aOrientation;
bool vertical =
!!(GetFlags() & gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT);
gfxFontShaper::RoundingFlags roundingFlags =
aFont->GetRoundOffsetsToPixels(aDrawTarget);
gfxShapedWord* sw = aFont->GetShapedWord(
aDrawTarget, &space, 1, gfxShapedWord::HashMix(0, ' '), Script::LATIN,
/* aLanguage = */ nullptr, vertical, mAppUnitsPerDevUnit, flags,
roundingFlags, nullptr);
if (sw) {
const GlyphRun* prevRun = TrailingGlyphRun();
bool isCJK = prevRun && prevRun->mFont == aFont &&
prevRun->mOrientation == aOrientation
? prevRun->mIsCJK
: false;
AddGlyphRun(aFont, FontMatchType::Kind::kUnspecified, aCharIndex, false,
aOrientation, isCJK);
CopyGlyphDataFrom(sw, aCharIndex);
GetCharacterGlyphs()[aCharIndex].SetIsSpace();
}
aFont->ProcessSingleSpaceShapedWord(
aDrawTarget, vertical, mAppUnitsPerDevUnit, flags, roundingFlags,
[&](gfxShapedWord* aShapedWord) {
const GlyphRun* prevRun = TrailingGlyphRun();
bool isCJK = prevRun && prevRun->mFont == aFont &&
prevRun->mOrientation == aOrientation
? prevRun->mIsCJK
: false;
AddGlyphRun(aFont, FontMatchType::Kind::kUnspecified, aCharIndex, false,
aOrientation, isCJK);
CopyGlyphDataFrom(aShapedWord, aCharIndex);
GetCharacterGlyphs()[aCharIndex].SetIsSpace();
});
}
bool gfxTextRun::SetSpaceGlyphIfSimple(gfxFont* aFont, uint32_t aCharIndex,