mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1251995 part 2 - Add gfxTextRun::Range to replace parameter pairs like (offset, length) and (start, end). r=jfkthame
Although this makes some places more complicated, code should generally be simpler and clearer. It could slightly improve performance on x64 for functions with more than four parameters, since it makes more data be passed via registers rather than the stack. MozReview-Commit-ID: D0GM2Jyrr6W --HG-- extra : source : bd88a2e478e23edf1845f724a32fef908c8cc007
This commit is contained in:
parent
ab357753a9
commit
b3ea3fa801
@ -658,10 +658,9 @@ ContentEventHandler::AppendFontRanges(FontRangeArray& aFontRanges,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t skipStart = iter.ConvertOriginalToSkipped(frameXPStart);
|
||||
uint32_t skipEnd = iter.ConvertOriginalToSkipped(frameXPEnd);
|
||||
gfxTextRun::GlyphRunIterator runIter(
|
||||
textRun, skipStart, skipEnd - skipStart);
|
||||
gfxTextRun::Range skipRange(iter.ConvertOriginalToSkipped(frameXPStart),
|
||||
iter.ConvertOriginalToSkipped(frameXPEnd));
|
||||
gfxTextRun::GlyphRunIterator runIter(textRun, skipRange);
|
||||
int32_t lastXPEndOffset = frameXPStart;
|
||||
while (runIter.NextRun()) {
|
||||
gfxFont* font = runIter.GetGlyphRun()->mFont.get();
|
||||
|
@ -81,7 +81,7 @@ private:
|
||||
|
||||
class StubPropertyProvider : public gfxTextRun::PropertyProvider {
|
||||
public:
|
||||
virtual void GetHyphenationBreaks(uint32_t aStart, uint32_t aLength,
|
||||
virtual void GetHyphenationBreaks(gfxTextRun::Range aRange,
|
||||
bool* aBreakBefore) {
|
||||
NS_ERROR("This shouldn't be called because we never call BreakAndMeasureText");
|
||||
}
|
||||
@ -101,8 +101,7 @@ public:
|
||||
NS_ERROR("This shouldn't be called because we never enable hyphens");
|
||||
return 60;
|
||||
}
|
||||
virtual void GetSpacing(uint32_t aStart, uint32_t aLength,
|
||||
Spacing* aSpacing) {
|
||||
virtual void GetSpacing(gfxTextRun::Range aRange, Spacing* aSpacing) {
|
||||
NS_ERROR("This shouldn't be called because we never enable spacing");
|
||||
}
|
||||
};
|
||||
@ -325,8 +324,11 @@ nsFontMetrics::GetWidth(const char* aString, uint32_t aLength,
|
||||
|
||||
StubPropertyProvider provider;
|
||||
AutoTextRun textRun(this, aDrawTarget, aString, aLength);
|
||||
return textRun.get() ?
|
||||
NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider)) : 0;
|
||||
if (textRun.get()) {
|
||||
return NSToCoordRound(
|
||||
textRun->GetAdvanceWidth(Range(0, aLength), &provider));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
nscoord
|
||||
@ -341,8 +343,11 @@ nsFontMetrics::GetWidth(const char16_t* aString, uint32_t aLength,
|
||||
|
||||
StubPropertyProvider provider;
|
||||
AutoTextRun textRun(this, aDrawTarget, aString, aLength);
|
||||
return textRun.get() ?
|
||||
NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider)) : 0;
|
||||
if (textRun.get()) {
|
||||
return NSToCoordRound(
|
||||
textRun->GetAdvanceWidth(Range(0, aLength), &provider));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw a string using this font handle on the surface passed in.
|
||||
@ -360,15 +365,16 @@ nsFontMetrics::DrawString(const char *aString, uint32_t aLength,
|
||||
return;
|
||||
}
|
||||
gfxPoint pt(aX, aY);
|
||||
Range range(0, aLength);
|
||||
if (mTextRunRTL) {
|
||||
if (mVertical) {
|
||||
pt.y += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
pt.y += textRun->GetAdvanceWidth(range, &provider);
|
||||
} else {
|
||||
pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
pt.x += textRun->GetAdvanceWidth(range, &provider);
|
||||
}
|
||||
}
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL, 0, aLength,
|
||||
&provider, nullptr, nullptr);
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL,
|
||||
range, &provider, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
@ -386,15 +392,16 @@ nsFontMetrics::DrawString(const char16_t* aString, uint32_t aLength,
|
||||
return;
|
||||
}
|
||||
gfxPoint pt(aX, aY);
|
||||
Range range(0, aLength);
|
||||
if (mTextRunRTL) {
|
||||
if (mVertical) {
|
||||
pt.y += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
pt.y += textRun->GetAdvanceWidth(range, &provider);
|
||||
} else {
|
||||
pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
|
||||
pt.x += textRun->GetAdvanceWidth(range, &provider);
|
||||
}
|
||||
}
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL, 0, aLength,
|
||||
&provider, nullptr, nullptr);
|
||||
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL,
|
||||
range, &provider, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static nsBoundingMetrics
|
||||
@ -409,8 +416,8 @@ GetTextBoundingMetrics(nsFontMetrics* aMetrics, const char16_t* aString,
|
||||
AutoTextRun textRun(aMetrics, aDrawTarget, aString, aLength);
|
||||
nsBoundingMetrics m;
|
||||
if (textRun.get()) {
|
||||
gfxTextRun::Metrics theMetrics =
|
||||
textRun->MeasureText(0, aLength, aType, aDrawTarget, &provider);
|
||||
gfxTextRun::Metrics theMetrics = textRun->MeasureText(
|
||||
gfxTextRun::Range(0, aLength), aType, aDrawTarget, &provider);
|
||||
|
||||
m.leftBearing = NSToCoordFloor( theMetrics.mBoundingBox.X());
|
||||
m.rightBearing = NSToCoordCeil( theMetrics.mBoundingBox.XMost());
|
||||
|
@ -46,6 +46,7 @@ struct nsBoundingMetrics;
|
||||
class nsFontMetrics final
|
||||
{
|
||||
public:
|
||||
typedef gfxTextRun::Range Range;
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
|
||||
nsFontMetrics();
|
||||
|
@ -1943,7 +1943,7 @@ gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
|
||||
const EmphasisMarkDrawParams& aParams)
|
||||
{
|
||||
gfxFloat& inlineCoord = aParams.isVertical ? aPt->y : aPt->x;
|
||||
uint32_t markLength = aParams.mark->GetLength();
|
||||
gfxTextRun::Range markRange(aParams.mark);
|
||||
|
||||
gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity();
|
||||
bool shouldDrawEmphasisMark = false;
|
||||
@ -1966,7 +1966,7 @@ gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
|
||||
gfxFloat delta = (clusterAdvance + aParams.advance) / 2;
|
||||
inlineCoord -= delta;
|
||||
aParams.mark->Draw(aParams.context, *aPt, DrawMode::GLYPH_FILL,
|
||||
0, markLength, nullptr, nullptr, nullptr);
|
||||
markRange, nullptr, nullptr, nullptr);
|
||||
inlineCoord += delta;
|
||||
shouldDrawEmphasisMark = false;
|
||||
}
|
||||
@ -3187,7 +3187,8 @@ gfxFont::InitFakeSmallCapsRun(DrawTarget *aDrawTarget,
|
||||
MergeCharactersInTextRun(mergedRun, tempRun,
|
||||
charsToMergeArray.Elements(),
|
||||
deletedCharsArray.Elements());
|
||||
aTextRun->CopyGlyphDataFrom(mergedRun, 0, runLength,
|
||||
gfxTextRun::Range runRange(0, runLength);
|
||||
aTextRun->CopyGlyphDataFrom(mergedRun, runRange,
|
||||
aOffset + runStart);
|
||||
}
|
||||
} else {
|
||||
|
@ -210,15 +210,14 @@ gfxTextRun::ReleaseFontGroup()
|
||||
}
|
||||
|
||||
bool
|
||||
gfxTextRun::SetPotentialLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
uint8_t *aBreakBefore)
|
||||
gfxTextRun::SetPotentialLineBreaks(Range aRange, uint8_t *aBreakBefore)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= GetLength(), "Overflow");
|
||||
NS_ASSERTION(aRange.end <= GetLength(), "Overflow");
|
||||
|
||||
uint32_t changed = 0;
|
||||
uint32_t i;
|
||||
CompressedGlyph *charGlyphs = mCharacterGlyphs + aStart;
|
||||
for (i = 0; i < aLength; ++i) {
|
||||
CompressedGlyph *charGlyphs = mCharacterGlyphs + aRange.start;
|
||||
for (i = 0; i < aRange.Length(); ++i) {
|
||||
uint8_t canBreak = aBreakBefore[i];
|
||||
if (canBreak && !charGlyphs[i].IsClusterStart()) {
|
||||
// This can happen ... there is no guarantee that our linebreaking rules
|
||||
@ -231,39 +230,39 @@ gfxTextRun::SetPotentialLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
}
|
||||
|
||||
gfxTextRun::LigatureData
|
||||
gfxTextRun::ComputeLigatureData(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
PropertyProvider *aProvider)
|
||||
gfxTextRun::ComputeLigatureData(Range aPartRange, PropertyProvider *aProvider)
|
||||
{
|
||||
NS_ASSERTION(aPartStart < aPartEnd, "Computing ligature data for empty range");
|
||||
NS_ASSERTION(aPartEnd <= GetLength(), "Character length overflow");
|
||||
NS_ASSERTION(aPartRange.start < aPartRange.end,
|
||||
"Computing ligature data for empty range");
|
||||
NS_ASSERTION(aPartRange.end <= GetLength(), "Character length overflow");
|
||||
|
||||
LigatureData result;
|
||||
CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
||||
|
||||
uint32_t i;
|
||||
for (i = aPartStart; !charGlyphs[i].IsLigatureGroupStart(); --i) {
|
||||
for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
|
||||
NS_ASSERTION(i > 0, "Ligature at the start of the run??");
|
||||
}
|
||||
result.mLigatureStart = i;
|
||||
for (i = aPartStart + 1; i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
|
||||
result.mRange.start = i;
|
||||
for (i = aPartRange.start + 1;
|
||||
i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
|
||||
}
|
||||
result.mLigatureEnd = i;
|
||||
result.mRange.end = i;
|
||||
|
||||
int32_t ligatureWidth =
|
||||
GetAdvanceForGlyphs(result.mLigatureStart, result.mLigatureEnd);
|
||||
int32_t ligatureWidth = GetAdvanceForGlyphs(result.mRange);
|
||||
// Count the number of started clusters we have seen
|
||||
uint32_t totalClusterCount = 0;
|
||||
uint32_t partClusterIndex = 0;
|
||||
uint32_t partClusterCount = 0;
|
||||
for (i = result.mLigatureStart; i < result.mLigatureEnd; ++i) {
|
||||
for (i = result.mRange.start; i < result.mRange.end; ++i) {
|
||||
// Treat the first character of the ligature as the start of a
|
||||
// cluster for our purposes of allocating ligature width to its
|
||||
// characters.
|
||||
if (i == result.mLigatureStart || charGlyphs[i].IsClusterStart()) {
|
||||
if (i == result.mRange.start || charGlyphs[i].IsClusterStart()) {
|
||||
++totalClusterCount;
|
||||
if (i < aPartStart) {
|
||||
if (i < aPartRange.start) {
|
||||
++partClusterIndex;
|
||||
} else if (i < aPartEnd) {
|
||||
} else if (i < aPartRange.end) {
|
||||
++partClusterCount;
|
||||
}
|
||||
}
|
||||
@ -275,7 +274,7 @@ gfxTextRun::ComputeLigatureData(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
// Any rounding errors are apportioned to the final part of the ligature,
|
||||
// so that measuring all parts of a ligature and summing them is equal to
|
||||
// the ligature width.
|
||||
if (aPartEnd == result.mLigatureEnd) {
|
||||
if (aPartRange.end == result.mRange.end) {
|
||||
gfxFloat allParts = totalClusterCount * (ligatureWidth / totalClusterCount);
|
||||
result.mPartWidth += ligatureWidth - allParts;
|
||||
}
|
||||
@ -296,12 +295,14 @@ gfxTextRun::ComputeLigatureData(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
|
||||
if (aProvider && (mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING)) {
|
||||
gfxFont::Spacing spacing;
|
||||
if (aPartStart == result.mLigatureStart) {
|
||||
aProvider->GetSpacing(aPartStart, 1, &spacing);
|
||||
if (aPartRange.start == result.mRange.start) {
|
||||
aProvider->GetSpacing(
|
||||
Range(aPartRange.start, aPartRange.start + 1), &spacing);
|
||||
result.mPartWidth += spacing.mBefore;
|
||||
}
|
||||
if (aPartEnd == result.mLigatureEnd) {
|
||||
aProvider->GetSpacing(aPartEnd - 1, 1, &spacing);
|
||||
if (aPartRange.end == result.mRange.end) {
|
||||
aProvider->GetSpacing(
|
||||
Range(aPartRange.end - 1, aPartRange.end), &spacing);
|
||||
result.mPartWidth += spacing.mAfter;
|
||||
}
|
||||
}
|
||||
@ -310,34 +311,34 @@ gfxTextRun::ComputeLigatureData(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
gfxTextRun::ComputePartialLigatureWidth(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
gfxTextRun::ComputePartialLigatureWidth(Range aPartRange,
|
||||
PropertyProvider *aProvider)
|
||||
{
|
||||
if (aPartStart >= aPartEnd)
|
||||
if (aPartRange.start >= aPartRange.end)
|
||||
return 0;
|
||||
LigatureData data = ComputeLigatureData(aPartStart, aPartEnd, aProvider);
|
||||
LigatureData data = ComputeLigatureData(aPartRange, aProvider);
|
||||
return data.mPartWidth;
|
||||
}
|
||||
|
||||
int32_t
|
||||
gfxTextRun::GetAdvanceForGlyphs(uint32_t aStart, uint32_t aEnd)
|
||||
gfxTextRun::GetAdvanceForGlyphs(Range aRange)
|
||||
{
|
||||
int32_t advance = 0;
|
||||
for (auto i = aStart; i < aEnd; ++i) {
|
||||
for (auto i = aRange.start; i < aRange.end; ++i) {
|
||||
advance += GetAdvanceForGlyph(i);
|
||||
}
|
||||
return advance;
|
||||
}
|
||||
|
||||
static void
|
||||
GetAdjustedSpacing(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
||||
GetAdjustedSpacing(gfxTextRun *aTextRun, gfxTextRun::Range aRange,
|
||||
gfxTextRun::PropertyProvider *aProvider,
|
||||
gfxTextRun::PropertyProvider::Spacing *aSpacing)
|
||||
{
|
||||
if (aStart >= aEnd)
|
||||
if (aRange.start >= aRange.end)
|
||||
return;
|
||||
|
||||
aProvider->GetSpacing(aStart, aEnd - aStart, aSpacing);
|
||||
aProvider->GetSpacing(aRange, aSpacing);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Check to see if we have spacing inside ligatures
|
||||
@ -345,11 +346,13 @@ GetAdjustedSpacing(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
||||
const gfxTextRun::CompressedGlyph *charGlyphs = aTextRun->GetCharacterGlyphs();
|
||||
uint32_t i;
|
||||
|
||||
for (i = aStart; i < aEnd; ++i) {
|
||||
for (i = aRange.start; i < aRange.end; ++i) {
|
||||
if (!charGlyphs[i].IsLigatureGroupStart()) {
|
||||
NS_ASSERTION(i == aStart || aSpacing[i - aStart].mBefore == 0,
|
||||
NS_ASSERTION(i == aRange.start ||
|
||||
aSpacing[i - aRange.start].mBefore == 0,
|
||||
"Before-spacing inside a ligature!");
|
||||
NS_ASSERTION(i - 1 <= aStart || aSpacing[i - 1 - aStart].mAfter == 0,
|
||||
NS_ASSERTION(i - 1 <= aRange.start ||
|
||||
aSpacing[i - 1 - aRange.start].mAfter == 0,
|
||||
"After-spacing inside a ligature!");
|
||||
}
|
||||
}
|
||||
@ -357,51 +360,53 @@ GetAdjustedSpacing(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
||||
}
|
||||
|
||||
bool
|
||||
gfxTextRun::GetAdjustedSpacingArray(uint32_t aStart, uint32_t aEnd,
|
||||
PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
gfxTextRun::GetAdjustedSpacingArray(Range aRange, PropertyProvider *aProvider,
|
||||
Range aSpacingRange,
|
||||
nsTArray<PropertyProvider::Spacing> *aSpacing)
|
||||
{
|
||||
if (!aProvider || !(mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING))
|
||||
return false;
|
||||
if (!aSpacing->AppendElements(aEnd - aStart))
|
||||
if (!aSpacing->AppendElements(aRange.Length()))
|
||||
return false;
|
||||
memset(aSpacing->Elements(), 0, sizeof(gfxFont::Spacing)*(aSpacingStart - aStart));
|
||||
GetAdjustedSpacing(this, aSpacingStart, aSpacingEnd, aProvider,
|
||||
aSpacing->Elements() + aSpacingStart - aStart);
|
||||
memset(aSpacing->Elements() + aSpacingEnd - aStart, 0, sizeof(gfxFont::Spacing)*(aEnd - aSpacingEnd));
|
||||
auto spacingOffset = aSpacingRange.start - aRange.start;
|
||||
memset(aSpacing->Elements(), 0, sizeof(gfxFont::Spacing) * spacingOffset);
|
||||
GetAdjustedSpacing(this, aSpacingRange, aProvider,
|
||||
aSpacing->Elements() + spacingOffset);
|
||||
memset(aSpacing->Elements() + aSpacingRange.end - aRange.start, 0,
|
||||
sizeof(gfxFont::Spacing) * (aRange.end - aSpacingRange.end));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::ShrinkToLigatureBoundaries(uint32_t *aStart, uint32_t *aEnd)
|
||||
gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange)
|
||||
{
|
||||
if (*aStart >= *aEnd)
|
||||
if (aRange->start >= aRange->end)
|
||||
return;
|
||||
|
||||
CompressedGlyph *charGlyphs = mCharacterGlyphs;
|
||||
|
||||
while (*aStart < *aEnd && !charGlyphs[*aStart].IsLigatureGroupStart()) {
|
||||
++(*aStart);
|
||||
while (aRange->start < aRange->end &&
|
||||
!charGlyphs[aRange->start].IsLigatureGroupStart()) {
|
||||
++aRange->start;
|
||||
}
|
||||
if (*aEnd < GetLength()) {
|
||||
while (*aEnd > *aStart && !charGlyphs[*aEnd].IsLigatureGroupStart()) {
|
||||
--(*aEnd);
|
||||
if (aRange->end < GetLength()) {
|
||||
while (aRange->end > aRange->start &&
|
||||
!charGlyphs[aRange->end].IsLigatureGroupStart()) {
|
||||
--aRange->end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::DrawGlyphs(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
gfxPoint *aPt, PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
gfxTextRun::DrawGlyphs(gfxFont *aFont, Range aRange, gfxPoint *aPt,
|
||||
PropertyProvider *aProvider, Range aSpacingRange,
|
||||
TextRunDrawParams& aParams, uint16_t aOrientation)
|
||||
{
|
||||
AutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
|
||||
bool haveSpacing = GetAdjustedSpacingArray(aStart, aEnd, aProvider,
|
||||
aSpacingStart, aSpacingEnd, &spacingBuffer);
|
||||
bool haveSpacing = GetAdjustedSpacingArray(aRange, aProvider,
|
||||
aSpacingRange, &spacingBuffer);
|
||||
aParams.spacing = haveSpacing ? spacingBuffer.Elements() : nullptr;
|
||||
aFont->Draw(this, aStart, aEnd, aPt, aParams, aOrientation);
|
||||
aFont->Draw(this, aRange.start, aRange.end, aPt, aParams, aOrientation);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -429,16 +434,16 @@ ClipPartialLigature(const gfxTextRun* aTextRun,
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::DrawPartialLigature(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
gfxTextRun::DrawPartialLigature(gfxFont *aFont, Range aRange,
|
||||
gfxPoint *aPt, PropertyProvider *aProvider,
|
||||
TextRunDrawParams& aParams, uint16_t aOrientation)
|
||||
{
|
||||
if (aStart >= aEnd) {
|
||||
if (aRange.start >= aRange.end) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw partial ligature. We hack this by clipping the ligature.
|
||||
LigatureData data = ComputeLigatureData(aStart, aEnd, aProvider);
|
||||
LigatureData data = ComputeLigatureData(aRange, aProvider);
|
||||
gfxRect clipExtents = aParams.context->GetClipExtents();
|
||||
gfxFloat start, end;
|
||||
if (aParams.isVerticalRun) {
|
||||
@ -473,8 +478,8 @@ gfxTextRun::DrawPartialLigature(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
pt = gfxPoint(aPt->x - aParams.direction * data.mPartAdvance, aPt->y);
|
||||
}
|
||||
|
||||
DrawGlyphs(aFont, data.mLigatureStart, data.mLigatureEnd, &pt,
|
||||
aProvider, aStart, aEnd, aParams, aOrientation);
|
||||
DrawGlyphs(aFont, data.mRange, &pt,
|
||||
aProvider, aRange, aParams, aOrientation);
|
||||
aParams.context->Restore();
|
||||
|
||||
if (aParams.isVerticalRun) {
|
||||
@ -489,9 +494,9 @@ gfxTextRun::DrawPartialLigature(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
// check whether the text run needs to be explicitly composited in order to
|
||||
// support opacity.
|
||||
static bool
|
||||
HasSyntheticBoldOrColor(gfxTextRun *aRun, uint32_t aStart, uint32_t aLength)
|
||||
HasSyntheticBoldOrColor(gfxTextRun *aRun, gfxTextRun::Range aRange)
|
||||
{
|
||||
gfxTextRun::GlyphRunIterator iter(aRun, aStart, aLength);
|
||||
gfxTextRun::GlyphRunIterator iter(aRun, aRange);
|
||||
while (iter.NextRun()) {
|
||||
gfxFont *font = iter.GetGlyphRun()->mFont;
|
||||
if (font) {
|
||||
@ -560,12 +565,12 @@ struct BufferAlphaColor {
|
||||
|
||||
void
|
||||
gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
|
||||
uint32_t aStart, uint32_t aLength,
|
||||
Range aRange,
|
||||
PropertyProvider *aProvider, gfxFloat *aAdvanceWidth,
|
||||
gfxTextContextPaint *aContextPaint,
|
||||
gfxTextRunDrawCallbacks *aCallbacks)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= GetLength(), "Substring out of range");
|
||||
NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
|
||||
NS_ASSERTION(aDrawMode == DrawMode::GLYPH_PATH ||
|
||||
!(int(aDrawMode) & int(DrawMode::GLYPH_PATH)),
|
||||
"GLYPH_PATH cannot be used with GLYPH_FILL, GLYPH_STROKE or GLYPH_STROKE_UNDERNEATH");
|
||||
@ -586,7 +591,7 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
|
||||
// We don't need to draw anything;
|
||||
// but if the caller wants advance width, we need to compute it here
|
||||
if (aAdvanceWidth) {
|
||||
gfxTextRun::Metrics metrics = MeasureText(aStart, aLength,
|
||||
gfxTextRun::Metrics metrics = MeasureText(aRange,
|
||||
gfxFont::LOOSE_INK_EXTENTS,
|
||||
aContext->GetDrawTarget(),
|
||||
aProvider);
|
||||
@ -605,10 +610,10 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
|
||||
|
||||
if (aDrawMode == DrawMode::GLYPH_FILL &&
|
||||
HasNonOpaqueNonTransparentColor(aContext, currentColor) &&
|
||||
HasSyntheticBoldOrColor(this, aStart, aLength)) {
|
||||
HasSyntheticBoldOrColor(this, aRange)) {
|
||||
needToRestore = true;
|
||||
// measure text, use the bounding box
|
||||
gfxTextRun::Metrics metrics = MeasureText(aStart, aLength,
|
||||
gfxTextRun::Metrics metrics = MeasureText(aRange,
|
||||
gfxFont::LOOSE_INK_EXTENTS,
|
||||
aContext->GetDrawTarget(),
|
||||
aProvider);
|
||||
@ -632,34 +637,33 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
|
||||
params.dt = aContext->GetDrawTarget();
|
||||
params.fontSmoothingBGColor = aContext->GetFontSmoothingBackgroundColor();
|
||||
|
||||
GlyphRunIterator iter(this, aStart, aLength);
|
||||
GlyphRunIterator iter(this, aRange);
|
||||
gfxFloat advance = 0.0;
|
||||
|
||||
while (iter.NextRun()) {
|
||||
gfxFont *font = iter.GetGlyphRun()->mFont;
|
||||
uint32_t start = iter.GetStringStart();
|
||||
uint32_t end = iter.GetStringEnd();
|
||||
uint32_t ligatureRunStart = start;
|
||||
uint32_t ligatureRunEnd = end;
|
||||
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
|
||||
Range ligatureRange(start, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
bool drawPartial = aDrawMode == DrawMode::GLYPH_FILL ||
|
||||
(aDrawMode == DrawMode::GLYPH_PATH && aCallbacks);
|
||||
gfxPoint origPt = aPt;
|
||||
|
||||
if (drawPartial) {
|
||||
DrawPartialLigature(font, start, ligatureRunStart, &aPt,
|
||||
aProvider, params,
|
||||
DrawPartialLigature(font, Range(start, ligatureRange.start),
|
||||
&aPt, aProvider, params,
|
||||
iter.GetGlyphRun()->mOrientation);
|
||||
}
|
||||
|
||||
DrawGlyphs(font, ligatureRunStart, ligatureRunEnd, &aPt,
|
||||
aProvider, ligatureRunStart, ligatureRunEnd, params,
|
||||
DrawGlyphs(font, ligatureRange, &aPt,
|
||||
aProvider, ligatureRange, params,
|
||||
iter.GetGlyphRun()->mOrientation);
|
||||
|
||||
if (drawPartial) {
|
||||
DrawPartialLigature(font, ligatureRunEnd, end, &aPt,
|
||||
aProvider, params,
|
||||
DrawPartialLigature(font, Range(ligatureRange.end, end),
|
||||
&aPt, aProvider, params,
|
||||
iter.GetGlyphRun()->mOrientation);
|
||||
}
|
||||
|
||||
@ -684,10 +688,9 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
|
||||
void
|
||||
gfxTextRun::DrawEmphasisMarks(gfxContext *aContext, gfxTextRun* aMark,
|
||||
gfxFloat aMarkAdvance, gfxPoint aPt,
|
||||
uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider* aProvider)
|
||||
Range aRange, PropertyProvider* aProvider)
|
||||
{
|
||||
MOZ_ASSERT(aStart + aLength <= GetLength());
|
||||
MOZ_ASSERT(aRange.end <= GetLength());
|
||||
|
||||
EmphasisMarkDrawParams params;
|
||||
params.context = aContext;
|
||||
@ -699,69 +702,65 @@ gfxTextRun::DrawEmphasisMarks(gfxContext *aContext, gfxTextRun* aMark,
|
||||
gfxFloat& inlineCoord = params.isVertical ? aPt.y : aPt.x;
|
||||
gfxFloat direction = params.direction;
|
||||
|
||||
GlyphRunIterator iter(this, aStart, aLength);
|
||||
GlyphRunIterator iter(this, aRange);
|
||||
while (iter.NextRun()) {
|
||||
gfxFont* font = iter.GetGlyphRun()->mFont;
|
||||
uint32_t start = iter.GetStringStart();
|
||||
uint32_t end = iter.GetStringEnd();
|
||||
uint32_t ligatureRunStart = start;
|
||||
uint32_t ligatureRunEnd = end;
|
||||
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
|
||||
Range ligatureRange(start, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
inlineCoord += direction *
|
||||
ComputePartialLigatureWidth(start, ligatureRunStart, aProvider);
|
||||
inlineCoord += direction * ComputePartialLigatureWidth(
|
||||
Range(start, ligatureRange.start), aProvider);
|
||||
|
||||
AutoTArray<PropertyProvider::Spacing, 200> spacingBuffer;
|
||||
bool haveSpacing = GetAdjustedSpacingArray(
|
||||
ligatureRunStart, ligatureRunEnd, aProvider,
|
||||
ligatureRunStart, ligatureRunEnd, &spacingBuffer);
|
||||
ligatureRange, aProvider, ligatureRange, &spacingBuffer);
|
||||
params.spacing = haveSpacing ? spacingBuffer.Elements() : nullptr;
|
||||
font->DrawEmphasisMarks(this, &aPt, ligatureRunStart,
|
||||
ligatureRunEnd - ligatureRunStart, params);
|
||||
font->DrawEmphasisMarks(this, &aPt, ligatureRange.start,
|
||||
ligatureRange.Length(), params);
|
||||
|
||||
inlineCoord += direction *
|
||||
ComputePartialLigatureWidth(ligatureRunEnd, end, aProvider);
|
||||
inlineCoord += direction * ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, end), aProvider);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::AccumulateMetricsForRun(gfxFont *aFont,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
gfxTextRun::AccumulateMetricsForRun(gfxFont *aFont, Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget,
|
||||
PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
Range aSpacingRange,
|
||||
uint16_t aOrientation,
|
||||
Metrics *aMetrics)
|
||||
{
|
||||
AutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
|
||||
bool haveSpacing = GetAdjustedSpacingArray(aStart, aEnd, aProvider,
|
||||
aSpacingStart, aSpacingEnd, &spacingBuffer);
|
||||
Metrics metrics = aFont->Measure(this, aStart, aEnd, aBoundingBoxType,
|
||||
aRefDrawTarget,
|
||||
bool haveSpacing = GetAdjustedSpacingArray(aRange, aProvider,
|
||||
aSpacingRange, &spacingBuffer);
|
||||
Metrics metrics = aFont->Measure(this, aRange.start, aRange.end,
|
||||
aBoundingBoxType, aRefDrawTarget,
|
||||
haveSpacing ? spacingBuffer.Elements() : nullptr,
|
||||
aOrientation);
|
||||
aMetrics->CombineWith(metrics, IsRightToLeft());
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont, Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aRefDrawTarget,
|
||||
PropertyProvider *aProvider, uint16_t aOrientation, Metrics *aMetrics)
|
||||
{
|
||||
if (aStart >= aEnd)
|
||||
if (aRange.start >= aRange.end)
|
||||
return;
|
||||
|
||||
// Measure partial ligature. We hack this by clipping the metrics in the
|
||||
// same way we clip the drawing.
|
||||
LigatureData data = ComputeLigatureData(aStart, aEnd, aProvider);
|
||||
LigatureData data = ComputeLigatureData(aRange, aProvider);
|
||||
|
||||
// First measure the complete ligature
|
||||
Metrics metrics;
|
||||
AccumulateMetricsForRun(aFont, data.mLigatureStart, data.mLigatureEnd,
|
||||
AccumulateMetricsForRun(aFont, data.mRange,
|
||||
aBoundingBoxType, aRefDrawTarget,
|
||||
aProvider, aStart, aEnd, aOrientation, &metrics);
|
||||
aProvider, aRange, aOrientation, &metrics);
|
||||
|
||||
// Clip the bounding box to the ligature part
|
||||
gfxFloat bboxLeft = metrics.mBoundingBox.X();
|
||||
@ -783,24 +782,24 @@ gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont,
|
||||
}
|
||||
|
||||
gfxTextRun::Metrics
|
||||
gfxTextRun::MeasureText(uint32_t aStart, uint32_t aLength,
|
||||
gfxTextRun::MeasureText(Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget,
|
||||
PropertyProvider *aProvider)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= GetLength(), "Substring out of range");
|
||||
NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
|
||||
|
||||
Metrics accumulatedMetrics;
|
||||
GlyphRunIterator iter(this, aStart, aLength);
|
||||
GlyphRunIterator iter(this, aRange);
|
||||
while (iter.NextRun()) {
|
||||
gfxFont *font = iter.GetGlyphRun()->mFont;
|
||||
uint32_t start = iter.GetStringStart();
|
||||
uint32_t end = iter.GetStringEnd();
|
||||
uint32_t ligatureRunStart = start;
|
||||
uint32_t ligatureRunEnd = end;
|
||||
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
|
||||
Range ligatureRange(start, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
AccumulatePartialLigatureMetrics(font, start, ligatureRunStart,
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(start, ligatureRange.start),
|
||||
aBoundingBoxType, aRefDrawTarget, aProvider,
|
||||
iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
|
||||
@ -810,11 +809,12 @@ gfxTextRun::MeasureText(uint32_t aStart, uint32_t aLength,
|
||||
// by getting some ascent/descent from the font and using our stored
|
||||
// advance widths.
|
||||
AccumulateMetricsForRun(font,
|
||||
ligatureRunStart, ligatureRunEnd, aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider, ligatureRunStart, ligatureRunEnd,
|
||||
ligatureRange, aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider, ligatureRange,
|
||||
iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
|
||||
AccumulatePartialLigatureMetrics(font, ligatureRunEnd, end,
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(ligatureRange.end, end),
|
||||
aBoundingBoxType, aRefDrawTarget, aProvider,
|
||||
iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
}
|
||||
@ -842,13 +842,12 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
|
||||
NS_ASSERTION(aStart + aMaxLength <= GetLength(), "Substring out of range");
|
||||
|
||||
uint32_t bufferStart = aStart;
|
||||
uint32_t bufferLength = std::min<uint32_t>(aMaxLength, MEASUREMENT_BUFFER_SIZE);
|
||||
Range bufferRange(aStart, aStart +
|
||||
std::min<uint32_t>(aMaxLength, MEASUREMENT_BUFFER_SIZE));
|
||||
PropertyProvider::Spacing spacingBuffer[MEASUREMENT_BUFFER_SIZE];
|
||||
bool haveSpacing = aProvider && (mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING) != 0;
|
||||
if (haveSpacing) {
|
||||
GetAdjustedSpacing(this, bufferStart, bufferStart + bufferLength, aProvider,
|
||||
spacingBuffer);
|
||||
GetAdjustedSpacing(this, bufferRange, aProvider, spacingBuffer);
|
||||
}
|
||||
bool hyphenBuffer[MEASUREMENT_BUFFER_SIZE];
|
||||
bool haveHyphenation = aProvider &&
|
||||
@ -856,8 +855,7 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
(aProvider->GetHyphensOption() == NS_STYLE_HYPHENS_MANUAL &&
|
||||
(mFlags & gfxTextRunFactory::TEXT_ENABLE_HYPHEN_BREAKS) != 0));
|
||||
if (haveHyphenation) {
|
||||
aProvider->GetHyphenationBreaks(bufferStart, bufferLength,
|
||||
hyphenBuffer);
|
||||
aProvider->GetHyphenationBreaks(bufferRange, hyphenBuffer);
|
||||
}
|
||||
|
||||
gfxFloat width = 0;
|
||||
@ -873,23 +871,21 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
uint32_t end = aStart + aMaxLength;
|
||||
bool lastBreakUsedHyphenation = false;
|
||||
|
||||
uint32_t ligatureRunStart = aStart;
|
||||
uint32_t ligatureRunEnd = end;
|
||||
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
|
||||
Range ligatureRange(aStart, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
uint32_t i;
|
||||
for (i = aStart; i < end; ++i) {
|
||||
if (i >= bufferStart + bufferLength) {
|
||||
if (i >= bufferRange.end) {
|
||||
// Fetch more spacing and hyphenation data
|
||||
bufferStart = i;
|
||||
bufferLength = std::min(aStart + aMaxLength, i + MEASUREMENT_BUFFER_SIZE) - i;
|
||||
bufferRange.start = i;
|
||||
bufferRange.end = std::min(aStart + aMaxLength,
|
||||
i + MEASUREMENT_BUFFER_SIZE);
|
||||
if (haveSpacing) {
|
||||
GetAdjustedSpacing(this, bufferStart, bufferStart + bufferLength, aProvider,
|
||||
spacingBuffer);
|
||||
GetAdjustedSpacing(this, bufferRange, aProvider, spacingBuffer);
|
||||
}
|
||||
if (haveHyphenation) {
|
||||
aProvider->GetHyphenationBreaks(bufferStart, bufferLength,
|
||||
hyphenBuffer);
|
||||
aProvider->GetHyphenationBreaks(bufferRange, hyphenBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -900,8 +896,8 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
if (aSuppressBreak != eSuppressAllBreaks &&
|
||||
(aSuppressBreak != eSuppressInitialBreak || i > aStart)) {
|
||||
bool atNaturalBreak = mCharacterGlyphs[i].CanBreakBefore() == 1;
|
||||
bool atHyphenationBreak =
|
||||
!atNaturalBreak && haveHyphenation && hyphenBuffer[i - bufferStart];
|
||||
bool atHyphenationBreak = !atNaturalBreak &&
|
||||
haveHyphenation && hyphenBuffer[i - bufferRange.start];
|
||||
bool atBreak = atNaturalBreak || atHyphenationBreak;
|
||||
bool wordWrapping =
|
||||
aCanWordWrap && mCharacterGlyphs[i].IsClusterStart() &&
|
||||
@ -934,14 +930,16 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
}
|
||||
|
||||
gfxFloat charAdvance;
|
||||
if (i >= ligatureRunStart && i < ligatureRunEnd) {
|
||||
charAdvance = GetAdvanceForGlyphs(i, i + 1);
|
||||
if (i >= ligatureRange.start && i < ligatureRange.end) {
|
||||
charAdvance = GetAdvanceForGlyphs(Range(i, i + 1));
|
||||
if (haveSpacing) {
|
||||
PropertyProvider::Spacing *space = &spacingBuffer[i - bufferStart];
|
||||
PropertyProvider::Spacing *space =
|
||||
&spacingBuffer[i - bufferRange.start];
|
||||
charAdvance += space->mBefore + space->mAfter;
|
||||
}
|
||||
} else {
|
||||
charAdvance = ComputePartialLigatureWidth(i, i + 1, aProvider);
|
||||
charAdvance =
|
||||
ComputePartialLigatureWidth(Range(i, i + 1), aProvider);
|
||||
}
|
||||
|
||||
advance += charAdvance;
|
||||
@ -978,13 +976,13 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
}
|
||||
|
||||
if (aMetrics) {
|
||||
*aMetrics = MeasureText(aStart, charsFit, aBoundingBoxType,
|
||||
auto fitEnd = aStart + charsFit;
|
||||
*aMetrics = MeasureText(Range(aStart, fitEnd), aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider);
|
||||
if (trimmableChars) {
|
||||
Metrics trimMetrics =
|
||||
MeasureText(aStart + charsFit - trimmableChars,
|
||||
trimmableChars, aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider);
|
||||
MeasureText(Range(fitEnd - trimmableChars, fitEnd),
|
||||
aBoundingBoxType, aRefDrawTarget, aProvider);
|
||||
aMetrics->mAdvanceWidth -= trimMetrics.mAdvanceWidth;
|
||||
}
|
||||
}
|
||||
@ -1006,18 +1004,19 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider *aProvider,
|
||||
gfxTextRun::GetAdvanceWidth(Range aRange, PropertyProvider *aProvider,
|
||||
PropertyProvider::Spacing* aSpacing)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= GetLength(), "Substring out of range");
|
||||
NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
|
||||
|
||||
uint32_t ligatureRunStart = aStart;
|
||||
uint32_t ligatureRunEnd = aStart + aLength;
|
||||
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
|
||||
Range ligatureRange = aRange;
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
gfxFloat result = ComputePartialLigatureWidth(aStart, ligatureRunStart, aProvider) +
|
||||
ComputePartialLigatureWidth(ligatureRunEnd, aStart + aLength, aProvider);
|
||||
gfxFloat result =
|
||||
ComputePartialLigatureWidth(Range(aRange.start, ligatureRange.start),
|
||||
aProvider) +
|
||||
ComputePartialLigatureWidth(Range(ligatureRange.end, aRange.end),
|
||||
aProvider);
|
||||
|
||||
if (aSpacing) {
|
||||
aSpacing->mBefore = aSpacing->mAfter = 0;
|
||||
@ -1028,10 +1027,10 @@ gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
if (aProvider && (mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING)) {
|
||||
uint32_t i;
|
||||
AutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
|
||||
if (spacingBuffer.AppendElements(aLength)) {
|
||||
GetAdjustedSpacing(this, ligatureRunStart, ligatureRunEnd, aProvider,
|
||||
if (spacingBuffer.AppendElements(aRange.Length())) {
|
||||
GetAdjustedSpacing(this, ligatureRange, aProvider,
|
||||
spacingBuffer.Elements());
|
||||
for (i = 0; i < ligatureRunEnd - ligatureRunStart; ++i) {
|
||||
for (i = 0; i < ligatureRange.Length(); ++i) {
|
||||
PropertyProvider::Spacing *space = &spacingBuffer[i];
|
||||
result += space->mBefore + space->mAfter;
|
||||
}
|
||||
@ -1042,11 +1041,11 @@ gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
}
|
||||
}
|
||||
|
||||
return result + GetAdvanceForGlyphs(ligatureRunStart, ligatureRunEnd);
|
||||
return result + GetAdvanceForGlyphs(ligatureRange);
|
||||
}
|
||||
|
||||
bool
|
||||
gfxTextRun::SetLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
gfxTextRun::SetLineBreaks(Range aRange,
|
||||
bool aLineBreakBefore, bool aLineBreakAfter,
|
||||
gfxFloat *aAdvanceWidthDelta)
|
||||
{
|
||||
@ -1244,12 +1243,11 @@ gfxTextRun::CopyGlyphDataFrom(gfxShapedWord *aShapedWord, uint32_t aOffset)
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
uint32_t aLength, uint32_t aDest)
|
||||
gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, Range aRange, uint32_t aDest)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= aSource->GetLength(),
|
||||
NS_ASSERTION(aRange.end <= aSource->GetLength(),
|
||||
"Source substring out of range");
|
||||
NS_ASSERTION(aDest + aLength <= GetLength(),
|
||||
NS_ASSERTION(aDest + aRange.Length() <= GetLength(),
|
||||
"Destination substring out of range");
|
||||
|
||||
if (aSource->mSkipDrawing) {
|
||||
@ -1257,9 +1255,9 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
}
|
||||
|
||||
// Copy base glyph data, and DetailedGlyph data where present
|
||||
const CompressedGlyph *srcGlyphs = aSource->mCharacterGlyphs + aStart;
|
||||
const CompressedGlyph *srcGlyphs = aSource->mCharacterGlyphs + aRange.start;
|
||||
CompressedGlyph *dstGlyphs = mCharacterGlyphs + aDest;
|
||||
for (uint32_t i = 0; i < aLength; ++i) {
|
||||
for (uint32_t i = 0; i < aRange.Length(); ++i) {
|
||||
CompressedGlyph g = srcGlyphs[i];
|
||||
g.SetCanBreakBefore(!g.IsClusterStart() ?
|
||||
CompressedGlyph::FLAG_BREAK_TYPE_NONE :
|
||||
@ -1269,7 +1267,8 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
if (count > 0) {
|
||||
DetailedGlyph *dst = AllocateDetailedGlyphs(i + aDest, count);
|
||||
if (dst) {
|
||||
DetailedGlyph *src = aSource->GetDetailedGlyphs(i + aStart);
|
||||
DetailedGlyph *src =
|
||||
aSource->GetDetailedGlyphs(i + aRange.start);
|
||||
if (src) {
|
||||
::memcpy(dst, src, count * sizeof(DetailedGlyph));
|
||||
} else {
|
||||
@ -1284,7 +1283,7 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
}
|
||||
|
||||
// Copy glyph runs
|
||||
GlyphRunIterator iter(aSource, aStart, aLength);
|
||||
GlyphRunIterator iter(aSource, aRange);
|
||||
#ifdef DEBUG
|
||||
GlyphRun *prevRun = nullptr;
|
||||
#endif
|
||||
@ -1315,7 +1314,7 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
"Ended font run in the middle of a cluster");
|
||||
|
||||
nsresult rv = AddGlyphRun(font, iter.GetGlyphRun()->mMatchType,
|
||||
start - aStart + aDest, false,
|
||||
start - aRange.start + aDest, false,
|
||||
iter.GetGlyphRun()->mOrientation);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
@ -1495,11 +1494,11 @@ gfxTextRun::ClusterIterator::NextCluster()
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
gfxTextRun::ClusterIterator::ClusterLength() const
|
||||
gfxTextRun::Range
|
||||
gfxTextRun::ClusterIterator::ClusterRange() const
|
||||
{
|
||||
if (mCurrentChar == uint32_t(-1)) {
|
||||
return 0;
|
||||
return Range(0, 0);
|
||||
}
|
||||
|
||||
uint32_t i = mCurrentChar,
|
||||
@ -1510,7 +1509,7 @@ gfxTextRun::ClusterIterator::ClusterLength() const
|
||||
}
|
||||
}
|
||||
|
||||
return i - mCurrentChar;
|
||||
return Range(mCurrentChar, i);
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
@ -1520,7 +1519,7 @@ gfxTextRun::ClusterIterator::ClusterAdvance(PropertyProvider *aProvider) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mTextRun->GetAdvanceWidth(mCurrentChar, ClusterLength(), aProvider);
|
||||
return mTextRun->GetAdvanceWidth(ClusterRange(), aProvider);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -134,10 +134,23 @@ public:
|
||||
return mCharacterGlyphs[aPos].CharMayHaveEmphasisMark();
|
||||
}
|
||||
|
||||
// All uint32_t aStart, uint32_t aLength ranges below are restricted to
|
||||
// grapheme cluster boundaries! All offsets are in terms of the string
|
||||
// passed into MakeTextRun.
|
||||
|
||||
// All offsets are in terms of the string passed into MakeTextRun.
|
||||
|
||||
// Describe range [start, end) of a text run. The range is
|
||||
// restricted to grapheme cluster boundaries.
|
||||
struct Range
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
uint32_t Length() const { return end - start; }
|
||||
|
||||
Range() : start(0), end(0) {}
|
||||
Range(uint32_t aStart, uint32_t aEnd)
|
||||
: start(aStart), end(aEnd) {}
|
||||
explicit Range(gfxTextRun* aTextRun)
|
||||
: start(0), end(aTextRun->GetLength()) {}
|
||||
};
|
||||
|
||||
// All coordinates are in layout/app units
|
||||
|
||||
/**
|
||||
@ -152,8 +165,7 @@ public:
|
||||
* @return true if this changed the linebreaks, false if the new line
|
||||
* breaks are the same as the old
|
||||
*/
|
||||
virtual bool SetPotentialLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
uint8_t *aBreakBefore);
|
||||
virtual bool SetPotentialLineBreaks(Range aRange, uint8_t *aBreakBefore);
|
||||
|
||||
/**
|
||||
* Layout provides PropertyProvider objects. These allow detection of
|
||||
@ -169,8 +181,7 @@ public:
|
||||
public:
|
||||
// Detect hyphenation break opportunities in the given range; breaks
|
||||
// not at cluster boundaries will be ignored.
|
||||
virtual void GetHyphenationBreaks(uint32_t aStart, uint32_t aLength,
|
||||
bool *aBreakBefore) = 0;
|
||||
virtual void GetHyphenationBreaks(Range aRange, bool *aBreakBefore) = 0;
|
||||
|
||||
// Returns the provider's hyphenation setting, so callers can decide
|
||||
// whether it is necessary to call GetHyphenationBreaks.
|
||||
@ -189,8 +200,7 @@ public:
|
||||
* CLUSTER_START, then character i-1 must have zero after-spacing and
|
||||
* character i must have zero before-spacing.
|
||||
*/
|
||||
virtual void GetSpacing(uint32_t aStart, uint32_t aLength,
|
||||
Spacing *aSpacing) = 0;
|
||||
virtual void GetSpacing(Range aRange, Spacing *aSpacing) = 0;
|
||||
|
||||
// Returns a gfxContext that can be used to measure the hyphen glyph.
|
||||
// Only called if the hyphen width is requested.
|
||||
@ -213,7 +223,7 @@ public:
|
||||
return mCurrentChar;
|
||||
}
|
||||
|
||||
uint32_t ClusterLength() const;
|
||||
Range ClusterRange() const;
|
||||
|
||||
gfxFloat ClusterAdvance(PropertyProvider *aProvider) const;
|
||||
|
||||
@ -230,22 +240,21 @@ public:
|
||||
* is returned here.
|
||||
*
|
||||
* Drawing should respect advance widths in the sense that for LTR runs,
|
||||
* Draw(ctx, pt, offset1, length1, dirty, &provider, &advance) followed by
|
||||
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), offset1 + length1, length2,
|
||||
* Draw(ctx, pt, Range(start, middle), dirty, &provider, &advance) followed by
|
||||
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), Range(middle, end),
|
||||
* dirty, &provider, nullptr) should have the same effect as
|
||||
* Draw(ctx, pt, offset1, length1+length2, dirty, &provider, nullptr).
|
||||
* Draw(ctx, pt, Range(start, end), dirty, &provider, nullptr).
|
||||
* For RTL runs the rule is:
|
||||
* Draw(ctx, pt, offset1 + length1, length2, dirty, &provider, &advance) followed by
|
||||
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), offset1, length1,
|
||||
* Draw(ctx, pt, Range(middle, end), dirty, &provider, &advance) followed by
|
||||
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), Range(start, middle),
|
||||
* dirty, &provider, nullptr) should have the same effect as
|
||||
* Draw(ctx, pt, offset1, length1+length2, dirty, &provider, nullptr).
|
||||
* Draw(ctx, pt, Range(start, end), dirty, &provider, nullptr).
|
||||
*
|
||||
* Glyphs should be drawn in logical content order, which can be significant
|
||||
* if they overlap (perhaps due to negative spacing).
|
||||
*/
|
||||
void Draw(gfxContext *aContext, gfxPoint aPt,
|
||||
DrawMode aDrawMode,
|
||||
uint32_t aStart, uint32_t aLength,
|
||||
DrawMode aDrawMode, Range aRange,
|
||||
PropertyProvider *aProvider,
|
||||
gfxFloat *aAdvanceWidth, gfxTextContextPaint *aContextPaint,
|
||||
gfxTextRunDrawCallbacks *aCallbacks = nullptr);
|
||||
@ -257,15 +266,14 @@ public:
|
||||
*/
|
||||
void DrawEmphasisMarks(gfxContext* aContext, gfxTextRun* aMark,
|
||||
gfxFloat aMarkAdvance, gfxPoint aPt,
|
||||
uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider* aProvider);
|
||||
Range aRange, PropertyProvider* aProvider);
|
||||
|
||||
/**
|
||||
* Computes the ReflowMetrics for a substring.
|
||||
* Uses GetSpacing from aBreakProvider.
|
||||
* @param aBoundingBoxType which kind of bounding box (loose/tight)
|
||||
*/
|
||||
Metrics MeasureText(uint32_t aStart, uint32_t aLength,
|
||||
Metrics MeasureText(Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aDrawTargetForTightBoundingBox,
|
||||
PropertyProvider* aProvider);
|
||||
@ -273,7 +281,7 @@ public:
|
||||
Metrics MeasureText(gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aDrawTargetForTightBoundingBox,
|
||||
PropertyProvider* aProvider = nullptr) {
|
||||
return MeasureText(0, GetLength(), aBoundingBoxType,
|
||||
return MeasureText(Range(this), aBoundingBoxType,
|
||||
aDrawTargetForTightBoundingBox, aProvider);
|
||||
}
|
||||
|
||||
@ -284,17 +292,16 @@ public:
|
||||
* the substring would be returned in it. NOTE: the spacing is
|
||||
* included in the advance width.
|
||||
*/
|
||||
gfxFloat GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider *aProvider,
|
||||
gfxFloat GetAdvanceWidth(Range aRange, PropertyProvider *aProvider,
|
||||
PropertyProvider::Spacing* aSpacing = nullptr);
|
||||
|
||||
gfxFloat GetAdvanceWidth() {
|
||||
return GetAdvanceWidth(0, GetLength(), nullptr);
|
||||
return GetAdvanceWidth(Range(this), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all stored line breaks for the given range (both before and after),
|
||||
* and then set the line-break state before aStart to aBreakBefore and
|
||||
* and then set the line-break state before aRange.start to aBreakBefore and
|
||||
* after the last cluster to aBreakAfter.
|
||||
*
|
||||
* We require that before and after line breaks be consistent. For clusters
|
||||
@ -319,9 +326,9 @@ public:
|
||||
* @param aAdvanceWidthDelta if non-null, returns the change in advance
|
||||
* width of the given range.
|
||||
*/
|
||||
virtual bool SetLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
bool aLineBreakBefore, bool aLineBreakAfter,
|
||||
gfxFloat* aAdvanceWidthDelta);
|
||||
virtual bool SetLineBreaks(Range aRange,
|
||||
bool aLineBreakBefore, bool aLineBreakAfter,
|
||||
gfxFloat* aAdvanceWidthDelta);
|
||||
|
||||
enum SuppressBreak {
|
||||
eNoSuppressBreak,
|
||||
@ -434,9 +441,11 @@ public:
|
||||
|
||||
class GlyphRunIterator {
|
||||
public:
|
||||
GlyphRunIterator(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aLength)
|
||||
: mTextRun(aTextRun), mStartOffset(aStart), mEndOffset(aStart + aLength) {
|
||||
mNextIndex = mTextRun->FindFirstGlyphRunContaining(aStart);
|
||||
GlyphRunIterator(gfxTextRun *aTextRun, Range aRange)
|
||||
: mTextRun(aTextRun)
|
||||
, mStartOffset(aRange.start)
|
||||
, mEndOffset(aRange.end) {
|
||||
mNextIndex = mTextRun->FindFirstGlyphRunContaining(aRange.start);
|
||||
}
|
||||
bool NextRun();
|
||||
GlyphRun *GetGlyphRun() { return mGlyphRun; }
|
||||
@ -557,8 +566,7 @@ public:
|
||||
|
||||
// Copy glyph data for a range of characters from aSource to this
|
||||
// textrun.
|
||||
void CopyGlyphDataFrom(gfxTextRun *aSource, uint32_t aStart,
|
||||
uint32_t aLength, uint32_t aDest);
|
||||
void CopyGlyphDataFrom(gfxTextRun *aSource, Range aRange, uint32_t aDest);
|
||||
|
||||
nsExpirationState *GetExpirationState() { return &mExpirationState; }
|
||||
|
||||
@ -571,9 +579,8 @@ public:
|
||||
void ReleaseFontGroup();
|
||||
|
||||
struct LigatureData {
|
||||
// textrun offsets of the start and end of the containing ligature
|
||||
uint32_t mLigatureStart;
|
||||
uint32_t mLigatureEnd;
|
||||
// textrun range of the containing ligature
|
||||
Range mRange;
|
||||
// appunits advance to the start of the ligature part within the ligature;
|
||||
// never includes any spacing
|
||||
gfxFloat mPartAdvance;
|
||||
@ -669,16 +676,15 @@ private:
|
||||
// **** general helpers ****
|
||||
|
||||
// Get the total advance for a range of glyphs.
|
||||
int32_t GetAdvanceForGlyphs(uint32_t aStart, uint32_t aEnd);
|
||||
int32_t GetAdvanceForGlyphs(Range aRange);
|
||||
|
||||
// Spacing for characters outside the range aSpacingStart/aSpacingEnd
|
||||
// is assumed to be zero; such characters are not passed to aProvider.
|
||||
// This is useful to protect aProvider from being passed character indices
|
||||
// it is not currently able to handle.
|
||||
bool GetAdjustedSpacingArray(uint32_t aStart, uint32_t aEnd,
|
||||
PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
nsTArray<PropertyProvider::Spacing> *aSpacing);
|
||||
bool GetAdjustedSpacingArray(Range aRange, PropertyProvider *aProvider,
|
||||
Range aSpacingRange,
|
||||
nsTArray<PropertyProvider::Spacing> *aSpacing);
|
||||
|
||||
CompressedGlyph& EnsureComplexGlyph(uint32_t aIndex)
|
||||
{
|
||||
@ -691,20 +697,20 @@ private:
|
||||
// to handle requests that begin or end inside a ligature)
|
||||
|
||||
// if aProvider is null then mBeforeSpacing and mAfterSpacing are set to zero
|
||||
LigatureData ComputeLigatureData(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
LigatureData ComputeLigatureData(Range aPartRange,
|
||||
PropertyProvider *aProvider);
|
||||
gfxFloat ComputePartialLigatureWidth(uint32_t aPartStart, uint32_t aPartEnd,
|
||||
gfxFloat ComputePartialLigatureWidth(Range aPartRange,
|
||||
PropertyProvider *aProvider);
|
||||
void DrawPartialLigature(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
void DrawPartialLigature(gfxFont *aFont, Range aRange,
|
||||
gfxPoint *aPt, PropertyProvider *aProvider,
|
||||
TextRunDrawParams& aParams, uint16_t aOrientation);
|
||||
// Advance aStart to the start of the nearest ligature; back up aEnd
|
||||
// to the nearest ligature end; may result in *aStart == *aEnd
|
||||
void ShrinkToLigatureBoundaries(uint32_t *aStart, uint32_t *aEnd);
|
||||
// Advance aRange.start to the start of the nearest ligature, back
|
||||
// up aRange.end to the nearest ligature end; may result in
|
||||
// aRange->start == aRange->end.
|
||||
void ShrinkToLigatureBoundaries(Range* aRange);
|
||||
// result in appunits
|
||||
gfxFloat GetPartialLigatureWidth(uint32_t aStart, uint32_t aEnd, PropertyProvider *aProvider);
|
||||
void AccumulatePartialLigatureMetrics(gfxFont *aFont,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
gfxFloat GetPartialLigatureWidth(Range aRange, PropertyProvider *aProvider);
|
||||
void AccumulatePartialLigatureMetrics(gfxFont *aFont, Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget,
|
||||
PropertyProvider *aProvider,
|
||||
@ -712,18 +718,17 @@ private:
|
||||
Metrics *aMetrics);
|
||||
|
||||
// **** measurement helper ****
|
||||
void AccumulateMetricsForRun(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
void AccumulateMetricsForRun(gfxFont *aFont, Range aRange,
|
||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget* aRefDrawTarget,
|
||||
PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
Range aSpacingRange,
|
||||
uint16_t aOrientation,
|
||||
Metrics *aMetrics);
|
||||
|
||||
// **** drawing helper ****
|
||||
void DrawGlyphs(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
|
||||
gfxPoint *aPt, PropertyProvider *aProvider,
|
||||
uint32_t aSpacingStart, uint32_t aSpacingEnd,
|
||||
void DrawGlyphs(gfxFont *aFont, Range aRange, gfxPoint *aPt,
|
||||
PropertyProvider *aProvider, Range aSpacingRange,
|
||||
TextRunDrawParams& aParams, uint16_t aOrientation);
|
||||
|
||||
// XXX this should be changed to a GlyphRun plus a maybe-null GlyphRun*,
|
||||
|
@ -773,12 +773,15 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||
}
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
typedef gfxTextRun::Range Range;
|
||||
|
||||
// Copy potential linebreaks into child so they're preserved
|
||||
// (and also child will be shaped appropriately)
|
||||
NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(),
|
||||
"Dropped characters or break-before values somewhere!");
|
||||
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
||||
canBreakBeforeArray.Elements());
|
||||
Range range(0, uint32_t(canBreakBeforeArray.Length()));
|
||||
child->SetPotentialLineBreaks(range, canBreakBeforeArray.Elements());
|
||||
if (transformedChild) {
|
||||
transformedChild->FinishSettingProperties(aRefDrawTarget, aMFR);
|
||||
}
|
||||
@ -796,6 +799,6 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||
// We can't steal the data because the child may be cached and stealing
|
||||
// the data would break the cache.
|
||||
aTextRun->ResetGlyphRuns();
|
||||
aTextRun->CopyGlyphDataFrom(child, 0, child->GetLength(), 0);
|
||||
aTextRun->CopyGlyphDataFrom(child, Range(child), 0);
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ nsDisplayTextOverflowMarker::PaintTextToContext(nsRenderingContext* aCtx,
|
||||
"Ellipsis textruns should always be LTR!");
|
||||
gfxPoint gfxPt(pt.x, pt.y);
|
||||
textRun->Draw(aCtx->ThebesContext(), gfxPt, DrawMode::GLYPH_FILL,
|
||||
0, textRun->GetLength(), nullptr, nullptr, nullptr);
|
||||
gfxTextRun::Range(textRun), nullptr, nullptr, nullptr);
|
||||
}
|
||||
} else {
|
||||
RefPtr<nsFontMetrics> fm;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,7 @@ class nsTextFrame : public nsTextFrameBase {
|
||||
typedef mozilla::gfx::Point Point;
|
||||
typedef mozilla::gfx::Rect Rect;
|
||||
typedef mozilla::gfx::Size Size;
|
||||
typedef gfxTextRun::Range Range;
|
||||
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsTextFrame)
|
||||
@ -406,8 +407,7 @@ public:
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
const gfxRect& aDirtyRect,
|
||||
PropertyProvider& aProvider,
|
||||
uint32_t aContentOffset,
|
||||
uint32_t aContentLength,
|
||||
Range aRange,
|
||||
nsTextPaintStyle& aTextPaintStyle,
|
||||
const nsCharClipDisplayItem::ClipEdges& aClipEdges,
|
||||
gfxTextContextPaint* aContextPaint,
|
||||
@ -422,8 +422,7 @@ public:
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
const gfxRect& aDirtyRect,
|
||||
PropertyProvider& aProvider,
|
||||
uint32_t aContentOffset,
|
||||
uint32_t aContentLength,
|
||||
Range aContentRange,
|
||||
nsTextPaintStyle& aTextPaintStyle,
|
||||
SelectionDetails* aDetails,
|
||||
SelectionType* aAllTypes,
|
||||
@ -435,8 +434,7 @@ public:
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
const gfxRect& aDirtyRect,
|
||||
PropertyProvider& aProvider,
|
||||
uint32_t aContentOffset,
|
||||
uint32_t aContentLength,
|
||||
Range aContentRange,
|
||||
nsTextPaintStyle& aTextPaintStyle,
|
||||
SelectionDetails* aDetails,
|
||||
SelectionType aSelectionType,
|
||||
@ -445,7 +443,7 @@ public:
|
||||
void DrawEmphasisMarks(gfxContext* aContext,
|
||||
mozilla::WritingMode aWM,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
uint32_t aOffset, uint32_t aLength,
|
||||
Range aRange,
|
||||
const nscolor* aDecorationOverrideColor,
|
||||
PropertyProvider& aProvider);
|
||||
|
||||
@ -598,8 +596,7 @@ protected:
|
||||
nsRect UpdateTextEmphasis(mozilla::WritingMode aWM,
|
||||
PropertyProvider& aProvider);
|
||||
|
||||
void PaintOneShadow(uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
void PaintOneShadow(Range aRange,
|
||||
nsCSSShadowItem* aShadowDetails,
|
||||
PropertyProvider* aProvider,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -613,7 +610,7 @@ protected:
|
||||
uint32_t aBlurFlags);
|
||||
|
||||
void PaintShadows(nsCSSShadowArray* aShadow,
|
||||
uint32_t aOffset, uint32_t aLength,
|
||||
Range aRange,
|
||||
const nsRect& aDirtyRect,
|
||||
const gfxPoint& aFramePt,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
@ -699,8 +696,7 @@ protected:
|
||||
|
||||
void DrawTextRun(gfxContext* const aCtx,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Range aRange,
|
||||
PropertyProvider& aProvider,
|
||||
nscolor aTextColor,
|
||||
gfxFloat& aAdvanceWidth,
|
||||
@ -712,8 +708,7 @@ protected:
|
||||
const gfxRect& aDirtyRect,
|
||||
const gfxPoint& aFramePt,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Range aRange,
|
||||
PropertyProvider& aProvider,
|
||||
const nsTextPaintStyle& aTextStyle,
|
||||
nscolor aTextColor,
|
||||
@ -729,8 +724,7 @@ protected:
|
||||
const gfxRect& aDirtyRect,
|
||||
const gfxPoint& aFramePt,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Range aRange,
|
||||
PropertyProvider& aProvider,
|
||||
const nsTextPaintStyle& aTextStyle,
|
||||
nscolor aTextColor,
|
||||
|
@ -69,11 +69,11 @@ nsTransformedTextRun::SetCapitalization(uint32_t aStart, uint32_t aLength,
|
||||
}
|
||||
|
||||
bool
|
||||
nsTransformedTextRun::SetPotentialLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
nsTransformedTextRun::SetPotentialLineBreaks(Range aRange,
|
||||
uint8_t* aBreakBefore)
|
||||
{
|
||||
bool changed =
|
||||
gfxTextRun::SetPotentialLineBreaks(aStart, aLength, aBreakBefore);
|
||||
gfxTextRun::SetPotentialLineBreaks(aRange, aBreakBefore);
|
||||
if (changed) {
|
||||
mNeedsRebuild = true;
|
||||
}
|
||||
@ -131,7 +131,7 @@ MergeCharactersInTextRun(gfxTextRun* aDest, gfxTextRun* aSrc,
|
||||
{
|
||||
aDest->ResetGlyphRuns();
|
||||
|
||||
gfxTextRun::GlyphRunIterator iter(aSrc, 0, aSrc->GetLength());
|
||||
gfxTextRun::GlyphRunIterator iter(aSrc, gfxTextRun::Range(aSrc));
|
||||
uint32_t offset = 0;
|
||||
AutoTArray<gfxTextRun::DetailedGlyph,2> glyphs;
|
||||
while (iter.NextRun()) {
|
||||
@ -646,8 +646,8 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||
// (and also child will be shaped appropriately)
|
||||
NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(),
|
||||
"Dropped characters or break-before values somewhere!");
|
||||
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
||||
canBreakBeforeArray.Elements());
|
||||
gfxTextRun::Range range(0, uint32_t(canBreakBeforeArray.Length()));
|
||||
child->SetPotentialLineBreaks(range, canBreakBeforeArray.Elements());
|
||||
if (transformedChild) {
|
||||
transformedChild->FinishSettingProperties(aRefDrawTarget, aMFR);
|
||||
}
|
||||
@ -666,6 +666,6 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||
// We can't steal the data because the child may be cached and stealing
|
||||
// the data would break the cache.
|
||||
aTextRun->ResetGlyphRuns();
|
||||
aTextRun->CopyGlyphDataFrom(child, 0, child->GetLength(), 0);
|
||||
aTextRun->CopyGlyphDataFrom(child, gfxTextRun::Range(child), 0);
|
||||
}
|
||||
}
|
||||
|
@ -130,8 +130,7 @@ public:
|
||||
|
||||
void SetCapitalization(uint32_t aStart, uint32_t aLength,
|
||||
bool* aCapitalization);
|
||||
virtual bool SetPotentialLineBreaks(uint32_t aStart, uint32_t aLength,
|
||||
uint8_t* aBreakBefore);
|
||||
virtual bool SetPotentialLineBreaks(Range aRange, uint8_t* aBreakBefore);
|
||||
/**
|
||||
* Called after SetCapitalization and SetPotentialLineBreaks
|
||||
* are done and before we request any data from the textrun. Also always
|
||||
|
@ -60,7 +60,8 @@ nsresult
|
||||
nsFontFaceList::AddFontsFromTextRun(gfxTextRun* aTextRun,
|
||||
uint32_t aOffset, uint32_t aLength)
|
||||
{
|
||||
gfxTextRun::GlyphRunIterator iter(aTextRun, aOffset, aLength);
|
||||
gfxTextRun::Range range(aOffset, aOffset + aLength);
|
||||
gfxTextRun::GlyphRunIterator iter(aTextRun, range);
|
||||
while (iter.NextRun()) {
|
||||
gfxFontEntry *fe = iter.GetGlyphRun()->mFont->GetFontEntry();
|
||||
// if we have already listed this face, just make sure the match type is
|
||||
|
@ -2147,7 +2147,7 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
|
||||
// XXXfredw verify if mGlyphs[0] is non-null to workaround bug 973322.
|
||||
if (mGlyphs[0]) {
|
||||
mGlyphs[0]->Draw(thebesContext, gfxPoint(0.0, mUnscaledAscent),
|
||||
DrawMode::GLYPH_FILL, 0, mGlyphs[0]->GetLength(),
|
||||
DrawMode::GLYPH_FILL, Range(mGlyphs[0]),
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
break;
|
||||
@ -2304,7 +2304,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
|
||||
if (!clipRect.IsEmpty()) {
|
||||
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
|
||||
mGlyphs[i]->Draw(aThebesContext, gfxPoint(dx, dy),
|
||||
DrawMode::GLYPH_FILL, 0, mGlyphs[i]->GetLength(),
|
||||
DrawMode::GLYPH_FILL, Range(mGlyphs[i]),
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
@ -2372,7 +2372,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
|
||||
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
|
||||
dy += bm.ascent;
|
||||
mGlyphs[3]->Draw(aThebesContext, gfxPoint(dx, dy),
|
||||
DrawMode::GLYPH_FILL, 0, mGlyphs[3]->GetLength(),
|
||||
DrawMode::GLYPH_FILL, Range(mGlyphs[3]),
|
||||
nullptr, nullptr, nullptr);
|
||||
dy += bm.descent;
|
||||
}
|
||||
@ -2476,7 +2476,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
||||
if (!clipRect.IsEmpty()) {
|
||||
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
|
||||
mGlyphs[i]->Draw(aThebesContext, gfxPoint(dx, dy),
|
||||
DrawMode::GLYPH_FILL, 0, mGlyphs[i]->GetLength(),
|
||||
DrawMode::GLYPH_FILL, Range(mGlyphs[i]),
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
@ -2542,7 +2542,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
||||
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
|
||||
dx -= bm.leftBearing;
|
||||
mGlyphs[3]->Draw(aThebesContext, gfxPoint(dx, dy),
|
||||
DrawMode::GLYPH_FILL, 0, mGlyphs[3]->GetLength(),
|
||||
DrawMode::GLYPH_FILL, Range(mGlyphs[3]),
|
||||
nullptr, nullptr, nullptr);
|
||||
dx += bm.rightBearing;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsString.h"
|
||||
#include "nsBoundingMetrics.h"
|
||||
#include "gfxFont.h"
|
||||
#include "gfxTextRun.h"
|
||||
|
||||
class nsGlyphTable;
|
||||
class nsIFrame;
|
||||
@ -85,6 +85,7 @@ struct nsGlyphCode {
|
||||
class nsMathMLChar
|
||||
{
|
||||
public:
|
||||
typedef gfxTextRun::Range Range;
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
|
||||
// constructor and destructor
|
||||
|
@ -60,34 +60,16 @@ using namespace mozilla::gfx;
|
||||
* in original char indexes to skipped char indexes.
|
||||
*
|
||||
* @param aIterator The gfxSkipCharsIterator to use for the conversion.
|
||||
* @param aOriginalOffset The original offset (input).
|
||||
* @param aOriginalLength The original length (input).
|
||||
* @param aSkippedOffset The skipped offset (output).
|
||||
* @param aSkippedLength The skipped length (output).
|
||||
* @param aOriginalOffset The original offset.
|
||||
* @param aOriginalLength The original length.
|
||||
*/
|
||||
static void
|
||||
static gfxTextRun::Range
|
||||
ConvertOriginalToSkipped(gfxSkipCharsIterator& aIterator,
|
||||
uint32_t aOriginalOffset, uint32_t aOriginalLength,
|
||||
uint32_t& aSkippedOffset, uint32_t& aSkippedLength)
|
||||
uint32_t aOriginalOffset, uint32_t aOriginalLength)
|
||||
{
|
||||
aSkippedOffset = aIterator.ConvertOriginalToSkipped(aOriginalOffset);
|
||||
uint32_t start = aIterator.ConvertOriginalToSkipped(aOriginalOffset);
|
||||
aIterator.AdvanceOriginal(aOriginalLength);
|
||||
aSkippedLength = aIterator.GetSkippedOffset() - aSkippedOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the specified gfxSkipCharsIterator, converts an offset and length
|
||||
* in original char indexes to skipped char indexes in place.
|
||||
*
|
||||
* @param aIterator The gfxSkipCharsIterator to use for the conversion.
|
||||
* @param aOriginalOffset The offset to convert from original to skipped.
|
||||
* @param aOriginalLength The length to convert from original to skipped.
|
||||
*/
|
||||
static void
|
||||
ConvertOriginalToSkipped(gfxSkipCharsIterator& aIterator,
|
||||
uint32_t& aOffset, uint32_t& aLength)
|
||||
{
|
||||
ConvertOriginalToSkipped(aIterator, aOffset, aLength, aOffset, aLength);
|
||||
return gfxTextRun::Range(start, aIterator.GetSkippedOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,15 +139,11 @@ GetAscentAndDescentInAppUnits(nsTextFrame* aFrame,
|
||||
gfxSkipCharsIterator it = aFrame->EnsureTextRun(nsTextFrame::eInflated);
|
||||
gfxTextRun* textRun = aFrame->GetTextRun(nsTextFrame::eInflated);
|
||||
|
||||
uint32_t offset, length;
|
||||
ConvertOriginalToSkipped(it,
|
||||
aFrame->GetContentOffset(),
|
||||
aFrame->GetContentLength(),
|
||||
offset, length);
|
||||
gfxTextRun::Range range = ConvertOriginalToSkipped(
|
||||
it, aFrame->GetContentOffset(), aFrame->GetContentLength());
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
textRun->MeasureText(offset, length, gfxFont::LOOSE_INK_EXTENTS, nullptr,
|
||||
nullptr);
|
||||
textRun->MeasureText(range, gfxFont::LOOSE_INK_EXTENTS, nullptr, nullptr);
|
||||
|
||||
aAscent = metrics.mAscent;
|
||||
aDescent = metrics.mDescent;
|
||||
@ -385,7 +363,7 @@ GetBaselinePosition(nsTextFrame* aFrame,
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given text run, returns the number of skipped characters that comprise
|
||||
* For a given text run, returns the range of skipped characters that comprise
|
||||
* the ligature group and/or cluster that includes the character represented
|
||||
* by the specified gfxSkipCharsIterator.
|
||||
*
|
||||
@ -394,8 +372,8 @@ GetBaselinePosition(nsTextFrame* aFrame,
|
||||
* @param aIterator The gfxSkipCharsIterator to use for the current position
|
||||
* in the text run.
|
||||
*/
|
||||
static uint32_t
|
||||
ClusterLength(gfxTextRun* aTextRun, const gfxSkipCharsIterator& aIterator)
|
||||
static gfxTextRun::Range
|
||||
ClusterRange(gfxTextRun* aTextRun, const gfxSkipCharsIterator& aIterator)
|
||||
{
|
||||
uint32_t start = aIterator.GetSkippedOffset();
|
||||
uint32_t end = start + 1;
|
||||
@ -404,7 +382,7 @@ ClusterLength(gfxTextRun* aTextRun, const gfxSkipCharsIterator& aIterator)
|
||||
!aTextRun->IsClusterStart(end))) {
|
||||
end++;
|
||||
}
|
||||
return end - start;
|
||||
return gfxTextRun::Range(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -481,6 +459,8 @@ namespace mozilla {
|
||||
*/
|
||||
struct TextRenderedRun
|
||||
{
|
||||
typedef gfxTextRun::Range Range;
|
||||
|
||||
/**
|
||||
* Constructs a TextRenderedRun that is uninitialized except for mFrame
|
||||
* being null.
|
||||
@ -938,17 +918,15 @@ TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext,
|
||||
gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated);
|
||||
|
||||
// Get the content range for this rendered run.
|
||||
uint32_t offset, length;
|
||||
ConvertOriginalToSkipped(it, mTextFrameContentOffset, mTextFrameContentLength,
|
||||
offset, length);
|
||||
if (length == 0) {
|
||||
Range range = ConvertOriginalToSkipped(it, mTextFrameContentOffset,
|
||||
mTextFrameContentLength);
|
||||
if (range.Length() == 0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// Measure that range.
|
||||
gfxTextRun::Metrics metrics =
|
||||
textRun->MeasureText(offset, length, gfxFont::LOOSE_INK_EXTENTS,
|
||||
nullptr, nullptr);
|
||||
textRun->MeasureText(range, gfxFont::LOOSE_INK_EXTENTS, nullptr, nullptr);
|
||||
// Make sure it includes the font-box.
|
||||
gfxRect fontBox(0, -metrics.mAscent,
|
||||
metrics.mAdvanceWidth, metrics.mAscent + metrics.mDescent);
|
||||
@ -961,7 +939,7 @@ TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext,
|
||||
gfxFloat x, width;
|
||||
if (aFlags & eNoHorizontalOverflow) {
|
||||
x = 0.0;
|
||||
width = textRun->GetAdvanceWidth(offset, length, nullptr);
|
||||
width = textRun->GetAdvanceWidth(range, nullptr);
|
||||
} else {
|
||||
x = metrics.mBoundingBox.x;
|
||||
width = metrics.mBoundingBox.width;
|
||||
@ -1058,13 +1036,12 @@ TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge,
|
||||
|
||||
// Get the covered content offset/length for this rendered run in skipped
|
||||
// characters, since that is what GetAdvanceWidth expects.
|
||||
uint32_t runOffset, runLength, frameOffset, frameLength;
|
||||
ConvertOriginalToSkipped(it, mTextFrameContentOffset, mTextFrameContentLength,
|
||||
runOffset, runLength);
|
||||
Range runRange = ConvertOriginalToSkipped(it, mTextFrameContentOffset,
|
||||
mTextFrameContentLength);
|
||||
|
||||
// Get the offset/length of the whole nsTextFrame.
|
||||
frameOffset = mFrame->GetContentOffset();
|
||||
frameLength = mFrame->GetContentLength();
|
||||
uint32_t frameOffset = mFrame->GetContentOffset();
|
||||
uint32_t frameLength = mFrame->GetContentLength();
|
||||
|
||||
// Trim the whole-nsTextFrame offset/length to remove any leading/trailing
|
||||
// white space, as the nsTextFrame when painting does not include them when
|
||||
@ -1075,19 +1052,17 @@ TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge,
|
||||
|
||||
// Convert the trimmed whole-nsTextFrame offset/length into skipped
|
||||
// characters.
|
||||
ConvertOriginalToSkipped(it, frameOffset, frameLength);
|
||||
Range frameRange = ConvertOriginalToSkipped(it, frameOffset, frameLength);
|
||||
|
||||
// Measure the advance width in the text run between the start of
|
||||
// frame's content and the start of the rendered run's content,
|
||||
nscoord startEdge =
|
||||
textRun->GetAdvanceWidth(frameOffset, runOffset - frameOffset, nullptr);
|
||||
nscoord startEdge = textRun->
|
||||
GetAdvanceWidth(Range(frameRange.start, runRange.start), nullptr);
|
||||
|
||||
// and between the end of the rendered run's content and the end
|
||||
// of the frame's content.
|
||||
nscoord endEdge =
|
||||
textRun->GetAdvanceWidth(runOffset + runLength,
|
||||
frameOffset + frameLength - (runOffset + runLength),
|
||||
nullptr);
|
||||
nscoord endEdge = textRun->
|
||||
GetAdvanceWidth(Range(runRange.end, frameRange.end), nullptr);
|
||||
|
||||
if (textRun->IsRightToLeft()) {
|
||||
aVisIStartEdge = endEdge;
|
||||
@ -1104,11 +1079,10 @@ TextRenderedRun::GetAdvanceWidth() const
|
||||
gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated);
|
||||
gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated);
|
||||
|
||||
uint32_t offset, length;
|
||||
ConvertOriginalToSkipped(it, mTextFrameContentOffset, mTextFrameContentLength,
|
||||
offset, length);
|
||||
Range range = ConvertOriginalToSkipped(it, mTextFrameContentOffset,
|
||||
mTextFrameContentLength);
|
||||
|
||||
return textRun->GetAdvanceWidth(offset, length, nullptr);
|
||||
return textRun->GetAdvanceWidth(range, nullptr);
|
||||
}
|
||||
|
||||
int32_t
|
||||
@ -1159,12 +1133,10 @@ TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext,
|
||||
|
||||
// Next check that the point lies horizontally within the left and right
|
||||
// edges of the text.
|
||||
uint32_t offset, length;
|
||||
ConvertOriginalToSkipped(it, mTextFrameContentOffset, mTextFrameContentLength,
|
||||
offset, length);
|
||||
Range range = ConvertOriginalToSkipped(it, mTextFrameContentOffset,
|
||||
mTextFrameContentLength);
|
||||
gfxFloat runAdvance =
|
||||
aContext->AppUnitsToGfxUnits(textRun->GetAdvanceWidth(offset, length,
|
||||
nullptr));
|
||||
aContext->AppUnitsToGfxUnits(textRun->GetAdvanceWidth(range, nullptr));
|
||||
|
||||
gfxFloat pos = writingMode.IsVertical() ? p.y : p.x;
|
||||
if (pos < 0 || pos >= runAdvance) {
|
||||
@ -1176,10 +1148,9 @@ TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext,
|
||||
// support letter-spacing and word-spacing.
|
||||
bool rtl = textRun->IsRightToLeft();
|
||||
for (int32_t i = mTextFrameContentLength - 1; i >= 0; i--) {
|
||||
ConvertOriginalToSkipped(it, mTextFrameContentOffset, i, offset, length);
|
||||
range = ConvertOriginalToSkipped(it, mTextFrameContentOffset, i);
|
||||
gfxFloat advance =
|
||||
aContext->AppUnitsToGfxUnits(textRun->GetAdvanceWidth(offset, length,
|
||||
nullptr));
|
||||
aContext->AppUnitsToGfxUnits(textRun->GetAdvanceWidth(range, nullptr));
|
||||
if ((rtl && pos < runAdvance - advance) ||
|
||||
(!rtl && pos >= advance)) {
|
||||
return i;
|
||||
@ -2137,6 +2108,8 @@ TextRenderedRunIterator::First()
|
||||
*/
|
||||
class CharIterator
|
||||
{
|
||||
typedef gfxTextRun::Range Range;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Values for the aFilter argument of the constructor, to indicate which
|
||||
@ -2628,12 +2601,12 @@ CharIterator::GetGlyphAdvance(nsPresContext* aContext) const
|
||||
GetOriginalGlyphOffsets(offset, length);
|
||||
|
||||
gfxSkipCharsIterator it = TextFrame()->EnsureTextRun(nsTextFrame::eInflated);
|
||||
ConvertOriginalToSkipped(it, offset, length);
|
||||
Range range = ConvertOriginalToSkipped(it, offset, length);
|
||||
|
||||
float cssPxPerDevPx = aContext->
|
||||
AppUnitsToFloatCSSPixels(aContext->AppUnitsPerDevPixel());
|
||||
|
||||
gfxFloat advance = mTextRun->GetAdvanceWidth(offset, length, nullptr);
|
||||
gfxFloat advance = mTextRun->GetAdvanceWidth(range, nullptr);
|
||||
return aContext->AppUnitsToGfxUnits(advance) *
|
||||
mLengthAdjustScaleFactor * cssPxPerDevPx;
|
||||
}
|
||||
@ -2644,8 +2617,9 @@ CharIterator::GetAdvance(nsPresContext* aContext) const
|
||||
float cssPxPerDevPx = aContext->
|
||||
AppUnitsToFloatCSSPixels(aContext->AppUnitsPerDevPixel());
|
||||
|
||||
gfxFloat advance =
|
||||
mTextRun->GetAdvanceWidth(mSkipCharsIterator.GetSkippedOffset(), 1, nullptr);
|
||||
uint32_t offset = mSkipCharsIterator.GetSkippedOffset();
|
||||
gfxFloat advance = mTextRun->
|
||||
GetAdvanceWidth(Range(offset, offset + 1), nullptr);
|
||||
return aContext->AppUnitsToGfxUnits(advance) *
|
||||
mLengthAdjustScaleFactor * cssPxPerDevPx;
|
||||
}
|
||||
@ -2661,12 +2635,12 @@ CharIterator::GetGlyphPartialAdvance(uint32_t aPartLength,
|
||||
length = aPartLength;
|
||||
|
||||
gfxSkipCharsIterator it = TextFrame()->EnsureTextRun(nsTextFrame::eInflated);
|
||||
ConvertOriginalToSkipped(it, offset, length);
|
||||
Range range = ConvertOriginalToSkipped(it, offset, length);
|
||||
|
||||
float cssPxPerDevPx = aContext->
|
||||
AppUnitsToFloatCSSPixels(aContext->AppUnitsPerDevPixel());
|
||||
|
||||
gfxFloat advance = mTextRun->GetAdvanceWidth(offset, length, nullptr);
|
||||
gfxFloat advance = mTextRun->GetAdvanceWidth(range, nullptr);
|
||||
return aContext->AppUnitsToGfxUnits(advance) *
|
||||
mLengthAdjustScaleFactor * cssPxPerDevPx;
|
||||
}
|
||||
@ -4218,10 +4192,10 @@ SVGTextFrame::GetSubStringLength(nsIContent* aContent,
|
||||
gfxSkipCharsIterator it =
|
||||
run.mFrame->EnsureTextRun(nsTextFrame::eInflated);
|
||||
gfxTextRun* textRun = run.mFrame->GetTextRun(nsTextFrame::eInflated);
|
||||
ConvertOriginalToSkipped(it, offset, length);
|
||||
Range range = ConvertOriginalToSkipped(it, offset, length);
|
||||
|
||||
// Accumulate the advance.
|
||||
textLength += textRun->GetAdvanceWidth(offset, length, nullptr);
|
||||
textLength += textRun->GetAdvanceWidth(range, nullptr);
|
||||
}
|
||||
|
||||
run = it.Next();
|
||||
@ -4720,8 +4694,9 @@ SVGTextFrame::DetermineCharPositions(nsTArray<nsPoint>& aPositions)
|
||||
!it.IsOriginalCharSkipped() &&
|
||||
(!textRun->IsLigatureGroupStart(it.GetSkippedOffset()) ||
|
||||
!textRun->IsClusterStart(it.GetSkippedOffset()))) {
|
||||
nscoord advance = textRun->GetAdvanceWidth(it.GetSkippedOffset(), 1,
|
||||
nullptr);
|
||||
uint32_t offset = it.GetSkippedOffset();
|
||||
nscoord advance = textRun->
|
||||
GetAdvanceWidth(Range(offset, offset + 1), nullptr);
|
||||
(textRun->IsVertical() ? position.y : position.x) +=
|
||||
textRun->IsRightToLeft() ? -advance : advance;
|
||||
aPositions.AppendElement(lastPosition);
|
||||
@ -4735,9 +4710,8 @@ SVGTextFrame::DetermineCharPositions(nsTArray<nsPoint>& aPositions)
|
||||
textRun->IsLigatureGroupStart(it.GetSkippedOffset()) &&
|
||||
textRun->IsClusterStart(it.GetSkippedOffset())) {
|
||||
// A real visible character.
|
||||
uint32_t length = ClusterLength(textRun, it);
|
||||
nscoord advance = textRun->GetAdvanceWidth(it.GetSkippedOffset(),
|
||||
length, nullptr);
|
||||
nscoord advance = textRun->
|
||||
GetAdvanceWidth(ClusterRange(textRun, it), nullptr);
|
||||
(textRun->IsVertical() ? position.y : position.x) +=
|
||||
textRun->IsRightToLeft() ? -advance : advance;
|
||||
lastPosition = position;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "gfxMatrix.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxSVGGlyphs.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "nsIContent.h" // for GetContent
|
||||
#include "nsStubMutationObserver.h"
|
||||
#include "nsSVGPaintServerFrame.h"
|
||||
@ -258,6 +259,7 @@ class SVGTextFrame final : public SVGTextFrameBase
|
||||
friend class MutationObserver;
|
||||
friend class nsDisplaySVGText;
|
||||
|
||||
typedef gfxTextRun::Range Range;
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::gfx::Path Path;
|
||||
typedef mozilla::gfx::Point Point;
|
||||
|
Loading…
Reference in New Issue
Block a user