20#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
23#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
30#include <emscripten.h>
31#include <emscripten/bind.h>
41 float* fourFloats =
reinterpret_cast<float*
>(cPtr);
42 SkColor4f color = {fourFloats[0], fourFloats[1], fourFloats[2], fourFloats[3]};
57#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
114 const char** fontFamilies =
reinterpret_cast<const char**
>(
s.fontFamiliesPtr);
115 if (fontFamilies !=
nullptr) {
116 std::vector<SkString> ff;
117 for (
int i = 0;
i <
s.fontFamiliesLen;
i++) {
118 ff.emplace_back(fontFamilies[
i]);
123 SkFontStyle fs(
s.fontStyle.weight,
s.fontStyle.width,
s.fontStyle.slant);
126 if (
s.fontSize != -1) {
129 if (
s.heightMultiplier != -1) {
135 if (
s.leading != 0) {
153 if (
s.foregroundColorPtr) {
159 if (
s.backgroundColorPtr) {
165 if (
s.fontSize != -1) {
168 if (
s.letterSpacing != 0) {
171 if (
s.wordSpacing != 0) {
175 if (
s.heightMultiplier != -1) {
184 if (
s.decorationThickness != 0) {
187 if (
s.decorationColorPtr) {
191 if (
s.localeLen > 0) {
192 const char* localePtr =
reinterpret_cast<const char*
>(
s.localePtr);
197 const char** fontFamilies =
reinterpret_cast<const char**
>(
s.fontFamiliesPtr);
198 if (fontFamilies !=
nullptr) {
199 std::vector<SkString> ff;
200 for (
int i = 0;
i <
s.fontFamiliesLen;
i++) {
201 ff.emplace_back(fontFamilies[
i]);
208 SkFontStyle fs(
s.fontStyle.weight,
s.fontStyle.width,
s.fontStyle.slant);
211 if (
s.shadowLen > 0) {
214 const float* blurRadii =
reinterpret_cast<const float*
>(
s.shadowBlurRadiiPtr);
215 for (
int i = 0;
i <
s.shadowLen;
i++) {
222 if (
s.fontFeatureLen > 0) {
223 const char** fontFeatureNames =
reinterpret_cast<const char**
>(
s.fontFeatureNamesPtr);
224 const int* fontFeatureValues =
reinterpret_cast<const int*
>(
s.fontFeatureValuesPtr);
225 for (
int i = 0;
i <
s.fontFeatureLen;
i++) {
232 if (
s.fontVariationLen > 0) {
233 const char** fontVariationAxes =
reinterpret_cast<const char**
>(
s.fontVariationAxesPtr);
234 const float* fontVariationValues =
reinterpret_cast<const float*
>(
s.fontVariationValuesPtr);
235 std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates;
236 for (
int i = 0;
i <
s.fontVariationLen;
i++) {
239 if (axis.
size() != 4) {
242 coordinates.push_back({
244 fontVariationValues[
i]
249 static_cast<int>(coordinates.size())
274 if (
s.disableHinting) {
278 if (
s.ellipsisLen > 0) {
279 const char* ellipsisPtr =
reinterpret_cast<const char*
>(
s.ellipsisPtr);
280 SkString eStr(ellipsisPtr,
s.ellipsisLen);
289 if (
s.heightMultiplier != -1) {
292 if (
s.maxLines != 0) {
312 return emscripten::val::null();
315 for (
size_t i = 0;
i < boxes.size();
i++) {
316 rects[
i].
rect = boxes[
i].rect;
317 if (boxes[
i].direction == para::TextDirection::kRtl) {
323 float* fPtr =
reinterpret_cast<float*
>(rects);
326 return Float32Array(typed_memory_view(boxes.size() * 5, fPtr));
334 std::vector<para::TextBox> boxes =
self.getRectsForRange(
start,
end, heightStyle, widthStyle);
339 std::vector<para::TextBox> boxes =
self.getRectsForPlaceholders();
353 m.set(
"width", metrics.
fWidth);
354 m.set(
"left", metrics.
fLeft);
361 JSObject object = emscripten::val::object();
363 JSObject range = emscripten::val::object();
366 object.set(
"graphemeClusterTextRange", range);
373 object.set(
"graphemeLayoutBounds",
rect);
381 std::vector<skia::textlayout::LineMetrics> metrics;
382 self.getLineMetrics(metrics);
384 for (
auto metric : metrics) {
392 return self.getLineMetricsAt(lineNumber, &metrics)
394 : emscripten::val::null();
399 return self.getGlyphInfoAtUTF16Offset(index, &glyphInfo)
401 : emscripten::val::null();
406 return self.getClosestUTF16GlyphInfoAt(
dx, dy, &glyphInfo)
408 : emscripten::val::null();
415 struct LineAccumulate {
417 uint32_t minOffset = 0xFFFFFFFF;
418 uint32_t maxOffset = 0;
420 float maxDescent = 0;
424 void reset(
int newLineNum) {
425 new (
this) LineAccumulate;
426 this->lineNumber = newLineNum;
431 JSArray jlines = emscripten::val::array();
432 JSObject jline = emscripten::val::null();
433 JSArray jruns = emscripten::val::null();
434 LineAccumulate accum;
436 self.visit([&](
int lineNumber,
const para::Paragraph::VisitorInfo*
info) {
440 JSObject range = emscripten::val::object();
441 range.set(
"first", accum.minOffset);
442 range.set(
"last", accum.maxOffset);
443 jline.set(
"textRange", range);
445 jline.set(
"top", accum.baseline + accum.minAscent);
446 jline.set(
"bottom", accum.baseline + accum.maxDescent);
447 jline.set(
"baseline", accum.baseline);
451 if (lineNumber != accum.lineNumber) {
452 SkASSERT(lineNumber == accum.lineNumber + 1);
454 accum.reset(lineNumber);
455 jruns = emscripten::val::array();
457 jline = emscripten::val::object();
458 jline.set(
"runs", jruns);
461 jlines.call<
void>(
"push", jline);
465 const int N =
info->count;
466 const int N1 =
N + 1;
468 JSObject jrun = emscripten::val::object();
470 jrun.set(
"flags",
info->flags);
474 jrun.set(
"typeface", emscripten::val::null());
475 jrun.set(
"size",
info->font.getSize());
476 if (
info->font.getScaleX()) {
477 jrun.set(
"scaleX",
info->font.getScaleX());
485 for (
int i = 0;
i <
N; ++
i) {
488 positions.
get()[
N] = {
info->advanceX, positions.
get()[
N - 1].fY };
491 jruns.call<
void>(
"push", jrun);
495 info->font.getMetrics(&fm);
499 accum.baseline =
info->origin.fY;
501 accum.minOffset =
std::min(accum.minOffset,
info->utf8Starts[0]);
502 accum.maxOffset =
std::max(accum.maxOffset,
info->utf8Starts[
N]);
510 std::vector<size_t> vec;
513 std::memcpy(vec.data(),
data,
count *
sizeof(
size_t));
519 for (
auto cp :
self.unresolvedCodepoints()) {
520 result.call<
void>(
"push", cp);
527 class_<para::Paragraph>(
"Paragraph")
550 class_<para::ParagraphBuilderImpl>(
"ParagraphBuilder")
554 -> std::unique_ptr<para::ParagraphBuilderImpl> {
555 auto fc = sk_make_sp<para::FontCollection>();
556 fc->setDefaultFontManager(
fontMgr);
557 fc->enableFontFallback();
560 return std::unique_ptr<para::ParagraphBuilderImpl>(
563 allow_raw_pointers())
565 "_MakeFromFontProvider",
568 -> std::unique_ptr<para::ParagraphBuilderImpl> {
569 auto fc = sk_make_sp<para::FontCollection>();
570 fc->setDefaultFontManager(fontProvider);
571 fc->enableFontFallback();
574 return std::unique_ptr<para::ParagraphBuilderImpl>(
577 allow_raw_pointers())
579 "_MakeFromFontCollection",
582 -> std::unique_ptr<para::ParagraphBuilderImpl> {
585 return std::unique_ptr<para::ParagraphBuilderImpl>(
588 allow_raw_pointers())
592 std::string textStorage = jtext.as<std::string>();
593 const char*
text = textStorage.data();
594 size_t textCount = textStorage.size();
596 auto fc = sk_make_sp<para::FontCollection>();
598 fc->enableFontFallback();
613 size_t runCount = jruns[
"length"].as<
size_t>();
614 for (
size_t i = 0;
i < runCount; ++
i) {
615 emscripten::val r = jruns[
i];
621 const size_t subTextCount = r[
"length"].as<
size_t>();
622 if (subTextCount > textCount) {
623 return emscripten::val(
"block runs exceed text length!");
626 pb->pushStyle(style);
627 pb->addText(
text, subTextCount);
630 text += subTextCount;
631 textCount -= subTextCount;
633 if (textCount != 0) {
634 return emscripten::val(
"Didn't have enough block runs to cover text");
637 auto pa = pb->Build();
647 allow_raw_pointers())
655#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
656 auto [words, graphemeBreaks, lineBreaks] =
self.getClientICUData();
659 self.SetUnicode(clientICU);
662 }), allow_raw_pointers())
674 .function(
"_pushPaintStyle",
679 ts.setForegroundColor(foreground);
680 ts.setBackgroundColor(background);
690 self.addPlaceholder(ps);
695 return emscripten::val(std::string(
text.data(),
text.size()).c_str());
697 .function(
"_setWordsUtf8",
700#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
704 .function(
"_setWordsUtf16",
707#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
711 .function(
"_setGraphemeBreaksUtf8",
714#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
718 .function(
"_setGraphemeBreaksUtf16",
721#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
725 .function(
"_setLineBreaksUtf8",
728#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
730 std::vector<SkUnicode::LineBreakBefore> lineBreaks;
731 for (
size_t i = 0;
i < lineBreaksNum;
i += 2) {
732 auto pos = lineBreakData[
i];
733 auto breakType = lineBreakData[
i+1];
734 if (breakType == 0) {
740 self.setLineBreaksUtf8(std::move(lineBreaks));
743 .function(
"_setLineBreaksUtf16",
746#if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
748 std::vector<SkUnicode::LineBreakBefore> lineBreaks;
749 for (
size_t i = 0;
i < lineBreaksNum;
i += 2) {
750 auto pos = lineBreakData[
i];
751 auto breakType = lineBreakData[
i+1];
752 if (breakType == 0) {
758 self.setLineBreaksUtf16(std::move(lineBreaks));
762 class_<para::TypefaceFontProvider, base<SkFontMgr>>(
"TypefaceFontProvider")
765 return sk_make_sp<para::TypefaceFontProvider>();
770 const char* fPtr =
reinterpret_cast<const char*
>(familyPtr);
772 self.registerTypeface(typeface,
fStr);
773 }), allow_raw_pointers());
775 class_<para::FontCollection>(
"FontCollection")
778 return sk_make_sp<para::FontCollection>();
782 self.setDefaultFontManager(fontManager);
783 }), allow_raw_pointers())
787 value_object<para::PositionWithAffinity>(
"PositionWithAffinity")
791 value_object<SimpleFontStyle>(
"FontStyle")
796 value_object<SimpleParagraphStyle>(
"ParagraphStyle")
810 value_object<SimpleStrutStyle>(
"StrutStyle")
821 value_object<SimpleTextStyle>(
"TextStyle")
853 value_object<para::SkRange<size_t>>(
"URange")
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
TypedArray MakeTypedArray(int count, const T src[])
emscripten::val Float32Array
static sk_sp< SkFontMgr > RefEmpty()
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
void enableFontFallback()
size_t fEndIncludingNewline
size_t fEndExcludingWhitespaces
static bool RequiresClientICU()
static std::unique_ptr< ParagraphBuilder > make(const ParagraphStyle &style, sk_sp< FontCollection > fontCollection, sk_sp< SkUnicode > unicode)
std::unique_ptr< Paragraph > Build() override
static std::unique_ptr< ParagraphBuilder > make(const ParagraphStyle &style, sk_sp< FontCollection > fontCollection, sk_sp< SkUnicode > unicode)
virtual SkRange< size_t > getWordBoundary(unsigned offset)=0
SkScalar getAlphabeticBaseline()
virtual int getLineNumberAt(TextIndex codeUnitIndex) const =0
virtual size_t lineNumber()=0
virtual PositionWithAffinity getGlyphPositionAtCoordinate(SkScalar dx, SkScalar dy)=0
SkScalar getMinIntrinsicWidth()
SkScalar getIdeographicBaseline()
virtual void layout(SkScalar width)=0
SkScalar getLongestLine()
SkScalar getMaxIntrinsicWidth()
void setTypeface(sk_sp< SkTypeface > typeface)
void setDecorationStyle(TextDecorationStyle style)
void addShadow(TextShadow shadow)
void setFontFamilies(std::vector< SkString > families)
void setHeight(SkScalar height)
void setLetterSpacing(SkScalar letterSpacing)
void setWordSpacing(SkScalar wordSpacing)
void setColor(SkColor color)
void setHeightOverride(bool heightOverride)
void setTextBaseline(TextBaseline baseline)
void setFontStyle(SkFontStyle fontStyle)
void setBackgroundColor(SkPaint paint)
void setLocale(const SkString &locale)
void setHalfLeading(bool halfLeading)
void setFontSize(SkScalar size)
void setFontArguments(const std::optional< SkFontArguments > &args)
void setForegroundColor(SkPaint paint)
void addFontFeature(const SkString &fontFeature, int value)
void setDecorationColor(SkColor color)
void setDecoration(TextDecoration decoration)
void setDecorationThicknessMultiplier(SkScalar m)
sk_sp< SkFontMgr > fontMgr
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
sk_sp< SkBlender > blender SkRect rect
PODArray< SkColor > colors
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SKUNICODE_API sk_sp< SkUnicode > Make(SkSpan< char > text, std::vector< SkUnicode::Position > words, std::vector< SkUnicode::Position > graphemeBreaks, std::vector< SkUnicode::LineBreakBefore > lineBreaks)
SKUNICODE_API sk_sp< SkUnicode > Make()
DEF_SWITCHES_START aot vmservice shared library name
PlaceholderAlignment
Where to vertically align the placeholder relative to the surrounding text.
JSArray UnresolvedCodepoints(para::Paragraph &self)
JSObject GetClosestGlyphInfoAtCoordinate(para::Paragraph &self, SkScalar dx, SkScalar dy)
JSArray GetLineMetrics(para::Paragraph &self)
EMSCRIPTEN_BINDINGS(Paragraph)
para::TextStyle toTextStyle(const SimpleTextStyle &s)
JSObject GetLineMetricsAt(para::Paragraph &self, size_t lineNumber)
Float32Array GetRectsForRange(para::Paragraph &self, unsigned start, unsigned end, para::RectHeightStyle heightStyle, para::RectWidthStyle widthStyle)
JSObject JSObjectFromLineMetrics(skia::textlayout::LineMetrics &metrics)
JSArray GetShapedLines(para::Paragraph &self)
JSObject GetGlyphInfoAt(para::Paragraph &self, size_t index)
JSObject JSObjectFromGlyphInfo(skia::textlayout::Paragraph::GlyphInfo &glyphInfo)
Float32Array GetRectsForPlaceholders(para::Paragraph &self)
para::ParagraphStyle toParagraphStyle(const SimpleParagraphStyle &s)
para::StrutStyle toStrutStyle(const SimpleStrutStyle &s)
static sk_sp< SkUnicode > get_unicode()
std::vector< SkUnicode::Position > convertArrayU32(WASMPointerU32 array, size_t count)
SkColor4f toSkColor4f(WASMPointerF32 cPtr)
Float32Array TextBoxesToFloat32Array(std::vector< para::TextBox > boxes)
SkFontStyle::Weight weight
SkScalar heightMultiplier
para::TextDirection textDirection
SimpleStrutStyle strutStyle
SimpleTextStyle textStyle
bool replaceTabCharacters
para::TextAlign textAlign
WASMPointerU8 ellipsisPtr
para::TextHeightBehavior textHeightBehavior
SimpleFontStyle fontStyle
SkScalar heightMultiplier
WASMPointerU32 fontFamiliesPtr
SkScalar decorationThickness
WASMPointerF32 fontVariationValuesPtr
WASMPointerF32 shadowOffsetsPtr
WASMPointerF32 fontFeatureNamesPtr
WASMPointerU8 fontFamiliesPtr
SkScalar heightMultiplier
WASMPointerF32 shadowBlurRadiiPtr
WASMPointerF32 decorationColorPtr
WASMPointerF32 backgroundColorPtr
WASMPointerF32 fontFeatureValuesPtr
para::TextBaseline textBaseline
WASMPointerF32 foregroundColorPtr
SimpleFontStyle fontStyle
WASMPointerF32 shadowColorsPtr
para::TextDecorationStyle decorationStyle
WASMPointerF32 fontVariationAxesPtr
SkFontArguments & setVariationDesignPosition(VariationPosition position)
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fDescent
distance to reserve below baseline, typically positive
constexpr float left() const
constexpr float top() const
constexpr float right() const
constexpr float bottom() const
void setReplaceTabCharacters(bool value)
void setEllipsis(const std::u16string &ellipsis)
void setTextDirection(TextDirection direction)
void setTextStyle(const TextStyle &textStyle)
void setMaxLines(size_t maxLines)
void setHeight(SkScalar height)
void setStrutStyle(StrutStyle strutStyle)
void setTextHeightBehavior(TextHeightBehavior v)
void setTextAlign(TextAlign align)
void setApplyRoundingHack(bool value)
TextRange fGraphemeClusterTextRange
SkRect fGraphemeLayoutBounds
void setHalfLeading(bool halfLeading)
void setFontFamilies(std::vector< SkString > families)
void setFontStyle(SkFontStyle fontStyle)
void setHeight(SkScalar height)
void setStrutEnabled(bool v)
void setForceStrutHeight(bool v)
void setHeightOverride(bool v)
void setLeading(SkScalar Leading)
void setFontSize(SkScalar size)
std::shared_ptr< const fml::Mapping > data