Bug 1736938 Part 2 - Make all LineBreaker's methods static, and adapt the callers. r=jfkthame

LineBreaker has no member variables and acts like "namespaces" with
utility functions. Therefore, its methods can be static and called
directly without needing a LineBreaker instance.

Rename GetJISx4051Breaks() to ComputeBreakPositions() per review
feedbacks.

Differential Revision: https://phabricator.services.mozilla.com/D129107
This commit is contained in:
Ting-Yu Lin 2021-10-25 19:00:22 +00:00
Родитель db09924f17
Коммит 427cc27771
8 изменённых файлов: 51 добавлений и 58 удалений

Просмотреть файл

@ -9,10 +9,12 @@
#include "gfxTextRun.h" // for the gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_* values
#include "nsHyphenationManager.h"
#include "nsHyphenator.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/intl/LineBreaker.h"
#include "mozilla/intl/MozLocale.h"
using mozilla::AutoRestore;
using mozilla::intl::LineBreaker;
using mozilla::intl::MozLocale;
@ -80,7 +82,7 @@ nsresult nsLineBreaker::FlushCurrentWord() {
: gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NONE,
length * sizeof(uint8_t));
} else {
nsContentUtils::LineBreaker()->GetJISx4051Breaks(
LineBreaker::ComputeBreakPositions(
mCurrentWord.Elements(), length, mWordBreak, mStrictness,
mScriptIsChineseOrJapanese, breakState.Elements());
}
@ -257,13 +259,12 @@ nsresult nsLineBreaker::AppendText(nsAtom* aHyphenationLanguage,
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NORMAL,
offset - wordStart);
} else if (wordHasComplexChar) {
// Save current start-of-word state because GetJISx4051Breaks will
// set it to false
uint8_t currentStart = breakState[wordStart];
nsContentUtils::LineBreaker()->GetJISx4051Breaks(
// Save current start-of-word state because ComputeBreakPositions()
// will set it to false.
AutoRestore<uint8_t> saveWordStartBreakState(breakState[wordStart]);
LineBreaker::ComputeBreakPositions(
aText + wordStart, offset - wordStart, mWordBreak, mStrictness,
mScriptIsChineseOrJapanese, breakState.Elements() + wordStart);
breakState[wordStart] = currentStart;
}
if (hyphenator) {
FindHyphenationPoints(hyphenator, aText + wordStart, aText + offset,
@ -422,13 +423,12 @@ nsresult nsLineBreaker::AppendText(nsAtom* aHyphenationLanguage,
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NORMAL,
offset - wordStart);
} else if (wordHasComplexChar) {
// Save current start-of-word state because GetJISx4051Breaks will
// set it to false
uint8_t currentStart = breakState[wordStart];
nsContentUtils::LineBreaker()->GetJISx4051Breaks(
// Save current start-of-word state because ComputeBreakPositions()
// will set it to false.
AutoRestore<uint8_t> saveWordStartBreakState(breakState[wordStart]);
LineBreaker::ComputeBreakPositions(
aText + wordStart, offset - wordStart, mWordBreak, mStrictness,
mScriptIsChineseOrJapanese, breakState.Elements() + wordStart);
breakState[wordStart] = currentStart;
}
}

Просмотреть файл

@ -29,6 +29,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLBRElement.h"
#include "mozilla/dom/Text.h"
#include "mozilla/intl/LineBreaker.h"
#include "mozilla/Span.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_converter.h"
@ -117,21 +118,20 @@ void nsPlainTextSerializer::CurrentLine::ResetContentAndIndentationHeader() {
}
int32_t nsPlainTextSerializer::CurrentLine::FindWrapIndexForContent(
const uint32_t aWrapColumn,
mozilla::intl::LineBreaker* aLineBreaker) const {
const uint32_t aWrapColumn, bool aUseLineBreaker) const {
MOZ_ASSERT(!mContent.IsEmpty());
const uint32_t prefixwidth = DeterminePrefixWidth();
int32_t goodSpace = 0;
if (aLineBreaker) {
if (aUseLineBreaker) {
// We advance one line break point at a time from the beginning of the
// mContent until we find a width less than or equal to wrap column.
uint32_t width = 0;
const auto len = mContent.Length();
while (true) {
int32_t nextGoodSpace =
aLineBreaker->Next(mContent.get(), len, goodSpace);
intl::LineBreaker::Next(mContent.get(), len, goodSpace);
if (nextGoodSpace == NS_LINEBREAKER_NEED_MORE_TEXT) {
// Line breaker reaches the end of mContent.
break;
@ -332,9 +332,7 @@ nsPlainTextSerializer::Init(const uint32_t aFlags, uint32_t aWrapColumn,
mSettings.Init(aFlags, aWrapColumn);
mOutputManager.emplace(mSettings.GetFlags(), aOutput);
if (mSettings.MayWrap() && mSettings.MayBreakLines()) {
mLineBreaker = nsContentUtils::LineBreaker();
}
mUseLineBreaker = mSettings.MayWrap() && mSettings.MayBreakLines();
mLineBreakDue = false;
mFloatingLines = -1;
@ -1239,7 +1237,7 @@ void nsPlainTextSerializer::MaybeWrapAndOutputCompleteLines() {
}
const int32_t goodSpace =
mCurrentLine.FindWrapIndexForContent(wrapColumn, mLineBreaker);
mCurrentLine.FindWrapIndexForContent(wrapColumn, mUseLineBreaker);
const int32_t contentLength = mCurrentLine.mContent.Length();
if ((goodSpace < contentLength) && (goodSpace > 0)) {

Просмотреть файл

@ -16,7 +16,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/intl/LineBreaker.h"
#include "nsCOMPtr.h"
#include "nsAtom.h"
#include "nsCycleCollectionParticipant.h"
@ -240,8 +239,8 @@ class nsPlainTextSerializer final : public nsIContentSerializer {
}
// @param aLineBreaker May be nullptr.
int32_t FindWrapIndexForContent(
uint32_t aWrapColumn, mozilla::intl::LineBreaker* aLineBreaker) const;
int32_t FindWrapIndexForContent(uint32_t aWrapColumn,
bool aUseLineBreaker) const;
// @return Combined width of cite quote level and indentation.
uint32_t DeterminePrefixWidth() const {
@ -368,7 +367,7 @@ class nsPlainTextSerializer final : public nsIContentSerializer {
uint32_t mULCount;
RefPtr<mozilla::intl::LineBreaker> mLineBreaker;
bool mUseLineBreaker = false;
// Conveniance constant. It would be nice to have it as a const static
// variable, but that causes issues with OpenBSD and module unloading.

Просмотреть файл

@ -1538,14 +1538,12 @@ bool nsXMLContentSerializer::AppendWrapped_NonWhitespaceSequence(
if (mAllowLineBreaking) {
MOZ_ASSERT(aPos < aEnd,
"We shouldn't be here if aPos reaches the end of text!");
mozilla::intl::LineBreaker* lineBreaker =
nsContentUtils::LineBreaker();
// Search forward from aSequenceStart until we find the largest
// wrap position less than or equal to aPos.
int32_t nextWrapPosition = 0;
while (true) {
nextWrapPosition = lineBreaker->Next(
nextWrapPosition = intl::LineBreaker::Next(
aSequenceStart, aEnd - aSequenceStart, wrapPosition);
MOZ_ASSERT(nextWrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT,
"We should've exited the loop when reaching the end of "

Просмотреть файл

@ -97,8 +97,6 @@ void InternetCiter::Rewrap(const nsAString& aInString, uint32_t aWrapCol,
aOutString.Truncate();
mozilla::intl::LineBreaker* lineBreaker = nsContentUtils::LineBreaker();
// Loop over lines in the input string, rewrapping each one.
uint32_t posInString = 0;
uint32_t outStringCol = 0;
@ -228,8 +226,8 @@ void InternetCiter::Rewrap(const nsAString& aInString, uint32_t aWrapCol,
int32_t breakPt = 0;
int32_t nextBreakPt = 0;
while (true) {
nextBreakPt = lineBreaker->Next(tString.get() + posInString,
length - posInString, breakPt);
nextBreakPt = intl::LineBreaker::Next(tString.get() + posInString,
length - posInString, breakPt);
if (nextBreakPt == NS_LINEBREAKER_NEED_MORE_TEXT ||
nextBreakPt > eol - (int32_t)posInString) {
break;

Просмотреть файл

@ -945,8 +945,8 @@ int32_t LineBreaker::Next(const char16_t* aText, uint32_t aLen, uint32_t aPos) {
// XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
breakState.AppendElements(end - begin);
GetJISx4051Breaks(aText + begin, end - begin, WordBreak::Normal,
Strictness::Auto, false, breakState.Elements());
ComputeBreakPositions(aText + begin, end - begin, WordBreak::Normal,
Strictness::Auto, false, breakState.Elements());
ret = aPos;
do {
@ -985,10 +985,11 @@ static bool SuppressBreakForKeepAll(uint32_t aPrev, uint32_t aCh) {
affectedByKeepAll(GetLineBreakClass(aCh));
}
void LineBreaker::GetJISx4051Breaks(const char16_t* aChars, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore) {
void LineBreaker::ComputeBreakPositions(const char16_t* aChars,
uint32_t aLength, WordBreak aWordBreak,
Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore) {
uint32_t cur;
int8_t lastClass = CLASS_NONE;
ContextState state(aChars, aLength);
@ -1113,10 +1114,10 @@ void LineBreaker::GetJISx4051Breaks(const char16_t* aChars, uint32_t aLength,
}
}
void LineBreaker::GetJISx4051Breaks(const uint8_t* aChars, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore) {
void LineBreaker::ComputeBreakPositions(const uint8_t* aChars, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore) {
uint32_t cur;
int8_t lastClass = CLASS_NONE;
ContextState state(aChars, aLength);

Просмотреть файл

@ -38,7 +38,7 @@ class LineBreaker {
//
// If aPos is already at the end of aText or beyond, i.e. aPos >= aLen, return
// NS_LINEBREAKER_NEED_MORE_TEXT.
int32_t Next(const char16_t* aText, uint32_t aLen, uint32_t aPos);
static int32_t Next(const char16_t* aText, uint32_t aLen, uint32_t aPos);
// Call this on a word with whitespace at either end. We will apply JISx4051
// rules to find breaks inside the word. aBreakBefore is set to the break-
@ -46,12 +46,14 @@ class LineBreaker {
// because we never return a break before the first character.
// aLength is the length of the aText array and also the length of the
// aBreakBefore output array.
void GetJISx4051Breaks(const char16_t* aText, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese, uint8_t* aBreakBefore);
void GetJISx4051Breaks(const uint8_t* aText, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese, uint8_t* aBreakBefore);
static void ComputeBreakPositions(const char16_t* aText, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore);
static void ComputeBreakPositions(const uint8_t* aText, uint32_t aLength,
WordBreak aWordBreak, Strictness aLevel,
bool aIsChineseOrJapanese,
uint8_t* aBreakBefore);
private:
~LineBreaker() = default;

Просмотреть файл

@ -16,6 +16,8 @@
#include "nsTArray.h"
#include "nsXPCOM.h"
using mozilla::intl::LineBreaker;
// Turn off clang-format to align the ruler comments to the test strings.
// clang-format off
@ -115,15 +117,14 @@ bool Check(const char* in, mozilla::Span<const uint32_t> out,
return ok;
}
bool TestASCIILB(mozilla::intl::LineBreaker* lb, const char* in,
mozilla::Span<const uint32_t> out) {
bool TestASCIILB(const char* in, mozilla::Span<const uint32_t> out) {
NS_ConvertASCIItoUTF16 input(in);
EXPECT_GT(input.Length(), 0u) << "Expect a non-empty input!";
nsTArray<uint32_t> result;
int32_t curr = 0;
while (true) {
curr = lb->Next(input.get(), input.Length(), curr);
curr = LineBreaker::Next(input.get(), input.Length(), curr);
if (curr == NS_LINEBREAKER_NEED_MORE_TEXT) {
break;
}
@ -153,14 +154,10 @@ bool TestASCIIWB(mozilla::intl::WordBreaker* wb, const char* in,
TEST(LineBreak, LineBreaker)
{
RefPtr<mozilla::intl::LineBreaker> t = mozilla::intl::LineBreaker::Create();
ASSERT_TRUE(t);
ASSERT_TRUE(TestASCIILB(t, teng0, lexp0));
ASSERT_TRUE(TestASCIILB(t, teng1, lexp1));
ASSERT_TRUE(TestASCIILB(t, teng2, lexp2));
ASSERT_TRUE(TestASCIILB(t, teng3, lexp3));
ASSERT_TRUE(TestASCIILB(teng0, lexp0));
ASSERT_TRUE(TestASCIILB(teng1, lexp1));
ASSERT_TRUE(TestASCIILB(teng2, lexp2));
ASSERT_TRUE(TestASCIILB(teng3, lexp3));
}
TEST(WordBreak, WordBreaker)