5#include "flutter/lib/ui/text/paragraph_builder.h"
9#include "flutter/common/settings.h"
10#include "flutter/common/task_runners.h"
11#include "flutter/fml/logging.h"
12#include "flutter/fml/task_runner.h"
13#include "flutter/lib/ui/text/font_collection.h"
14#include "flutter/lib/ui/ui_dart_state.h"
15#include "flutter/lib/ui/window/platform_configuration.h"
16#include "flutter/third_party/txt/src/txt/font_style.h"
17#include "flutter/third_party/txt/src/txt/font_weight.h"
18#include "flutter/third_party/txt/src/txt/paragraph_style.h"
19#include "flutter/third_party/txt/src/txt/text_baseline.h"
20#include "flutter/third_party/txt/src/txt/text_decoration.h"
21#include "flutter/third_party/txt/src/txt/text_style.h"
22#include "third_party/icu/source/common/unicode/ustring.h"
35const int kTSLeadingDistributionIndex = 0;
36const int kTSColorIndex = 1;
37const int kTSTextDecorationIndex = 2;
38const int kTSTextDecorationColorIndex = 3;
39const int kTSTextDecorationStyleIndex = 4;
40const int kTSFontWeightIndex = 5;
41const int kTSFontStyleIndex = 6;
42const int kTSTextBaselineIndex = 7;
43const int kTSTextDecorationThicknessIndex = 8;
44const int kTSFontFamilyIndex = 9;
45const int kTSFontSizeIndex = 10;
46const int kTSLetterSpacingIndex = 11;
47const int kTSWordSpacingIndex = 12;
48const int kTSHeightIndex = 13;
49const int kTSLocaleIndex = 14;
50const int kTSBackgroundIndex = 15;
51const int kTSForegroundIndex = 16;
52const int kTSTextShadowsIndex = 17;
53const int kTSFontFeaturesIndex = 18;
54const int kTSFontVariationsIndex = 19;
56const int kTSLeadingDistributionMask = 1 << kTSLeadingDistributionIndex;
57const int kTSColorMask = 1 << kTSColorIndex;
58const int kTSTextDecorationMask = 1 << kTSTextDecorationIndex;
59const int kTSTextDecorationColorMask = 1 << kTSTextDecorationColorIndex;
60const int kTSTextDecorationStyleMask = 1 << kTSTextDecorationStyleIndex;
61const int kTSTextDecorationThicknessMask = 1 << kTSTextDecorationThicknessIndex;
62const int kTSFontWeightMask = 1 << kTSFontWeightIndex;
63const int kTSFontStyleMask = 1 << kTSFontStyleIndex;
64const int kTSTextBaselineMask = 1 << kTSTextBaselineIndex;
65const int kTSFontFamilyMask = 1 << kTSFontFamilyIndex;
66const int kTSFontSizeMask = 1 << kTSFontSizeIndex;
67const int kTSLetterSpacingMask = 1 << kTSLetterSpacingIndex;
68const int kTSWordSpacingMask = 1 << kTSWordSpacingIndex;
69const int kTSHeightMask = 1 << kTSHeightIndex;
70const int kTSLocaleMask = 1 << kTSLocaleIndex;
71const int kTSBackgroundMask = 1 << kTSBackgroundIndex;
72const int kTSForegroundMask = 1 << kTSForegroundIndex;
73const int kTSTextShadowsMask = 1 << kTSTextShadowsIndex;
74const int kTSFontFeaturesMask = 1 << kTSFontFeaturesIndex;
75const int kTSFontVariationsMask = 1 << kTSFontVariationsIndex;
79const int kPSTextAlignIndex = 1;
80const int kPSTextDirectionIndex = 2;
81const int kPSFontWeightIndex = 3;
82const int kPSFontStyleIndex = 4;
83const int kPSMaxLinesIndex = 5;
84const int kPSTextHeightBehaviorIndex = 6;
85const int kPSFontFamilyIndex = 7;
86const int kPSFontSizeIndex = 8;
87const int kPSHeightIndex = 9;
88const int kPSStrutStyleIndex = 10;
89const int kPSEllipsisIndex = 11;
90const int kPSLocaleIndex = 12;
92const int kPSTextAlignMask = 1 << kPSTextAlignIndex;
93const int kPSTextDirectionMask = 1 << kPSTextDirectionIndex;
94const int kPSFontWeightMask = 1 << kPSFontWeightIndex;
95const int kPSFontStyleMask = 1 << kPSFontStyleIndex;
96const int kPSMaxLinesMask = 1 << kPSMaxLinesIndex;
97const int kPSFontFamilyMask = 1 << kPSFontFamilyIndex;
98const int kPSFontSizeMask = 1 << kPSFontSizeIndex;
99const int kPSHeightMask = 1 << kPSHeightIndex;
100const int kPSTextHeightBehaviorMask = 1 << kPSTextHeightBehaviorIndex;
101const int kPSStrutStyleMask = 1 << kPSStrutStyleIndex;
102const int kPSEllipsisMask = 1 << kPSEllipsisIndex;
103const int kPSLocaleMask = 1 << kPSLocaleIndex;
108constexpr uint32_t kBytesPerShadow = 16;
109constexpr uint32_t kShadowPropertiesCount = 4;
110constexpr uint32_t kColorOffset = 0;
111constexpr uint32_t kXOffset = 1;
112constexpr uint32_t kYOffset = 2;
113constexpr uint32_t kBlurOffset = 3;
116constexpr uint32_t kBytesPerFontFeature = 8;
117constexpr uint32_t kFontFeatureTagLength = 4;
120constexpr uint32_t kBytesPerFontVariation = 8;
121constexpr uint32_t kFontVariationTagLength = 4;
124const int kSFontWeightIndex = 0;
125const int kSFontStyleIndex = 1;
126const int kSFontFamilyIndex = 2;
127const int kSLeadingDistributionIndex = 3;
128const int kSFontSizeIndex = 4;
129const int kSHeightIndex = 5;
130const int kSLeadingIndex = 6;
131const int kSForceStrutHeightIndex = 7;
133const int kSFontWeightMask = 1 << kSFontWeightIndex;
134const int kSFontStyleMask = 1 << kSFontStyleIndex;
135const int kSFontFamilyMask = 1 << kSFontFamilyIndex;
136const int kSLeadingDistributionMask = 1 << kSLeadingDistributionIndex;
137const int kSFontSizeMask = 1 << kSFontSizeIndex;
138const int kSHeightMask = 1 << kSHeightIndex;
139const int kSLeadingMask = 1 << kSLeadingIndex;
140const int kSForceStrutHeightMask = 1 << kSForceStrutHeightIndex;
149 const std::string& fontFamily,
150 const std::vector<std::string>& strutFontFamilies,
153 const std::u16string& ellipsis,
154 const std::string& locale) {
156 auto res = fml::MakeRefCounted<ParagraphBuilder>(
157 encoded_handle, strutData, fontFamily, strutFontFamilies, fontSize,
158 height, ellipsis, locale);
159 res->AssociateWithDartWrapper(wrapper);
165 const std::vector<std::string>& strut_font_families,
177 const uint8_t* uint8_data =
static_cast<const uint8_t*
>(byte_data.
data());
178 uint8_t mask = uint8_data[0];
183 size_t byte_count = 1;
184 if (mask & kSFontWeightMask) {
188 if (mask & kSFontStyleMask) {
195 std::vector<float> float_data;
197 memcpy(float_data.data(),
198 static_cast<const char*
>(byte_data.
data()) + byte_count,
200 size_t float_count = 0;
201 if (mask & kSFontSizeMask) {
204 if (mask & kSHeightMask) {
205 paragraph_style.
strut_height = float_data[float_count++];
208 if (mask & kSLeadingMask) {
216 if (mask & kSFontFamilyMask) {
225ParagraphBuilder::ParagraphBuilder(
228 const std::string& fontFamily,
229 const std::vector<std::string>& strutFontFamilies,
232 const std::u16string& ellipsis,
233 const std::string& locale) {
237 tonic::Int32List encoded(encoded_data);
241 if (mask & kPSTextAlignMask) {
246 if (mask & kPSTextDirectionMask) {
251 if (mask & kPSFontWeightMask) {
256 if (mask & kPSFontStyleMask) {
261 if (mask & kPSFontFamilyMask) {
265 if (mask & kPSFontSizeMask) {
269 if (mask & kPSHeightMask) {
274 if (mask & kPSTextHeightBehaviorMask) {
278 if (mask & kPSMaxLinesMask) {
279 style.
max_lines = encoded[kPSMaxLinesIndex];
283 if (mask & kPSStrutStyleMask) {
287 if (mask & kPSEllipsisMask) {
291 if (mask & kPSLocaleMask) {
302 style, font_collection.GetFontCollection(), impeller_enabled);
309 std::vector<txt::TextShadow>& decoded_shadows) {
310 decoded_shadows.clear();
315 const uint32_t* uint_data =
static_cast<const uint32_t*
>(byte_data.
data());
316 const float* float_data =
static_cast<const float*
>(byte_data.
data());
319 size_t shadow_count_offset = 0;
320 for (
size_t shadow_index = 0; shadow_index < shadow_count; ++shadow_index) {
321 shadow_count_offset = shadow_index * kShadowPropertiesCount;
323 uint_data[shadow_count_offset + kColorOffset] ^
kColorDefault;
324 decoded_shadows.emplace_back(
327 float_data[shadow_count_offset + kYOffset]),
328 float_data[shadow_count_offset + kBlurOffset]);
337 size_t feature_count = byte_data.
length_in_bytes() / kBytesPerFontFeature;
338 for (
size_t feature_index = 0; feature_index < feature_count;
340 size_t feature_offset = feature_index * kBytesPerFontFeature;
341 const char* feature_bytes =
342 static_cast<const char*
>(byte_data.
data()) + feature_offset;
343 std::string tag(feature_bytes, kFontFeatureTagLength);
344 int32_t
value = *(
reinterpret_cast<const int32_t*
>(feature_bytes +
345 kFontFeatureTagLength));
355 size_t variation_count = byte_data.
length_in_bytes() / kBytesPerFontVariation;
356 for (
size_t variation_index = 0; variation_index < variation_count;
358 size_t variation_offset = variation_index * kBytesPerFontVariation;
359 const char* variation_bytes =
360 static_cast<const char*
>(byte_data.
data()) + variation_offset;
361 std::string tag(variation_bytes, kFontVariationTagLength);
362 float value = *(
reinterpret_cast<const float*
>(variation_bytes +
363 kFontVariationTagLength));
369 const std::vector<std::string>& fontFamilies,
371 double letterSpacing,
374 double decorationThickness,
375 const std::string& locale,
385 int32_t mask = encoded[0];
394 if (mask & kTSColorMask) {
395 style.
color = encoded[kTSColorIndex];
398 if (mask & kTSTextDecorationMask) {
403 if (mask & kTSTextDecorationColorMask) {
407 if (mask & kTSTextDecorationStyleMask) {
409 encoded[kTSTextDecorationStyleIndex]);
412 if (mask & kTSTextDecorationThicknessMask) {
416 if (mask & kTSTextBaselineMask) {
421 if (mask & (kTSFontWeightMask | kTSFontStyleMask | kTSFontSizeMask |
422 kTSLetterSpacingMask | kTSWordSpacingMask)) {
423 if (mask & kTSFontWeightMask) {
428 if (mask & kTSFontStyleMask) {
433 if (mask & kTSFontSizeMask) {
437 if (mask & kTSLetterSpacingMask) {
441 if (mask & kTSWordSpacingMask) {
446 if (mask & kTSHeightMask) {
451 if (mask & kTSLocaleMask) {
455 if (mask & kTSBackgroundMask) {
456 Paint background(background_objects, background_data);
464 if (mask & kTSForegroundMask) {
465 Paint foreground(foreground_objects, foreground_data);
473 if (mask & kTSTextShadowsMask) {
477 if (mask & kTSFontFamilyMask) {
484 if (mask & kTSFontFeaturesMask) {
488 if (mask & kTSFontVariationsMask) {
492 m_paragraph_builder_->PushStyle(style);
496 m_paragraph_builder_->Pop();
507 const UChar* text_ptr =
reinterpret_cast<const UChar*
>(
text.data());
508 UErrorCode error_code = U_ZERO_ERROR;
509 u_strToUTF8(
nullptr, 0,
nullptr, text_ptr,
text.size(), &error_code);
510 if (error_code != U_BUFFER_OVERFLOW_ERROR) {
514 m_paragraph_builder_->AddText(
text);
522 double baseline_offset,
528 m_paragraph_builder_->AddPlaceholder(placeholder_run);
533 m_paragraph_builder_.reset();
void toDlPaint(DlPaint &paint) const
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(std::string tag, int value)
void SetAxisValue(std::string tag, float value)
static std::unique_ptr< ParagraphBuilder > CreateSkiaBuilder(const ParagraphStyle &style, 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
FontWeight strut_font_weight
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
struct _Dart_Handle * Dart_Handle
DART_EXPORT Dart_Handle Dart_Null(void)
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
constexpr uint32_t kColorDefault
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.
static constexpr SkPoint Make(float x, float y)