Skip to content

Commit

Permalink
Fix RTL justification alignment with newline (flutter#11842)
Browse files Browse the repository at this point in the history
  • Loading branch information
GaryQian authored Sep 3, 2019
1 parent fde7c8c commit e18298c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
6 changes: 3 additions & 3 deletions third_party/txt/src/txt/paragraph_txt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ void ParagraphTxt::Layout(double width) {

// Adjust the glyph positions based on the alignment of the line.
double line_x_offset =
GetLineXOffset(run_x_offset, line_number, line_limit);
GetLineXOffset(run_x_offset, line_number, justify_line);
if (line_x_offset) {
for (CodeUnitRun& code_unit_run : line_code_unit_runs) {
code_unit_run.Shift(line_x_offset);
Expand Down Expand Up @@ -1192,7 +1192,7 @@ void ParagraphTxt::Layout(double width) {

double ParagraphTxt::GetLineXOffset(double line_total_advance,
size_t line_number,
size_t line_limit) {
bool justify_line) {
if (isinf(width_))
return 0;

Expand All @@ -1201,7 +1201,7 @@ double ParagraphTxt::GetLineXOffset(double line_total_advance,
if (align == TextAlign::right ||
(align == TextAlign::justify &&
paragraph_style_.text_direction == TextDirection::rtl &&
line_number == line_limit - 1)) {
!justify_line)) {
return width_ - line_total_advance;
} else if (align == TextAlign::center) {
return (width_ - line_total_advance) / 2;
Expand Down
3 changes: 2 additions & 1 deletion third_party/txt/src/txt/paragraph_txt.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class ParagraphTxt : public Paragraph {
FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, CenterAlignParagraph);
FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyAlignParagraph);
FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyRTL);
FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyRTLNewLine);
FRIEND_TEST(ParagraphTest, DecorationsParagraph);
FRIEND_TEST(ParagraphTest, ItalicsParagraph);
FRIEND_TEST(ParagraphTest, ChineseParagraph);
Expand Down Expand Up @@ -362,7 +363,7 @@ class ParagraphTxt : public Paragraph {
// alignment.
double GetLineXOffset(double line_total_advance,
size_t line_number,
size_t line_limit);
bool justify_line);

// Creates and draws the decorations onto the canvas.
void PaintDecorations(SkCanvas* canvas,
Expand Down
85 changes: 85 additions & 0 deletions third_party/txt/tests/paragraph_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,91 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyRTL)) {
}
}

TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyRTLNewLine)) {
const char* text =
"אאא בּבּבּבּ אאאא\nבּבּ אאא בּבּבּ אאאאא בּבּבּבּ אאאא בּבּבּבּבּ "
"אאאאא בּבּבּבּבּ אאאבּבּבּבּבּבּאאאאא בּבּבּבּבּבּאאאאאבּבּבּבּבּבּ אאאאא בּבּבּבּבּ "
"אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ אאאאא בּבּבּבּבּבּ";

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.max_lines = 14;
paragraph_style.text_align = TextAlign::justify;
paragraph_style.text_direction = TextDirection::rtl;
txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection());

txt::TextStyle text_style;
text_style.font_families = std::vector<std::string>(1, "Ahem");
text_style.font_size = 26;
text_style.color = SK_ColorBLACK;
text_style.height = 1;
builder.PushStyle(text_style);

builder.AddText(u16_text);

builder.Pop();

auto paragraph = BuildParagraph(builder);
size_t paragraph_width = GetTestCanvasWidth() - 100;
paragraph->Layout(paragraph_width);

paragraph->Paint(GetCanvas(), 0, 0);

auto glyph_line_width = [&paragraph](int index) {
size_t second_to_last_position_index =
paragraph->glyph_lines_[index].positions.size() - 1;
return paragraph->glyph_lines_[index]
.positions[second_to_last_position_index]
.x_pos.end;
};

SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
paint.setAntiAlias(true);
paint.setStrokeWidth(1);

ASSERT_TRUE(Snapshot());

// Tests for GetRectsForRange()
Paragraph::RectHeightStyle rect_height_style =
Paragraph::RectHeightStyle::kMax;
Paragraph::RectWidthStyle rect_width_style =
Paragraph::RectWidthStyle::kTight;
paint.setColor(SK_ColorRED);
std::vector<txt::Paragraph::TextBox> boxes =
paragraph->GetRectsForRange(0, 30, rect_height_style, rect_width_style);
for (size_t i = 0; i < boxes.size(); ++i) {
GetCanvas()->drawRect(boxes[i].rect, paint);
}
ASSERT_EQ(boxes.size(), 2ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 562);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), -1.4305115e-06);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 900);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 26);

paint.setColor(SK_ColorBLUE);
boxes = paragraph->GetRectsForRange(240, 250, rect_height_style,
rect_width_style);
for (size_t i = 0; i < boxes.size(); ++i) {
GetCanvas()->drawRect(boxes[i].rect, paint);
}
ASSERT_EQ(boxes.size(), 1ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 68);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 130);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 120);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 156);
ASSERT_TRUE(Snapshot());

// All lines should be justified to the width of the
// paragraph.
for (size_t i = 0; i < paragraph->glyph_lines_.size(); ++i) {
ASSERT_EQ(glyph_line_width(i), paragraph_width);
}
}

TEST_F(ParagraphTest, DecorationsParagraph) {
txt::ParagraphStyle paragraph_style;
paragraph_style.max_lines = 14;
Expand Down

0 comments on commit e18298c

Please sign in to comment.