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

View file

@ -62,13 +62,14 @@ void
gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
uint32_t aLength, gfxShapedText *aShapedText)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
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.
gfxFT2LockedFace faceLock(this);
FT_Face face = faceLock.get();
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs();
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs();
const gfxFT2Font::CachedGlyphData *cgd = nullptr, *cgdNext = nullptr;
@ -135,8 +136,8 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
}
if (advance >= 0 &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(advance) &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(gid)) {
CompressedGlyph::IsSimpleAdvance(advance) &&
CompressedGlyph::IsSimpleGlyphID(gid)) {
charGlyphs[aOffset].SetSimpleGlyph(advance, gid);
} else if (gid == 0) {
// 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.mXOffset = 0;
details.mYOffset = 0;
gfxShapedText::CompressedGlyph g;
g.SetComplex(charGlyphs[aOffset].IsClusterStart(), true, 1);
aShapedText->SetGlyphs(aOffset, g, &details);
bool isClusterStart = charGlyphs[aOffset].IsClusterStart();
aShapedText->SetGlyphs(aOffset,
CompressedGlyph::MakeComplex(isClusterStart,
true, 1),
&details);
}
}
}

View file

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

View file

@ -712,8 +712,6 @@ public:
*/
class CompressedGlyph {
public:
CompressedGlyph() { mValue = 0; }
enum {
// Indicates that a cluster and ligature group starts at this
// character; this character has a single glyph with a reasonable
@ -843,25 +841,52 @@ public:
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(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");
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_IS_SIMPLE_GLYPH |
(aAdvanceAppUnits << ADVANCE_SHIFT) | aGlyph;
MakeSimpleGlyph(aAdvanceAppUnits, aGlyph).mValue;
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,
uint32_t aGlyphCount) {
uint32_t aGlyphCount) {
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_NOT_MISSING |
CharTypeFlags() |
(aClusterStart ? 0 : FLAG_NOT_CLUSTER_START) |
(aLigatureStart ? 0 : FLAG_NOT_LIGATURE_GROUP_START) |
(aGlyphCount << GLYPH_COUNT_SHIFT);
MakeComplex(aClusterStart, aLigatureStart, aGlyphCount).mValue;
return *this;
}
/**
* Missing glyphs are treated as ligature group starts; don't mess with
* the cluster-start flag (see bugs 618870 and 619286).

View file

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

View file

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

View file

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

View file

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