diff --git a/third_party/txt/src/txt/paragraph_txt.cc b/third_party/txt/src/txt/paragraph_txt.cc index 1c149e96b6a3f991048e5fa7878f0479451fa9a8..122c1de39a988f08c0cd987b82415bdff32f15d4 100644 --- a/third_party/txt/src/txt/paragraph_txt.cc +++ b/third_party/txt/src/txt/paragraph_txt.cc @@ -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); @@ -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; @@ -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; diff --git a/third_party/txt/src/txt/paragraph_txt.h b/third_party/txt/src/txt/paragraph_txt.h index 319190101c58f68855ba5516c310237cc6330718..b7ae9ad98b614d7d12407bfb5472bd9bbdf610df 100644 --- a/third_party/txt/src/txt/paragraph_txt.h +++ b/third_party/txt/src/txt/paragraph_txt.h @@ -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); @@ -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, diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 1d8ed94f5803bbbb1aa3c9536e6a249bf61b0dfc..78e28d771ad847dec39e217d7f14307c6e9c9240 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -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(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 = [¶graph](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 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;