Bug 1056516 - use HyphenType to store different types of hyphenations.
MozReview-Commit-ID: LUVboirjZjb
--- a/gfx/src/nsFontMetrics.cpp
+++ b/gfx/src/nsFontMetrics.cpp
@@ -79,17 +79,17 @@ private:
}
RefPtr<gfxTextRun> mTextRun;
};
class StubPropertyProvider : public gfxTextRun::PropertyProvider {
public:
virtual void GetHyphenationBreaks(gfxTextRun::Range aRange,
- nsTArray<bool>& aBreakBefore) {
+ nsTArray<gfxTextRun::HyphenType>& aBreakBefore) {
NS_ERROR("This shouldn't be called because we never call BreakAndMeasureText");
}
virtual mozilla::StyleHyphens GetHyphensOption() {
NS_ERROR("This shouldn't be called because we never call BreakAndMeasureText");
return mozilla::StyleHyphens::None;
}
virtual gfxFloat GetHyphenWidth() {
NS_ERROR("This shouldn't be called because we never enable hyphens");
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -854,17 +854,17 @@ gfxTextRun::BreakAndMeasureText(uint32_t
Range bufferRange(aStart, aStart + aMaxLength);
AutoTArray<PropertyProvider::Spacing, 100> spacingBuffer;
spacingBuffer.AppendElements(bufferRange.Length());
bool haveSpacing = aProvider && (mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING) != 0;
if (haveSpacing) {
GetAdjustedSpacing(this, bufferRange, aProvider, spacingBuffer.Elements());
}
- AutoTArray<bool, 100> hyphenBuffer;
+ AutoTArray<HyphenType, 100> hyphenBuffer;
hyphenBuffer.AppendElements(bufferRange.Length());
bool haveHyphenation = aProvider &&
(aProvider->GetHyphensOption() == StyleHyphens::Auto ||
(aProvider->GetHyphensOption() == StyleHyphens::Manual &&
(mFlags & gfxTextRunFactory::TEXT_ENABLE_HYPHEN_BREAKS) != 0));
if (haveHyphenation) {
aProvider->GetHyphenationBreaks(bufferRange, hyphenBuffer);
}
@@ -889,18 +889,19 @@ gfxTextRun::BreakAndMeasureText(uint32_t
for (i = aStart; i < end; ++i) {
// 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
// could be the first and last break opportunity on the line, and that
// would trigger an infinite loop.
if (aSuppressBreak != eSuppressAllBreaks &&
(aSuppressBreak != eSuppressInitialBreak || i > aStart)) {
bool atNaturalBreak = mCharacterGlyphs[i].CanBreakBefore() == 1;
- bool atHyphenationBreak = !atNaturalBreak &&
- haveHyphenation && hyphenBuffer[i - bufferRange.start];
+ bool atHyphenationBreak =
+ !atNaturalBreak && haveHyphenation &&
+ hyphenBuffer[i - bufferRange.start] != HyphenType::None;
bool atBreak = atNaturalBreak || atHyphenationBreak;
bool wordWrapping =
aCanWordWrap && mCharacterGlyphs[i].IsClusterStart() &&
*aBreakPriority <= gfxBreakPriority::eWordWrapBreak;
if (atBreak || wordWrapping) {
gfxFloat hyphenatedAdvance = advance;
if (atHyphenationBreak) {
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -170,32 +170,38 @@ public:
* This function is virtual so that those textruns can reshape themselves.
*
* @return true if this changed the linebreaks, false if the new line
* breaks are the same as the old
*/
virtual bool SetPotentialLineBreaks(Range aRange,
const uint8_t* aBreakBefore);
+ enum class HyphenType : uint8_t {
+ None,
+ Manual,
+ Auto
+ };
+
/**
* Layout provides PropertyProvider objects. These allow detection of
* potential line break points and computation of spacing. We pass the data
* this way to allow lazy data acquisition; for example BreakAndMeasureText
* 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
* is unable to apply it in some context. Exception: spacing around a
* whitespace character MUST always be applied.
*/
class PropertyProvider {
public:
// Detect hyphenation break opportunities in the given range; breaks
// not at cluster boundaries will be ignored.
virtual void GetHyphenationBreaks(Range aRange,
- nsTArray<bool>& aBreakBefore) = 0;
+ nsTArray<HyphenType>& aBreakBefore) = 0;
// Returns the provider's hyphenation setting, so callers can decide
// whether it is necessary to call GetHyphenationBreaks.
// Result is an StyleHyphens value.
virtual mozilla::StyleHyphens GetHyphensOption() = 0;
// Returns the extra width that will be consumed by a hyphen. This should
// be constant for a given textrun.
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -3072,16 +3072,17 @@ static bool IsInBounds(const gfxSkipChar
gfxSkipCharsIterator iter(aStart);
iter.AdvanceOriginal(aContentLength);
return iter.GetSkippedOffset() >= aRange.end;
}
#endif
class MOZ_STACK_CLASS PropertyProvider : public gfxTextRun::PropertyProvider {
typedef gfxTextRun::Range Range;
+ typedef gfxTextRun::HyphenType HyphenType;
public:
/**
* Use this constructor for reflow, when we don't know what text is
* really mapped by the frame and we have a lot of other data around.
*
* @param aLength can be INT32_MAX to indicate we cover all the text
* associated with aFrame up to where its flow chain ends in the given
@@ -3136,17 +3137,17 @@ public:
// Call this after construction if you're not going to reflow the text
void InitializeForDisplay(bool aTrimAfter);
void InitializeForMeasure();
virtual void GetSpacing(Range aRange, Spacing* aSpacing);
virtual gfxFloat GetHyphenWidth();
- virtual void GetHyphenationBreaks(Range aRange, nsTArray<bool>& aBreakBefore);
+ virtual void GetHyphenationBreaks(Range aRange, nsTArray<HyphenType>& aBreakBefore);
virtual StyleHyphens GetHyphensOption() {
return mTextStyle->mHyphens;
}
virtual already_AddRefed<DrawTarget> GetDrawTarget() {
return CreateReferenceDrawTarget(GetFrame());
}
@@ -3574,25 +3575,27 @@ PropertyProvider::GetHyphenWidth()
{
if (mHyphenWidth < 0) {
mHyphenWidth = GetFontGroup()->GetHyphenWidth(this);
}
return mHyphenWidth + mLetterSpacing;
}
void
-PropertyProvider::GetHyphenationBreaks(Range aRange, nsTArray<bool>& aBreakBefore)
+PropertyProvider::GetHyphenationBreaks(Range aRange,
+ nsTArray<HyphenType>& aBreakBefore)
{
NS_PRECONDITION(IsInBounds(mStart, mLength, aRange), "Range out of bounds");
NS_PRECONDITION(mLength != INT32_MAX, "Can't call this with undefined length");
if (!mTextStyle->WhiteSpaceCanWrap(mFrame) ||
mTextStyle->mHyphens == StyleHyphens::None)
{
- memset(aBreakBefore.Elements(), false, aRange.Length() * sizeof(bool));
+ memset(aBreakBefore.Elements(), static_cast<uint8_t>(HyphenType::None),
+ aRange.Length() * sizeof(HyphenType));
return;
}
// Iterate through the original-string character runs
nsSkipCharsRunIterator run(
mStart, nsSkipCharsRunIterator::LENGTH_UNSKIPPED_ONLY, aRange.Length());
run.SetSkippedOffset(aRange.start);
// We need to visit skipped characters so that we can detect SHY
@@ -3609,30 +3612,33 @@ PropertyProvider::GetHyphenationBreaks(R
if (run.IsSkipped()) {
// Check if there's a soft hyphen which would let us hyphenate before
// the next non-skipped character. Don't look at soft hyphens followed
// by other skipped characters, we won't use them.
allowHyphenBreakBeforeNextChar =
mFrag->CharAt(run.GetOriginalOffset() + run.GetRunLength() - 1) == CH_SHY;
} else {
int32_t runOffsetInSubstring = run.GetSkippedOffset() - aRange.start;
- memset(aBreakBefore.Elements() + runOffsetInSubstring, false,
- run.GetRunLength() * sizeof(bool));
+ memset(aBreakBefore.Elements() + runOffsetInSubstring,
+ static_cast<uint8_t>(HyphenType::None),
+ run.GetRunLength() * sizeof(HyphenType));
// Don't allow hyphen breaks at the start of the line
- aBreakBefore[runOffsetInSubstring] = allowHyphenBreakBeforeNextChar &&
+ aBreakBefore[runOffsetInSubstring] =
+ allowHyphenBreakBeforeNextChar &&
(!(mFrame->GetStateBits() & TEXT_START_OF_LINE) ||
- run.GetSkippedOffset() > mStart.GetSkippedOffset());
+ run.GetSkippedOffset() > mStart.GetSkippedOffset()) ?
+ HyphenType::Manual : HyphenType::None;
allowHyphenBreakBeforeNextChar = false;
}
}
if (mTextStyle->mHyphens == StyleHyphens::Auto) {
for (uint32_t i = 0; i < aRange.Length(); ++i) {
if (mTextRun->CanHyphenateBefore(aRange.start + i)) {
- aBreakBefore[i] = true;
+ aBreakBefore[i] = HyphenType::Auto;
}
}
}
}
void
PropertyProvider::InitializeForDisplay(bool aTrimAfter)
{
@@ -8365,17 +8371,17 @@ nsTextFrame::AddInlineMinISizeForFlow(ns
if (start < flowEndInTextRun && textRun->CanBreakLineBefore(start)) {
aData->OptionallyBreak();
}
aData->mCurrentLine += provider.GetFontMetrics()->EmHeight();
aData->mTrailingWhitespace = 0;
return;
}
- AutoTArray<bool,BIG_TEXT_NODE_SIZE> hyphBuffer;
+ AutoTArray<gfxTextRun::HyphenType, BIG_TEXT_NODE_SIZE> hyphBuffer;
if (hyphenating &&
hyphBuffer.AppendElements(flowEndInTextRun - start, fallible)) {
provider.GetHyphenationBreaks(Range(start, flowEndInTextRun), hyphBuffer);
}
for (uint32_t i = start, wordStart = start; i <= flowEndInTextRun; ++i) {
bool preformattedNewline = false;
bool preformattedTab = false;
@@ -8383,17 +8389,18 @@ nsTextFrame::AddInlineMinISizeForFlow(ns
// XXXldb Shouldn't we be including the newline as part of the
// segment that it ends rather than part of the segment that it
// starts?
preformattedNewline = preformatNewlines && textRun->CharIsNewline(i);
preformattedTab = preformatTabs && textRun->CharIsTab(i);
if (!textRun->CanBreakLineBefore(i) &&
!preformattedNewline &&
!preformattedTab &&
- (hyphBuffer.IsEmpty() || !hyphBuffer[i - start]))
+ (hyphBuffer.IsEmpty() ||
+ hyphBuffer[i - start] == gfxTextRun::HyphenType::None))
{
// we can't break here (and it's not the end of the flow)
continue;
}
}
if (i > wordStart) {
nscoord width = NSToCoordCeilClamped(
@@ -8431,17 +8438,17 @@ nsTextFrame::AddInlineMinISizeForFlow(ns
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
wordStart = i + 1;
} else if (i < flowEndInTextRun ||
(i == textRun->GetLength() &&
(textRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK))) {
if (preformattedNewline) {
aData->ForceBreak();
} else if (i < flowEndInTextRun && !hyphBuffer.IsEmpty() &&
- hyphBuffer[i - start]) {
+ hyphBuffer[i - start] != gfxTextRun::HyphenType::None) {
aData->OptionallyBreak(NSToCoordRound(provider.GetHyphenWidth()));
} else {
aData->OptionallyBreak();
}
wordStart = i;
}
}