From aa727ca6cf1a920f9e2efaca16ca2c4783187c7b Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Tue, 18 Jun 2019 13:50:56 -0700 Subject: [PATCH] Minimal integration with the Skia text shaper module This converts the libtxt Paragraph and ParagraphBuilder classes into interfaces with Minikin and SkShaper/SkParagraph based implementations. Use the --enable-skshaper GN flag to select the Skia shaper implementation at build time. --- ci/licenses_golden/licenses_flutter | 9 +- common/config.gni | 3 + lib/ui/BUILD.gn | 5 + lib/ui/text/paragraph_builder.cc | 13 +- third_party/txt/BUILD.gn | 21 +- .../txt/benchmarks/paragraph_benchmarks.cc | 56 +-- .../paragraph_builder_benchmarks.cc | 20 +- .../txt/src/skia/paragraph_builder_skia.cc | 164 +++++++ .../txt/src/skia/paragraph_builder_skia.h | 49 +++ third_party/txt/src/skia/paragraph_skia.cc | 105 +++++ third_party/txt/src/skia/paragraph_skia.h | 72 +++ third_party/txt/src/txt/font_collection.cc | 21 + third_party/txt/src/txt/font_collection.h | 8 + third_party/txt/src/txt/paragraph.h | 412 ++---------------- third_party/txt/src/txt/paragraph_builder.cc | 70 +-- third_party/txt/src/txt/paragraph_builder.h | 49 +-- .../txt/src/txt/paragraph_builder_txt.cc | 84 ++++ .../txt/src/txt/paragraph_builder_txt.h | 65 +++ .../txt/{paragraph.cc => paragraph_txt.cc} | 132 +++--- third_party/txt/src/txt/paragraph_txt.h | 400 +++++++++++++++++ third_party/txt/tests/paragraph_unittests.cc | 263 ++++++----- third_party/txt/tests/txt_test_utils.cc | 8 + third_party/txt/tests/txt_test_utils.h | 4 + tools/gn | 2 + 24 files changed, 1334 insertions(+), 701 deletions(-) create mode 100644 third_party/txt/src/skia/paragraph_builder_skia.cc create mode 100644 third_party/txt/src/skia/paragraph_builder_skia.h create mode 100644 third_party/txt/src/skia/paragraph_skia.cc create mode 100644 third_party/txt/src/skia/paragraph_skia.h create mode 100644 third_party/txt/src/txt/paragraph_builder_txt.cc create mode 100644 third_party/txt/src/txt/paragraph_builder_txt.h rename third_party/txt/src/txt/{paragraph.cc => paragraph_txt.cc} (94%) create mode 100644 third_party/txt/src/txt/paragraph_txt.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 42517d5b01b75..c155fd185baab 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1069,6 +1069,10 @@ FILE: ../../../flutter/third_party/txt/src/minikin/SparseBitSet.cpp FILE: ../../../flutter/third_party/txt/src/minikin/SparseBitSet.h FILE: ../../../flutter/third_party/txt/src/minikin/WordBreaker.cpp FILE: ../../../flutter/third_party/txt/src/minikin/WordBreaker.h +FILE: ../../../flutter/third_party/txt/src/skia/paragraph_builder_skia.cc +FILE: ../../../flutter/third_party/txt/src/skia/paragraph_builder_skia.h +FILE: ../../../flutter/third_party/txt/src/skia/paragraph_skia.cc +FILE: ../../../flutter/third_party/txt/src/skia/paragraph_skia.h FILE: ../../../flutter/third_party/txt/src/txt/asset_font_manager.cc FILE: ../../../flutter/third_party/txt/src/txt/asset_font_manager.h FILE: ../../../flutter/third_party/txt/src/txt/font_asset_provider.cc @@ -1083,12 +1087,15 @@ FILE: ../../../flutter/third_party/txt/src/txt/font_style.h FILE: ../../../flutter/third_party/txt/src/txt/font_weight.h FILE: ../../../flutter/third_party/txt/src/txt/paint_record.cc FILE: ../../../flutter/third_party/txt/src/txt/paint_record.h -FILE: ../../../flutter/third_party/txt/src/txt/paragraph.cc FILE: ../../../flutter/third_party/txt/src/txt/paragraph.h FILE: ../../../flutter/third_party/txt/src/txt/paragraph_builder.cc FILE: ../../../flutter/third_party/txt/src/txt/paragraph_builder.h +FILE: ../../../flutter/third_party/txt/src/txt/paragraph_builder_txt.cc +FILE: ../../../flutter/third_party/txt/src/txt/paragraph_builder_txt.h FILE: ../../../flutter/third_party/txt/src/txt/paragraph_style.cc FILE: ../../../flutter/third_party/txt/src/txt/paragraph_style.h +FILE: ../../../flutter/third_party/txt/src/txt/paragraph_txt.cc +FILE: ../../../flutter/third_party/txt/src/txt/paragraph_txt.h FILE: ../../../flutter/third_party/txt/src/txt/placeholder_run.cc FILE: ../../../flutter/third_party/txt/src/txt/placeholder_run.h FILE: ../../../flutter/third_party/txt/src/txt/styled_runs.cc diff --git a/common/config.gni b/common/config.gni index b897a9f9095f6..ec196f631a87e 100644 --- a/common/config.gni +++ b/common/config.gni @@ -17,6 +17,9 @@ if (target_cpu == "arm" || target_cpu == "arm64") { declare_args() { # The runtime mode ("debug", "profile", or "release") flutter_runtime_mode = "debug" + + # Whether to use the Skia text shaper module + flutter_enable_skshaper = false } # feature_defines_list --------------------------------------------------------- diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 06f1aa786936b..d1b4dc7e0ad4c 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/fuchsia/sdk.gni") +import("$flutter_root/common/config.gni") import("$flutter_root/testing/testing.gni") source_set("ui") { @@ -126,6 +127,10 @@ source_set("ui") { "$flutter_root/third_party/txt", ] + if (flutter_enable_skshaper) { + defines = [ "FLUTTER_ENABLE_SKSHAPER" ] + } + if (is_fuchsia) { sources += [ "compositing/scene_host.cc", diff --git a/lib/ui/text/paragraph_builder.cc b/lib/ui/text/paragraph_builder.cc index bef66a700b98e..a32676731acf9 100644 --- a/lib/ui/text/paragraph_builder.cc +++ b/lib/ui/text/paragraph_builder.cc @@ -283,9 +283,16 @@ ParagraphBuilder::ParagraphBuilder( FontCollection& font_collection = UIDartState::Current()->window()->client()->GetFontCollection(); - m_paragraphBuilder = std::make_unique( - style, font_collection.GetFontCollection()); -} // namespace flutter + +#if FLUTTER_ENABLE_SKSHAPER +#define FLUTTER_PARAGRAPH_BUILDER txt::ParagraphBuilder::CreateSkiaBuilder +#else +#define FLUTTER_PARAGRAPH_BUILDER txt::ParagraphBuilder::CreateTxtBuilder +#endif + + m_paragraphBuilder = + FLUTTER_PARAGRAPH_BUILDER(style, font_collection.GetFontCollection()); +} ParagraphBuilder::~ParagraphBuilder() = default; diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index 79c52ee1d1dc0..d77d4b9c9f41d 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("$flutter_root/common/config.gni") + declare_args() { flutter_use_fontconfig = false } @@ -30,6 +32,9 @@ source_set("txt") { if (flutter_use_fontconfig) { defines += [ "FLUTTER_USE_FONTCONFIG" ] } + if (flutter_enable_skshaper) { + defines += [ "FLUTTER_ENABLE_SKSHAPER" ] + } sources = [ "src/log/log.cc", @@ -84,12 +89,15 @@ source_set("txt") { "src/txt/font_weight.h", "src/txt/paint_record.cc", "src/txt/paint_record.h", - "src/txt/paragraph.cc", "src/txt/paragraph.h", "src/txt/paragraph_builder.cc", "src/txt/paragraph_builder.h", + "src/txt/paragraph_builder_txt.cc", + "src/txt/paragraph_builder_txt.h", "src/txt/paragraph_style.cc", "src/txt/paragraph_style.h", + "src/txt/paragraph_txt.cc", + "src/txt/paragraph_txt.h", "src/txt/placeholder_run.cc", "src/txt/placeholder_run.h", "src/txt/platform.h", @@ -130,6 +138,17 @@ source_set("txt") { deps += [ "//third_party/fontconfig" ] } + if (flutter_enable_skshaper) { + sources += [ + "src/skia/paragraph_builder_skia.cc", + "src/skia/paragraph_builder_skia.h", + "src/skia/paragraph_skia.cc", + "src/skia/paragraph_skia.h", + ] + + deps += [ "//third_party/skia/modules/skparagraph" ] + } + if (is_mac || is_ios) { sources += [ "src/txt/platform_mac.mm" ] deps += [ "$flutter_root/fml" ] diff --git a/third_party/txt/benchmarks/paragraph_benchmarks.cc b/third_party/txt/benchmarks/paragraph_benchmarks.cc index a9699f4071eab..cf7402ba448b4 100644 --- a/third_party/txt/benchmarks/paragraph_benchmarks.cc +++ b/third_party/txt/benchmarks/paragraph_benchmarks.cc @@ -30,7 +30,7 @@ #include "txt/font_style.h" #include "txt/font_weight.h" #include "txt/paragraph.h" -#include "txt/paragraph_builder.h" +#include "txt/paragraph_builder_txt.h" namespace txt { @@ -45,15 +45,15 @@ static void BM_ParagraphShortLayout(benchmark::State& state) { txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } } BENCHMARK(BM_ParagraphShortLayout); @@ -87,15 +87,15 @@ static void BM_ParagraphLongLayout(benchmark::State& state) { text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } } BENCHMARK(BM_ParagraphLongLayout); @@ -130,15 +130,15 @@ static void BM_ParagraphJustifyLayout(benchmark::State& state) { text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } } BENCHMARK(BM_ParagraphJustifyLayout); @@ -154,15 +154,15 @@ static void BM_ParagraphManyStylesLayout(benchmark::State& state) { txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); for (int i = 0; i < 1000; ++i) { builder.PushStyle(text_style); builder.AddText(u16_text); } - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } } BENCHMARK(BM_ParagraphManyStylesLayout); @@ -181,15 +181,15 @@ static void BM_ParagraphTextBigO(benchmark::State& state) { text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } state.SetComplexityN(state.range(0)); } @@ -210,16 +210,16 @@ static void BM_ParagraphStylesBigO(benchmark::State& state) { text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); for (int i = 0; i < state.range(0); ++i) { builder.PushStyle(text_style); builder.AddText(u16_text); } - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); while (state.KeepRunning()) { paragraph->SetDirty(); - paragraph->Layout(300, true); + paragraph->Layout(300); } state.SetComplexityN(state.range(0)); } @@ -239,11 +239,11 @@ static void BM_ParagraphPaintSimple(benchmark::State& state) { txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); - auto paragraph = builder.Build(); - paragraph->Layout(300, true); + auto paragraph = BuildParagraph(builder); + paragraph->Layout(300); std::unique_ptr bitmap = std::make_unique(); bitmap->allocN32Pixels(1000, 1000); @@ -286,11 +286,11 @@ static void BM_ParagraphPaintLarge(benchmark::State& state) { txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); - auto paragraph = builder.Build(); - paragraph->Layout(300, true); + auto paragraph = BuildParagraph(builder); + paragraph->Layout(300); std::unique_ptr bitmap = std::make_unique(); bitmap->allocN32Pixels(1000, 1000); @@ -322,7 +322,7 @@ static void BM_ParagraphPaintDecoration(benchmark::State& state) { text_style.decoration_style = TextDecorationStyle(kSolid); text_style.color = SK_ColorBLACK; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.PushStyle(text_style); builder.AddText(u16_text); @@ -335,8 +335,8 @@ static void BM_ParagraphPaintDecoration(benchmark::State& state) { builder.PushStyle(text_style); builder.AddText(u16_text); - auto paragraph = builder.Build(); - paragraph->Layout(300, true); + auto paragraph = BuildParagraph(builder); + paragraph->Layout(300); std::unique_ptr bitmap = std::make_unique(); bitmap->allocN32Pixels(1000, 1000); diff --git a/third_party/txt/benchmarks/paragraph_builder_benchmarks.cc b/third_party/txt/benchmarks/paragraph_builder_benchmarks.cc index 84ac4431cc8bc..7e378f365c6e1 100644 --- a/third_party/txt/benchmarks/paragraph_builder_benchmarks.cc +++ b/third_party/txt/benchmarks/paragraph_builder_benchmarks.cc @@ -23,7 +23,7 @@ #include "txt/font_style.h" #include "txt/font_weight.h" #include "txt/paragraph.h" -#include "txt/paragraph_builder.h" +#include "txt/paragraph_builder_txt.h" namespace txt { @@ -31,7 +31,7 @@ static void BM_ParagraphBuilderConstruction(benchmark::State& state) { txt::ParagraphStyle paragraph_style; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); } } BENCHMARK(BM_ParagraphBuilderConstruction); @@ -43,7 +43,7 @@ static void BM_ParagraphBuilderPushStyle(benchmark::State& state) { text_style.color = SK_ColorBLACK; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.PushStyle(text_style); } } @@ -51,7 +51,7 @@ BENCHMARK(BM_ParagraphBuilderPushStyle); static void BM_ParagraphBuilderPushPop(benchmark::State& state) { txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.color = SK_ColorBLACK; @@ -70,7 +70,7 @@ static void BM_ParagraphBuilderAddTextString(benchmark::State& state) { txt::ParagraphStyle paragraph_style; while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.AddText(text); } } @@ -82,7 +82,7 @@ static void BM_ParagraphBuilderAddTextChar(benchmark::State& state) { txt::ParagraphStyle paragraph_style; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.AddText(text); } } @@ -97,7 +97,7 @@ static void BM_ParagraphBuilderAddTextU16stringShort(benchmark::State& state) { txt::ParagraphStyle paragraph_style; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.AddText(u16_text); } } @@ -131,7 +131,7 @@ static void BM_ParagraphBuilderAddTextU16stringLong(benchmark::State& state) { txt::ParagraphStyle paragraph_style; while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.AddText(u16_text); } } @@ -150,7 +150,7 @@ static void BM_ParagraphBuilderShortParagraphConstruct( text_style.color = SK_ColorBLACK; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); @@ -188,7 +188,7 @@ static void BM_ParagraphBuilderLongParagraphConstruct(benchmark::State& state) { text_style.color = SK_ColorBLACK; auto font_collection = GetTestFontCollection(); while (state.KeepRunning()) { - txt::ParagraphBuilder builder(paragraph_style, font_collection); + txt::ParagraphBuilderTxt builder(paragraph_style, font_collection); builder.PushStyle(text_style); builder.AddText(u16_text); builder.Pop(); diff --git a/third_party/txt/src/skia/paragraph_builder_skia.cc b/third_party/txt/src/skia/paragraph_builder_skia.cc new file mode 100644 index 0000000000000..17cd9af9713e6 --- /dev/null +++ b/third_party/txt/src/skia/paragraph_builder_skia.cc @@ -0,0 +1,164 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "paragraph_builder_skia.h" +#include "paragraph_skia.h" + +#include "third_party/skia/modules/skparagraph/include/ParagraphStyle.h" +#include "third_party/skia/modules/skparagraph/include/TextStyle.h" +#include "txt/paragraph_style.h" + +namespace skt = skia::textlayout; + +namespace txt { + +namespace { + +// Convert txt::FontWeight values (ranging from 0-8) to SkFontStyle::Weight +// values (ranging from 100-900). +SkFontStyle::Weight GetSkFontStyleWeight(txt::FontWeight font_weight) { + return static_cast(static_cast(font_weight) * 100 + + 100); +} + +SkFontStyle MakeSkFontStyle(txt::FontWeight font_weight, + txt::FontStyle font_style) { + return SkFontStyle( + GetSkFontStyleWeight(font_weight), SkFontStyle::Width::kNormal_Width, + font_style == txt::FontStyle::normal ? SkFontStyle::Slant::kUpright_Slant + : SkFontStyle::Slant::kItalic_Slant); +} + +skt::ParagraphStyle TxtToSkia(const ParagraphStyle& txt) { + skt::ParagraphStyle skia; + skt::TextStyle text_style; + + text_style.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style)); + text_style.setFontSize(SkDoubleToScalar(txt.font_size)); + text_style.setHeight(SkDoubleToScalar(txt.height)); + text_style.setFontFamilies({SkString(txt.font_family.c_str())}); + text_style.setLocale(SkString(txt.locale.c_str())); + skia.setTextStyle(text_style); + + skt::StrutStyle strut_style; + strut_style.setFontStyle( + MakeSkFontStyle(txt.strut_font_weight, txt.strut_font_style)); + strut_style.setFontSize(SkDoubleToScalar(txt.strut_font_size)); + strut_style.setHeight(SkDoubleToScalar(txt.strut_height)); + + std::vector strut_fonts; + std::transform(txt.strut_font_families.begin(), txt.strut_font_families.end(), + std::back_inserter(strut_fonts), + [](const std::string& f) { return SkString(f.c_str()); }); + strut_style.setFontFamilies(strut_fonts); + strut_style.setLeading(txt.strut_leading); + strut_style.setForceStrutHeight(txt.force_strut_height); + strut_style.setStrutEnabled(txt.strut_enabled); + skia.setStrutStyle(strut_style); + + skia.setTextAlign(static_cast(txt.text_align)); + skia.setTextDirection(static_cast(txt.text_direction)); + skia.setMaxLines(txt.max_lines); + skia.setEllipsis(txt.ellipsis); + + skia.turnHintingOff(); + + return skia; +} + +skt::TextStyle TxtToSkia(const TextStyle& txt) { + skt::TextStyle skia; + + skia.setColor(txt.color); + skia.setDecoration(static_cast(txt.decoration)); + skia.setDecorationColor(txt.decoration_color); + skia.setDecorationStyle( + static_cast(txt.decoration_style)); + skia.setDecorationThicknessMultiplier( + SkDoubleToScalar(txt.decoration_thickness_multiplier)); + skia.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style)); + skia.setTextBaseline(static_cast(txt.text_baseline)); + + std::vector skia_fonts; + std::transform(txt.font_families.begin(), txt.font_families.end(), + std::back_inserter(skia_fonts), + [](const std::string& f) { return SkString(f.c_str()); }); + skia.setFontFamilies(skia_fonts); + + skia.setFontSize(SkDoubleToScalar(txt.font_size)); + skia.setLetterSpacing(SkDoubleToScalar(txt.letter_spacing)); + skia.setWordSpacing(SkDoubleToScalar(txt.word_spacing)); + skia.setHeight(SkDoubleToScalar(txt.height)); + + skia.setLocale(SkString(txt.locale.c_str())); + if (txt.has_background) { + skia.setBackgroundColor(txt.background); + } + if (txt.has_foreground) { + skia.setForegroundColor(txt.foreground); + } + + skia.resetShadows(); + for (const txt::TextShadow& txt_shadow : txt.text_shadows) { + skt::TextShadow shadow; + shadow.fOffset = txt_shadow.offset; + shadow.fBlurRadius = txt_shadow.blur_radius; + shadow.fColor = txt_shadow.color; + skia.addShadow(shadow); + } + + return skia; +} + +} // anonymous namespace + +ParagraphBuilderSkia::ParagraphBuilderSkia( + const ParagraphStyle& style, + std::shared_ptr font_collection) + : builder_(skt::ParagraphBuilder::make( + TxtToSkia(style), + font_collection->CreateSktFontCollection())), + base_style_(style.GetTextStyle()) {} + +ParagraphBuilderSkia::~ParagraphBuilderSkia() = default; + +void ParagraphBuilderSkia::PushStyle(const TextStyle& style) { + builder_->pushStyle(TxtToSkia(style)); + txt_style_stack_.push(style); +} + +void ParagraphBuilderSkia::Pop() { + builder_->pop(); + txt_style_stack_.pop(); +} + +const TextStyle& ParagraphBuilderSkia::PeekStyle() { + return txt_style_stack_.empty() ? base_style_ : txt_style_stack_.top(); +} + +void ParagraphBuilderSkia::AddText(const std::u16string& text) { + builder_->addText(text); +} + +void ParagraphBuilderSkia::AddPlaceholder(PlaceholderRun& span) { + assert(false); +} + +std::unique_ptr ParagraphBuilderSkia::Build() { + return std::make_unique(builder_->Build()); +} + +} // namespace txt diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h new file mode 100644 index 0000000000000..06b00caf43c52 --- /dev/null +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_TXT_SRC_PARAGRAPH_BUILDER_SKIA_H_ +#define LIB_TXT_SRC_PARAGRAPH_BUILDER_SKIA_H_ + +#include "txt/paragraph_builder.h" + +#include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" + +namespace txt { + +// Implementation of ParagraphBuilder based on Skia's text layout module. +class ParagraphBuilderSkia : public ParagraphBuilder { + public: + ParagraphBuilderSkia(const ParagraphStyle& style, + std::shared_ptr font_collection); + + virtual ~ParagraphBuilderSkia(); + + virtual void PushStyle(const TextStyle& style) override; + virtual void Pop() override; + virtual const TextStyle& PeekStyle() override; + virtual void AddText(const std::u16string& text) override; + virtual void AddPlaceholder(PlaceholderRun& span) override; + virtual std::unique_ptr Build() override; + + private: + std::shared_ptr builder_; + TextStyle base_style_; + std::stack txt_style_stack_; +}; + +} // namespace txt + +#endif // LIB_TXT_SRC_PARAGRAPH_BUILDER_SKIA_H_ diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc new file mode 100644 index 0000000000000..685c4a45b0b63 --- /dev/null +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -0,0 +1,105 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "paragraph_skia.h" + +namespace txt { + +namespace skt = skia::textlayout; + +ParagraphSkia::ParagraphSkia(std::unique_ptr paragraph) + : paragraph_(std::move(paragraph)) {} + +double ParagraphSkia::GetMaxWidth() { + return paragraph_->getMaxWidth(); +} + +double ParagraphSkia::GetHeight() { + return paragraph_->getHeight(); +} + +double ParagraphSkia::GetLongestLine() { + // TODO: implement + return 0; +} + +double ParagraphSkia::GetMinIntrinsicWidth() { + return paragraph_->getMinIntrinsicWidth(); +} + +double ParagraphSkia::GetMaxIntrinsicWidth() { + return paragraph_->getMaxIntrinsicWidth(); +} + +double ParagraphSkia::GetAlphabeticBaseline() { + return paragraph_->getAlphabeticBaseline(); +} + +double ParagraphSkia::GetIdeographicBaseline() { + return paragraph_->getIdeographicBaseline(); +} + +bool ParagraphSkia::DidExceedMaxLines() { + return paragraph_->didExceedMaxLines(); +} + +void ParagraphSkia::Layout(double width) { + paragraph_->layout(width); +} + +void ParagraphSkia::Paint(SkCanvas* canvas, double x, double y) { + paragraph_->paint(canvas, x, y); +} + +std::vector ParagraphSkia::GetRectsForRange( + size_t start, + size_t end, + RectHeightStyle rect_height_style, + RectWidthStyle rect_width_style) { + std::vector skia_boxes = paragraph_->getRectsForRange( + start, end, static_cast(rect_height_style), + static_cast(rect_width_style)); + + std::vector boxes; + for (const skt::TextBox skia_box : skia_boxes) { + boxes.emplace_back(skia_box.rect, + static_cast(skia_box.direction)); + } + + return boxes; +} + +std::vector ParagraphSkia::GetRectsForPlaceholders() { + // TODO: implement + return {}; +} + +Paragraph::PositionWithAffinity ParagraphSkia::GetGlyphPositionAtCoordinate( + double dx, + double dy) { + skt::PositionWithAffinity skia_pos = + paragraph_->getGlyphPositionAtCoordinate(dx, dy); + + return ParagraphSkia::PositionWithAffinity( + skia_pos.position, static_cast(skia_pos.affinity)); +} + +Paragraph::Range ParagraphSkia::GetWordBoundary(size_t offset) { + skt::SkRange range = paragraph_->getWordBoundary(offset); + return Paragraph::Range(range.start, range.end); +} + +} // namespace txt diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h new file mode 100644 index 0000000000000..00d713436fd1d --- /dev/null +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -0,0 +1,72 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_TXT_SRC_PARAGRAPH_SKIA_H_ +#define LIB_TXT_SRC_PARAGRAPH_SKIA_H_ + +#include "txt/paragraph.h" + +#include "third_party/skia/modules/skparagraph/include/Paragraph.h" + +namespace txt { + +// Implementation of Paragraph based on Skia's text layout module. +class ParagraphSkia : public Paragraph { + public: + ParagraphSkia(std::unique_ptr paragraph); + + virtual ~ParagraphSkia() = default; + + double GetMaxWidth() override; + + double GetHeight() override; + + double GetLongestLine() override; + + double GetMinIntrinsicWidth() override; + + double GetMaxIntrinsicWidth() override; + + double GetAlphabeticBaseline() override; + + double GetIdeographicBaseline() override; + + bool DidExceedMaxLines() override; + + void Layout(double width) override; + + void Paint(SkCanvas* canvas, double x, double y) override; + + std::vector GetRectsForRange( + size_t start, + size_t end, + RectHeightStyle rect_height_style, + RectWidthStyle rect_width_style) override; + + std::vector GetRectsForPlaceholders() override; + + PositionWithAffinity GetGlyphPositionAtCoordinate(double dx, + double dy) override; + + Range GetWordBoundary(size_t offset) override; + + private: + std::unique_ptr paragraph_; +}; + +} // namespace txt + +#endif // LIB_TXT_SRC_PARAGRAPH_SKIA_H_ diff --git a/third_party/txt/src/txt/font_collection.cc b/third_party/txt/src/txt/font_collection.cc index 99be0100957d1..dfa554714b9b7 100644 --- a/third_party/txt/src/txt/font_collection.cc +++ b/third_party/txt/src/txt/font_collection.cc @@ -302,4 +302,25 @@ void FontCollection::ClearFontFamilyCache() { font_collections_cache_.clear(); } +#if FLUTTER_ENABLE_SKSHAPER + +sk_sp +FontCollection::CreateSktFontCollection() { + sk_sp skt_collection = + sk_make_sp(); + + skt_collection->setDefaultFontManager(default_font_manager_, + GetDefaultFontFamily().c_str()); + skt_collection->setAssetFontManager(asset_font_manager_); + skt_collection->setDynamicFontManager(dynamic_font_manager_); + skt_collection->setTestFontManager(test_font_manager_); + if (!enable_font_fallback_) { + skt_collection->disableFontFallback(); + } + + return skt_collection; +} + +#endif // FLUTTER_ENABLE_SKSHAPER + } // namespace txt diff --git a/third_party/txt/src/txt/font_collection.h b/third_party/txt/src/txt/font_collection.h index 5bae9e8974288..d7d294c4f3eaa 100644 --- a/third_party/txt/src/txt/font_collection.h +++ b/third_party/txt/src/txt/font_collection.h @@ -27,6 +27,7 @@ #include "third_party/googletest/googletest/include/gtest/gtest_prod.h" // nogncheck #include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/modules/skparagraph/include/FontCollection.h" #include "txt/asset_font_manager.h" #include "txt/text_style.h" @@ -63,6 +64,13 @@ class FontCollection : public std::enable_shared_from_this { // Remove all entries in the font family cache. void ClearFontFamilyCache(); +#if FLUTTER_ENABLE_SKSHAPER + + // Construct a Skia text layout FontCollection based on this collection. + sk_sp CreateSktFontCollection(); + +#endif // FLUTTER_ENABLE_SKSHAPER + private: struct FamilyKey { FamilyKey(const std::vector& families, const std::string& loc); diff --git a/third_party/txt/src/txt/paragraph.h b/third_party/txt/src/txt/paragraph.h index 2d6e30827ea54..a197cddd8315f 100644 --- a/third_party/txt/src/txt/paragraph.h +++ b/third_party/txt/src/txt/paragraph.h @@ -17,52 +17,17 @@ #ifndef LIB_TXT_SRC_PARAGRAPH_H_ #define LIB_TXT_SRC_PARAGRAPH_H_ -#include -#include -#include - -#include "flutter/fml/compiler_specific.h" -#include "flutter/fml/macros.h" -#include "font_collection.h" -#include "minikin/LineBreaker.h" -#include "paint_record.h" #include "paragraph_style.h" -#include "placeholder_run.h" -#include "styled_runs.h" -#include "third_party/googletest/googletest/include/gtest/gtest_prod.h" // nogncheck -#include "third_party/skia/include/core/SkFontMetrics.h" -#include "third_party/skia/include/core/SkRect.h" -#include "utils/WindowsUtils.h" class SkCanvas; namespace txt { -using GlyphID = uint32_t; - -// Constant with the unicode codepoint for the "Object replacement character". -// Used as a stand-in character for Placeholder boxes. -const int objReplacementChar = 0xFFFC; -// Constant with the unicode codepoint for the "Replacement character". This is -// the character that commonly renders as a black diamond with a white question -// mark. Used to replace non-placeholder instances of 0xFFFC in the text buffer. -const int replacementChar = 0xFFFD; - -// Paragraph provides Layout, metrics, and painting capabilities for text. Once -// a Paragraph is constructed with ParagraphBuilder::Build(), an example basic -// workflow can be this: -// -// std::unique_ptr paragraph = paragraph_builder.Build(); -// paragraph->Layout(); -// paragraph->Paint(, , ); +// Interface for text layout engines. The original implementation was based on +// the Minikin text layout library used by Android. Another implementation is +// available based on Skia's SkShaper/SkParagraph text layout module. class Paragraph { public: - // Constructor. It is highly recommended to construct a paragraph with a - // ParagraphBuilder. - Paragraph(); - - ~Paragraph(); - enum Affinity { UPSTREAM, DOWNSTREAM }; // Options for various types of bounding boxes provided by @@ -135,69 +100,57 @@ class Paragraph { } }; - // Minikin Layout doLayout() and LineBreaker addStyleRun() has an - // O(N^2) (according to benchmarks) time complexity where N is the total - // number of characters. However, this is not significant for reasonably sized - // paragraphs. It is currently recommended to break up very long paragraphs - // (10k+ characters) to ensure speedy layout. - // - // Layout calculates the positioning of all the glyphs. Must call this method - // before Painting and getting any statistics from this class. - void Layout(double width, bool force = false); - - // Paints the Laid out text onto the supplied SkCanvas at (x, y) offset from - // the origin. Only valid after Layout() is called. - void Paint(SkCanvas* canvas, double x, double y); - - // Getter for paragraph_style_. - const ParagraphStyle& GetParagraphStyle() const; + virtual ~Paragraph() = default; - // Returns the number of characters/unicode characters. AKA text_.size() - size_t TextSize() const; + // Returns the width provided in the Layout() method. This is the maximum + // width any line in the laid out paragraph can occupy. We expect that + // GetMaxWidth() >= GetLayoutWidth(). + virtual double GetMaxWidth() = 0; // Returns the height of the laid out paragraph. NOTE this is not a tight // bounding height of the glyphs, as some glyphs do not reach as low as they // can. - double GetHeight() const; - - // Returns the width provided in the Layout() method. This is the maximum - // width any line in the laid out paragraph can occupy. We expect that - // GetMaxWidth() >= GetLayoutWidth(). - double GetMaxWidth() const; + virtual double GetHeight() = 0; // Returns the width of the longest line as found in Layout(), which is // defined as the horizontal distance from the left edge of the leftmost glyph // to the right edge of the rightmost glyph. We expect that // GetLongestLine() <= GetMaxWidth(). - double GetLongestLine() const; + virtual double GetLongestLine() = 0; + + // Returns the actual max width of the longest line after Layout(). + virtual double GetMinIntrinsicWidth() = 0; + + // Returns the total width covered by the paragraph without linebreaking. + virtual double GetMaxIntrinsicWidth() = 0; // Distance from top of paragraph to the Alphabetic baseline of the first // line. Used for alphabetic fonts (A-Z, a-z, greek, etc.) - double GetAlphabeticBaseline() const; + virtual double GetAlphabeticBaseline() = 0; // Distance from top of paragraph to the Ideographic baseline of the first // line. Used for ideographic fonts (Chinese, Japanese, Korean, etc.) - double GetIdeographicBaseline() const; + virtual double GetIdeographicBaseline() = 0; - // Returns the total width covered by the paragraph without linebreaking. - double GetMaxIntrinsicWidth() const; + // Checks if the layout extends past the maximum lines and had to be + // truncated. + virtual bool DidExceedMaxLines() = 0; - // Currently, calculated similarly to as GetLayoutWidth(), however this is not - // nessecarily 100% correct in all cases. - // - // Returns the actual max width of the longest line after Layout(). - double GetMinIntrinsicWidth() const; + // Layout calculates the positioning of all the glyphs. Must call this method + // before Painting and getting any statistics from this class. + virtual void Layout(double width) = 0; + + // Paints the laid out text onto the supplied SkCanvas at (x, y) offset from + // the origin. Only valid after Layout() is called. + virtual void Paint(SkCanvas* canvas, double x, double y) = 0; // Returns a vector of bounding boxes that enclose all text between start and // end glyph indexes, including start and excluding end. - std::vector GetRectsForRange(size_t start, - size_t end, - RectHeightStyle rect_height_style, - RectWidthStyle rect_width_style) const; - - // Returns the index of the glyph that corresponds to the provided coordinate, - // with the top left corner as the origin, and +y direction as down. - PositionWithAffinity GetGlyphPositionAtCoordinate(double dx, double dy) const; + virtual std::vector GetRectsForRange( + size_t start, + size_t end, + RectHeightStyle rect_height_style, + RectWidthStyle rect_width_style) = 0; // Returns a vector of bounding boxes that bound all inline placeholders in // the paragraph. @@ -208,301 +161,16 @@ class Paragraph { // // More granular boxes may be obtained through GetRectsForRange, which will // return bounds on both text as well as inline placeholders. - std::vector GetRectsForPlaceholders() const; + virtual std::vector GetRectsForPlaceholders() = 0; + + // Returns the index of the glyph that corresponds to the provided coordinate, + // with the top left corner as the origin, and +y direction as down. + virtual PositionWithAffinity GetGlyphPositionAtCoordinate(double dx, + double dy) = 0; // Finds the first and last glyphs that define a word containing the glyph at // index offset. - Range GetWordBoundary(size_t offset) const; - - // Returns the number of lines the paragraph takes up. If the text exceeds the - // amount width and maxlines provides, Layout() truncates the extra text from - // the layout and this will return the max lines allowed. - size_t GetLineCount() const; - - // Checks if the layout extends past the maximum lines and had to be - // truncated. - bool DidExceedMaxLines() const; - - // Sets the needs_layout_ to dirty. When Layout() is called, a new Layout will - // be performed when this is set to true. Can also be used to prevent a new - // Layout from being calculated by setting to false. - void SetDirty(bool dirty = true); - - private: - friend class ParagraphBuilder; - FRIEND_TEST(ParagraphTest, SimpleParagraph); - FRIEND_TEST(ParagraphTest, SimpleRedParagraph); - FRIEND_TEST(ParagraphTest, RainbowParagraph); - FRIEND_TEST(ParagraphTest, DefaultStyleParagraph); - FRIEND_TEST(ParagraphTest, BoldParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, LeftAlignParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, RightAlignParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, CenterAlignParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyAlignParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyRTL); - FRIEND_TEST(ParagraphTest, DecorationsParagraph); - FRIEND_TEST(ParagraphTest, ItalicsParagraph); - FRIEND_TEST(ParagraphTest, ChineseParagraph); - FRIEND_TEST(ParagraphTest, DISABLED_ArabicParagraph); - FRIEND_TEST(ParagraphTest, SpacingParagraph); - FRIEND_TEST(ParagraphTest, LongWordParagraph); - FRIEND_TEST(ParagraphTest, KernScaleParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, NewlineParagraph); - FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, EmojiParagraph); - FRIEND_TEST(ParagraphTest, HyphenBreakParagraph); - FRIEND_TEST(ParagraphTest, RepeatLayoutParagraph); - FRIEND_TEST(ParagraphTest, Ellipsize); - FRIEND_TEST(ParagraphTest, UnderlineShiftParagraph); - FRIEND_TEST(ParagraphTest, WavyDecorationParagraph); - FRIEND_TEST(ParagraphTest, SimpleShadow); - FRIEND_TEST(ParagraphTest, ComplexShadow); - FRIEND_TEST(ParagraphTest, FontFallbackParagraph); - FRIEND_TEST(ParagraphTest, InlinePlaceholder0xFFFCParagraph); - FRIEND_TEST(ParagraphTest, FontFeaturesParagraph); - - // Starting data to layout. - std::vector text_; - // A vector of PlaceholderRuns, which detail the sizes, positioning and break - // behavior of the empty spaces to leave. Each placeholder span corresponds to - // a 0xFFFC (object replacement character) in text_, which indicates the - // position in the text where the placeholder will occur. There should be an - // equal number of 0xFFFC characters and elements in this vector. - std::vector inline_placeholders_; - // The indexes of the boxes that correspond to an inline placeholder. - std::vector inline_placeholder_boxes_; - // The indexes of instances of 0xFFFC that correspond to placeholders. This is - // necessary since the user may pass in manually entered 0xFFFC values using - // AddText(). - std::unordered_set obj_replacement_char_indexes_; - StyledRuns runs_; - ParagraphStyle paragraph_style_; - std::shared_ptr font_collection_; - - minikin::LineBreaker breaker_; - mutable std::unique_ptr word_breaker_; - - struct LineRange { - LineRange(size_t s, size_t e, size_t eew, size_t ein, bool h) - : start(s), - end(e), - end_excluding_whitespace(eew), - end_including_newline(ein), - hard_break(h) {} - size_t start, end; - size_t end_excluding_whitespace; - size_t end_including_newline; - bool hard_break; - }; - std::vector line_ranges_; - std::vector line_widths_; - - // Stores the result of Layout(). - std::vector records_; - - std::vector line_heights_; - std::vector line_baselines_; - bool did_exceed_max_lines_; - - // Strut metrics of zero will have no effect on the layout. - struct StrutMetrics { - double ascent = 0; // Positive value to keep signs clear. - double descent = 0; - double leading = 0; - double half_leading = 0; - double line_height = 0; - bool force_strut = false; - }; - - StrutMetrics strut_; - - // Metrics for use in GetRectsForRange(...); - // Per-line max metrics over all runs in a given line. - std::vector line_max_spacings_; - std::vector line_max_descent_; - std::vector line_max_ascent_; - // Overall left and right extremes over all lines. - double max_right_; - double min_left_; - - class BidiRun { - public: - // Constructs a BidiRun with is_ghost defaulted to false. - BidiRun(size_t s, size_t e, TextDirection d, const TextStyle& st) - : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(false) {} - - // Constructs a BidiRun with a custom is_ghost flag. - BidiRun(size_t s, - size_t e, - TextDirection d, - const TextStyle& st, - bool is_ghost) - : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(is_ghost) {} - - // Constructs a placeholder bidi run. - BidiRun(size_t s, - size_t e, - TextDirection d, - const TextStyle& st, - PlaceholderRun& placeholder) - : start_(s), - end_(e), - direction_(d), - style_(&st), - placeholder_run_(&placeholder) {} - - size_t start() const { return start_; } - size_t end() const { return end_; } - size_t size() const { return end_ - start_; } - TextDirection direction() const { return direction_; } - const TextStyle& style() const { return *style_; } - PlaceholderRun* placeholder_run() const { return placeholder_run_; } - bool is_rtl() const { return direction_ == TextDirection::rtl; } - // Tracks if the run represents trailing whitespace. - bool is_ghost() const { return is_ghost_; } - bool is_placeholder_run() const { return placeholder_run_ != nullptr; } - - private: - size_t start_, end_; - TextDirection direction_; - const TextStyle* style_; - bool is_ghost_; - PlaceholderRun* placeholder_run_ = nullptr; - }; - - struct GlyphPosition { - Range code_units; - Range x_pos; - - GlyphPosition(double x_start, - double x_advance, - size_t code_unit_index, - size_t code_unit_width); - - void Shift(double delta); - }; - - struct GlyphLine { - // Glyph positions sorted by x coordinate. - const std::vector positions; - const size_t total_code_units; - - GlyphLine(std::vector&& p, size_t tcu); - }; - - struct CodeUnitRun { - // Glyph positions sorted by code unit index. - std::vector positions; - Range code_units; - Range x_pos; - size_t line_number; - SkFontMetrics font_metrics; - TextDirection direction; - const PlaceholderRun* placeholder_run; - - CodeUnitRun(std::vector&& p, - Range cu, - Range x, - size_t line, - const SkFontMetrics& metrics, - TextDirection dir, - const PlaceholderRun* placeholder); - - void Shift(double delta); - }; - - // Holds the laid out x positions of each glyph. - std::vector glyph_lines_; - - // Holds the positions of each range of code units in the text. - // Sorted in code unit index order. - std::vector code_unit_runs_; - // Holds the positions of the inline placeholders. - std::vector inline_placeholder_code_unit_runs_; - - // The max width of the paragraph as provided in the most recent Layout() - // call. - double width_ = -1.0f; - double longest_line_ = -1.0f; - double max_intrinsic_width_ = 0; - double min_intrinsic_width_ = 0; - double alphabetic_baseline_ = FLT_MAX; - double ideographic_baseline_ = FLT_MAX; - - bool needs_layout_ = true; - - struct WaveCoordinates { - double x_start; - double y_start; - double x_end; - double y_end; - - WaveCoordinates(double x_s, double y_s, double x_e, double y_e) - : 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 text, StyledRuns runs); - - void SetParagraphStyle(const ParagraphStyle& style); - - void SetFontCollection(std::shared_ptr font_collection); - - void SetInlinePlaceholders( - std::vector inline_placeholders, - std::unordered_set obj_replacement_char_indexes); - - // Break the text into lines. - bool ComputeLineBreaks(); - - // Break the text into runs based on LTR/RTL text direction. - bool ComputeBidiRuns(std::vector* result); - - // Calculates and populates strut based on paragraph_style_ strut info. - void ComputeStrut(StrutMetrics* strut, SkFont& font); - - // Adjusts the ascent and descent based on the existence and type of - // placeholder. This method sets the proper metrics to achieve the different - // PlaceholderAlignment options. - void ComputePlaceholder(PlaceholderRun* placeholder_run, - double& ascent, - double& descent); - - bool IsStrutValid() const; - - // Calculate the starting X offset of a line based on the line's width and - // alignment. - double GetLineXOffset(double line_total_advance); - - // Creates and draws the decorations onto the canvas. - void PaintDecorations(SkCanvas* canvas, - const PaintRecord& record, - SkPoint base_offset); - - // Computes the beziers for a wavy decoration. The results will be - // applied to path. - void ComputeWavyDecoration(SkPath& path, - double x, - double y, - double width, - double thickness); - - // Draws the background onto the canvas. - void PaintBackground(SkCanvas* canvas, - const PaintRecord& record, - SkPoint base_offset); - - // Draws the shadows onto the canvas. - void PaintShadow(SkCanvas* canvas, const PaintRecord& record, SkPoint offset); - - // Obtain a Minikin font collection matching this text style. - std::shared_ptr GetMinikinFontCollectionForStyle( - const TextStyle& style); - - // Get a default SkTypeface for a text style. - sk_sp GetDefaultSkiaTypeface(const TextStyle& style); - - FML_DISALLOW_COPY_AND_ASSIGN(Paragraph); + virtual Range GetWordBoundary(size_t offset) = 0; }; } // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder.cc b/third_party/txt/src/txt/paragraph_builder.cc index 1e25e27ad963a..a5a5b0a3f4322 100644 --- a/third_party/txt/src/txt/paragraph_builder.cc +++ b/third_party/txt/src/txt/paragraph_builder.cc @@ -13,75 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "flutter/fml/logging.h" - -#include #include "paragraph_builder.h" +#include "flutter/third_party/txt/src/skia/paragraph_builder_skia.h" +#include "paragraph_builder_txt.h" #include "paragraph_style.h" #include "third_party/icu/source/common/unicode/unistr.h" namespace txt { -ParagraphBuilder::ParagraphBuilder( - ParagraphStyle style, - std::shared_ptr font_collection) - : font_collection_(std::move(font_collection)) { - SetParagraphStyle(style); -} - -ParagraphBuilder::~ParagraphBuilder() = default; - -void ParagraphBuilder::SetParagraphStyle(const ParagraphStyle& style) { - paragraph_style_ = style; - paragraph_style_index_ = runs_.AddStyle(style.GetTextStyle()); - runs_.StartRun(paragraph_style_index_, text_.size()); +std::unique_ptr ParagraphBuilder::CreateTxtBuilder( + const ParagraphStyle& style, + std::shared_ptr font_collection) { + return std::make_unique(style, font_collection); } -void ParagraphBuilder::PushStyle(const TextStyle& style) { - size_t style_index = runs_.AddStyle(style); - style_stack_.push_back(style_index); - runs_.StartRun(style_index, text_.size()); -} - -void ParagraphBuilder::Pop() { - if (style_stack_.empty()) - return; - style_stack_.pop_back(); - runs_.StartRun(PeekStyleIndex(), text_.size()); -} +#if FLUTTER_ENABLE_SKSHAPER -size_t ParagraphBuilder::PeekStyleIndex() const { - return style_stack_.size() ? style_stack_.back() : paragraph_style_index_; +std::unique_ptr ParagraphBuilder::CreateSkiaBuilder( + const ParagraphStyle& style, + std::shared_ptr font_collection) { + return std::make_unique(style, font_collection); } -const TextStyle& ParagraphBuilder::PeekStyle() const { - return runs_.GetStyle(PeekStyleIndex()); -} - -void ParagraphBuilder::AddText(const std::u16string& text) { - text_.insert(text_.end(), text.begin(), text.end()); -} - -void ParagraphBuilder::AddPlaceholder(PlaceholderRun& span) { - obj_replacement_char_indexes_.insert(text_.size()); - runs_.StartRun(PeekStyleIndex(), text_.size()); - AddText(std::u16string(1ull, objReplacementChar)); - runs_.StartRun(PeekStyleIndex(), text_.size()); - inline_placeholders_.push_back(span); -} - -std::unique_ptr ParagraphBuilder::Build() { - runs_.EndRunIfNeeded(text_.size()); - - std::unique_ptr paragraph = std::make_unique(); - paragraph->SetText(std::move(text_), std::move(runs_)); - paragraph->SetInlinePlaceholders(std::move(inline_placeholders_), - std::move(obj_replacement_char_indexes_)); - paragraph->SetParagraphStyle(paragraph_style_); - paragraph->SetFontCollection(font_collection_); - SetParagraphStyle(paragraph_style_); - return paragraph; -} +#endif // FLUTTER_ENABLE_SKSHAPER } // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder.h b/third_party/txt/src/txt/paragraph_builder.h index ccedf685383dc..c54526e771f12 100644 --- a/third_party/txt/src/txt/paragraph_builder.h +++ b/third_party/txt/src/txt/paragraph_builder.h @@ -25,21 +25,27 @@ #include "paragraph.h" #include "paragraph_style.h" #include "placeholder_run.h" -#include "styled_runs.h" #include "text_style.h" namespace txt { class ParagraphBuilder { public: - ParagraphBuilder(ParagraphStyle style, - std::shared_ptr font_collection); + static std::unique_ptr CreateTxtBuilder( + const ParagraphStyle& style, + std::shared_ptr font_collection); - ~ParagraphBuilder(); +#if FLUTTER_ENABLE_SKSHAPER + static std::unique_ptr CreateSkiaBuilder( + const ParagraphStyle& style, + std::shared_ptr font_collection); +#endif + + virtual ~ParagraphBuilder() = default; // Push a style to the stack. The corresponding text added with AddText will // use the top-most style. - void PushStyle(const TextStyle& style); + virtual void PushStyle(const TextStyle& style) = 0; // Remove a style from the stack. Useful to apply different styles to chunks // of text such as bolding. @@ -52,14 +58,14 @@ class ParagraphBuilder { // // builder.Pop(); // builder.AddText(" Back to normal again."); - void Pop(); + virtual void Pop() = 0; // Returns the last TextStyle on the stack. - const TextStyle& PeekStyle() const; + virtual const TextStyle& PeekStyle() = 0; // Adds text to the builder. Forms the proper runs to use the upper-most style // on the style_stack_; - void AddText(const std::u16string& text); + virtual void AddText(const std::u16string& text) = 0; // Pushes the information requried to leave an open space, where Flutter may // draw a custom placeholder into. @@ -67,33 +73,16 @@ class ParagraphBuilder { // Internally, this method adds a single object replacement character (0xFFFC) // and emplaces a new PlaceholderRun instance to the vector of inline // placeholders. - void AddPlaceholder(PlaceholderRun& span); - - void SetParagraphStyle(const ParagraphStyle& style); + virtual void AddPlaceholder(PlaceholderRun& span) = 0; // Constructs a Paragraph object that can be used to layout and paint the text // to a SkCanvas. - std::unique_ptr Build(); + virtual std::unique_ptr Build() = 0; - private: - std::vector text_; - // A vector of PlaceholderRuns, which detail the sizes, positioning and break - // behavior of the empty spaces to leave. Each placeholder span corresponds to - // a 0xFFFC (object replacement character) in text_, which indicates the - // position in the text where the placeholder will occur. There should be an - // equal number of 0xFFFC characters and elements in this vector. - std::vector inline_placeholders_; - // The indexes of the obj replacement characters added through - // ParagraphBuilder::addPlaceholder(). - std::unordered_set obj_replacement_char_indexes_; - std::vector style_stack_; - std::shared_ptr font_collection_; - StyledRuns runs_; - ParagraphStyle paragraph_style_; - size_t paragraph_style_index_; - - size_t PeekStyleIndex() const; + protected: + ParagraphBuilder() = default; + private: FML_DISALLOW_COPY_AND_ASSIGN(ParagraphBuilder); }; diff --git a/third_party/txt/src/txt/paragraph_builder_txt.cc b/third_party/txt/src/txt/paragraph_builder_txt.cc new file mode 100644 index 0000000000000..47d5e8088e1f4 --- /dev/null +++ b/third_party/txt/src/txt/paragraph_builder_txt.cc @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "paragraph_builder_txt.h" +#include "paragraph_txt.h" + +namespace txt { + +ParagraphBuilderTxt::ParagraphBuilderTxt( + const ParagraphStyle& style, + std::shared_ptr font_collection) + : font_collection_(std::move(font_collection)) { + SetParagraphStyle(style); +} + +ParagraphBuilderTxt::~ParagraphBuilderTxt() = default; + +void ParagraphBuilderTxt::SetParagraphStyle(const ParagraphStyle& style) { + paragraph_style_ = style; + paragraph_style_index_ = runs_.AddStyle(style.GetTextStyle()); + runs_.StartRun(paragraph_style_index_, text_.size()); +} + +void ParagraphBuilderTxt::PushStyle(const TextStyle& style) { + size_t style_index = runs_.AddStyle(style); + style_stack_.push_back(style_index); + runs_.StartRun(style_index, text_.size()); +} + +void ParagraphBuilderTxt::Pop() { + if (style_stack_.empty()) { + return; + } + style_stack_.pop_back(); + runs_.StartRun(PeekStyleIndex(), text_.size()); +} + +size_t ParagraphBuilderTxt::PeekStyleIndex() const { + return style_stack_.size() ? style_stack_.back() : paragraph_style_index_; +} + +const TextStyle& ParagraphBuilderTxt::PeekStyle() { + return runs_.GetStyle(PeekStyleIndex()); +} + +void ParagraphBuilderTxt::AddText(const std::u16string& text) { + text_.insert(text_.end(), text.begin(), text.end()); +} + +void ParagraphBuilderTxt::AddPlaceholder(PlaceholderRun& span) { + obj_replacement_char_indexes_.insert(text_.size()); + runs_.StartRun(PeekStyleIndex(), text_.size()); + AddText(std::u16string(1ull, objReplacementChar)); + runs_.StartRun(PeekStyleIndex(), text_.size()); + inline_placeholders_.push_back(span); +} + +std::unique_ptr ParagraphBuilderTxt::Build() { + runs_.EndRunIfNeeded(text_.size()); + + std::unique_ptr paragraph = std::make_unique(); + paragraph->SetText(std::move(text_), std::move(runs_)); + paragraph->SetInlinePlaceholders(std::move(inline_placeholders_), + std::move(obj_replacement_char_indexes_)); + paragraph->SetParagraphStyle(paragraph_style_); + paragraph->SetFontCollection(font_collection_); + SetParagraphStyle(paragraph_style_); + return paragraph; +} + +} // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder_txt.h b/third_party/txt/src/txt/paragraph_builder_txt.h new file mode 100644 index 0000000000000..1a48b93f027d6 --- /dev/null +++ b/third_party/txt/src/txt/paragraph_builder_txt.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_TXT_SRC_PARAGRAPH_BUILDER_TXT_H_ +#define LIB_TXT_SRC_PARAGRAPH_BUILDER_TXT_H_ + +#include "paragraph_builder.h" +#include "styled_runs.h" + +namespace txt { + +// Implementation of ParagraphBuilder that produces paragraphs backed by the +// Minikin text layout library. +class ParagraphBuilderTxt : public ParagraphBuilder { + public: + ParagraphBuilderTxt(const ParagraphStyle& style, + std::shared_ptr font_collection); + + virtual ~ParagraphBuilderTxt(); + + virtual void PushStyle(const TextStyle& style) override; + virtual void Pop() override; + virtual const TextStyle& PeekStyle() override; + virtual void AddText(const std::u16string& text) override; + virtual void AddPlaceholder(PlaceholderRun& span) override; + virtual std::unique_ptr Build() override; + + private: + std::vector text_; + // A vector of PlaceholderRuns, which detail the sizes, positioning and break + // behavior of the empty spaces to leave. Each placeholder span corresponds to + // a 0xFFFC (object replacement character) in text_, which indicates the + // position in the text where the placeholder will occur. There should be an + // equal number of 0xFFFC characters and elements in this vector. + std::vector inline_placeholders_; + // The indexes of the obj replacement characters added through + // ParagraphBuilder::addPlaceholder(). + std::unordered_set obj_replacement_char_indexes_; + std::vector style_stack_; + std::shared_ptr font_collection_; + StyledRuns runs_; + ParagraphStyle paragraph_style_; + size_t paragraph_style_index_; + + void SetParagraphStyle(const ParagraphStyle& style); + + size_t PeekStyleIndex() const; +}; + +} // namespace txt + +#endif // LIB_TXT_SRC_PARAGRAPH_BUILDER_TXT_H_ diff --git a/third_party/txt/src/txt/paragraph.cc b/third_party/txt/src/txt/paragraph_txt.cc similarity index 94% rename from third_party/txt/src/txt/paragraph.cc rename to third_party/txt/src/txt/paragraph_txt.cc index cdd3968c1269c..50fe8bb2109eb 100644 --- a/third_party/txt/src/txt/paragraph.cc +++ b/third_party/txt/src/txt/paragraph_txt.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "paragraph.h" +#include "paragraph_txt.h" #include #include @@ -190,27 +190,27 @@ void FindWords(const std::vector& text, static const float kDoubleDecorationSpacing = 3.0f; -Paragraph::GlyphPosition::GlyphPosition(double x_start, - double x_advance, - size_t code_unit_index, - size_t code_unit_width) +ParagraphTxt::GlyphPosition::GlyphPosition(double x_start, + double x_advance, + size_t code_unit_index, + size_t code_unit_width) : code_units(code_unit_index, code_unit_index + code_unit_width), x_pos(x_start, x_start + x_advance) {} -void Paragraph::GlyphPosition::Shift(double delta) { +void ParagraphTxt::GlyphPosition::Shift(double delta) { x_pos.Shift(delta); } -Paragraph::GlyphLine::GlyphLine(std::vector&& p, size_t tcu) +ParagraphTxt::GlyphLine::GlyphLine(std::vector&& p, size_t tcu) : positions(std::move(p)), total_code_units(tcu) {} -Paragraph::CodeUnitRun::CodeUnitRun(std::vector&& p, - Range cu, - Range x, - size_t line, - const SkFontMetrics& metrics, - TextDirection dir, - const PlaceholderRun* placeholder) +ParagraphTxt::CodeUnitRun::CodeUnitRun(std::vector&& p, + Range cu, + Range x, + size_t line, + const SkFontMetrics& metrics, + TextDirection dir, + const PlaceholderRun* placeholder) : positions(std::move(p)), code_units(cu), x_pos(x), @@ -219,19 +219,19 @@ Paragraph::CodeUnitRun::CodeUnitRun(std::vector&& p, direction(dir), placeholder_run(placeholder) {} -void Paragraph::CodeUnitRun::Shift(double delta) { +void ParagraphTxt::CodeUnitRun::Shift(double delta) { x_pos.Shift(delta); for (GlyphPosition& position : positions) position.Shift(delta); } -Paragraph::Paragraph() { +ParagraphTxt::ParagraphTxt() { breaker_.setLocale(icu::Locale(), nullptr); } -Paragraph::~Paragraph() = default; +ParagraphTxt::~ParagraphTxt() = default; -void Paragraph::SetText(std::vector text, StyledRuns runs) { +void ParagraphTxt::SetText(std::vector text, StyledRuns runs) { needs_layout_ = true; if (text.size() == 0) return; @@ -239,7 +239,7 @@ void Paragraph::SetText(std::vector text, StyledRuns runs) { runs_ = std::move(runs); } -void Paragraph::SetInlinePlaceholders( +void ParagraphTxt::SetInlinePlaceholders( std::vector inline_placeholders, std::unordered_set obj_replacement_char_indexes) { needs_layout_ = true; @@ -247,7 +247,7 @@ void Paragraph::SetInlinePlaceholders( obj_replacement_char_indexes_ = std::move(obj_replacement_char_indexes); } -bool Paragraph::ComputeLineBreaks() { +bool ParagraphTxt::ComputeLineBreaks() { line_ranges_.clear(); line_widths_.clear(); max_intrinsic_width_ = 0; @@ -379,7 +379,7 @@ bool Paragraph::ComputeLineBreaks() { return true; } -bool Paragraph::ComputeBidiRuns(std::vector* result) { +bool ParagraphTxt::ComputeBidiRuns(std::vector* result) { if (text_.empty()) return true; @@ -496,13 +496,13 @@ bool Paragraph::ComputeBidiRuns(std::vector* result) { return true; } -bool Paragraph::IsStrutValid() const { +bool ParagraphTxt::IsStrutValid() const { // Font size must be positive. return (paragraph_style_.strut_enabled && paragraph_style_.strut_font_size >= 0); } -void Paragraph::ComputeStrut(StrutMetrics* strut, SkFont& font) { +void ParagraphTxt::ComputeStrut(StrutMetrics* strut, SkFont& font) { strut->ascent = 0; strut->descent = 0; strut->leading = 0; @@ -567,9 +567,9 @@ void Paragraph::ComputeStrut(StrutMetrics* strut, SkFont& font) { } } -void Paragraph::ComputePlaceholder(PlaceholderRun* placeholder_run, - double& ascent, - double& descent) { +void ParagraphTxt::ComputePlaceholder(PlaceholderRun* placeholder_run, + double& ascent, + double& descent) { if (placeholder_run != nullptr) { // Calculate how much to shift the ascent and descent to account // for the baseline choice. @@ -641,10 +641,10 @@ void Paragraph::ComputePlaceholder(PlaceholderRun* placeholder_run, // -Apply letter spacing, alignment, justification, etc // -Calculate line vertical layout (ascent, descent, etc) // -Store per-line metrics -void Paragraph::Layout(double width, bool force) { +void ParagraphTxt::Layout(double width) { double rounded_width = floor(width); // Do not allow calling layout multiple times without changing anything. - if (!needs_layout_ && rounded_width == width_ && !force) { + if (!needs_layout_ && rounded_width == width_) { return; } @@ -1174,7 +1174,7 @@ void Paragraph::Layout(double width, bool force) { longest_line_ = max_right_ - min_left_; } -double Paragraph::GetLineXOffset(double line_total_advance) { +double ParagraphTxt::GetLineXOffset(double line_total_advance) { if (isinf(width_)) return 0; @@ -1189,56 +1189,56 @@ double Paragraph::GetLineXOffset(double line_total_advance) { } } -const ParagraphStyle& Paragraph::GetParagraphStyle() const { +const ParagraphStyle& ParagraphTxt::GetParagraphStyle() const { return paragraph_style_; } -double Paragraph::GetAlphabeticBaseline() const { +double ParagraphTxt::GetAlphabeticBaseline() { // Currently -fAscent return alphabetic_baseline_; } -double Paragraph::GetIdeographicBaseline() const { +double ParagraphTxt::GetIdeographicBaseline() { // TODO(garyq): Currently -fAscent + fUnderlinePosition. Verify this. return ideographic_baseline_; } -double Paragraph::GetMaxIntrinsicWidth() const { +double ParagraphTxt::GetMaxIntrinsicWidth() { return max_intrinsic_width_; } -double Paragraph::GetMinIntrinsicWidth() const { +double ParagraphTxt::GetMinIntrinsicWidth() { return min_intrinsic_width_; } -size_t Paragraph::TextSize() const { +size_t ParagraphTxt::TextSize() const { return text_.size(); } -double Paragraph::GetHeight() const { +double ParagraphTxt::GetHeight() { return line_heights_.size() ? line_heights_.back() : 0; } -double Paragraph::GetMaxWidth() const { +double ParagraphTxt::GetMaxWidth() { return width_; } -double Paragraph::GetLongestLine() const { +double ParagraphTxt::GetLongestLine() { return longest_line_; } -void Paragraph::SetParagraphStyle(const ParagraphStyle& style) { +void ParagraphTxt::SetParagraphStyle(const ParagraphStyle& style) { needs_layout_ = true; paragraph_style_ = style; } -void Paragraph::SetFontCollection( +void ParagraphTxt::SetFontCollection( std::shared_ptr font_collection) { font_collection_ = std::move(font_collection); } std::shared_ptr -Paragraph::GetMinikinFontCollectionForStyle(const TextStyle& style) { +ParagraphTxt::GetMinikinFontCollectionForStyle(const TextStyle& style) { std::string locale; if (!style.locale.empty()) { uint32_t language_list_id = @@ -1254,7 +1254,7 @@ Paragraph::GetMinikinFontCollectionForStyle(const TextStyle& style) { style.font_families, locale); } -sk_sp Paragraph::GetDefaultSkiaTypeface(const TextStyle& style) { +sk_sp ParagraphTxt::GetDefaultSkiaTypeface(const TextStyle& style) { std::shared_ptr collection = GetMinikinFontCollectionForStyle(style); if (!collection) { @@ -1267,7 +1267,7 @@ sk_sp Paragraph::GetDefaultSkiaTypeface(const TextStyle& style) { // The x,y coordinates will be the very top left corner of the rendered // paragraph. -void Paragraph::Paint(SkCanvas* canvas, double x, double y) { +void ParagraphTxt::Paint(SkCanvas* canvas, double x, double y) { SkPoint base_offset = SkPoint::Make(x, y); SkPaint paint; // Paint the background first before painting any text to prevent @@ -1291,9 +1291,9 @@ void Paragraph::Paint(SkCanvas* canvas, double x, double y) { } } -void Paragraph::PaintDecorations(SkCanvas* canvas, - const PaintRecord& record, - SkPoint base_offset) { +void ParagraphTxt::PaintDecorations(SkCanvas* canvas, + const PaintRecord& record, + SkPoint base_offset) { if (record.style().decoration == TextDecoration::kNone) return; @@ -1443,11 +1443,11 @@ void Paragraph::PaintDecorations(SkCanvas* canvas, } } -void Paragraph::ComputeWavyDecoration(SkPath& path, - double x, - double y, - double width, - double thickness) { +void ParagraphTxt::ComputeWavyDecoration(SkPath& path, + double x, + double y, + double width, + double thickness) { int wave_count = 0; double x_start = 0; // One full wavelength is 4 * thickness. @@ -1485,9 +1485,9 @@ void Paragraph::ComputeWavyDecoration(SkPath& path, path.rQuadTo(x1, y1, x2, y2); } -void Paragraph::PaintBackground(SkCanvas* canvas, - const PaintRecord& record, - SkPoint base_offset) { +void ParagraphTxt::PaintBackground(SkCanvas* canvas, + const PaintRecord& record, + SkPoint base_offset) { if (!record.style().has_background) return; @@ -1498,9 +1498,9 @@ void Paragraph::PaintBackground(SkCanvas* canvas, canvas->drawRect(rect, record.style().background); } -void Paragraph::PaintShadow(SkCanvas* canvas, - const PaintRecord& record, - SkPoint offset) { +void ParagraphTxt::PaintShadow(SkCanvas* canvas, + const PaintRecord& record, + SkPoint offset) { if (record.style().text_shadows.size() == 0) return; for (TextShadow text_shadow : record.style().text_shadows) { @@ -1519,11 +1519,11 @@ void Paragraph::PaintShadow(SkCanvas* canvas, } } -std::vector Paragraph::GetRectsForRange( +std::vector ParagraphTxt::GetRectsForRange( size_t start, size_t end, RectHeightStyle rect_height_style, - RectWidthStyle rect_width_style) const { + RectWidthStyle rect_width_style) { // Struct that holds calculated metrics for each line. struct LineBoxMetrics { std::vector boxes; @@ -1742,9 +1742,9 @@ std::vector Paragraph::GetRectsForRange( return boxes; } -Paragraph::PositionWithAffinity Paragraph::GetGlyphPositionAtCoordinate( +Paragraph::PositionWithAffinity ParagraphTxt::GetGlyphPositionAtCoordinate( double dx, - double dy) const { + double dy) { if (line_heights_.empty()) return PositionWithAffinity(0, DOWNSTREAM); @@ -1803,7 +1803,7 @@ Paragraph::PositionWithAffinity Paragraph::GetGlyphPositionAtCoordinate( // We don't cache this because since this returns all boxes, it is usually // unnecessary to call this multiple times in succession. -std::vector Paragraph::GetRectsForPlaceholders() const { +std::vector ParagraphTxt::GetRectsForPlaceholders() { // Struct that holds calculated metrics for each line. struct LineBoxMetrics { std::vector boxes; @@ -1841,7 +1841,7 @@ std::vector Paragraph::GetRectsForPlaceholders() const { return boxes; } -Paragraph::Range Paragraph::GetWordBoundary(size_t offset) const { +Paragraph::Range ParagraphTxt::GetWordBoundary(size_t offset) { if (text_.size() == 0) return Range(0, 0); @@ -1864,15 +1864,15 @@ Paragraph::Range Paragraph::GetWordBoundary(size_t offset) const { return Range(prev_boundary, next_boundary); } -size_t Paragraph::GetLineCount() const { +size_t ParagraphTxt::GetLineCount() { return line_heights_.size(); } -bool Paragraph::DidExceedMaxLines() const { +bool ParagraphTxt::DidExceedMaxLines() { return did_exceed_max_lines_; } -void Paragraph::SetDirty(bool dirty) { +void ParagraphTxt::SetDirty(bool dirty) { needs_layout_ = dirty; } diff --git a/third_party/txt/src/txt/paragraph_txt.h b/third_party/txt/src/txt/paragraph_txt.h new file mode 100644 index 0000000000000..b049902b55b60 --- /dev/null +++ b/third_party/txt/src/txt/paragraph_txt.h @@ -0,0 +1,400 @@ +/* + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIB_TXT_SRC_PARAGRAPH_TXT_H_ +#define LIB_TXT_SRC_PARAGRAPH_TXT_H_ + +#include +#include +#include + +#include "flutter/fml/compiler_specific.h" +#include "flutter/fml/macros.h" +#include "font_collection.h" +#include "minikin/LineBreaker.h" +#include "paint_record.h" +#include "paragraph.h" +#include "paragraph_style.h" +#include "placeholder_run.h" +#include "styled_runs.h" +#include "third_party/googletest/googletest/include/gtest/gtest_prod.h" // nogncheck +#include "third_party/skia/include/core/SkFontMetrics.h" +#include "third_party/skia/include/core/SkRect.h" +#include "utils/WindowsUtils.h" + +namespace txt { + +using GlyphID = uint32_t; + +// Constant with the unicode codepoint for the "Object replacement character". +// Used as a stand-in character for Placeholder boxes. +const int objReplacementChar = 0xFFFC; +// Constant with the unicode codepoint for the "Replacement character". This is +// the character that commonly renders as a black diamond with a white question +// mark. Used to replace non-placeholder instances of 0xFFFC in the text buffer. +const int replacementChar = 0xFFFD; + +// Paragraph provides Layout, metrics, and painting capabilities for text. Once +// a Paragraph is constructed with ParagraphBuilder::Build(), an example basic +// workflow can be this: +// +// std::unique_ptr paragraph = paragraph_builder.Build(); +// paragraph->Layout(); +// paragraph->Paint(, , ); +class ParagraphTxt : public Paragraph { + public: + // Constructor. It is highly recommended to construct a paragraph with a + // ParagraphBuilder. + ParagraphTxt(); + + virtual ~ParagraphTxt(); + + // Minikin Layout doLayout() and LineBreaker addStyleRun() has an + // O(N^2) (according to benchmarks) time complexity where N is the total + // number of characters. However, this is not significant for reasonably sized + // paragraphs. It is currently recommended to break up very long paragraphs + // (10k+ characters) to ensure speedy layout. + virtual void Layout(double width) override; + + virtual void Paint(SkCanvas* canvas, double x, double y) override; + + // Getter for paragraph_style_. + const ParagraphStyle& GetParagraphStyle() const; + + // Returns the number of characters/unicode characters. AKA text_.size() + size_t TextSize() const; + + double GetHeight() override; + + double GetMaxWidth() override; + + double GetLongestLine() override; + + double GetAlphabeticBaseline() override; + + double GetIdeographicBaseline() override; + + double GetMaxIntrinsicWidth() override; + + // Currently, calculated similarly to as GetLayoutWidth(), however this is not + // necessarily 100% correct in all cases. + double GetMinIntrinsicWidth() override; + + std::vector GetRectsForRange( + size_t start, + size_t end, + RectHeightStyle rect_height_style, + RectWidthStyle rect_width_style) override; + + PositionWithAffinity GetGlyphPositionAtCoordinate(double dx, + double dy) override; + + std::vector GetRectsForPlaceholders() override; + + Range GetWordBoundary(size_t offset) override; + + // Returns the number of lines the paragraph takes up. If the text exceeds the + // amount width and maxlines provides, Layout() truncates the extra text from + // the layout and this will return the max lines allowed. + size_t GetLineCount(); + + bool DidExceedMaxLines() override; + + // Sets the needs_layout_ to dirty. When Layout() is called, a new Layout will + // be performed when this is set to true. Can also be used to prevent a new + // Layout from being calculated by setting to false. + void SetDirty(bool dirty = true); + + private: + friend class ParagraphBuilderTxt; + FRIEND_TEST(ParagraphTest, SimpleParagraph); + FRIEND_TEST(ParagraphTest, SimpleRedParagraph); + FRIEND_TEST(ParagraphTest, RainbowParagraph); + FRIEND_TEST(ParagraphTest, DefaultStyleParagraph); + FRIEND_TEST(ParagraphTest, BoldParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, LeftAlignParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, RightAlignParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, CenterAlignParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyAlignParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyRTL); + FRIEND_TEST(ParagraphTest, DecorationsParagraph); + FRIEND_TEST(ParagraphTest, ItalicsParagraph); + FRIEND_TEST(ParagraphTest, ChineseParagraph); + FRIEND_TEST(ParagraphTest, DISABLED_ArabicParagraph); + FRIEND_TEST(ParagraphTest, SpacingParagraph); + FRIEND_TEST(ParagraphTest, LongWordParagraph); + FRIEND_TEST(ParagraphTest, KernScaleParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, NewlineParagraph); + FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, EmojiParagraph); + FRIEND_TEST(ParagraphTest, HyphenBreakParagraph); + FRIEND_TEST(ParagraphTest, RepeatLayoutParagraph); + FRIEND_TEST(ParagraphTest, Ellipsize); + FRIEND_TEST(ParagraphTest, UnderlineShiftParagraph); + FRIEND_TEST(ParagraphTest, WavyDecorationParagraph); + FRIEND_TEST(ParagraphTest, SimpleShadow); + FRIEND_TEST(ParagraphTest, ComplexShadow); + FRIEND_TEST(ParagraphTest, FontFallbackParagraph); + FRIEND_TEST(ParagraphTest, InlinePlaceholder0xFFFCParagraph); + FRIEND_TEST(ParagraphTest, FontFeaturesParagraph); + + // Starting data to layout. + std::vector text_; + // A vector of PlaceholderRuns, which detail the sizes, positioning and break + // behavior of the empty spaces to leave. Each placeholder span corresponds to + // a 0xFFFC (object replacement character) in text_, which indicates the + // position in the text where the placeholder will occur. There should be an + // equal number of 0xFFFC characters and elements in this vector. + std::vector inline_placeholders_; + // The indexes of the boxes that correspond to an inline placeholder. + std::vector inline_placeholder_boxes_; + // The indexes of instances of 0xFFFC that correspond to placeholders. This is + // necessary since the user may pass in manually entered 0xFFFC values using + // AddText(). + std::unordered_set obj_replacement_char_indexes_; + StyledRuns runs_; + ParagraphStyle paragraph_style_; + std::shared_ptr font_collection_; + + minikin::LineBreaker breaker_; + mutable std::unique_ptr word_breaker_; + + struct LineRange { + LineRange(size_t s, size_t e, size_t eew, size_t ein, bool h) + : start(s), + end(e), + end_excluding_whitespace(eew), + end_including_newline(ein), + hard_break(h) {} + size_t start, end; + size_t end_excluding_whitespace; + size_t end_including_newline; + bool hard_break; + }; + std::vector line_ranges_; + std::vector line_widths_; + + // Stores the result of Layout(). + std::vector records_; + + std::vector line_heights_; + std::vector line_baselines_; + bool did_exceed_max_lines_; + + // Strut metrics of zero will have no effect on the layout. + struct StrutMetrics { + double ascent = 0; // Positive value to keep signs clear. + double descent = 0; + double leading = 0; + double half_leading = 0; + double line_height = 0; + bool force_strut = false; + }; + + StrutMetrics strut_; + + // Metrics for use in GetRectsForRange(...); + // Per-line max metrics over all runs in a given line. + std::vector line_max_spacings_; + std::vector line_max_descent_; + std::vector line_max_ascent_; + // Overall left and right extremes over all lines. + double max_right_; + double min_left_; + + class BidiRun { + public: + // Constructs a BidiRun with is_ghost defaulted to false. + BidiRun(size_t s, size_t e, TextDirection d, const TextStyle& st) + : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(false) {} + + // Constructs a BidiRun with a custom is_ghost flag. + BidiRun(size_t s, + size_t e, + TextDirection d, + const TextStyle& st, + bool is_ghost) + : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(is_ghost) {} + + // Constructs a placeholder bidi run. + BidiRun(size_t s, + size_t e, + TextDirection d, + const TextStyle& st, + PlaceholderRun& placeholder) + : start_(s), + end_(e), + direction_(d), + style_(&st), + placeholder_run_(&placeholder) {} + + size_t start() const { return start_; } + size_t end() const { return end_; } + size_t size() const { return end_ - start_; } + TextDirection direction() const { return direction_; } + const TextStyle& style() const { return *style_; } + PlaceholderRun* placeholder_run() const { return placeholder_run_; } + bool is_rtl() const { return direction_ == TextDirection::rtl; } + // Tracks if the run represents trailing whitespace. + bool is_ghost() const { return is_ghost_; } + bool is_placeholder_run() const { return placeholder_run_ != nullptr; } + + private: + size_t start_, end_; + TextDirection direction_; + const TextStyle* style_; + bool is_ghost_; + PlaceholderRun* placeholder_run_ = nullptr; + }; + + struct GlyphPosition { + Range code_units; + Range x_pos; + + GlyphPosition(double x_start, + double x_advance, + size_t code_unit_index, + size_t code_unit_width); + + void Shift(double delta); + }; + + struct GlyphLine { + // Glyph positions sorted by x coordinate. + const std::vector positions; + const size_t total_code_units; + + GlyphLine(std::vector&& p, size_t tcu); + }; + + struct CodeUnitRun { + // Glyph positions sorted by code unit index. + std::vector positions; + Range code_units; + Range x_pos; + size_t line_number; + SkFontMetrics font_metrics; + TextDirection direction; + const PlaceholderRun* placeholder_run; + + CodeUnitRun(std::vector&& p, + Range cu, + Range x, + size_t line, + const SkFontMetrics& metrics, + TextDirection dir, + const PlaceholderRun* placeholder); + + void Shift(double delta); + }; + + // Holds the laid out x positions of each glyph. + std::vector glyph_lines_; + + // Holds the positions of each range of code units in the text. + // Sorted in code unit index order. + std::vector code_unit_runs_; + // Holds the positions of the inline placeholders. + std::vector inline_placeholder_code_unit_runs_; + + // The max width of the paragraph as provided in the most recent Layout() + // call. + double width_ = -1.0f; + double longest_line_ = -1.0f; + double max_intrinsic_width_ = 0; + double min_intrinsic_width_ = 0; + double alphabetic_baseline_ = FLT_MAX; + double ideographic_baseline_ = FLT_MAX; + + bool needs_layout_ = true; + + struct WaveCoordinates { + double x_start; + double y_start; + double x_end; + double y_end; + + WaveCoordinates(double x_s, double y_s, double x_e, double y_e) + : 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 text, StyledRuns runs); + + void SetParagraphStyle(const ParagraphStyle& style); + + void SetFontCollection(std::shared_ptr font_collection); + + void SetInlinePlaceholders( + std::vector inline_placeholders, + std::unordered_set obj_replacement_char_indexes); + + // Break the text into lines. + bool ComputeLineBreaks(); + + // Break the text into runs based on LTR/RTL text direction. + bool ComputeBidiRuns(std::vector* result); + + // Calculates and populates strut based on paragraph_style_ strut info. + void ComputeStrut(StrutMetrics* strut, SkFont& font); + + // Adjusts the ascent and descent based on the existence and type of + // placeholder. This method sets the proper metrics to achieve the different + // PlaceholderAlignment options. + void ComputePlaceholder(PlaceholderRun* placeholder_run, + double& ascent, + double& descent); + + bool IsStrutValid() const; + + // Calculate the starting X offset of a line based on the line's width and + // alignment. + double GetLineXOffset(double line_total_advance); + + // Creates and draws the decorations onto the canvas. + void PaintDecorations(SkCanvas* canvas, + const PaintRecord& record, + SkPoint base_offset); + + // Computes the beziers for a wavy decoration. The results will be + // applied to path. + void ComputeWavyDecoration(SkPath& path, + double x, + double y, + double width, + double thickness); + + // Draws the background onto the canvas. + void PaintBackground(SkCanvas* canvas, + const PaintRecord& record, + SkPoint base_offset); + + // Draws the shadows onto the canvas. + void PaintShadow(SkCanvas* canvas, const PaintRecord& record, SkPoint offset); + + // Obtain a Minikin font collection matching this text style. + std::shared_ptr GetMinikinFontCollectionForStyle( + const TextStyle& style); + + // Get a default SkTypeface for a text style. + sk_sp GetDefaultSkiaTypeface(const TextStyle& style); + + FML_DISALLOW_COPY_AND_ASSIGN(ParagraphTxt); +}; + +} // namespace txt + +#endif // LIB_TXT_SRC_PARAGRAPH_TXT_H_ diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 07b53f4c19cd6..69ad4e5f10d7a 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -23,8 +23,8 @@ #include "third_party/skia/include/core/SkPath.h" #include "txt/font_style.h" #include "txt/font_weight.h" -#include "txt/paragraph.h" -#include "txt/paragraph_builder.h" +#include "txt/paragraph_builder_txt.h" +#include "txt/paragraph_txt.h" #include "txt/placeholder_run.h" #include "txt_test_utils.h" @@ -41,7 +41,7 @@ TEST_F(ParagraphTest, SimpleParagraph) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; // We must supply a font here, as the default is Arial, and we do not @@ -55,7 +55,7 @@ TEST_F(ParagraphTest, SimpleParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -79,7 +79,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -129,7 +129,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -204,7 +204,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBaselineParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -227,7 +227,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBaselineParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -279,7 +279,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -303,7 +303,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -355,7 +355,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -379,7 +379,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -430,7 +430,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBottomParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -453,7 +453,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBottomParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -504,7 +504,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderTopParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -527,7 +527,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderTopParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -578,7 +578,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderMiddleParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -601,7 +601,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderMiddleParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -653,7 +653,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Source Han Serif CN"); @@ -676,7 +676,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -727,7 +727,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBreakParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -809,7 +809,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderBreakParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -882,7 +882,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderGetRectsParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -954,7 +954,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholderGetRectsParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -1032,7 +1032,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholder0xFFFCParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1075,7 +1075,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(InlinePlaceholder0xFFFCParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -1120,7 +1120,7 @@ TEST_F(ParagraphTest, SimpleRedParagraph) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1131,7 +1131,7 @@ TEST_F(ParagraphTest, SimpleRedParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -1174,7 +1174,7 @@ TEST_F(ParagraphTest, RainbowParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 2; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style1; text_style1.font_families = std::vector(1, "Roboto"); @@ -1223,7 +1223,7 @@ TEST_F(ParagraphTest, RainbowParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -1253,13 +1253,13 @@ TEST_F(ParagraphTest, DefaultStyleParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.font_family = "Roboto"; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); builder.AddText(u16_text); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -1280,7 +1280,7 @@ TEST_F(ParagraphTest, BoldParagraph) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1294,7 +1294,7 @@ TEST_F(ParagraphTest, BoldParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 60.0); @@ -1331,7 +1331,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(HeightOverrideParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1347,7 +1347,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(HeightOverrideParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -1410,7 +1410,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(LeftAlignParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1427,7 +1427,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(LeftAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -1507,7 +1507,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(RightAlignParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::right; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1524,7 +1524,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(RightAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); int available_width = GetTestCanvasWidth() - 100; paragraph->Layout(available_width); @@ -1626,7 +1626,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(CenterAlignParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::center; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1643,7 +1643,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(CenterAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -1735,7 +1735,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyAlignParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::justify; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1752,7 +1752,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -1812,7 +1812,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyRTL)) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::justify; paragraph_style.text_direction = TextDirection::rtl; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Ahem"); @@ -1825,7 +1825,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(JustifyRTL)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); size_t paragraph_width = GetTestCanvasWidth() - 100; paragraph->Layout(paragraph_width); @@ -1871,7 +1871,7 @@ TEST_F(ParagraphTest, DecorationsParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1915,7 +1915,7 @@ TEST_F(ParagraphTest, DecorationsParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -1968,7 +1968,7 @@ TEST_F(ParagraphTest, WavyDecorationParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -1990,7 +1990,7 @@ TEST_F(ParagraphTest, WavyDecorationParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2104,7 +2104,7 @@ TEST_F(ParagraphTest, WavyDecorationParagraph) { TEST_F(ParagraphTest, ItalicsParagraph) { txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -2120,7 +2120,7 @@ TEST_F(ParagraphTest, ItalicsParagraph) { builder.Pop(); builder.AddText(u"No Italic again."); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -2148,7 +2148,7 @@ TEST_F(ParagraphTest, ChineseParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::justify; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.color = SK_ColorBLACK; @@ -2166,7 +2166,7 @@ TEST_F(ParagraphTest, ChineseParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2193,7 +2193,7 @@ TEST_F(ParagraphTest, DISABLED_ArabicParagraph) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::right; paragraph_style.text_direction = TextDirection::rtl; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.color = SK_ColorBLACK; @@ -2211,7 +2211,7 @@ TEST_F(ParagraphTest, DISABLED_ArabicParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2244,7 +2244,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsParagraph)) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::right; paragraph_style.text_direction = TextDirection::rtl; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Noto Naskh Arabic"); @@ -2261,7 +2261,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2312,7 +2312,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsLTRLeftAlignParagraph)) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::left; paragraph_style.text_direction = TextDirection::ltr; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Noto Naskh Arabic"); @@ -2329,7 +2329,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsLTRLeftAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2375,7 +2375,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsLTRRightAlignParagraph)) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::right; paragraph_style.text_direction = TextDirection::ltr; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Noto Naskh Arabic"); @@ -2392,7 +2392,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(ArabicRectsLTRRightAlignParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -2442,7 +2442,7 @@ TEST_F(ParagraphTest, GetGlyphPositionAtCoordinateParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -2457,7 +2457,7 @@ TEST_F(ParagraphTest, GetGlyphPositionAtCoordinateParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -2510,7 +2510,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -2526,7 +2526,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -2640,7 +2640,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeTight)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Noto Sans CJK JP"); @@ -2656,7 +2656,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeTight)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -2731,7 +2731,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -2748,7 +2748,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -2880,7 +2880,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -2897,7 +2897,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3029,7 +3029,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3046,7 +3046,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3174,7 +3174,7 @@ TEST_F(ParagraphTest, GetRectsForRangeIncludeCombiningCharacter) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3189,7 +3189,7 @@ TEST_F(ParagraphTest, GetRectsForRangeIncludeCombiningCharacter) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -3261,7 +3261,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeCenterParagraph)) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::center; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3277,7 +3277,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeCenterParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3368,7 +3368,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::center; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3384,7 +3384,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3446,7 +3446,7 @@ TEST_F(ParagraphTest, txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::center; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3462,7 +3462,7 @@ TEST_F(ParagraphTest, builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3578,7 +3578,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrut)) { paragraph_style.strut_enabled = true; paragraph_style.strut_font_families.push_back("Roboto"); paragraph_style.strut_font_size = 14; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families.push_back("Noto Sans CJK JP"); @@ -3590,7 +3590,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrut)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3635,7 +3635,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrutFallback)) { txt::ParagraphStyle paragraph_style; paragraph_style.strut_enabled = false; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families.push_back("Noto Sans CJK JP"); @@ -3646,7 +3646,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrutFallback)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); std::vector strut_boxes = @@ -3661,8 +3661,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeStrutFallback)) { ASSERT_EQ(strut_boxes.front().rect, tight_boxes.front().rect); } -SkRect GetCoordinatesForGlyphPosition(const txt::Paragraph& paragraph, - size_t pos) { +SkRect GetCoordinatesForGlyphPosition(txt::Paragraph& paragraph, size_t pos) { std::vector boxes = paragraph.GetRectsForRange(pos, pos + 1, Paragraph::RectHeightStyle::kMax, Paragraph::RectWidthStyle::kTight); @@ -3680,7 +3679,7 @@ TEST_F(ParagraphTest, GetWordBoundaryParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3696,7 +3695,7 @@ TEST_F(ParagraphTest, GetWordBoundaryParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3787,7 +3786,7 @@ TEST_F(ParagraphTest, SpacingParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 10; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3842,7 +3841,7 @@ TEST_F(ParagraphTest, SpacingParagraph) { builder.AddText(u"H "); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -3876,7 +3875,7 @@ TEST_F(ParagraphTest, LongWordParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3890,7 +3889,7 @@ TEST_F(ParagraphTest, LongWordParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() / 2); paragraph->Paint(GetCanvas(), 0, 0); @@ -3913,7 +3912,7 @@ TEST_F(ParagraphTest, KernScaleParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Droid Serif"); @@ -3936,7 +3935,7 @@ TEST_F(ParagraphTest, KernScaleParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() / scale); GetCanvas()->scale(scale, scale); paragraph->Paint(GetCanvas(), 0, 0); @@ -3955,7 +3954,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(NewlineParagraph)) { paragraph_style.font_family = "Roboto"; paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -3971,7 +3970,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(NewlineParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 300); paragraph->Paint(GetCanvas(), 0, 0); @@ -4001,7 +4000,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(EmojiParagraph)) { txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.color = SK_ColorBLACK; @@ -4013,7 +4012,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(EmojiParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -4046,7 +4045,7 @@ TEST_F(ParagraphTest, HyphenBreakParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -4060,7 +4059,7 @@ TEST_F(ParagraphTest, HyphenBreakParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() / 2); paragraph->Paint(GetCanvas(), 0, 0); @@ -4090,7 +4089,7 @@ TEST_F(ParagraphTest, RepeatLayoutParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.break_strategy = minikin::kBreakStrategy_HighQuality; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -4105,7 +4104,7 @@ TEST_F(ParagraphTest, RepeatLayoutParagraph) { builder.Pop(); // First Layout. - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(300); paragraph->Paint(GetCanvas(), 0, 0); @@ -4150,7 +4149,7 @@ TEST_F(ParagraphTest, Ellipsize) { txt::ParagraphStyle paragraph_style; paragraph_style.ellipsis = u"\u2026"; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -4160,7 +4159,7 @@ TEST_F(ParagraphTest, Ellipsize) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); @@ -4191,7 +4190,7 @@ TEST_F(ParagraphTest, UnderlineShiftParagraph) { txt::ParagraphStyle paragraph_style; paragraph_style.max_lines = 2; paragraph_style.text_align = TextAlign::left; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style1; text_style1.color = SK_ColorBLACK; @@ -4212,7 +4211,7 @@ TEST_F(ParagraphTest, UnderlineShiftParagraph) { builder.Pop(); // Construct single run paragraph. - txt::ParagraphBuilder builder2(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder2(paragraph_style, GetTestFontCollection()); builder2.PushStyle(text_style1); @@ -4221,13 +4220,13 @@ TEST_F(ParagraphTest, UnderlineShiftParagraph) { builder2.Pop(); // Build multi-run paragraph - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 0, 0); // Build single-run paragraph - auto paragraph2 = builder2.Build(); + auto paragraph2 = BuildParagraph(builder2); paragraph2->Layout(GetTestCanvasWidth()); paragraph2->Paint(GetCanvas(), 0, 25); @@ -4261,7 +4260,7 @@ TEST_F(ParagraphTest, SimpleShadow) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -4273,7 +4272,7 @@ TEST_F(ParagraphTest, SimpleShadow) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -4300,7 +4299,7 @@ TEST_F(ParagraphTest, ComplexShadow) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -4330,7 +4329,7 @@ TEST_F(ParagraphTest, ComplexShadow) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -4375,7 +4374,7 @@ TEST_F(ParagraphTest, BaselineParagraph) { paragraph_style.max_lines = 14; paragraph_style.text_align = TextAlign::justify; paragraph_style.height = 1.5; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.color = SK_ColorBLACK; @@ -4390,7 +4389,7 @@ TEST_F(ParagraphTest, BaselineParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth() - 100); paragraph->Paint(GetCanvas(), 0, 0); @@ -4430,7 +4429,7 @@ TEST_F(ParagraphTest, FontFallbackParagraph) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; // No chinese fallback provided, should not be able to render the chinese. @@ -4475,7 +4474,7 @@ TEST_F(ParagraphTest, FontFallbackParagraph) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -4523,7 +4522,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph1)) { paragraph_style.strut_leading = 0.1; paragraph_style.strut_enabled = true; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "ahem"); @@ -4540,7 +4539,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph1)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -4649,7 +4648,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph2)) { paragraph_style.strut_height = 1.6; paragraph_style.strut_has_height_override = true; paragraph_style.strut_enabled = true; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "ahem"); @@ -4666,7 +4665,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph2)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -4775,7 +4774,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph3)) { paragraph_style.strut_height = 1.2; paragraph_style.strut_has_height_override = true; paragraph_style.strut_enabled = true; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "ahem"); @@ -4792,7 +4791,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutParagraph3)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -4903,7 +4902,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutForceParagraph)) { paragraph_style.strut_leading = 0.1; paragraph_style.force_strut_height = true; paragraph_style.strut_enabled = true; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "ahem"); @@ -4919,7 +4918,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutForceParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -5029,7 +5028,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutDefaultParagraph)) { paragraph_style.strut_leading = 0.1; paragraph_style.force_strut_height = false; paragraph_style.strut_enabled = true; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "ahem"); @@ -5045,7 +5044,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(StrutDefaultParagraph)) { builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(550); paragraph->Paint(GetCanvas(), 0, 0); @@ -5102,7 +5101,7 @@ TEST_F(ParagraphTest, FontFeaturesParagraph) { icu_text.getBuffer() + icu_text.length()); txt::ParagraphStyle paragraph_style; - txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection()); + txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); txt::TextStyle text_style; text_style.font_families = std::vector(1, "Roboto"); @@ -5119,7 +5118,7 @@ TEST_F(ParagraphTest, FontFeaturesParagraph) { builder.Pop(); builder.Pop(); - auto paragraph = builder.Build(); + auto paragraph = BuildParagraph(builder); paragraph->Layout(GetTestCanvasWidth()); paragraph->Paint(GetCanvas(), 10.0, 15.0); @@ -5127,13 +5126,13 @@ TEST_F(ParagraphTest, FontFeaturesParagraph) { ASSERT_EQ(paragraph->glyph_lines_.size(), 3ull); // Tabular numbers should have equal widths. - const txt::Paragraph::GlyphLine& tnum_line = paragraph->glyph_lines_[0]; + const txt::ParagraphTxt::GlyphLine& tnum_line = paragraph->glyph_lines_[0]; ASSERT_EQ(tnum_line.positions.size(), 4ull); EXPECT_FLOAT_EQ(tnum_line.positions[0].x_pos.width(), tnum_line.positions[1].x_pos.width()); // Proportional numbers should have variable widths. - const txt::Paragraph::GlyphLine& pnum_line = paragraph->glyph_lines_[1]; + const txt::ParagraphTxt::GlyphLine& pnum_line = paragraph->glyph_lines_[1]; ASSERT_EQ(pnum_line.positions.size(), 4ull); EXPECT_NE(pnum_line.positions[0].x_pos.width(), pnum_line.positions[1].x_pos.width()); diff --git a/third_party/txt/tests/txt_test_utils.cc b/third_party/txt/tests/txt_test_utils.cc index a7ea4fbb47f29..3dd8d4e940f07 100644 --- a/third_party/txt/tests/txt_test_utils.cc +++ b/third_party/txt/tests/txt_test_utils.cc @@ -118,4 +118,12 @@ std::shared_ptr GetTestFontCollection() { return collection; } +// Build a paragraph and return it as a ParagraphTxt usable by tests that need +// access to ParagraphTxt internals. +std::unique_ptr BuildParagraph( + txt::ParagraphBuilderTxt& builder) { + return std::unique_ptr( + static_cast(builder.Build().release())); +} + } // namespace txt diff --git a/third_party/txt/tests/txt_test_utils.h b/third_party/txt/tests/txt_test_utils.h index ed0844ed9d437..096f8f630a5ce 100644 --- a/third_party/txt/tests/txt_test_utils.h +++ b/third_party/txt/tests/txt_test_utils.h @@ -18,6 +18,8 @@ #include "flutter/fml/command_line.h" #include "txt/font_collection.h" +#include "txt/paragraph_builder_txt.h" +#include "txt/paragraph_txt.h" namespace txt { @@ -31,4 +33,6 @@ void SetCommandLine(fml::CommandLine cmd); std::shared_ptr GetTestFontCollection(); +std::unique_ptr BuildParagraph(ParagraphBuilderTxt& builder); + } // namespace txt diff --git a/tools/gn b/tools/gn index b59ac39ba4b9f..43030a6e203af 100755 --- a/tools/gn +++ b/tools/gn @@ -92,6 +92,7 @@ def to_gn_args(args): gn_args['skia_use_expat'] = args.target_os == 'android' gn_args['skia_use_fontconfig'] = args.enable_fontconfig gn_args['flutter_use_fontconfig'] = args.enable_fontconfig + gn_args['flutter_enable_skshaper'] = args.enable_skshaper gn_args['is_official_build'] = True # Disable Skia test utilities. gn_args['dart_component_kind'] = 'static_library' # Always link Dart in statically. gn_args['is_debug'] = args.unoptimized @@ -306,6 +307,7 @@ def parse_args(args): parser.add_argument('--enable-metal', action='store_true', default=False) parser.add_argument('--enable-fontconfig', action='store_true', default=False) + parser.add_argument('--enable-skshaper', action='store_true', default=False) parser.add_argument('--embedder-for-target', dest='embedder_for_target', action='store_true', default=False)