22#include "third_party/icu/source/common/unicode/ustring.h"
23#include "third_party/skia/include/core/SkColor.h"
33const double kTextHeightNone = 0.0;
37const int kTSLeadingDistributionIndex = 0;
38const int kTSColorIndex = 1;
39const int kTSTextDecorationIndex = 2;
40const int kTSTextDecorationColorIndex = 3;
41const int kTSTextDecorationStyleIndex = 4;
42const int kTSFontWeightIndex = 5;
43const int kTSFontStyleIndex = 6;
44const int kTSTextBaselineIndex = 7;
45const int kTSTextDecorationThicknessIndex = 8;
46const int kTSFontFamilyIndex = 9;
47const int kTSFontSizeIndex = 10;
48const int kTSLetterSpacingIndex = 11;
49const int kTSWordSpacingIndex = 12;
50const int kTSHeightIndex = 13;
51const int kTSLocaleIndex = 14;
52const int kTSBackgroundIndex = 15;
53const int kTSForegroundIndex = 16;
54const int kTSTextShadowsIndex = 17;
55const int kTSFontFeaturesIndex = 18;
56const int kTSFontVariationsIndex = 19;
58const int kTSLeadingDistributionMask = 1 << kTSLeadingDistributionIndex;
59const int kTSColorMask = 1 << kTSColorIndex;
60const int kTSTextDecorationMask = 1 << kTSTextDecorationIndex;
61const int kTSTextDecorationColorMask = 1 << kTSTextDecorationColorIndex;
62const int kTSTextDecorationStyleMask = 1 << kTSTextDecorationStyleIndex;
63const int kTSTextDecorationThicknessMask = 1 << kTSTextDecorationThicknessIndex;
64const int kTSFontWeightMask = 1 << kTSFontWeightIndex;
65const int kTSFontStyleMask = 1 << kTSFontStyleIndex;
66const int kTSTextBaselineMask = 1 << kTSTextBaselineIndex;
67const int kTSFontFamilyMask = 1 << kTSFontFamilyIndex;
68const int kTSFontSizeMask = 1 << kTSFontSizeIndex;
69const int kTSLetterSpacingMask = 1 << kTSLetterSpacingIndex;
70const int kTSWordSpacingMask = 1 << kTSWordSpacingIndex;
71const int kTSHeightMask = 1 << kTSHeightIndex;
72const int kTSLocaleMask = 1 << kTSLocaleIndex;
73const int kTSBackgroundMask = 1 << kTSBackgroundIndex;
74const int kTSForegroundMask = 1 << kTSForegroundIndex;
75const int kTSTextShadowsMask = 1 << kTSTextShadowsIndex;
76const int kTSFontFeaturesMask = 1 << kTSFontFeaturesIndex;
77const int kTSFontVariationsMask = 1 << kTSFontVariationsIndex;
81const int kPSTextAlignIndex = 1;
82const int kPSTextDirectionIndex = 2;
83const int kPSFontWeightIndex = 3;
84const int kPSFontStyleIndex = 4;
85const int kPSMaxLinesIndex = 5;
86const int kPSTextHeightBehaviorIndex = 6;
87const int kPSFontFamilyIndex = 7;
88const int kPSFontSizeIndex = 8;
89const int kPSHeightIndex = 9;
90const int kPSStrutStyleIndex = 10;
91const int kPSEllipsisIndex = 11;
92const int kPSLocaleIndex = 12;
94const int kPSTextAlignMask = 1 << kPSTextAlignIndex;
95const int kPSTextDirectionMask = 1 << kPSTextDirectionIndex;
96const int kPSFontWeightMask = 1 << kPSFontWeightIndex;
97const int kPSFontStyleMask = 1 << kPSFontStyleIndex;
98const int kPSMaxLinesMask = 1 << kPSMaxLinesIndex;
99const int kPSFontFamilyMask = 1 << kPSFontFamilyIndex;
100const int kPSFontSizeMask = 1 << kPSFontSizeIndex;
101const int kPSHeightMask = 1 << kPSHeightIndex;
102const int kPSTextHeightBehaviorMask = 1 << kPSTextHeightBehaviorIndex;
103const int kPSStrutStyleMask = 1 << kPSStrutStyleIndex;
104const int kPSEllipsisMask = 1 << kPSEllipsisIndex;
105const int kPSLocaleMask = 1 << kPSLocaleIndex;
109constexpr uint32_t kColorDefault = 0xFF000000;
110constexpr uint32_t kBytesPerShadow = 16;
111constexpr uint32_t kShadowPropertiesCount = 4;
112constexpr uint32_t kColorOffset = 0;
113constexpr uint32_t kXOffset = 1;
114constexpr uint32_t kYOffset = 2;
115constexpr uint32_t kBlurOffset = 3;
118constexpr uint32_t kBytesPerFontFeature = 8;
119constexpr uint32_t kFontFeatureTagLength = 4;
122constexpr uint32_t kBytesPerFontVariation = 8;
123constexpr uint32_t kFontVariationTagLength = 4;
126const int kSFontWeightIndex = 0;
127const int kSFontStyleIndex = 1;
128const int kSFontFamilyIndex = 2;
129const int kSLeadingDistributionIndex = 3;
130const int kSFontSizeIndex = 4;
131const int kSHeightIndex = 5;
132const int kSLeadingIndex = 6;
133const int kSForceStrutHeightIndex = 7;
135const int kSFontWeightMask = 1 << kSFontWeightIndex;
136const int kSFontStyleMask = 1 << kSFontStyleIndex;
137const int kSFontFamilyMask = 1 << kSFontFamilyIndex;
138const int kSLeadingDistributionMask = 1 << kSLeadingDistributionIndex;
139const int kSFontSizeMask = 1 << kSFontSizeIndex;
140const int kSHeightMask = 1 << kSHeightIndex;
141const int kSLeadingMask = 1 << kSLeadingIndex;
142const int kSForceStrutHeightMask = 1 << kSForceStrutHeightIndex;
149 Dart_Handle encoded_handle,
150 Dart_Handle strutData,
151 const std::string& fontFamily,
152 const std::vector<std::string>& strutFontFamilies,
155 const std::u16string& ellipsis,
156 const std::string& locale) {
158 auto res = fml::MakeRefCounted<ParagraphBuilder>(
159 encoded_handle, strutData, fontFamily, strutFontFamilies, fontSize,
160 height, ellipsis, locale);
161 res->AssociateWithDartWrapper(wrapper);
167 const std::vector<std::string>& strut_font_families,
169 if (strut_data == Dart_Null()) {
179 const int32_t* int32_data =
static_cast<const int32_t*
>(byte_data.
data());
180 int32_t mask = int32_data[0];
182 size_t int32_count = 1;
183 if (mask & kSFontWeightMask) {
186 if (mask & kSFontStyleMask) {
193 std::vector<float> float_data;
195 memcpy(float_data.data(), int32_data + int32_count, float_data.size() * 4);
196 size_t float_count = 0;
197 if (mask & kSFontSizeMask) {
200 if (mask & kSHeightMask) {
201 paragraph_style.
strut_height = float_data[float_count++];
204 if (mask & kSLeadingMask) {
212 if (mask & kSFontFamilyMask) {
221ParagraphBuilder::ParagraphBuilder(
222 Dart_Handle encoded_data,
223 Dart_Handle strutData,
224 const std::string& fontFamily,
225 const std::vector<std::string>& strutFontFamilies,
228 const std::u16string& ellipsis,
229 const std::string& locale) {
233 tonic::Int32List encoded(encoded_data);
237 if (mask & kPSTextAlignMask) {
242 if (mask & kPSTextDirectionMask) {
247 if (mask & kPSFontWeightMask) {
251 if (mask & kPSFontStyleMask) {
256 if (mask & kPSFontFamilyMask) {
260 if (mask & kPSFontSizeMask) {
264 if (mask & kPSHeightMask) {
269 if (mask & kPSTextHeightBehaviorMask) {
273 if (mask & kPSMaxLinesMask) {
274 style.
max_lines = encoded[kPSMaxLinesIndex];
278 if (mask & kPSStrutStyleMask) {
282 if (mask & kPSEllipsisMask) {
286 if (mask & kPSLocaleMask) {
297 style, font_collection.GetFontCollection(), impeller_enabled);
303 Dart_Handle shadows_data,
304 std::vector<txt::TextShadow>& decoded_shadows) {
305 decoded_shadows.clear();
310 const uint32_t* uint_data =
static_cast<const uint32_t*
>(byte_data.
data());
311 const float* float_data =
static_cast<const float*
>(byte_data.
data());
314 size_t shadow_count_offset = 0;
315 for (
size_t shadow_index = 0; shadow_index < shadow_count; ++shadow_index) {
316 shadow_count_offset = shadow_index * kShadowPropertiesCount;
318 uint_data[shadow_count_offset + kColorOffset] ^ kColorDefault;
319 decoded_shadows.emplace_back(
321 SkPoint::Make(float_data[shadow_count_offset + kXOffset],
322 float_data[shadow_count_offset + kYOffset]),
323 float_data[shadow_count_offset + kBlurOffset]);
332 size_t feature_count = byte_data.
length_in_bytes() / kBytesPerFontFeature;
333 for (
size_t feature_index = 0; feature_index < feature_count;
335 size_t feature_offset = feature_index * kBytesPerFontFeature;
336 const char* feature_bytes =
337 static_cast<const char*
>(byte_data.
data()) + feature_offset;
338 std::string tag(feature_bytes, kFontFeatureTagLength);
339 int32_t
value = *(
reinterpret_cast<const int32_t*
>(feature_bytes +
340 kFontFeatureTagLength));
350 size_t variation_count = byte_data.
length_in_bytes() / kBytesPerFontVariation;
351 for (
size_t variation_index = 0; variation_index < variation_count;
353 size_t variation_offset = variation_index * kBytesPerFontVariation;
354 const char* variation_bytes =
355 static_cast<const char*
>(byte_data.
data()) + variation_offset;
356 std::string tag(variation_bytes, kFontVariationTagLength);
357 float value = *(
reinterpret_cast<const float*
>(variation_bytes +
358 kFontVariationTagLength));
364 const std::vector<std::string>& fontFamilies,
366 double letterSpacing,
369 double decorationThickness,
370 const std::string& locale,
371 Dart_Handle background_objects,
372 Dart_Handle background_data,
373 Dart_Handle foreground_objects,
374 Dart_Handle foreground_data,
375 Dart_Handle shadows_data,
376 Dart_Handle font_features_data,
377 Dart_Handle font_variations_data) {
380 int32_t mask = encoded[0];
389 if (mask & kTSColorMask) {
390 style.
color = encoded[kTSColorIndex];
393 if (mask & kTSTextDecorationMask) {
398 if (mask & kTSTextDecorationColorMask) {
402 if (mask & kTSTextDecorationStyleMask) {
404 encoded[kTSTextDecorationStyleIndex]);
407 if (mask & kTSTextDecorationThicknessMask) {
411 if (mask & kTSTextBaselineMask) {
416 if (mask & (kTSFontWeightMask | kTSFontStyleMask | kTSFontSizeMask |
417 kTSLetterSpacingMask | kTSWordSpacingMask)) {
418 if (mask & kTSFontWeightMask) {
422 if (mask & kTSFontStyleMask) {
427 if (mask & kTSFontSizeMask) {
431 if (mask & kTSLetterSpacingMask) {
435 if (mask & kTSWordSpacingMask) {
440 if (mask & kTSHeightMask) {
445 if (mask & kTSLocaleMask) {
449 if (mask & kTSBackgroundMask) {
450 Paint background(background_objects, background_data);
451 if (background.isNotNull()) {
459 if (mask & kTSForegroundMask) {
460 Paint foreground(foreground_objects, foreground_data);
461 if (foreground.isNotNull()) {
469 if (mask & kTSTextShadowsMask) {
473 if (mask & kTSFontFamilyMask) {
480 if (mask & kTSFontFeaturesMask) {
484 if (mask & kTSFontVariationsMask) {
488 m_paragraph_builder_->PushStyle(style);
492 m_paragraph_builder_->Pop();
503 const UChar* text_ptr =
reinterpret_cast<const UChar*
>(
text.data());
504 UErrorCode error_code = U_ZERO_ERROR;
505 u_strToUTF8(
nullptr, 0,
nullptr, text_ptr,
text.size(), &error_code);
506 if (error_code != U_BUFFER_OVERFLOW_ERROR) {
510 m_paragraph_builder_->AddText(
text);
518 double baseline_offset,
524 m_paragraph_builder_->AddPlaceholder(placeholder_run);
529 m_paragraph_builder_.reset();
static constexpr DisplayListAttributeFlags kDrawParagraphFlags
static void Create(Dart_Handle wrapper, Dart_Handle encoded_handle, Dart_Handle strutData, const std::string &fontFamily, const std::vector< std::string > &strutFontFamilies, double fontSize, double height, const std::u16string &ellipsis, const std::string &locale)
void build(Dart_Handle paragraph_handle)
void pushStyle(const tonic::Int32List &encoded, const std::vector< std::string > &fontFamilies, double fontSize, double letterSpacing, double wordSpacing, double height, double decorationThickness, const std::string &locale, Dart_Handle background_objects, Dart_Handle background_data, Dart_Handle foreground_objects, Dart_Handle foreground_data, Dart_Handle shadows_data, Dart_Handle font_features_data, Dart_Handle font_variations_data)
~ParagraphBuilder() override
void addPlaceholder(double width, double height, unsigned alignment, double baseline_offset, unsigned baseline)
Dart_Handle addText(const std::u16string &text)
static void Create(Dart_Handle paragraph_handle, std::unique_ptr< txt::Paragraph > txt_paragraph)
PlatformConfiguration * platform_configuration() const
bool IsImpellerEnabled() const
Whether Impeller is enabled for this application.
static UIDartState * Current()
static void ThrowIfUIOperationsProhibited()
const void * data() const
size_t length_in_bytes() const
void SetFeature(const std::string &tag, int value)
void SetAxisValue(const std::string &tag, float value)
static std::unique_ptr< ParagraphBuilder > CreateSkiaBuilder(const ParagraphStyle &style, const std::shared_ptr< FontCollection > &font_collection, const bool impeller_enabled)
Creates a |ParagraphBuilder| based on Skia's text layout module.
bool strut_has_height_override
TextDirection text_direction
size_t text_height_behavior
FontStyle strut_font_style
std::vector< std::string > strut_font_families
std::vector< std::string > font_families
std::optional< flutter::DlPaint > foreground
TextDecorationStyle decoration_style
FontFeatures font_features
FontVariations font_variations
std::vector< TextShadow > text_shadows
double decoration_thickness_multiplier
std::optional< flutter::DlPaint > background
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
void decodeStrut(Dart_Handle strut_data, const std::vector< std::string > &strut_font_families, txt::ParagraphStyle ¶graph_style)
void decodeFontVariations(Dart_Handle font_variations_data, txt::FontVariations &font_variations)
void decodeTextShadows(Dart_Handle shadows_data, std::vector< txt::TextShadow > &decoded_shadows)
void decodeFontFeatures(Dart_Handle font_features_data, txt::FontFeatures &font_features)
Dart_Handle ToDart(const T &object)
PlaceholderAlignment
Where to vertically align the placeholder relative to the surrounding text.