Issue #457 - Remove the constructor from gfxShapedText::CompressedGlyph and make it a trivial class

Also provide a couple of convenience "factory" methods to create simple and complex glyph values.
This commit is contained in:
trav90 2022-05-28 11:45:35 -05:00 • committed by roytam1
commit c782076add
9 changed files with 137 additions and 102 deletions

View file

@ -310,6 +310,8 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
CTRunRef aCTRun, CTRunRef aCTRun,
int32_t aStringOffset) int32_t aStringOffset)
{ {
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
// The word has been bidi-wrapped; aStringOffset is the number // The word has been bidi-wrapped; aStringOffset is the number
// of chars at the beginning of the CTLine that we should skip. // of chars at the beginning of the CTLine that we should skip.
// aCTRun is a glyph run from the CoreText layout process. // aCTRun is a glyph run from the CoreText layout process.
@ -392,8 +394,7 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
nullptr, nullptr, nullptr); nullptr, nullptr, nullptr);
AutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs; AutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
gfxShapedText::CompressedGlyph *charGlyphs = CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
aShapedText->GetCharacterGlyphs() + aOffset;
// CoreText gives us the glyphindex-to-charindex mapping, which relates each glyph // CoreText gives us the glyphindex-to-charindex mapping, which relates each glyph
// to a source text character; we also need the charindex-to-glyphindex mapping to // to a source text character; we also need the charindex-to-glyphindex mapping to
@ -614,10 +615,10 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
advance = int32_t(toNextGlyph * appUnitsPerDevUnit); advance = int32_t(toNextGlyph * appUnitsPerDevUnit);
} }
gfxTextRun::CompressedGlyph textRunGlyph; bool isClusterStart = charGlyphs[baseCharIndex].IsClusterStart();
textRunGlyph.SetComplex(charGlyphs[baseCharIndex].IsClusterStart(), aShapedText->SetGlyphs(aOffset + baseCharIndex,
true, detailedGlyphs.Length()); CompressedGlyph::MakeComplex(isClusterStart, true,
aShapedText->SetGlyphs(aOffset + baseCharIndex, textRunGlyph, detailedGlyphs.Length()),
detailedGlyphs.Elements()); detailedGlyphs.Elements());
detailedGlyphs.Clear(); detailedGlyphs.Clear();
@ -625,7 +626,7 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
// the rest of the chars in the group are ligature continuations, no associated glyphs // the rest of the chars in the group are ligature continuations, no associated glyphs
while (++baseCharIndex != endCharIndex && baseCharIndex < wordLength) { while (++baseCharIndex != endCharIndex && baseCharIndex < wordLength) {
gfxShapedText::CompressedGlyph &shapedTextGlyph = charGlyphs[baseCharIndex]; CompressedGlyph &shapedTextGlyph = charGlyphs[baseCharIndex];
NS_ASSERTION(!shapedTextGlyph.IsSimpleGlyph(), "overwriting a simple glyph"); NS_ASSERTION(!shapedTextGlyph.IsSimpleGlyph(), "overwriting a simple glyph");
shapedTextGlyph.SetComplex(inOrder && shapedTextGlyph.IsClusterStart(), false, 0); shapedTextGlyph.SetComplex(inOrder && shapedTextGlyph.IsClusterStart(), false, 0);
} }

View file

@ -62,13 +62,14 @@ void
gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset, gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
uint32_t aLength, gfxShapedText *aShapedText) uint32_t aLength, gfxShapedText *aShapedText)
{ {
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
const uint32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit(); const uint32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
// we'll pass this in/figure it out dynamically, but at this point there can be only one face. // we'll pass this in/figure it out dynamically, but at this point there can be only one face.
gfxFT2LockedFace faceLock(this); gfxFT2LockedFace faceLock(this);
FT_Face face = faceLock.get(); FT_Face face = faceLock.get();
gfxShapedText::CompressedGlyph *charGlyphs = CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs();
aShapedText->GetCharacterGlyphs();
const gfxFT2Font::CachedGlyphData *cgd = nullptr, *cgdNext = nullptr; const gfxFT2Font::CachedGlyphData *cgd = nullptr, *cgdNext = nullptr;
@ -135,8 +136,8 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
} }
if (advance >= 0 && if (advance >= 0 &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(advance) && CompressedGlyph::IsSimpleAdvance(advance) &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(gid)) { CompressedGlyph::IsSimpleGlyphID(gid)) {
charGlyphs[aOffset].SetSimpleGlyph(advance, gid); charGlyphs[aOffset].SetSimpleGlyph(advance, gid);
} else if (gid == 0) { } else if (gid == 0) {
// gid = 0 only happens when the glyph is missing from the font // gid = 0 only happens when the glyph is missing from the font
@ -149,9 +150,11 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
details.mAdvance = advance; details.mAdvance = advance;
details.mXOffset = 0; details.mXOffset = 0;
details.mYOffset = 0; details.mYOffset = 0;
gfxShapedText::CompressedGlyph g; bool isClusterStart = charGlyphs[aOffset].IsClusterStart();
g.SetComplex(charGlyphs[aOffset].IsClusterStart(), true, 1); aShapedText->SetGlyphs(aOffset,
aShapedText->SetGlyphs(aOffset, g, &details); CompressedGlyph::MakeComplex(isClusterStart,
true, 1),
&details);
} }
} }
} }

View file

@ -639,10 +639,10 @@ gfxShapedText::SetupClusterBoundaries(uint32_t aOffset,
const char16_t *aString, const char16_t *aString,
uint32_t aLength) uint32_t aLength)
{ {
CompressedGlyph *glyphs = GetCharacterGlyphs() + aOffset; CompressedGlyph* glyphs = GetCharacterGlyphs() + aOffset;
gfxTextRun::CompressedGlyph extendCluster; CompressedGlyph extendCluster =
extendCluster.SetComplex(false, true, 0); CompressedGlyph::MakeComplex(false, true, 0);
ClusterIterator iter(aString, aLength); ClusterIterator iter(aString, aLength);

View file

@ -712,8 +712,6 @@ public:
*/ */
class CompressedGlyph { class CompressedGlyph {
public: public:
CompressedGlyph() { mValue = 0; }
enum { enum {
// Indicates that a cluster and ligature group starts at this // Indicates that a cluster and ligature group starts at this
// character; this character has a single glyph with a reasonable // character; this character has a single glyph with a reasonable
@ -843,25 +841,52 @@ public:
return toggle; return toggle;
} }
CompressedGlyph& SetSimpleGlyph(uint32_t aAdvanceAppUnits, uint32_t aGlyph) { // Create a CompressedGlyph value representing a simple glyph with
// no extra flags (line-break or is_space) set.
static CompressedGlyph
MakeSimpleGlyph(uint32_t aAdvanceAppUnits, uint32_t aGlyph) {
NS_ASSERTION(IsSimpleAdvance(aAdvanceAppUnits), "Advance overflow"); NS_ASSERTION(IsSimpleAdvance(aAdvanceAppUnits), "Advance overflow");
NS_ASSERTION(IsSimpleGlyphID(aGlyph), "Glyph overflow"); NS_ASSERTION(IsSimpleGlyphID(aGlyph), "Glyph overflow");
CompressedGlyph g;
g.mValue = FLAG_IS_SIMPLE_GLYPH |
(aAdvanceAppUnits << ADVANCE_SHIFT) |
aGlyph;
return g;
}
// Assign a simple glyph value to an existing CompressedGlyph record,
// preserving line-break/is-space flags if present.
CompressedGlyph& SetSimpleGlyph(uint32_t aAdvanceAppUnits,
uint32_t aGlyph) {
NS_ASSERTION(!CharTypeFlags(), "Char type flags lost"); NS_ASSERTION(!CharTypeFlags(), "Char type flags lost");
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) | mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_IS_SIMPLE_GLYPH | MakeSimpleGlyph(aAdvanceAppUnits, aGlyph).mValue;
(aAdvanceAppUnits << ADVANCE_SHIFT) | aGlyph;
return *this; return *this;
} }
// Create a CompressedGlyph value representing a complex glyph record,
// without any line-break or char-type flags.
static CompressedGlyph
MakeComplex(bool aClusterStart, bool aLigatureStart,
uint32_t aGlyphCount) {
CompressedGlyph g;
g.mValue = FLAG_NOT_MISSING |
(aClusterStart ? 0 : FLAG_NOT_CLUSTER_START) |
(aLigatureStart ? 0 : FLAG_NOT_LIGATURE_GROUP_START) |
(aGlyphCount << GLYPH_COUNT_SHIFT);
return g;
}
// Assign a complex glyph value to an existing CompressedGlyph record,
// preserving line-break/char-type flags if present.
CompressedGlyph& SetComplex(bool aClusterStart, bool aLigatureStart, CompressedGlyph& SetComplex(bool aClusterStart, bool aLigatureStart,
uint32_t aGlyphCount) { uint32_t aGlyphCount) {
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) | mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_NOT_MISSING |
CharTypeFlags() | CharTypeFlags() |
(aClusterStart ? 0 : FLAG_NOT_CLUSTER_START) | MakeComplex(aClusterStart, aLigatureStart, aGlyphCount).mValue;
(aLigatureStart ? 0 : FLAG_NOT_LIGATURE_GROUP_START) |
(aGlyphCount << GLYPH_COUNT_SHIFT);
return *this; return *this;
} }
/** /**
* Missing glyphs are treated as ligature group starts; don't mess with * Missing glyphs are treated as ligature group starts; don't mess with
* the cluster-start flag (see bugs 618870 and 619286). * the cluster-start flag (see bugs 618870 and 619286).

View file

@ -215,6 +215,8 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
const char16_t *aText, const char16_t *aText,
gr_segment *aSegment) gr_segment *aSegment)
{ {
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
int32_t dev2appUnits = aShapedText->GetAppUnitsPerDevUnit(); int32_t dev2appUnits = aShapedText->GetAppUnitsPerDevUnit();
bool rtl = aShapedText->IsRightToLeft(); bool rtl = aShapedText->IsRightToLeft();
@ -291,8 +293,7 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
bool roundX, roundY; bool roundX, roundY;
GetRoundOffsetsToPixels(aDrawTarget, &roundX, &roundY); GetRoundOffsetsToPixels(aDrawTarget, &roundX, &roundY);
gfxShapedText::CompressedGlyph *charGlyphs = CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
aShapedText->GetCharacterGlyphs() + aOffset;
// now put glyphs into the textrun, one cluster at a time // now put glyphs into the textrun, one cluster at a time
for (uint32_t i = 0; i <= cIndex; ++i) { for (uint32_t i = 0; i <= cIndex; ++i) {
@ -325,8 +326,8 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
uint32_t appAdvance = roundX ? NSToIntRound(adv) * dev2appUnits : uint32_t appAdvance = roundX ? NSToIntRound(adv) * dev2appUnits :
NSToIntRound(adv * dev2appUnits); NSToIntRound(adv * dev2appUnits);
if (c.nGlyphs == 1 && if (c.nGlyphs == 1 &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(gids[c.baseGlyph]) && CompressedGlyph::IsSimpleGlyphID(gids[c.baseGlyph]) &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(appAdvance) && CompressedGlyph::IsSimpleAdvance(appAdvance) &&
charGlyphs[offs].IsClusterStart() && charGlyphs[offs].IsClusterStart() &&
yLocs[c.baseGlyph] == 0) yLocs[c.baseGlyph] == 0)
{ {
@ -352,15 +353,17 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
d->mAdvance = 0; d->mAdvance = 0;
} }
} }
gfxShapedText::CompressedGlyph g; bool isClusterStart = charGlyphs[offs].IsClusterStart();
g.SetComplex(charGlyphs[offs].IsClusterStart(), aShapedText->SetGlyphs(aOffset + offs,
true, details.Length()); CompressedGlyph::MakeComplex(isClusterStart,
aShapedText->SetGlyphs(aOffset + offs, g, details.Elements()); true,
details.Length()),
details.Elements());
} }
for (uint32_t j = c.baseChar + 1; j < c.baseChar + c.nChars; ++j) { for (uint32_t j = c.baseChar + 1; j < c.baseChar + c.nChars; ++j) {
NS_ASSERTION(j < aLength, "unexpected offset"); NS_ASSERTION(j < aLength, "unexpected offset");
gfxShapedText::CompressedGlyph &g = charGlyphs[j]; CompressedGlyph &g = charGlyphs[j];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph"); NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(g.IsClusterStart(), false, 0); g.SetComplex(g.IsClusterStart(), false, 0);
} }

View file

@ -1503,6 +1503,8 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(DrawTarget *aDrawTarget,
hb_buffer_t *aBuffer, hb_buffer_t *aBuffer,
bool aVertical) bool aVertical)
{ {
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
uint32_t numGlyphs; uint32_t numGlyphs;
const hb_glyph_info_t *ginfo = hb_buffer_get_glyph_infos(aBuffer, &numGlyphs); const hb_glyph_info_t *ginfo = hb_buffer_get_glyph_infos(aBuffer, &numGlyphs);
if (numGlyphs == 0) { if (numGlyphs == 0) {
@ -1541,8 +1543,7 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(DrawTarget *aDrawTarget,
} }
int32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit(); int32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
gfxShapedText::CompressedGlyph *charGlyphs = CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
aShapedText->GetCharacterGlyphs() + aOffset;
// factor to convert 16.16 fixed-point pixels to app units // factor to convert 16.16 fixed-point pixels to app units
// (only used if not rounding) // (only used if not rounding)
@ -1688,8 +1689,8 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(DrawTarget *aDrawTarget,
} }
// Check if it's a simple one-to-one mapping // Check if it's a simple one-to-one mapping
if (glyphsInClump == 1 && if (glyphsInClump == 1 &&
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(ginfo[glyphStart].codepoint) && CompressedGlyph::IsSimpleGlyphID(ginfo[glyphStart].codepoint) &&
gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) && CompressedGlyph::IsSimpleAdvance(advance) &&
charGlyphs[baseCharIndex].IsClusterStart() && charGlyphs[baseCharIndex].IsClusterStart() &&
iOffset == 0 && b_offset == 0 && iOffset == 0 && b_offset == 0 &&
b_advance == 0 && bPos == 0) b_advance == 0 && bPos == 0)
@ -1760,11 +1761,12 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(DrawTarget *aDrawTarget,
} }
} }
gfxShapedText::CompressedGlyph g; bool isClusterStart = charGlyphs[baseCharIndex].IsClusterStart();
g.SetComplex(charGlyphs[baseCharIndex].IsClusterStart(),
true, detailedGlyphs.Length());
aShapedText->SetGlyphs(aOffset + baseCharIndex, aShapedText->SetGlyphs(aOffset + baseCharIndex,
g, detailedGlyphs.Elements()); CompressedGlyph::MakeComplex(isClusterStart,
true,
detailedGlyphs.Length()),
detailedGlyphs.Elements());
detailedGlyphs.Clear(); detailedGlyphs.Clear();
} }
@ -1773,7 +1775,7 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(DrawTarget *aDrawTarget,
// no associated glyphs // no associated glyphs
while (++baseCharIndex != endCharIndex && while (++baseCharIndex != endCharIndex &&
baseCharIndex < int32_t(wordLength)) { baseCharIndex < int32_t(wordLength)) {
gfxShapedText::CompressedGlyph &g = charGlyphs[baseCharIndex]; CompressedGlyph &g = charGlyphs[baseCharIndex];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph"); NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(g.IsClusterStart(), false, 0); g.SetComplex(g.IsClusterStart(), false, 0);
} }

View file

@ -1439,8 +1439,8 @@ gfxTextRun::SetSpaceGlyphIfSimple(gfxFont* aFont, uint32_t aCharIndex,
AddGlyphRun(aFont, gfxTextRange::kFontGroup, aCharIndex, false, AddGlyphRun(aFont, gfxTextRange::kFontGroup, aCharIndex, false,
aOrientation); aOrientation);
CompressedGlyph g; CompressedGlyph g =
g.SetSimpleGlyph(spaceWidthAppUnits, spaceGlyph); CompressedGlyph::MakeSimpleGlyph(spaceWidthAppUnits, spaceGlyph);
if (aSpaceChar == ' ') { if (aSpaceChar == ' ') {
g.SetIsSpace(); g.SetIsSpace();
} }
@ -2514,8 +2514,8 @@ gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget,
detailedGlyph.mGlyphID = mainFont->GetSpaceGlyph(); detailedGlyph.mGlyphID = mainFont->GetSpaceGlyph();
detailedGlyph.mAdvance = advance; detailedGlyph.mAdvance = advance;
detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0; detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0;
gfxShapedText::CompressedGlyph g; CompressedGlyph g =
g.SetComplex(true, true, 1); CompressedGlyph::MakeComplex(true, true, 1);
aTextRun->SetGlyphs(aOffset + index, aTextRun->SetGlyphs(aOffset + index,
g, &detailedGlyph); g, &detailedGlyph);
} }

View file

@ -765,6 +765,7 @@ private:
class gfxFontGroup : public gfxTextRunFactory { class gfxFontGroup : public gfxTextRunFactory {
public: public:
typedef mozilla::unicode::Script Script; typedef mozilla::unicode::Script Script;
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
static void Shutdown(); // platform must call this to release the languageAtomService static void Shutdown(); // platform must call this to release the languageAtomService

View file

@ -581,9 +581,9 @@ nsOpenTypeTable::MakeTextRun(DrawTarget* aDrawTarget,
aFontGroup->GetFirstValidFont()-> aFontGroup->GetFirstValidFont()->
GetGlyphHAdvance(aDrawTarget, aGlyph.glyphID)); GetGlyphHAdvance(aDrawTarget, aGlyph.glyphID));
detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0; detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0;
gfxShapedText::CompressedGlyph g; textRun->SetGlyphs(0,
g.SetComplex(true, true, 1); gfxShapedText::CompressedGlyph::MakeComplex(true, true, 1),
textRun->SetGlyphs(0, g, &detailedGlyph); &detailedGlyph);
return textRun.forget(); return textRun.forget();
} }