mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-23 15:47:30 +09:00
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:
parent
1cdbf6eb6a
commit
c782076add
9 changed files with 137 additions and 102 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ struct gfxTextRange {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Font cache design:
|
* Font cache design:
|
||||||
*
|
*
|
||||||
* The mFonts hashtable contains most fonts, indexed by (gfxFontEntry*, style).
|
* The mFonts hashtable contains most fonts, indexed by (gfxFontEntry*, style).
|
||||||
* It does not add a reference to the fonts it contains.
|
* It does not add a reference to the fonts it contains.
|
||||||
* When a font's refcount decreases to zero, instead of deleting it we
|
* When a font's refcount decreases to zero, instead of deleting it we
|
||||||
|
|
@ -699,21 +699,19 @@ public:
|
||||||
* This class records the information associated with a character in the
|
* This class records the information associated with a character in the
|
||||||
* input string. It's optimized for the case where there is one glyph
|
* input string. It's optimized for the case where there is one glyph
|
||||||
* representing that character alone.
|
* representing that character alone.
|
||||||
*
|
*
|
||||||
* A character can have zero or more associated glyphs. Each glyph
|
* A character can have zero or more associated glyphs. Each glyph
|
||||||
* has an advance width and an x and y offset.
|
* has an advance width and an x and y offset.
|
||||||
* A character may be the start of a cluster.
|
* A character may be the start of a cluster.
|
||||||
* A character may be the start of a ligature group.
|
* A character may be the start of a ligature group.
|
||||||
* A character can be "missing", indicating that the system is unable
|
* A character can be "missing", indicating that the system is unable
|
||||||
* to render the character.
|
* to render the character.
|
||||||
*
|
*
|
||||||
* All characters in a ligature group conceptually share all the glyphs
|
* All characters in a ligature group conceptually share all the glyphs
|
||||||
* associated with the characters in a group.
|
* associated with the characters in a group.
|
||||||
*/
|
*/
|
||||||
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).
|
||||||
|
|
@ -914,7 +939,7 @@ public:
|
||||||
/** The advance, x-offset and y-offset of the glyph, in appunits
|
/** The advance, x-offset and y-offset of the glyph, in appunits
|
||||||
* mAdvance is in the text direction (RTL or LTR)
|
* mAdvance is in the text direction (RTL or LTR)
|
||||||
* mXOffset is always from left to right
|
* mXOffset is always from left to right
|
||||||
* mYOffset is always from top to bottom */
|
* mYOffset is always from top to bottom */
|
||||||
int32_t mAdvance;
|
int32_t mAdvance;
|
||||||
float mXOffset, mYOffset;
|
float mXOffset, mYOffset;
|
||||||
};
|
};
|
||||||
|
|
@ -1039,7 +1064,7 @@ protected:
|
||||||
|
|
||||||
// For characters whose glyph data does not fit the "simple" glyph criteria
|
// For characters whose glyph data does not fit the "simple" glyph criteria
|
||||||
// in CompressedGlyph, we use a sorted array to store the association
|
// in CompressedGlyph, we use a sorted array to store the association
|
||||||
// between the source character offset and an index into an array
|
// between the source character offset and an index into an array
|
||||||
// DetailedGlyphs. The CompressedGlyph record includes a count of
|
// DetailedGlyphs. The CompressedGlyph record includes a count of
|
||||||
// the number of DetailedGlyph records that belong to the character,
|
// the number of DetailedGlyph records that belong to the character,
|
||||||
// starting at the given index.
|
// starting at the given index.
|
||||||
|
|
@ -1581,11 +1606,11 @@ public:
|
||||||
// (offset1, length1) plus the advance width of (offset1 + length1,
|
// (offset1, length1) plus the advance width of (offset1 + length1,
|
||||||
// length2) should be the advance width of (offset1, length1 + length2)
|
// length2) should be the advance width of (offset1, length1 + length2)
|
||||||
gfxFloat mAdvanceWidth;
|
gfxFloat mAdvanceWidth;
|
||||||
|
|
||||||
// For zero-width substrings, these must be zero!
|
// For zero-width substrings, these must be zero!
|
||||||
gfxFloat mAscent; // always non-negative
|
gfxFloat mAscent; // always non-negative
|
||||||
gfxFloat mDescent; // always non-negative
|
gfxFloat mDescent; // always non-negative
|
||||||
|
|
||||||
// Bounding box that is guaranteed to include everything drawn.
|
// Bounding box that is guaranteed to include everything drawn.
|
||||||
// If a tight boundingBox was requested when these metrics were
|
// If a tight boundingBox was requested when these metrics were
|
||||||
// generated, this will tightly wrap the glyphs, otherwise it is
|
// generated, this will tightly wrap the glyphs, otherwise it is
|
||||||
|
|
@ -1648,11 +1673,11 @@ public:
|
||||||
* @param aSpacing spacing to insert before and after glyphs. The bounding box
|
* @param aSpacing spacing to insert before and after glyphs. The bounding box
|
||||||
* need not include the spacing itself, but the spacing affects the glyph
|
* need not include the spacing itself, but the spacing affects the glyph
|
||||||
* positions. null if there is no spacing.
|
* positions. null if there is no spacing.
|
||||||
*
|
*
|
||||||
* Callers guarantee:
|
* Callers guarantee:
|
||||||
* -- aStart and aEnd are aligned to cluster and ligature boundaries
|
* -- aStart and aEnd are aligned to cluster and ligature boundaries
|
||||||
* -- all glyphs use this font
|
* -- all glyphs use this font
|
||||||
*
|
*
|
||||||
* The default implementation just uses font metrics and aTextRun's
|
* The default implementation just uses font metrics and aTextRun's
|
||||||
* advances, and assumes no characters fall outside the font box. In
|
* advances, and assumes no characters fall outside the font box. In
|
||||||
* general this is insufficient, because that assumption is not always true.
|
* general this is insufficient, because that assumption is not always true.
|
||||||
|
|
@ -1707,7 +1732,7 @@ public:
|
||||||
(mUnicodeRangeMap && !mUnicodeRangeMap->test(ch))) {
|
(mUnicodeRangeMap && !mUnicodeRangeMap->test(ch))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mFontEntry->HasCharacter(ch);
|
return mFontEntry->HasCharacter(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gfxCharacterMap* GetUnicodeRangeMap() const {
|
const gfxCharacterMap* GetUnicodeRangeMap() const {
|
||||||
|
|
@ -1722,7 +1747,7 @@ public:
|
||||||
if (!mIsValid) {
|
if (!mIsValid) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return mFontEntry->GetUVSGlyph(aCh, aVS);
|
return mFontEntry->GetUVSGlyph(aCh, aVS);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -817,7 +817,7 @@ GetKernValueVersion1Fmt3(const void* aSubtable,
|
||||||
hdr->leftClassCount * hdr->rightClassCount > aSubtableLen) {
|
hdr->leftClassCount * hdr->rightClassCount > aSubtableLen) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFirstGlyph >= glyphCount || aSecondGlyph >= glyphCount) {
|
if (aFirstGlyph >= glyphCount || aSecondGlyph >= glyphCount) {
|
||||||
// glyphs are out of range for the class tables
|
// glyphs are out of range for the class tables
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ gfxTextRun::ComputeLigatureData(Range aPartRange,
|
||||||
NS_ASSERTION(aPartRange.start < aPartRange.end,
|
NS_ASSERTION(aPartRange.start < aPartRange.end,
|
||||||
"Computing ligature data for empty range");
|
"Computing ligature data for empty range");
|
||||||
NS_ASSERTION(aPartRange.end <= GetLength(), "Character length overflow");
|
NS_ASSERTION(aPartRange.end <= GetLength(), "Character length overflow");
|
||||||
|
|
||||||
LigatureData result;
|
LigatureData result;
|
||||||
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
||||||
|
|
||||||
|
|
@ -392,7 +392,7 @@ gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange) const
|
||||||
{
|
{
|
||||||
if (aRange->start >= aRange->end)
|
if (aRange->start >= aRange->end)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
||||||
|
|
||||||
while (aRange->start < aRange->end &&
|
while (aRange->start < aRange->end &&
|
||||||
|
|
@ -440,7 +440,7 @@ ClipPartialLigature(const gfxTextRun* aTextRun,
|
||||||
} else {
|
} else {
|
||||||
*aEnd = std::min(*aEnd, endEdge);
|
*aEnd = std::min(*aEnd, endEdge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -789,7 +789,7 @@ gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont, Range aRange,
|
||||||
// ligature. Shift it left.
|
// ligature. Shift it left.
|
||||||
metrics.mBoundingBox.x -=
|
metrics.mBoundingBox.x -=
|
||||||
IsRightToLeft() ? metrics.mAdvanceWidth - (data.mPartAdvance + data.mPartWidth)
|
IsRightToLeft() ? metrics.mAdvanceWidth - (data.mPartAdvance + data.mPartWidth)
|
||||||
: data.mPartAdvance;
|
: data.mPartAdvance;
|
||||||
metrics.mAdvanceWidth = data.mPartWidth;
|
metrics.mAdvanceWidth = data.mPartWidth;
|
||||||
|
|
||||||
aMetrics->CombineWith(metrics, IsRightToLeft());
|
aMetrics->CombineWith(metrics, IsRightToLeft());
|
||||||
|
|
@ -905,7 +905,7 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
// There can't be a word-wrap break opportunity at the beginning of the
|
// There can't be a word-wrap break opportunity at the beginning of the
|
||||||
// line: if the width is too small for even one character to fit, it
|
// line: if the width is too small for even one character to fit, it
|
||||||
// could be the first and last break opportunity on the line, and that
|
// could be the first and last break opportunity on the line, and that
|
||||||
// would trigger an infinite loop.
|
// would trigger an infinite loop.
|
||||||
if (aSuppressBreak != eSuppressAllBreaks &&
|
if (aSuppressBreak != eSuppressAllBreaks &&
|
||||||
|
|
@ -923,7 +923,7 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||||
if (atHyphenationBreak) {
|
if (atHyphenationBreak) {
|
||||||
hyphenatedAdvance += aProvider->GetHyphenWidth();
|
hyphenatedAdvance += aProvider->GetHyphenWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastBreak < 0 || width + hyphenatedAdvance - trimmableAdvance <= aWidth) {
|
if (lastBreak < 0 || width + hyphenatedAdvance - trimmableAdvance <= aWidth) {
|
||||||
// We can break here.
|
// We can break here.
|
||||||
lastBreak = i;
|
lastBreak = i;
|
||||||
|
|
@ -943,7 +943,7 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFloat charAdvance;
|
gfxFloat charAdvance;
|
||||||
if (i >= ligatureRange.start && i < ligatureRange.end) {
|
if (i >= ligatureRange.start && i < ligatureRange.end) {
|
||||||
charAdvance = GetAdvanceForGlyphs(Range(i, i + 1));
|
charAdvance = GetAdvanceForGlyphs(Range(i, i + 1));
|
||||||
|
|
@ -956,7 +956,7 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||||
charAdvance =
|
charAdvance =
|
||||||
ComputePartialLigatureWidth(Range(i, i + 1), aProvider);
|
ComputePartialLigatureWidth(Range(i, i + 1), aProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
advance += charAdvance;
|
advance += charAdvance;
|
||||||
if (aTrimWhitespace || aWhitespaceCanHang) {
|
if (aTrimWhitespace || aWhitespaceCanHang) {
|
||||||
if (mCharacterGlyphs[i].CharIsSpace()) {
|
if (mCharacterGlyphs[i].CharIsSpace()) {
|
||||||
|
|
@ -1145,7 +1145,7 @@ gfxTextRun::AddGlyphRun(gfxFont *aFont, uint8_t aMatchType,
|
||||||
"mixed orientation should have been resolved");
|
"mixed orientation should have been resolved");
|
||||||
if (!aFont) {
|
if (!aFont) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
uint32_t numGlyphRuns = mGlyphRuns.Length();
|
uint32_t numGlyphRuns = mGlyphRuns.Length();
|
||||||
if (!aForceNewRun && numGlyphRuns > 0) {
|
if (!aForceNewRun && numGlyphRuns > 0) {
|
||||||
GlyphRun *lastGlyphRun = &mGlyphRuns[numGlyphRuns - 1];
|
GlyphRun *lastGlyphRun = &mGlyphRuns[numGlyphRuns - 1];
|
||||||
|
|
@ -1405,7 +1405,7 @@ gfxTextRun::SetSpaceGlyph(gfxFont* aFont, DrawTarget* aDrawTarget,
|
||||||
(GetFlags() & gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT) != 0;
|
(GetFlags() & gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT) != 0;
|
||||||
gfxShapedWord* sw = aFont->GetShapedWord(aDrawTarget,
|
gfxShapedWord* sw = aFont->GetShapedWord(aDrawTarget,
|
||||||
&space, 1,
|
&space, 1,
|
||||||
gfxShapedWord::HashMix(0, ' '),
|
gfxShapedWord::HashMix(0, ' '),
|
||||||
Script::LATIN,
|
Script::LATIN,
|
||||||
vertical,
|
vertical,
|
||||||
mAppUnitsPerDevUnit,
|
mAppUnitsPerDevUnit,
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
@ -1471,7 +1471,7 @@ gfxTextRun::FetchGlyphExtents(DrawTarget* aRefDrawTarget)
|
||||||
bool fontIsSetup = false;
|
bool fontIsSetup = false;
|
||||||
uint32_t j;
|
uint32_t j;
|
||||||
gfxGlyphExtents *extents = font->GetOrCreateGlyphExtents(mAppUnitsPerDevUnit);
|
gfxGlyphExtents *extents = font->GetOrCreateGlyphExtents(mAppUnitsPerDevUnit);
|
||||||
|
|
||||||
for (j = start; j < end; ++j) {
|
for (j = start; j < end; ++j) {
|
||||||
const gfxTextRun::CompressedGlyph *glyphData = &charGlyphs[j];
|
const gfxTextRun::CompressedGlyph *glyphData = &charGlyphs[j];
|
||||||
if (glyphData->IsSimpleGlyph()) {
|
if (glyphData->IsSimpleGlyph()) {
|
||||||
|
|
@ -1943,13 +1943,13 @@ gfxFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
return fg;
|
return fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
gfxFontGroup::IsInvalidChar(uint8_t ch)
|
gfxFontGroup::IsInvalidChar(uint8_t ch)
|
||||||
{
|
{
|
||||||
return ((ch & 0x7f) < 0x20 || ch == 0x7f);
|
return ((ch & 0x7f) < 0x20 || ch == 0x7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
gfxFontGroup::IsInvalidChar(char16_t ch)
|
gfxFontGroup::IsInvalidChar(char16_t ch)
|
||||||
{
|
{
|
||||||
// All printable 7-bit ASCII values are OK
|
// All printable 7-bit ASCII values are OK
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
@ -3128,7 +3128,7 @@ gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh)
|
||||||
uint32_t unicodeRange = FindCharUnicodeRange(aCh);
|
uint32_t unicodeRange = FindCharUnicodeRange(aCh);
|
||||||
charLang = pfl->GetFontPrefLangFor(unicodeRange);
|
charLang = pfl->GetFontPrefLangFor(unicodeRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the last pref font was the first family in the pref list, no need to recheck through a list of families
|
// if the last pref font was the first family in the pref list, no need to recheck through a list of families
|
||||||
if (mLastPrefFont && charLang == mLastPrefLang &&
|
if (mLastPrefFont && charLang == mLastPrefLang &&
|
||||||
mLastPrefFirstFont && mLastPrefFont->HasCharacter(aCh)) {
|
mLastPrefFirstFont && mLastPrefFont->HasCharacter(aCh)) {
|
||||||
|
|
@ -3190,7 +3190,7 @@ already_AddRefed<gfxFont>
|
||||||
gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
|
gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh,
|
||||||
Script aRunScript)
|
Script aRunScript)
|
||||||
{
|
{
|
||||||
gfxFontEntry *fe =
|
gfxFontEntry *fe =
|
||||||
gfxPlatformFontList::PlatformFontList()->
|
gfxPlatformFontList::PlatformFontList()->
|
||||||
SystemFindFontForChar(aCh, aNextCh, aRunScript, &mStyle);
|
SystemFindFontForChar(aCh, aNextCh, aRunScript, &mStyle);
|
||||||
if (fe) {
|
if (fe) {
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ struct gfxTextRunDrawCallbacks {
|
||||||
* of text. It stores runs of positioned glyph data, each run having a single
|
* of text. It stores runs of positioned glyph data, each run having a single
|
||||||
* gfxFont. The glyphs are associated with a string of source text, and the
|
* gfxFont. The glyphs are associated with a string of source text, and the
|
||||||
* gfxTextRun APIs take parameters that are offsets into that source text.
|
* gfxTextRun APIs take parameters that are offsets into that source text.
|
||||||
*
|
*
|
||||||
* gfxTextRuns are mostly immutable. The only things that can change are
|
* gfxTextRuns are mostly immutable. The only things that can change are
|
||||||
* inter-cluster spacing and line break placement. Spacing is always obtained
|
* inter-cluster spacing and line break placement. Spacing is always obtained
|
||||||
* lazily by methods that need it, it is not cached. Line breaks are stored
|
* lazily by methods that need it, it is not cached. Line breaks are stored
|
||||||
|
|
@ -78,7 +78,7 @@ struct gfxTextRunDrawCallbacks {
|
||||||
* not actually do anything to explicitly account for line breaks). Initially
|
* not actually do anything to explicitly account for line breaks). Initially
|
||||||
* there are no line breaks. The textrun can record line breaks before or after
|
* there are no line breaks. The textrun can record line breaks before or after
|
||||||
* any given cluster. (Line breaks specified inside clusters are ignored.)
|
* any given cluster. (Line breaks specified inside clusters are ignored.)
|
||||||
*
|
*
|
||||||
* It is important that zero-length substrings are handled correctly. This will
|
* It is important that zero-length substrings are handled correctly. This will
|
||||||
* be on the test!
|
* be on the test!
|
||||||
*/
|
*/
|
||||||
|
|
@ -163,11 +163,11 @@ public:
|
||||||
* Set the potential linebreaks for a substring of the textrun. These are
|
* Set the potential linebreaks for a substring of the textrun. These are
|
||||||
* the "allow break before" points. Initially, there are no potential
|
* the "allow break before" points. Initially, there are no potential
|
||||||
* linebreaks.
|
* linebreaks.
|
||||||
*
|
*
|
||||||
* This can change glyphs and/or geometry! Some textruns' shapes
|
* This can change glyphs and/or geometry! Some textruns' shapes
|
||||||
* depend on potential line breaks (e.g., title-case-converting textruns).
|
* depend on potential line breaks (e.g., title-case-converting textruns).
|
||||||
* This function is virtual so that those textruns can reshape themselves.
|
* This function is virtual so that those textruns can reshape themselves.
|
||||||
*
|
*
|
||||||
* @return true if this changed the linebreaks, false if the new line
|
* @return true if this changed the linebreaks, false if the new line
|
||||||
* breaks are the same as the old
|
* breaks are the same as the old
|
||||||
*/
|
*/
|
||||||
|
|
@ -179,7 +179,7 @@ public:
|
||||||
* potential line break points and computation of spacing. We pass the data
|
* potential line break points and computation of spacing. We pass the data
|
||||||
* this way to allow lazy data acquisition; for example BreakAndMeasureText
|
* this way to allow lazy data acquisition; for example BreakAndMeasureText
|
||||||
* will want to only ask for properties of text it's actually looking at.
|
* will want to only ask for properties of text it's actually looking at.
|
||||||
*
|
*
|
||||||
* NOTE that requested spacing may not actually be applied, if the textrun
|
* NOTE that requested spacing may not actually be applied, if the textrun
|
||||||
* is unable to apply it in some context. Exception: spacing around a
|
* is unable to apply it in some context. Exception: spacing around a
|
||||||
* whitespace character MUST always be applied.
|
* whitespace character MUST always be applied.
|
||||||
|
|
@ -238,7 +238,7 @@ public:
|
||||||
* Draws a substring. Uses only GetSpacing from aBreakProvider.
|
* Draws a substring. Uses only GetSpacing from aBreakProvider.
|
||||||
* The provided point is the baseline origin on the left of the string
|
* The provided point is the baseline origin on the left of the string
|
||||||
* for LTR, on the right of the string for RTL.
|
* for LTR, on the right of the string for RTL.
|
||||||
*
|
*
|
||||||
* Drawing should respect advance widths in the sense that for LTR runs,
|
* Drawing should respect advance widths in the sense that for LTR runs,
|
||||||
* Draw(Range(start, middle), pt, ...) followed by
|
* Draw(Range(start, middle), pt, ...) followed by
|
||||||
* Draw(Range(middle, end), gfxPoint(pt.x + advance, pt.y), ...)
|
* Draw(Range(middle, end), gfxPoint(pt.x + advance, pt.y), ...)
|
||||||
|
|
@ -250,7 +250,7 @@ public:
|
||||||
* Draw(Range(start, middle), gfxPoint(pt.x + advance, pt.y), ...)
|
* Draw(Range(start, middle), gfxPoint(pt.x + advance, pt.y), ...)
|
||||||
* should have the same effect as
|
* should have the same effect as
|
||||||
* Draw(Range(start, end), pt, ...)
|
* Draw(Range(start, end), pt, ...)
|
||||||
*
|
*
|
||||||
* Glyphs should be drawn in logical content order, which can be significant
|
* Glyphs should be drawn in logical content order, which can be significant
|
||||||
* if they overlap (perhaps due to negative spacing).
|
* if they overlap (perhaps due to negative spacing).
|
||||||
*/
|
*/
|
||||||
|
|
@ -307,14 +307,14 @@ public:
|
||||||
* Clear all stored line breaks for the given range (both before and after),
|
* Clear all stored line breaks for the given range (both before and after),
|
||||||
* and then set the line-break state before aRange.start to aBreakBefore and
|
* and then set the line-break state before aRange.start to aBreakBefore and
|
||||||
* after the last cluster to aBreakAfter.
|
* after the last cluster to aBreakAfter.
|
||||||
*
|
*
|
||||||
* We require that before and after line breaks be consistent. For clusters
|
* We require that before and after line breaks be consistent. For clusters
|
||||||
* i and i+1, we require that if there is a break after cluster i, a break
|
* i and i+1, we require that if there is a break after cluster i, a break
|
||||||
* will be specified before cluster i+1. This may be temporarily violated
|
* will be specified before cluster i+1. This may be temporarily violated
|
||||||
* (e.g. after reflowing line L and before reflowing line L+1); to handle
|
* (e.g. after reflowing line L and before reflowing line L+1); to handle
|
||||||
* these temporary violations, we say that there is a break betwen i and i+1
|
* these temporary violations, we say that there is a break betwen i and i+1
|
||||||
* if a break is specified after i OR a break is specified before i+1.
|
* if a break is specified after i OR a break is specified before i+1.
|
||||||
*
|
*
|
||||||
* This can change textrun geometry! The existence of a linebreak can affect
|
* This can change textrun geometry! The existence of a linebreak can affect
|
||||||
* the advance width of the cluster before the break (when kerning) or the
|
* the advance width of the cluster before the break (when kerning) or the
|
||||||
* geometry of one cluster before the break or any number of clusters
|
* geometry of one cluster before the break or any number of clusters
|
||||||
|
|
@ -322,11 +322,11 @@ public:
|
||||||
* arbitrary; if some scripts require breaking it, then we need to
|
* arbitrary; if some scripts require breaking it, then we need to
|
||||||
* alter nsTextFrame::TrimTrailingWhitespace, perhaps drastically becase
|
* alter nsTextFrame::TrimTrailingWhitespace, perhaps drastically becase
|
||||||
* it could affect the layout of frames before it...)
|
* it could affect the layout of frames before it...)
|
||||||
*
|
*
|
||||||
* We return true if glyphs or geometry changed, false otherwise. This
|
* We return true if glyphs or geometry changed, false otherwise. This
|
||||||
* function is virtual so that gfxTextRun subclasses can reshape
|
* function is virtual so that gfxTextRun subclasses can reshape
|
||||||
* properly.
|
* properly.
|
||||||
*
|
*
|
||||||
* @param aAdvanceWidthDelta if non-null, returns the change in advance
|
* @param aAdvanceWidthDelta if non-null, returns the change in advance
|
||||||
* width of the given range.
|
* width of the given range.
|
||||||
*/
|
*/
|
||||||
|
|
@ -393,7 +393,7 @@ public:
|
||||||
* @param aBreakPriority in/out the priority of the break opportunity
|
* @param aBreakPriority in/out the priority of the break opportunity
|
||||||
* saved in the line. If we are prioritizing break opportunities, we will
|
* saved in the line. If we are prioritizing break opportunities, we will
|
||||||
* not set a break with a lower priority. @see gfxBreakPriority.
|
* not set a break with a lower priority. @see gfxBreakPriority.
|
||||||
*
|
*
|
||||||
* Note that negative advance widths are possible especially if negative
|
* Note that negative advance widths are possible especially if negative
|
||||||
* spacing is provided.
|
* spacing is provided.
|
||||||
*/
|
*/
|
||||||
|
|
@ -596,11 +596,11 @@ public:
|
||||||
// when the part is at the start of the ligature, and after-spacing
|
// when the part is at the start of the ligature, and after-spacing
|
||||||
// when the part is as the end of the ligature
|
// when the part is as the end of the ligature
|
||||||
gfxFloat mPartWidth;
|
gfxFloat mPartWidth;
|
||||||
|
|
||||||
bool mClipBeforePart;
|
bool mClipBeforePart;
|
||||||
bool mClipAfterPart;
|
bool mClipAfterPart;
|
||||||
};
|
};
|
||||||
|
|
||||||
// return storage used by this run, for memory reporter;
|
// return storage used by this run, for memory reporter;
|
||||||
// nsTransformedTextRun needs to override this as it holds additional data
|
// nsTransformedTextRun needs to override this as it holds additional data
|
||||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||||
|
|
@ -681,7 +681,7 @@ protected:
|
||||||
CompressedGlyph *mCharacterGlyphs;
|
CompressedGlyph *mCharacterGlyphs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// **** general helpers ****
|
// **** general helpers ****
|
||||||
|
|
||||||
// Get the total advance for a range of glyphs.
|
// Get the total advance for a range of glyphs.
|
||||||
int32_t GetAdvanceForGlyphs(Range aRange) const;
|
int32_t GetAdvanceForGlyphs(Range aRange) const;
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
@ -1459,7 +1459,7 @@ nsMathMLChar::StretchEnumContext::EnumCallback(const FontFamilyName& aFamily,
|
||||||
if (!openTypeTable) {
|
if (!openTypeTable) {
|
||||||
if (context->mTablesTried.Contains(glyphTable))
|
if (context->mTablesTried.Contains(glyphTable))
|
||||||
return true; // already tried this one
|
return true; // already tried this one
|
||||||
|
|
||||||
// Only try this table once.
|
// Only try this table once.
|
||||||
context->mTablesTried.AppendElement(glyphTable);
|
context->mTablesTried.AppendElement(glyphTable);
|
||||||
}
|
}
|
||||||
|
|
@ -1626,7 +1626,7 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
|
||||||
if (!maxWidth && !largeop) {
|
if (!maxWidth && !largeop) {
|
||||||
// Doing Stretch() not GetMaxWidth(),
|
// Doing Stretch() not GetMaxWidth(),
|
||||||
// and not a largeop in display mode; we're done if size fits
|
// and not a largeop in display mode; we're done if size fits
|
||||||
if ((targetSize <= 0) ||
|
if ((targetSize <= 0) ||
|
||||||
((isVertical && charSize >= targetSize) ||
|
((isVertical && charSize >= targetSize) ||
|
||||||
IsSizeOK(charSize, targetSize, aStretchHint)))
|
IsSizeOK(charSize, targetSize, aStretchHint)))
|
||||||
done = true;
|
done = true;
|
||||||
|
|
@ -1678,7 +1678,7 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
|
||||||
// variables accordingly.
|
// variables accordingly.
|
||||||
mUnscaledAscent = aDesiredStretchSize.ascent;
|
mUnscaledAscent = aDesiredStretchSize.ascent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glyphFound) {
|
if (glyphFound) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1695,7 +1695,7 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
|
||||||
if (!Preferences::GetBool("mathml.scale_stretchy_operators.enabled", true)) {
|
if (!Preferences::GetBool("mathml.scale_stretchy_operators.enabled", true)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stretchy character
|
// stretchy character
|
||||||
if (stretchy) {
|
if (stretchy) {
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
|
|
@ -1863,7 +1863,7 @@ public:
|
||||||
nsDisplayMathMLCharForeground(nsDisplayListBuilder* aBuilder,
|
nsDisplayMathMLCharForeground(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame, nsMathMLChar* aChar,
|
nsIFrame* aFrame, nsMathMLChar* aChar,
|
||||||
uint32_t aIndex, bool aIsSelected)
|
uint32_t aIndex, bool aIsSelected)
|
||||||
: nsDisplayItem(aBuilder, aFrame), mChar(aChar),
|
: nsDisplayItem(aBuilder, aFrame), mChar(aChar),
|
||||||
mIndex(aIndex), mIsSelected(aIsSelected) {
|
mIndex(aIndex), mIsSelected(aIsSelected) {
|
||||||
MOZ_COUNT_CTOR(nsDisplayMathMLCharForeground);
|
MOZ_COUNT_CTOR(nsDisplayMathMLCharForeground);
|
||||||
}
|
}
|
||||||
|
|
@ -1886,7 +1886,7 @@ public:
|
||||||
temp.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
temp.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx) override
|
nsRenderingContext* aCtx) override
|
||||||
{
|
{
|
||||||
|
|
@ -1901,7 +1901,7 @@ public:
|
||||||
bool snap;
|
bool snap;
|
||||||
return GetBounds(aBuilder, &snap);
|
return GetBounds(aBuilder, &snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint32_t GetPerFrameKey() override {
|
virtual uint32_t GetPerFrameKey() override {
|
||||||
return (mIndex << nsDisplayItem::TYPE_BITS)
|
return (mIndex << nsDisplayItem::TYPE_BITS)
|
||||||
| nsDisplayItem::GetPerFrameKey();
|
| nsDisplayItem::GetPerFrameKey();
|
||||||
|
|
@ -2355,7 +2355,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
||||||
// _cairo_scaled_font_glyph_device_extents rounds outwards to the nearest
|
// _cairo_scaled_font_glyph_device_extents rounds outwards to the nearest
|
||||||
// pixel, so the bm values can include 1 row of faint pixels on each edge.
|
// pixel, so the bm values can include 1 row of faint pixels on each edge.
|
||||||
// Don't rely on this pixel as it can look like a gap.
|
// Don't rely on this pixel as it can look like a gap.
|
||||||
if (bm.rightBearing - bm.leftBearing >= 2 * oneDevPixel) {
|
if (bm.rightBearing - bm.leftBearing >= 2 * oneDevPixel) {
|
||||||
start[i] = dx + bm.leftBearing + oneDevPixel; // left join
|
start[i] = dx + bm.leftBearing + oneDevPixel; // left join
|
||||||
end[i] = dx + bm.rightBearing - oneDevPixel; // right join
|
end[i] = dx + bm.rightBearing - oneDevPixel; // right join
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue