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) {
486 positions.
get()[i] =
info->positions[i] +
info->origin;
488 positions.
get()[
N] = {
info->advanceX, positions.
get()[
N - 1].fY };
491 jruns.call<
void>(
"push", jrun);
495 info->font.getMetrics(&fm);
497 accum.minAscent = std::min(accum.minAscent, fm.
fAscent);
498 accum.maxDescent = std::max(accum.maxDescent, fm.
fDescent);
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]);
527 class_<para::Paragraph>(
"Paragraph")
528 .function(
"didExceedMaxLines", ¶::Paragraph::didExceedMaxLines)
529 .function(
"getAlphabeticBaseline", ¶::Paragraph::getAlphabeticBaseline)
530 .function(
"getGlyphPositionAtCoordinate", ¶::Paragraph::getGlyphPositionAtCoordinate)
531 .function(
"getHeight", ¶::Paragraph::getHeight)
532 .function(
"getIdeographicBaseline", ¶::Paragraph::getIdeographicBaseline)
535 .function(
"getLineNumberAt", ¶::Paragraph::getLineNumberAt)
536 .function(
"getLongestLine", ¶::Paragraph::getLongestLine)
537 .function(
"getMaxIntrinsicWidth", ¶::Paragraph::getMaxIntrinsicWidth)
538 .function(
"getMaxWidth", ¶::Paragraph::getMaxWidth)
539 .function(
"getMinIntrinsicWidth", ¶::Paragraph::getMinIntrinsicWidth)
540 .function(
"getNumberOfLines", ¶::Paragraph::lineNumber)
546 .function(
"getWordBoundary", ¶::Paragraph::getWordBoundary)
547 .function(
"layout", ¶::Paragraph::layout)
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();
559 auto pb = para::ParagraphBuilderImpl::make(ps, fc,
get_unicode());
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();
573 auto pb = para::ParagraphBuilderImpl::make(ps, fc,
get_unicode());
574 return std::unique_ptr<para::ParagraphBuilderImpl>(
577 allow_raw_pointers())
579 "_MakeFromFontCollection",
582 -> std::unique_ptr<para::ParagraphBuilderImpl> {
584 auto pb = para::ParagraphBuilderImpl::make(ps, fontCollection,
get_unicode());
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();
610 auto pb = para::ParagraphBuilder::make(pstyle, fc,
get_unicode());
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())
648 .class_function(
"RequiresClientICU", ¶::ParagraphBuilderImpl::RequiresClientICU)
653 .function(
"build", ¶::ParagraphBuilderImpl::Build, 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())
663 .
function(
"pop", ¶::ParagraphBuilderImpl::pop)
664 .function(
"reset", ¶::ParagraphBuilderImpl::Reset, 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())
784 .
function(
"enableFontFallback", ¶::FontCollection::enableFontFallback);
787 value_object<para::PositionWithAffinity>(
"PositionWithAffinity")
788 .field(
"pos", ¶::PositionWithAffinity::position)
789 .field(
"affinity", ¶::PositionWithAffinity::affinity);
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")
858 constant(
"NoDecoration",
int(para::TextDecoration::kNoDecoration));
859 constant(
"UnderlineDecoration",
int(para::TextDecoration::kUnderline));
860 constant(
"OverlineDecoration",
int(para::TextDecoration::kOverline));
861 constant(
"LineThroughDecoration",
int(para::TextDecoration::kLineThrough));
PlaceholderAlignment
Where to vertically align the placeholder relative to the surrounding text.