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"
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;
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;
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,
179 const uint8_t* uint8_data =
static_cast<const uint8_t*
>(byte_data.
data());
180 uint8_t mask = uint8_data[0];
185 size_t byte_count = 1;
186 if (mask & kSFontWeightMask) {
190 if (mask & kSFontStyleMask) {
197 std::vector<float> float_data;
199 memcpy(float_data.data(),
200 static_cast<const char*
>(byte_data.
data()) + byte_count,
202 size_t float_count = 0;
203 if (mask & kSFontSizeMask) {
206 if (mask & kSHeightMask) {
207 paragraph_style.
strut_height = float_data[float_count++];
210 if (mask & kSLeadingMask) {
218 if (mask & kSFontFamilyMask) {
227ParagraphBuilder::ParagraphBuilder(
230 const std::string& fontFamily,
231 const std::vector<std::string>& strutFontFamilies,
234 const std::u16string& ellipsis,
235 const std::string& locale) {
239 tonic::Int32List encoded(encoded_data);
243 if (mask & kPSTextAlignMask) {
248 if (mask & kPSTextDirectionMask) {
253 if (mask & kPSFontWeightMask) {
258 if (mask & kPSFontStyleMask) {
263 if (mask & kPSFontFamilyMask) {
267 if (mask & kPSFontSizeMask) {
271 if (mask & kPSHeightMask) {
276 if (mask & kPSTextHeightBehaviorMask) {
280 if (mask & kPSMaxLinesMask) {
281 style.
max_lines = encoded[kPSMaxLinesIndex];
285 if (mask & kPSStrutStyleMask) {
289 if (mask & kPSEllipsisMask) {
293 if (mask & kPSLocaleMask) {
304 style, font_collection.GetFontCollection(), impeller_enabled);
311 std::vector<txt::TextShadow>& decoded_shadows) {
312 decoded_shadows.clear();
317 const uint32_t* uint_data =
static_cast<const uint32_t*
>(byte_data.
data());
318 const float* float_data =
static_cast<const float*
>(byte_data.
data());
321 size_t shadow_count_offset = 0;
322 for (
size_t shadow_index = 0; shadow_index < shadow_count; ++shadow_index) {
323 shadow_count_offset = shadow_index * kShadowPropertiesCount;
325 uint_data[shadow_count_offset + kColorOffset] ^
kColorDefault;
326 decoded_shadows.emplace_back(
329 float_data[shadow_count_offset + kYOffset]),
330 float_data[shadow_count_offset + kBlurOffset]);
339 size_t feature_count = byte_data.
length_in_bytes() / kBytesPerFontFeature;
340 for (
size_t feature_index = 0; feature_index < feature_count;
342 size_t feature_offset = feature_index * kBytesPerFontFeature;
343 const char* feature_bytes =
344 static_cast<const char*
>(byte_data.
data()) + feature_offset;
345 std::string tag(feature_bytes, kFontFeatureTagLength);
346 int32_t
value = *(
reinterpret_cast<const int32_t*
>(feature_bytes +
347 kFontFeatureTagLength));
357 size_t variation_count = byte_data.
length_in_bytes() / kBytesPerFontVariation;
358 for (
size_t variation_index = 0; variation_index < variation_count;
360 size_t variation_offset = variation_index * kBytesPerFontVariation;
361 const char* variation_bytes =
362 static_cast<const char*
>(byte_data.
data()) + variation_offset;
363 std::string tag(variation_bytes, kFontVariationTagLength);
364 float value = *(
reinterpret_cast<const float*
>(variation_bytes +
365 kFontVariationTagLength));
371 const std::vector<std::string>& fontFamilies,
373 double letterSpacing,
376 double decorationThickness,
377 const std::string& locale,
387 int32_t mask = encoded[0];
396 if (mask & kTSColorMask) {
397 style.
color = encoded[kTSColorIndex];
400 if (mask & kTSTextDecorationMask) {
405 if (mask & kTSTextDecorationColorMask) {
409 if (mask & kTSTextDecorationStyleMask) {
411 encoded[kTSTextDecorationStyleIndex]);
414 if (mask & kTSTextDecorationThicknessMask) {
418 if (mask & kTSTextBaselineMask) {
423 if (mask & (kTSFontWeightMask | kTSFontStyleMask | kTSFontSizeMask |
424 kTSLetterSpacingMask | kTSWordSpacingMask)) {
425 if (mask & kTSFontWeightMask) {
430 if (mask & kTSFontStyleMask) {
435 if (mask & kTSFontSizeMask) {
439 if (mask & kTSLetterSpacingMask) {
443 if (mask & kTSWordSpacingMask) {
448 if (mask & kTSHeightMask) {
453 if (mask & kTSLocaleMask) {
457 if (mask & kTSBackgroundMask) {
458 Paint background(background_objects, background_data);
466 if (mask & kTSForegroundMask) {
467 Paint foreground(foreground_objects, foreground_data);
475 if (mask & kTSTextShadowsMask) {
479 if (mask & kTSFontFamilyMask) {
486 if (mask & kTSFontFeaturesMask) {
490 if (mask & kTSFontVariationsMask) {
494 m_paragraph_builder_->PushStyle(style);
498 m_paragraph_builder_->Pop();
509 const UChar* text_ptr =
reinterpret_cast<const UChar*
>(
text.data());
510 UErrorCode error_code = U_ZERO_ERROR;
511 u_strToUTF8(
nullptr, 0,
nullptr, text_ptr,
text.size(), &error_code);
512 if (error_code != U_BUFFER_OVERFLOW_ERROR) {
516 m_paragraph_builder_->AddText(
text);
524 double baseline_offset,
530 m_paragraph_builder_->AddPlaceholder(placeholder_run);
535 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 FML_CHECK(condition)
#define FML_DCHECK(condition)
IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, FlutterGpuTestClass)
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)
const double kTextHeightNone