diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index a0602179f6de4..9be3b1fbbac03 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -43298,6 +43298,12 @@ ORIGIN: ../../../flutter/impeller/toolkit/interop/object.cc + ../../../flutter/L ORIGIN: ../../../flutter/impeller/toolkit/interop/object.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/paint.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/paint.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph_builder.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph_builder.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph_style.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/paragraph_style.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/path.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/path.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/path_builder.cc + ../../../flutter/LICENSE @@ -43308,6 +43314,8 @@ ORIGIN: ../../../flutter/impeller/toolkit/interop/surface.cc + ../../../flutter/ ORIGIN: ../../../flutter/impeller/toolkit/interop/surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/texture.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/texture.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/typography_context.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/typography_context.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/typographer/backends/skia/typeface_skia.cc + ../../../flutter/LICENSE @@ -46168,6 +46176,12 @@ FILE: ../../../flutter/impeller/toolkit/interop/object.cc FILE: ../../../flutter/impeller/toolkit/interop/object.h FILE: ../../../flutter/impeller/toolkit/interop/paint.cc FILE: ../../../flutter/impeller/toolkit/interop/paint.h +FILE: ../../../flutter/impeller/toolkit/interop/paragraph.cc +FILE: ../../../flutter/impeller/toolkit/interop/paragraph.h +FILE: ../../../flutter/impeller/toolkit/interop/paragraph_builder.cc +FILE: ../../../flutter/impeller/toolkit/interop/paragraph_builder.h +FILE: ../../../flutter/impeller/toolkit/interop/paragraph_style.cc +FILE: ../../../flutter/impeller/toolkit/interop/paragraph_style.h FILE: ../../../flutter/impeller/toolkit/interop/path.cc FILE: ../../../flutter/impeller/toolkit/interop/path.h FILE: ../../../flutter/impeller/toolkit/interop/path_builder.cc @@ -46178,6 +46192,8 @@ FILE: ../../../flutter/impeller/toolkit/interop/surface.cc FILE: ../../../flutter/impeller/toolkit/interop/surface.h FILE: ../../../flutter/impeller/toolkit/interop/texture.cc FILE: ../../../flutter/impeller/toolkit/interop/texture.h +FILE: ../../../flutter/impeller/toolkit/interop/typography_context.cc +FILE: ../../../flutter/impeller/toolkit/interop/typography_context.h FILE: ../../../flutter/impeller/tools/malioc.json FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h diff --git a/impeller/toolkit/interop/BUILD.gn b/impeller/toolkit/interop/BUILD.gn index 5fa2fe26d9a73..59a6c816b2da6 100644 --- a/impeller/toolkit/interop/BUILD.gn +++ b/impeller/toolkit/interop/BUILD.gn @@ -4,6 +4,14 @@ import("//flutter/impeller/tools/impeller.gni") +embed_blob("embedded_icu_data") { + symbol_name = "embedded_icu_data" + blob = "//flutter/third_party/icu/flutter/icudtl.dat" + hdr = "$target_gen_dir/embedded_icu_data.h" + cc = "$target_gen_dir/embedded_icu_data.cc" + deps = [] +} + impeller_component("interop") { sources = [ "color_filter.cc", @@ -29,6 +37,12 @@ impeller_component("interop") { "object.h", "paint.cc", "paint.h", + "paragraph.cc", + "paragraph.h", + "paragraph_builder.cc", + "paragraph_builder.h", + "paragraph_style.cc", + "paragraph_style.h", "path.cc", "path.h", "path_builder.cc", @@ -37,16 +51,21 @@ impeller_component("interop") { "surface.h", "texture.cc", "texture.h", + "typography_context.cc", + "typography_context.h", ] - deps = [ + public_deps = [ "../../base", "../../display_list", "../../entity", "../../renderer/backend", "//flutter/display_list", "//flutter/fml", + "//flutter/third_party/txt", ] + + deps = [ ":embedded_icu_data" ] } impeller_component("library") { diff --git a/impeller/toolkit/interop/dl_builder.cc b/impeller/toolkit/interop/dl_builder.cc index b8547f3c464d6..5299c2a04cf17 100644 --- a/impeller/toolkit/interop/dl_builder.cc +++ b/impeller/toolkit/interop/dl_builder.cc @@ -176,4 +176,13 @@ void DisplayListBuilder::DrawTextureRect(const Texture& texture, ); } +void DisplayListBuilder::DrawParagraph(const Paragraph& paragraph, + Point point) { + const auto& handle = paragraph.GetHandle(); + if (!handle) { + return; + } + handle->Paint(&builder_, point.x, point.y); +} + } // namespace impeller::interop diff --git a/impeller/toolkit/interop/dl_builder.h b/impeller/toolkit/interop/dl_builder.h index da790fcff21fd..f2e07d1803367 100644 --- a/impeller/toolkit/interop/dl_builder.h +++ b/impeller/toolkit/interop/dl_builder.h @@ -15,6 +15,7 @@ #include "impeller/toolkit/interop/impeller.h" #include "impeller/toolkit/interop/object.h" #include "impeller/toolkit/interop/paint.h" +#include "impeller/toolkit/interop/paragraph.h" #include "impeller/toolkit/interop/path.h" #include "impeller/toolkit/interop/texture.h" @@ -106,6 +107,8 @@ class DisplayListBuilder final void DrawDisplayList(const DisplayList& dl, Scalar opacity); + void DrawParagraph(const Paragraph& paragraph, Point point); + ScopedObject Build(); private: diff --git a/impeller/toolkit/interop/formats.h b/impeller/toolkit/interop/formats.h index 4acd3a73b2edc..89fa141b12b9d 100644 --- a/impeller/toolkit/interop/formats.h +++ b/impeller/toolkit/interop/formats.h @@ -9,6 +9,9 @@ #include "flutter/display_list/dl_builder.h" #include "flutter/display_list/dl_color.h" +#include "flutter/third_party/txt/src/txt/font_style.h" +#include "flutter/third_party/txt/src/txt/font_weight.h" +#include "flutter/third_party/txt/src/txt/paragraph_style.h" #include "impeller/entity/entity.h" #include "impeller/geometry/color.h" #include "impeller/geometry/matrix.h" @@ -418,6 +421,68 @@ constexpr flutter::DlColor ToDisplayListType(ImpellerColor color) { ); } +constexpr txt::FontWeight ToTxtType(ImpellerFontWeight weight) { + switch (weight) { + case kImpellerFontWeight100: + return txt::FontWeight::w100; + case kImpellerFontWeight200: + return txt::FontWeight::w200; + case kImpellerFontWeight300: + return txt::FontWeight::w300; + case kImpellerFontWeight400: + return txt::FontWeight::w400; + case kImpellerFontWeight500: + return txt::FontWeight::w500; + case kImpellerFontWeight600: + return txt::FontWeight::w600; + case kImpellerFontWeight700: + return txt::FontWeight::w700; + case kImpellerFontWeight800: + return txt::FontWeight::w800; + case kImpellerFontWeight900: + return txt::FontWeight::w900; + } + return txt::FontWeight::w400; +} + +constexpr txt::FontStyle ToTxtType(ImpellerFontStyle style) { + switch (style) { + case kImpellerFontStyleNormal: + return txt::FontStyle::normal; + case kImpellerFontStyleItalic: + return txt::FontStyle::italic; + } + return txt::FontStyle::normal; +} + +constexpr txt::TextAlign ToTxtType(ImpellerTextAlignment align) { + switch (align) { + case kImpellerTextAlignmentLeft: + return txt::TextAlign::left; + case kImpellerTextAlignmentRight: + return txt::TextAlign::right; + case kImpellerTextAlignmentCenter: + return txt::TextAlign::center; + case kImpellerTextAlignmentJustify: + return txt::TextAlign::justify; + case kImpellerTextAlignmentStart: + return txt::TextAlign::start; + case kImpellerTextAlignmentEnd: + return txt::TextAlign::end; + } + return txt::TextAlign::left; +} + +constexpr txt::TextDirection ToTxtType(ImpellerTextDirection direction) { + switch (direction) { + case kImpellerTextDirectionRTL: + return txt::TextDirection::rtl; + case kImpellerTextDirectionLTR: + return txt::TextDirection::ltr; + } + return txt::TextDirection::ltr; +} + } // namespace impeller::interop #endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_FORMATS_H_ diff --git a/impeller/toolkit/interop/impeller.cc b/impeller/toolkit/interop/impeller.cc index e371d27485545..56b0fba1e3e4e 100644 --- a/impeller/toolkit/interop/impeller.cc +++ b/impeller/toolkit/interop/impeller.cc @@ -18,10 +18,14 @@ #include "impeller/toolkit/interop/mask_filter.h" #include "impeller/toolkit/interop/object.h" #include "impeller/toolkit/interop/paint.h" +#include "impeller/toolkit/interop/paragraph.h" +#include "impeller/toolkit/interop/paragraph_builder.h" +#include "impeller/toolkit/interop/paragraph_style.h" #include "impeller/toolkit/interop/path.h" #include "impeller/toolkit/interop/path_builder.h" #include "impeller/toolkit/interop/surface.h" #include "impeller/toolkit/interop/texture.h" +#include "impeller/toolkit/interop/typography_context.h" namespace impeller::interop { @@ -38,10 +42,14 @@ DEFINE_PEER_GETTER(DisplayListBuilder, ImpellerDisplayListBuilder); DEFINE_PEER_GETTER(ImageFilter, ImpellerImageFilter); DEFINE_PEER_GETTER(MaskFilter, ImpellerMaskFilter); DEFINE_PEER_GETTER(Paint, ImpellerPaint); +DEFINE_PEER_GETTER(Paragraph, ImpellerParagraph); +DEFINE_PEER_GETTER(ParagraphBuilder, ImpellerParagraphBuilder); +DEFINE_PEER_GETTER(ParagraphStyle, ImpellerParagraphStyle); DEFINE_PEER_GETTER(Path, ImpellerPath); DEFINE_PEER_GETTER(PathBuilder, ImpellerPathBuilder); DEFINE_PEER_GETTER(Surface, ImpellerSurface); DEFINE_PEER_GETTER(Texture, ImpellerTexture); +DEFINE_PEER_GETTER(TypographyContext, ImpellerTypographyContext); static std::string GetVersionAsString(uint32_t version) { std::stringstream stream; @@ -453,8 +461,8 @@ IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithContentsNew( ImpellerContext context, const ImpellerTextureDescriptor* descriptor, - const ImpellerMapping* IMPELLER_NONNULL contents, - void* IMPELLER_NULLABLE contents_on_release_user_data) { + const ImpellerMapping* contents, + void* contents_on_release_user_data) { TextureDescriptor desc; desc.storage_mode = StorageMode::kDevicePrivate; desc.type = TextureType::kTexture2D; @@ -817,4 +825,223 @@ void ImpellerPaintSetMaskFilter(ImpellerPaint paint, GetPeer(paint)->SetMaskFilter(*GetPeer(mask_filter)); } +IMPELLER_EXTERN_C ImpellerParagraphStyle ImpellerParagraphStyleNew() { + return Create().Leak(); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleRetain(ImpellerParagraphStyle paragraph_style) { + ObjectBase::SafeRetain(paragraph_style); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleRelease(ImpellerParagraphStyle paragraph_style) { + ObjectBase::SafeRelease(paragraph_style); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetForeground(ImpellerParagraphStyle paragraph_style, + ImpellerPaint paint) { + GetPeer(paragraph_style)->SetForeground(Ref(GetPeer(paint))); +} + +IMPELLER_EXTERN_C void ImpellerParagraphStyleSetBackground( + ImpellerParagraphStyle paragraph_style, + ImpellerPaint paint) { + GetPeer(paragraph_style)->SetBackground(Ref(GetPeer(paint))); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetFontWeight(ImpellerParagraphStyle paragraph_style, + ImpellerFontWeight weight) { + GetPeer(paragraph_style)->SetFontWeight(ToTxtType(weight)); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetFontStyle(ImpellerParagraphStyle paragraph_style, + ImpellerFontStyle style) { + GetPeer(paragraph_style)->SetFontStyle(ToTxtType(style)); +} + +static std::string ReadString(const char* string) { + if (string == nullptr) { + return ""; + } + return std::string{string}; +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetFontFamily(ImpellerParagraphStyle paragraph_style, + const char* family_name) { + GetPeer(paragraph_style)->SetFontFamily(ReadString(family_name)); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetFontSize(ImpellerParagraphStyle paragraph_style, + float size) { + GetPeer(paragraph_style)->SetFontSize(size); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetHeight(ImpellerParagraphStyle paragraph_style, + float height) { + GetPeer(paragraph_style)->SetHeight(height); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetTextAlignment( + ImpellerParagraphStyle paragraph_style, + ImpellerTextAlignment align) { + GetPeer(paragraph_style)->SetTextAlignment(ToTxtType(align)); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetTextDirection( + ImpellerParagraphStyle paragraph_style, + ImpellerTextDirection direction) { + GetPeer(paragraph_style)->SetTextDirection(ToTxtType(direction)); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetMaxLines(ImpellerParagraphStyle paragraph_style, + uint32_t max_lines) { + GetPeer(paragraph_style)->SetMaxLines(max_lines); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphStyleSetLocale(ImpellerParagraphStyle paragraph_style, + const char* locale) { + GetPeer(paragraph_style)->SetLocale(ReadString(locale)); +} + +IMPELLER_EXTERN_C +void ImpellerDisplayListBuilderDrawParagraph(ImpellerDisplayListBuilder builder, + ImpellerParagraph paragraph, + const ImpellerPoint* point) { + GetPeer(builder)->DrawParagraph(*GetPeer(paragraph), ToImpellerType(*point)); +} + +IMPELLER_EXTERN_C ImpellerParagraphBuilder ImpellerParagraphBuilderNew( + ImpellerTypographyContext context) { + auto builder = Create(*GetPeer(context)); + if (!builder->IsValid()) { + VALIDATION_LOG << "Could not create valid paragraph builder."; + return nullptr; + } + return builder.Leak(); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphBuilderRetain( + ImpellerParagraphBuilder paragraph_builder) { + ObjectBase::SafeRetain(paragraph_builder); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphBuilderRelease( + ImpellerParagraphBuilder paragraph_builder) { + ObjectBase::SafeRelease(paragraph_builder); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphBuilderPushStyle( + ImpellerParagraphBuilder paragraph_builder, + ImpellerParagraphStyle style) { + GetPeer(paragraph_builder)->PushStyle(*GetPeer(style)); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphBuilderPopStyle( + ImpellerParagraphBuilder paragraph_builder) { + GetPeer(paragraph_builder)->PopStyle(); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphBuilderAddText(ImpellerParagraphBuilder paragraph_builder, + const uint8_t* data, + uint32_t length) { + if (data == nullptr) { + length = 0; + } + if (length == 0) { + return; + } + GetPeer(paragraph_builder)->AddText(data, length); +} + +IMPELLER_EXTERN_C ImpellerParagraph ImpellerParagraphBuilderBuildParagraphNew( + ImpellerParagraphBuilder paragraph_builder, + float width) { + return GetPeer(paragraph_builder)->Build(width).Leak(); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphRetain(ImpellerParagraph paragraph) { + ObjectBase::SafeRetain(paragraph); +} + +IMPELLER_EXTERN_C +void ImpellerParagraphRelease(ImpellerParagraph paragraph) { + ObjectBase::SafeRelease(paragraph); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetMaxWidth(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetMaxWidth(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetHeight(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetHeight(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetLongestLineWidth(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetLongestLineWidth(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetMinInstrinsicWidth(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetMinIntrinsicWidth(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetMaxInstrinsicWidth(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetMaxInstrinsicWidth(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetIdeographicBaseline(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetIdeographicBaseline(); +} + +IMPELLER_EXTERN_C +float ImpellerParagraphGetAlphabeticBaseline(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetAlphabeticBaseline(); +} + +IMPELLER_EXTERN_C +uint32_t ImpellerParagraphGetLineCount(ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetLineCount(); +} + +IMPELLER_EXTERN_C ImpellerTypographyContext ImpellerTypographyContextNew() { + auto context = Create(); + if (!context->IsValid()) { + VALIDATION_LOG << "Could not create typography context."; + return nullptr; + } + return Create().Leak(); +} + +IMPELLER_EXTERN_C +void ImpellerTypographyContextRetain(ImpellerTypographyContext context) { + ObjectBase::SafeRetain(context); +} + +IMPELLER_EXTERN_C +void ImpellerTypographyContextRelease(ImpellerTypographyContext context) { + ObjectBase::SafeRelease(context); +} + } // namespace impeller::interop diff --git a/impeller/toolkit/interop/impeller.h b/impeller/toolkit/interop/impeller.h index 112cfc317d434..3b2c139ff93c4 100644 --- a/impeller/toolkit/interop/impeller.h +++ b/impeller/toolkit/interop/impeller.h @@ -57,7 +57,7 @@ IMPELLER_EXTERN_C_BEGIN #define IMPELLER_VERSION_VARIANT 1 #define IMPELLER_VERSION_MAJOR 1 -#define IMPELLER_VERSION_MINOR 0 +#define IMPELLER_VERSION_MINOR 1 #define IMPELLER_VERSION_PATCH 0 #define IMPELLER_VERSION \ @@ -87,10 +87,14 @@ IMPELLER_DEFINE_HANDLE(ImpellerDisplayListBuilder); IMPELLER_DEFINE_HANDLE(ImpellerImageFilter); IMPELLER_DEFINE_HANDLE(ImpellerMaskFilter); IMPELLER_DEFINE_HANDLE(ImpellerPaint); +IMPELLER_DEFINE_HANDLE(ImpellerParagraph); +IMPELLER_DEFINE_HANDLE(ImpellerParagraphBuilder); +IMPELLER_DEFINE_HANDLE(ImpellerParagraphStyle); IMPELLER_DEFINE_HANDLE(ImpellerPath); IMPELLER_DEFINE_HANDLE(ImpellerPathBuilder); IMPELLER_DEFINE_HANDLE(ImpellerSurface); IMPELLER_DEFINE_HANDLE(ImpellerTexture); +IMPELLER_DEFINE_HANDLE(ImpellerTypographyContext); //------------------------------------------------------------------------------ // Signatures @@ -193,6 +197,37 @@ typedef enum ImpellerColorSpace { kImpellerColorSpaceDisplayP3, } ImpellerColorSpace; +typedef enum ImpellerFontWeight { + kImpellerFontWeight100, // Thin + kImpellerFontWeight200, // Extra-Light + kImpellerFontWeight300, // Light + kImpellerFontWeight400, // Normal/Regular + kImpellerFontWeight500, // Medium + kImpellerFontWeight600, // Semi-bold + kImpellerFontWeight700, // Bold + kImpellerFontWeight800, // Extra-Bold + kImpellerFontWeight900, // Black +} ImpellerFontWeight; + +typedef enum ImpellerFontStyle { + kImpellerFontStyleNormal, + kImpellerFontStyleItalic, +} ImpellerFontStyle; + +typedef enum ImpellerTextAlignment { + kImpellerTextAlignmentLeft, + kImpellerTextAlignmentRight, + kImpellerTextAlignmentCenter, + kImpellerTextAlignmentJustify, + kImpellerTextAlignmentStart, + kImpellerTextAlignmentEnd, +} ImpellerTextAlignment; + +typedef enum ImpellerTextDirection { + kImpellerTextDirectionRTL, + kImpellerTextDirectionLTR, +} ImpellerTextDirection; + //------------------------------------------------------------------------------ // Non-opaque structs //------------------------------------------------------------------------------ @@ -755,6 +790,12 @@ void ImpellerDisplayListBuilderDrawDisplayList( ImpellerDisplayList IMPELLER_NONNULL display_list, float opacity); +IMPELLER_EXPORT +void ImpellerDisplayListBuilderDrawParagraph( + ImpellerDisplayListBuilder IMPELLER_NONNULL builder, + ImpellerParagraph IMPELLER_NONNULL paragraph, + const ImpellerPoint* IMPELLER_NONNULL point); + //------------------------------------------------------------------------------ // Display List Builder: Drawing Textures //------------------------------------------------------------------------------ @@ -776,6 +817,167 @@ void ImpellerDisplayListBuilderDrawTextureRect( ImpellerTextureSampling sampling, ImpellerPaint IMPELLER_NULLABLE paint); +//------------------------------------------------------------------------------ +// Typography Context +//------------------------------------------------------------------------------ + +IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerTypographyContext IMPELLER_NULLABLE +ImpellerTypographyContextNew(); + +IMPELLER_EXPORT +void ImpellerTypographyContextRetain( + ImpellerTypographyContext IMPELLER_NULLABLE context); + +IMPELLER_EXPORT +void ImpellerTypographyContextRelease( + ImpellerTypographyContext IMPELLER_NULLABLE context); + +//------------------------------------------------------------------------------ +// Paragraph Style +//------------------------------------------------------------------------------ + +IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraphStyle IMPELLER_NULLABLE +ImpellerParagraphStyleNew(); + +IMPELLER_EXPORT +void ImpellerParagraphStyleRetain( + ImpellerParagraphStyle IMPELLER_NULLABLE paragraph_style); + +IMPELLER_EXPORT +void ImpellerParagraphStyleRelease( + ImpellerParagraphStyle IMPELLER_NULLABLE paragraph_style); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetForeground( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerPaint IMPELLER_NONNULL paint); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetBackground( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerPaint IMPELLER_NONNULL paint); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetFontWeight( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerFontWeight weight); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetFontStyle( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerFontStyle style); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetFontFamily( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + const char* IMPELLER_NONNULL family_name); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetFontSize( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + float size); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetHeight( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + float height); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetTextAlignment( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerTextAlignment align); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetTextDirection( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + ImpellerTextDirection direction); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetMaxLines( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + uint32_t max_lines); + +IMPELLER_EXPORT +void ImpellerParagraphStyleSetLocale( + ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, + const char* IMPELLER_NONNULL locale); + +//------------------------------------------------------------------------------ +// Paragraph Builder +//------------------------------------------------------------------------------ + +IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraphBuilder IMPELLER_NULLABLE +ImpellerParagraphBuilderNew(ImpellerTypographyContext IMPELLER_NONNULL context); + +IMPELLER_EXPORT +void ImpellerParagraphBuilderRetain( + ImpellerParagraphBuilder IMPELLER_NULLABLE paragraph_builder); + +IMPELLER_EXPORT +void ImpellerParagraphBuilderRelease( + ImpellerParagraphBuilder IMPELLER_NULLABLE paragraph_builder); + +IMPELLER_EXPORT +void ImpellerParagraphBuilderPushStyle( + ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, + ImpellerParagraphStyle IMPELLER_NONNULL style); + +IMPELLER_EXPORT +void ImpellerParagraphBuilderPopStyle( + ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder); + +IMPELLER_EXPORT +void ImpellerParagraphBuilderAddText( + ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, + const uint8_t* IMPELLER_NULLABLE data, + uint32_t length); + +IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraph IMPELLER_NULLABLE +ImpellerParagraphBuilderBuildParagraphNew( + ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, + float width); + +//------------------------------------------------------------------------------ +// Paragraph +//------------------------------------------------------------------------------ + +IMPELLER_EXPORT +void ImpellerParagraphRetain(ImpellerParagraph IMPELLER_NULLABLE paragraph); + +IMPELLER_EXPORT +void ImpellerParagraphRelease(ImpellerParagraph IMPELLER_NULLABLE paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetMaxWidth( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetHeight(ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetLongestLineWidth( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetMinInstrinsicWidth( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetMaxInstrinsicWidth( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetIdeographicBaseline( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +float ImpellerParagraphGetAlphabeticBaseline( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +IMPELLER_EXPORT +uint32_t ImpellerParagraphGetLineCount( + ImpellerParagraph IMPELLER_NONNULL paragraph); + IMPELLER_EXTERN_C_END #endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_IMPELLER_H_ diff --git a/impeller/toolkit/interop/impeller_unittests.cc b/impeller/toolkit/interop/impeller_unittests.cc index 03ef5577241e7..2f7e9fdf9d5fe 100644 --- a/impeller/toolkit/interop/impeller_unittests.cc +++ b/impeller/toolkit/interop/impeller_unittests.cc @@ -9,9 +9,13 @@ #include "impeller/toolkit/interop/formats.h" #include "impeller/toolkit/interop/impeller.h" #include "impeller/toolkit/interop/paint.h" +#include "impeller/toolkit/interop/paragraph.h" +#include "impeller/toolkit/interop/paragraph_builder.h" +#include "impeller/toolkit/interop/paragraph_style.h" #include "impeller/toolkit/interop/playground_test.h" #include "impeller/toolkit/interop/surface.h" #include "impeller/toolkit/interop/texture.h" +#include "impeller/toolkit/interop/typography_context.h" namespace impeller::interop::testing { @@ -107,4 +111,66 @@ TEST_P(InteropPlaygroundTest, CanDrawImage) { })); } +TEST_P(InteropPlaygroundTest, CanCreateParagraphs) { + // Create a typography context. + auto type_context = Adopt(ImpellerTypographyContextNew()); + ASSERT_TRUE(type_context); + + // Create a builder. + auto builder = + Adopt(ImpellerParagraphBuilderNew(type_context.GetC())); + ASSERT_TRUE(builder); + + // Create a paragraph style with the font size and foreground and background + // colors. + auto style = Adopt(ImpellerParagraphStyleNew()); + ASSERT_TRUE(style); + ImpellerParagraphStyleSetFontSize(style.GetC(), 150.0f); + + { + auto paint = Adopt(ImpellerPaintNew()); + ASSERT_TRUE(paint); + ImpellerColor color = {1.0, 0.0, 0.0, 1.0}; + ImpellerPaintSetColor(paint.GetC(), &color); + ImpellerParagraphStyleSetForeground(style.GetC(), paint.GetC()); + } + + { + auto paint = Adopt(ImpellerPaintNew()); + ASSERT_TRUE(paint); + ImpellerColor color = {1.0, 1.0, 1.0, 1.0}; + ImpellerPaintSetColor(paint.GetC(), &color); + ImpellerParagraphStyleSetBackground(style.GetC(), paint.GetC()); + } + + // Push the style onto the style stack. + ImpellerParagraphBuilderPushStyle(builder.GetC(), style.GetC()); + std::string text = "the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶."; + + // Add the paragraph text data. + ImpellerParagraphBuilderAddText(builder.GetC(), + reinterpret_cast(text.data()), + text.size()); + + // Layout and build the paragraph. + auto paragraph = Adopt( + ImpellerParagraphBuilderBuildParagraphNew(builder.GetC(), 1200.0f)); + ASSERT_TRUE(paragraph); + + // Create a display list with just the paragraph drawn into it. + auto dl_builder = + Adopt(ImpellerDisplayListBuilderNew(nullptr)); + ImpellerPoint point = {20, 20}; + ImpellerDisplayListBuilderDrawParagraph(dl_builder.GetC(), paragraph.GetC(), + &point); + auto dl = Adopt( + ImpellerDisplayListBuilderCreateDisplayListNew(dl_builder.GetC())); + + ASSERT_TRUE( + OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool { + ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC()); + return true; + })); +} + } // namespace impeller::interop::testing diff --git a/impeller/toolkit/interop/paragraph.cc b/impeller/toolkit/interop/paragraph.cc new file mode 100644 index 0000000000000..6fe2846e521e3 --- /dev/null +++ b/impeller/toolkit/interop/paragraph.cc @@ -0,0 +1,50 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/toolkit/interop/paragraph.h" + +namespace impeller::interop { + +Paragraph::Paragraph(std::unique_ptr paragraph) + : paragraph_(std::move(paragraph)) {} + +Paragraph::~Paragraph() = default; + +Scalar Paragraph::GetMaxWidth() const { + return paragraph_->GetMaxWidth(); +} + +Scalar Paragraph::GetHeight() const { + return paragraph_->GetHeight(); +} + +Scalar Paragraph::GetLongestLineWidth() const { + return paragraph_->GetLongestLine(); +} + +Scalar Paragraph::GetMinIntrinsicWidth() const { + return paragraph_->GetMinIntrinsicWidth(); +} + +Scalar Paragraph::GetMaxInstrinsicWidth() const { + return paragraph_->GetMaxIntrinsicWidth(); +} + +Scalar Paragraph::GetIdeographicBaseline() const { + return paragraph_->GetIdeographicBaseline(); +} + +Scalar Paragraph::GetAlphabeticBaseline() const { + return paragraph_->GetAlphabeticBaseline(); +} + +uint32_t Paragraph::GetLineCount() const { + return paragraph_->GetNumberOfLines(); +} + +const std::unique_ptr& Paragraph::GetHandle() const { + return paragraph_; +} + +} // namespace impeller::interop diff --git a/impeller/toolkit/interop/paragraph.h b/impeller/toolkit/interop/paragraph.h new file mode 100644 index 0000000000000..de3bd6349cfe2 --- /dev/null +++ b/impeller/toolkit/interop/paragraph.h @@ -0,0 +1,50 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_H_ + +#include "flutter/third_party/txt/src/txt/paragraph.h" +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" + +namespace impeller::interop { + +class Paragraph final + : public Object { + public: + explicit Paragraph(std::unique_ptr paragraph); + + ~Paragraph() override; + + Paragraph(const Paragraph&) = delete; + + Paragraph& operator=(const Paragraph&) = delete; + + Scalar GetMaxWidth() const; + + Scalar GetHeight() const; + + Scalar GetLongestLineWidth() const; + + Scalar GetMinIntrinsicWidth() const; + + Scalar GetMaxInstrinsicWidth() const; + + Scalar GetIdeographicBaseline() const; + + Scalar GetAlphabeticBaseline() const; + + uint32_t GetLineCount() const; + + const std::unique_ptr& GetHandle() const; + + private: + std::unique_ptr paragraph_; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_H_ diff --git a/impeller/toolkit/interop/paragraph_builder.cc b/impeller/toolkit/interop/paragraph_builder.cc new file mode 100644 index 0000000000000..4997d591f0f25 --- /dev/null +++ b/impeller/toolkit/interop/paragraph_builder.cc @@ -0,0 +1,55 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/toolkit/interop/paragraph_builder.h" + +#include "flutter/third_party/txt/src/skia/paragraph_builder_skia.h" +#include "impeller/base/validation.h" +#include "impeller/toolkit/interop/paragraph.h" + +namespace impeller::interop { + +ParagraphBuilder::ParagraphBuilder(const TypographyContext& context) { + if (!context.IsValid()) { + VALIDATION_LOG << "Invalid typography context."; + return; + } + + static txt::ParagraphStyle kBaseStyle; + + builder_ = std::make_unique( + kBaseStyle, // + context.GetFontCollection(), // + true // is impeller enabled + ); +} + +ParagraphBuilder::~ParagraphBuilder() = default; + +bool ParagraphBuilder::IsValid() const { + return !!builder_; +} + +void ParagraphBuilder::PushStyle(const ParagraphStyle& style) { + builder_->PushStyle(style.CreateTextStyle()); +} + +void ParagraphBuilder::PopStyle() { + builder_->Pop(); +} + +void ParagraphBuilder::AddText(const uint8_t* data, size_t byte_length) { + builder_->AddText(data, byte_length); +} + +ScopedObject ParagraphBuilder::Build(Scalar width) const { + auto txt_paragraph = builder_->Build(); + if (!txt_paragraph) { + return nullptr; + } + txt_paragraph->Layout(width); + return Create(std::move(txt_paragraph)); +} + +} // namespace impeller::interop diff --git a/impeller/toolkit/interop/paragraph_builder.h b/impeller/toolkit/interop/paragraph_builder.h new file mode 100644 index 0000000000000..15604460d009a --- /dev/null +++ b/impeller/toolkit/interop/paragraph_builder.h @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_BUILDER_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_BUILDER_H_ + +#include + +#include "flutter/third_party/txt/src/txt/paragraph_builder.h" +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" +#include "impeller/toolkit/interop/paragraph.h" +#include "impeller/toolkit/interop/paragraph_style.h" +#include "impeller/toolkit/interop/typography_context.h" + +namespace impeller::interop { + +class ParagraphBuilder final + : public Object { + public: + explicit ParagraphBuilder(const TypographyContext& context); + + ~ParagraphBuilder() override; + + ParagraphBuilder(const ParagraphBuilder&) = delete; + + ParagraphBuilder& operator=(const ParagraphBuilder&) = delete; + + bool IsValid() const; + + void PushStyle(const ParagraphStyle& style); + + void PopStyle(); + + void AddText(const uint8_t* data, size_t byte_length); + + ScopedObject Build(Scalar width) const; + + private: + std::unique_ptr builder_; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_BUILDER_H_ diff --git a/impeller/toolkit/interop/paragraph_style.cc b/impeller/toolkit/interop/paragraph_style.cc new file mode 100644 index 0000000000000..14733dc795576 --- /dev/null +++ b/impeller/toolkit/interop/paragraph_style.cc @@ -0,0 +1,68 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/toolkit/interop/paragraph_style.h" + +namespace impeller::interop { + +ParagraphStyle::ParagraphStyle() = default; + +ParagraphStyle::~ParagraphStyle() = default; + +void ParagraphStyle::SetFontWeight(txt::FontWeight weight) { + style_.font_weight = weight; +} + +void ParagraphStyle::SetFontStyle(txt::FontStyle style) { + style_.font_style = style; +} + +void ParagraphStyle::SetFontFamily(std::string family) { + style_.font_family = std::move(family); +} + +void ParagraphStyle::SetFontSize(double size) { + style_.font_size = size; +} + +void ParagraphStyle::SetHeight(double height) { + style_.height = height; +} + +void ParagraphStyle::SetTextAlignment(txt::TextAlign alignment) { + style_.text_align = alignment; +} + +void ParagraphStyle::SetTextDirection(txt::TextDirection direction) { + style_.text_direction = direction; +} + +void ParagraphStyle::SetMaxLines(size_t max_lines) { + style_.max_lines = max_lines; +} + +void ParagraphStyle::SetLocale(std::string locale) { + style_.locale = std::move(locale); +} + +void ParagraphStyle::SetForeground(ScopedObject paint) { + foreground_ = std::move(paint); +} + +void ParagraphStyle::SetBackground(ScopedObject paint) { + backgrond_ = std::move(paint); +} + +txt::TextStyle ParagraphStyle::CreateTextStyle() const { + auto style = style_.GetTextStyle(); + if (foreground_) { + style.foreground = foreground_->GetPaint(); + } + if (backgrond_) { + style.background = backgrond_->GetPaint(); + } + return style; +} + +} // namespace impeller::interop diff --git a/impeller/toolkit/interop/paragraph_style.h b/impeller/toolkit/interop/paragraph_style.h new file mode 100644 index 0000000000000..37165e34d88ee --- /dev/null +++ b/impeller/toolkit/interop/paragraph_style.h @@ -0,0 +1,59 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_STYLE_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_STYLE_H_ + +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" +#include "impeller/toolkit/interop/paint.h" +#include "third_party/txt/src/txt/paragraph_style.h" + +namespace impeller::interop { + +class ParagraphStyle final + : public Object { + public: + explicit ParagraphStyle(); + + ~ParagraphStyle() override; + + ParagraphStyle(const ParagraphStyle&) = delete; + + ParagraphStyle& operator=(const ParagraphStyle&) = delete; + + void SetForeground(ScopedObject paint); + + void SetBackground(ScopedObject paint); + + void SetFontWeight(txt::FontWeight weight); + + void SetFontStyle(txt::FontStyle style); + + void SetFontFamily(std::string family); + + void SetFontSize(double size); + + void SetHeight(double height); + + void SetTextAlignment(txt::TextAlign alignment); + + void SetTextDirection(txt::TextDirection direction); + + void SetMaxLines(size_t max_lines); + + void SetLocale(std::string locale); + + txt::TextStyle CreateTextStyle() const; + + private: + txt::ParagraphStyle style_; + ScopedObject foreground_; + ScopedObject backgrond_; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_STYLE_H_ diff --git a/impeller/toolkit/interop/typography_context.cc b/impeller/toolkit/interop/typography_context.cc new file mode 100644 index 0000000000000..70b24338eba1d --- /dev/null +++ b/impeller/toolkit/interop/typography_context.cc @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/toolkit/interop/typography_context.h" + +#include + +#include "flutter/fml/icu_util.h" +#include "impeller/toolkit/interop/embedded_icu_data.h" + +namespace impeller::interop { + +TypographyContext::TypographyContext() + : collection_(std::make_shared()) { + static std::once_flag sICUInitOnceFlag; + std::call_once(sICUInitOnceFlag, []() { + auto icu_data = std::make_unique( + impeller_embedded_icu_data_data, impeller_embedded_icu_data_length); + fml::icu::InitializeICUFromMapping(std::move(icu_data)); + }); + collection_->SetupDefaultFontManager(0u); +} + +TypographyContext::~TypographyContext() = default; + +bool TypographyContext::IsValid() const { + return !!collection_; +} + +const std::shared_ptr& +TypographyContext::GetFontCollection() const { + return collection_; +} + +} // namespace impeller::interop diff --git a/impeller/toolkit/interop/typography_context.h b/impeller/toolkit/interop/typography_context.h new file mode 100644 index 0000000000000..8c68c30825609 --- /dev/null +++ b/impeller/toolkit/interop/typography_context.h @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_TYPOGRAPHY_CONTEXT_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_TYPOGRAPHY_CONTEXT_H_ + +#include + +#include "flutter/third_party/txt/src/txt/font_collection.h" +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" + +namespace impeller::interop { + +class TypographyContext final + : public Object { + public: + TypographyContext(); + + ~TypographyContext() override; + + TypographyContext(const TypographyContext&) = delete; + + TypographyContext& operator=(const TypographyContext&) = delete; + + bool IsValid() const; + + const std::shared_ptr& GetFontCollection() const; + + private: + std::shared_ptr collection_; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_TYPOGRAPHY_CONTEXT_H_ diff --git a/third_party/txt/src/skia/paragraph_builder_skia.cc b/third_party/txt/src/skia/paragraph_builder_skia.cc index 0468e5f55475b..6cba3ec34fcc7 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.cc +++ b/third_party/txt/src/skia/paragraph_builder_skia.cc @@ -51,8 +51,7 @@ ParagraphBuilderSkia::ParagraphBuilderSkia( const bool impeller_enabled) : base_style_(style.GetTextStyle()), impeller_enabled_(impeller_enabled) { builder_ = skt::ParagraphBuilder::make( - TxtToSkia(style), - font_collection->CreateSktFontCollection(), + TxtToSkia(style), font_collection->CreateSktFontCollection(), SkUnicodes::ICU::Make()); } @@ -76,6 +75,11 @@ void ParagraphBuilderSkia::AddText(const std::u16string& text) { builder_->addText(text); } +void ParagraphBuilderSkia::AddText(const uint8_t* utf8_data, + size_t byte_length) { + builder_->addText(reinterpret_cast(utf8_data), byte_length); +} + void ParagraphBuilderSkia::AddPlaceholder(PlaceholderRun& span) { skt::PlaceholderStyle placeholder_style; placeholder_style.fHeight = span.height; diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h index 6269285899f58..54e703cddbdfa 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.h +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -41,6 +41,7 @@ class ParagraphBuilderSkia : public ParagraphBuilder { virtual void Pop() override; virtual const TextStyle& PeekStyle() override; virtual void AddText(const std::u16string& text) override; + virtual void AddText(const uint8_t* utf8_data, size_t byte_length) override; virtual void AddPlaceholder(PlaceholderRun& span) override; virtual std::unique_ptr Build() override; diff --git a/third_party/txt/src/txt/paragraph_builder.h b/third_party/txt/src/txt/paragraph_builder.h index acd5e952c2fce..573f9b218ba72 100644 --- a/third_party/txt/src/txt/paragraph_builder.h +++ b/third_party/txt/src/txt/paragraph_builder.h @@ -59,9 +59,15 @@ class ParagraphBuilder { virtual const TextStyle& PeekStyle() = 0; // Adds text to the builder. Forms the proper runs to use the upper-most style - // on the style_stack_; + // on the style stack. virtual void AddText(const std::u16string& text) = 0; + // Adds text to the builder. Forms the proper runs to use the upper-most style + // on the style stack. + // + // Data must be in UTF-8 encoding. + virtual void AddText(const uint8_t* utf8_data, size_t byte_length) = 0; + // Pushes the information required to leave an open space, where Flutter may // draw a custom placeholder into. //