forked from firka/flutter
Reset breaker after every layout to handle different widths.
Change-Id: I786c4c42b4db9418f4f802b4cbb70a051b35925a
This commit is contained in:
@@ -140,7 +140,9 @@ void Paragraph::SetText(std::vector<uint16_t> text, StyledRuns runs) {
|
||||
return;
|
||||
text_ = std::move(text);
|
||||
runs_ = std::move(runs);
|
||||
}
|
||||
|
||||
void Paragraph::InitBreaker() {
|
||||
breaker_.setLocale(icu::Locale(), nullptr);
|
||||
breaker_.resize(text_.size());
|
||||
memcpy(breaker_.buffer(), text_.data(), text_.size() * sizeof(text_[0]));
|
||||
@@ -182,7 +184,7 @@ void Paragraph::FillWhitespaceSet(size_t start,
|
||||
|
||||
void Paragraph::Layout(double width, bool force) {
|
||||
// Do not allow calling layout multiple times without changing anything.
|
||||
if (!needs_layout_ && !force && width == width_)
|
||||
if (!needs_layout_ && width == width_ && !force)
|
||||
return;
|
||||
needs_layout_ = false;
|
||||
|
||||
@@ -199,6 +201,7 @@ void Paragraph::Layout(double width, bool force) {
|
||||
// minikin::Hyphenator::loadBinary(<paramsgohere>);
|
||||
// breaker_.setLocale(icu::Locale::getRoot(), &hyph);
|
||||
//
|
||||
InitBreaker();
|
||||
AddRunsToLineBreaker(collection_map);
|
||||
breaker_.setJustified(paragraph_style_.text_align == TextAlign::justify);
|
||||
breaker_.setStrategy(paragraph_style_.break_strategy);
|
||||
@@ -505,6 +508,7 @@ void Paragraph::Layout(double width, bool force) {
|
||||
line_widths_ =
|
||||
std::vector<double>(breaker_.getWidths(), breaker_.getWidths() + lines_);
|
||||
CalculateIntrinsicWidths();
|
||||
breaker_.finish();
|
||||
}
|
||||
|
||||
// Amends the buffers to incorporate justification.
|
||||
|
||||
@@ -163,6 +163,7 @@ class Paragraph {
|
||||
FRIEND_TEST(RenderTest, NewlineParagraph);
|
||||
FRIEND_TEST(RenderTest, EmojiParagraph);
|
||||
FRIEND_TEST(RenderTest, HyphenBreakParagraph);
|
||||
FRIEND_TEST(RenderTest, RepeatLayoutParagraph);
|
||||
|
||||
// Starting data to layout.
|
||||
std::vector<uint16_t> text_;
|
||||
@@ -187,7 +188,7 @@ class Paragraph {
|
||||
|
||||
// The max width of the paragraph as provided in the most recent Layout()
|
||||
// call.
|
||||
double width_ = 0.0f;
|
||||
double width_ = -1.0f;
|
||||
SkScalar height_ = 0.0f;
|
||||
size_t lines_ = 0;
|
||||
double max_intrinsic_width_ = 0;
|
||||
@@ -207,8 +208,14 @@ class Paragraph {
|
||||
: x_start(x_s), y_start(y_s), x_end(x_e), y_end(y_e) {}
|
||||
};
|
||||
|
||||
// Passes in the text and Styled Runs. text_ and runs_ will later be passed
|
||||
// into breaker_ in InitBreaker(), which is called in Layout().
|
||||
void SetText(std::vector<uint16_t> text, StyledRuns runs);
|
||||
|
||||
// Sets up breaker_ with the contents of text_ and runs_. This is called every
|
||||
// Layout() call to allow for different widths to be used.
|
||||
void InitBreaker();
|
||||
|
||||
void SetParagraphStyle(const ParagraphStyle& style);
|
||||
|
||||
void SetFontCollection(FontCollection* font_collection);
|
||||
|
||||
@@ -77,6 +77,7 @@ class StyledRuns {
|
||||
FRIEND_TEST(RenderTest, LongWordParagraph);
|
||||
FRIEND_TEST(RenderTest, KernParagraph);
|
||||
FRIEND_TEST(RenderTest, HyphenBreakParagraph);
|
||||
FRIEND_TEST(RenderTest, RepeatLayoutParagraph);
|
||||
|
||||
struct IndexedRun {
|
||||
size_t style_index = 0;
|
||||
|
||||
@@ -1484,4 +1484,65 @@ TEST_F(RenderTest, HyphenBreakParagraph) {
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
TEST_F(RenderTest, RepeatLayoutParagraph) {
|
||||
const char* text =
|
||||
"Sentence to layout at diff widths to get diff line counts. short words "
|
||||
"short words short words short words short words short words short words "
|
||||
"short words short words short words short words short words short words";
|
||||
auto icu_text = icu::UnicodeString::fromUTF8(text);
|
||||
std::u16string u16_text(icu_text.getBuffer(),
|
||||
icu_text.getBuffer() + icu_text.length());
|
||||
|
||||
txt::ParagraphStyle paragraph_style;
|
||||
paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality;
|
||||
auto font_collection = FontCollection::GetFontCollection(txt::GetFontDir());
|
||||
txt::ParagraphBuilder builder(paragraph_style, &font_collection);
|
||||
|
||||
txt::TextStyle text_style;
|
||||
text_style.font_family = "Roboto";
|
||||
text_style.font_size = 31;
|
||||
text_style.letter_spacing = 0;
|
||||
text_style.word_spacing = 0;
|
||||
text_style.color = SK_ColorBLACK;
|
||||
text_style.height = 1;
|
||||
builder.PushStyle(text_style);
|
||||
builder.AddText(u16_text);
|
||||
|
||||
builder.Pop();
|
||||
|
||||
// First Layout.
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->Layout(300);
|
||||
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
ASSERT_EQ(paragraph->text_.size(), std::string{text}.length());
|
||||
for (size_t i = 0; i < u16_text.length(); i++) {
|
||||
ASSERT_EQ(paragraph->text_[i], u16_text[i]);
|
||||
}
|
||||
ASSERT_EQ(paragraph->runs_.runs_.size(), 1ull);
|
||||
ASSERT_EQ(paragraph->runs_.styles_.size(), 1ull);
|
||||
ASSERT_TRUE(paragraph->runs_.styles_[0].equals(text_style));
|
||||
ASSERT_EQ(paragraph->records_[0].style().color, text_style.color);
|
||||
ASSERT_EQ(paragraph->GetLineCount(), 12);
|
||||
|
||||
// Second Layout.
|
||||
SetUp();
|
||||
paragraph->Layout(600);
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
ASSERT_EQ(paragraph->text_.size(), std::string{text}.length());
|
||||
for (size_t i = 0; i < u16_text.length(); i++) {
|
||||
ASSERT_EQ(paragraph->text_[i], u16_text[i]);
|
||||
}
|
||||
ASSERT_EQ(paragraph->runs_.runs_.size(), 1ull);
|
||||
ASSERT_EQ(paragraph->runs_.styles_.size(), 1ull);
|
||||
ASSERT_TRUE(paragraph->runs_.styles_[0].equals(text_style));
|
||||
ASSERT_EQ(paragraph->records_[0].style().color, text_style.color);
|
||||
ASSERT_EQ(paragraph->GetLineCount(), 6);
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
} // namespace txt
|
||||
|
||||
Reference in New Issue
Block a user