/*
 * Copyright 2019 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkColor.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkString.h"

#include "modules/skparagraph/include/DartTypes.h"
#include "modules/skparagraph/include/Paragraph.h"
#include "modules/skparagraph/include/TextStyle.h"
#include "modules/skparagraph/include/TypefaceFontProvider.h"
#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
#include "modules/skparagraph/src/ParagraphImpl.h"

#include <string>
#include <vector>

#include <emscripten.h>
#include <emscripten/bind.h>
#include "modules/canvaskit/WasmCommon.h"

using namespace emscripten;

namespace para = skia::textlayout;

SkColor4f toSkColor4f(WASMPointerF32 cPtr) {
    float* fourFloats = reinterpret_cast<float*>(cPtr);
    SkColor4f color = {fourFloats[0], fourFloats[1], fourFloats[2], fourFloats[3]};
    return color;
}

struct SimpleFontStyle {
    SkFontStyle::Slant slant;
    SkFontStyle::Weight weight;
    SkFontStyle::Width width;
};

struct SimpleTextStyle {
    WASMPointerF32 colorPtr;
    WASMPointerF32 foregroundColorPtr;
    WASMPointerF32 backgroundColorPtr;
    uint8_t decoration;
    SkScalar decorationThickness;
    WASMPointerF32 decorationColorPtr;
    para::TextDecorationStyle decorationStyle;
    para::TextBaseline textBaseline;
    SkScalar fontSize;
    SkScalar letterSpacing;
    SkScalar wordSpacing;
    SkScalar heightMultiplier;
    bool halfLeading;
    WASMPointerU8 localePtr;
    int localeLen;
    SimpleFontStyle fontStyle;

    WASMPointerU8 fontFamiliesPtr;
    int fontFamiliesLen;

    int shadowLen;
    WASMPointerF32 shadowColorsPtr;
    WASMPointerF32 shadowOffsetsPtr;
    WASMPointerF32 shadowBlurRadiiPtr;

    int fontFeatureLen;
    WASMPointerF32 fontFeatureNamesPtr;
    WASMPointerF32 fontFeatureValuesPtr;

    int fontVariationLen;
    WASMPointerF32 fontVariationAxesPtr;
    WASMPointerF32 fontVariationValuesPtr;
};

struct SimpleStrutStyle {
    WASMPointerU32 fontFamiliesPtr;
    int fontFamiliesLen;
    SimpleFontStyle fontStyle;
    SkScalar fontSize;
    SkScalar heightMultiplier;
    bool halfLeading;
    SkScalar leading;
    bool strutEnabled;
    bool forceStrutHeight;
};

para::StrutStyle toStrutStyle(const SimpleStrutStyle& s) {
    para::StrutStyle ss;

    const char** fontFamilies = reinterpret_cast<const char**>(s.fontFamiliesPtr);
    if (fontFamilies != nullptr) {
        std::vector<SkString> ff;
        for (int i = 0; i < s.fontFamiliesLen; i++) {
            ff.emplace_back(fontFamilies[i]);
        }
        ss.setFontFamilies(ff);
    }

    SkFontStyle fs(s.fontStyle.weight, s.fontStyle.width, s.fontStyle.slant);
    ss.setFontStyle(fs);

    if (s.fontSize != 0) {
        ss.setFontSize(s.fontSize);
    }
    if (s.heightMultiplier != 0) {
        ss.setHeight(s.heightMultiplier);
        ss.setHeightOverride(true);
    }
    ss.setHalfLeading(s.halfLeading);

    if (s.leading != 0) {
        ss.setLeading(s.leading);
    }

    ss.setStrutEnabled(s.strutEnabled);
    ss.setForceStrutHeight(s.forceStrutHeight);

    return ss;
}

para::TextStyle toTextStyle(const SimpleTextStyle& s) {
    para::TextStyle ts;

    // textstyle.color doesn't support a 4f color, however the foreground and background fields
    // below do.
    ts.setColor(toSkColor4f(s.colorPtr).toSkColor());

    // It is functionally important that these paints be unset when no value was provided.
    if (s.foregroundColorPtr) {
        SkPaint p1;
        p1.setColor4f(toSkColor4f(s.foregroundColorPtr));
        ts.setForegroundColor(p1);
    }

    if (s.backgroundColorPtr) {
        SkPaint p2;
        p2.setColor4f(toSkColor4f(s.backgroundColorPtr));
        ts.setBackgroundColor(p2);
    }

    if (s.fontSize != 0) {
        ts.setFontSize(s.fontSize);
    }
    if (s.letterSpacing != 0) {
        ts.setLetterSpacing(s.letterSpacing);
    }
    if (s.wordSpacing != 0) {
        ts.setWordSpacing(s.wordSpacing);
    }

    if (s.heightMultiplier != 0) {
        ts.setHeight(s.heightMultiplier);
        ts.setHeightOverride(true);
    }

    ts.setHalfLeading(s.halfLeading);

    ts.setDecoration(para::TextDecoration(s.decoration));
    ts.setDecorationStyle(s.decorationStyle);
    if (s.decorationThickness != 0) {
        ts.setDecorationThicknessMultiplier(s.decorationThickness);
    }
    if (s.decorationColorPtr) {
        ts.setDecorationColor(toSkColor4f(s.decorationColorPtr).toSkColor());
    }

    if (s.localeLen > 0) {
        const char* localePtr = reinterpret_cast<const char*>(s.localePtr);
        SkString lStr(localePtr, s.localeLen);
        ts.setLocale(lStr);
    }

    const char** fontFamilies = reinterpret_cast<const char**>(s.fontFamiliesPtr);
    if (fontFamilies != nullptr) {
        std::vector<SkString> ff;
        for (int i = 0; i < s.fontFamiliesLen; i++) {
            ff.emplace_back(fontFamilies[i]);
        }
        ts.setFontFamilies(ff);
    }

    ts.setTextBaseline(s.textBaseline);

    SkFontStyle fs(s.fontStyle.weight, s.fontStyle.width, s.fontStyle.slant);
    ts.setFontStyle(fs);

    if (s.shadowLen > 0) {
        const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(s.shadowColorsPtr);
        const SkPoint* offsets = reinterpret_cast<const SkPoint*>(s.shadowOffsetsPtr);
        const float* blurRadii = reinterpret_cast<const float*>(s.shadowBlurRadiiPtr);
        for (int i = 0; i < s.shadowLen; i++) {
            para::TextShadow shadow(colors[i].toSkColor(), offsets[i], blurRadii[i]);
            ts.addShadow(shadow);
        }
    }


    if (s.fontFeatureLen > 0) {
        const char** fontFeatureNames = reinterpret_cast<const char**>(s.fontFeatureNamesPtr);
        const int* fontFeatureValues = reinterpret_cast<const int*>(s.fontFeatureValuesPtr);
        for (int i = 0; i < s.fontFeatureLen; i++) {
            // Font features names are 4-character simple strings.
            SkString name(fontFeatureNames[i], 4);
            ts.addFontFeature(name, fontFeatureValues[i]);
        }
    }

    if (s.fontVariationLen > 0) {
        const char** fontVariationAxes = reinterpret_cast<const char**>(s.fontVariationAxesPtr);
        const float* fontVariationValues = reinterpret_cast<const float*>(s.fontVariationValuesPtr);
        std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates;
        for (int i = 0; i < s.fontVariationLen; i++) {
            // Font variation axis tags are 4-character simple strings.
            SkString axis(fontVariationAxes[i]);
            if (axis.size() != 4) {
                continue;
            }
            coordinates.push_back({
                SkSetFourByteTag(axis[0], axis[1], axis[2], axis[3]),
                fontVariationValues[i]
            });
        }
        SkFontArguments::VariationPosition position = {
            coordinates.data(),
            static_cast<int>(coordinates.size())
        };
        ts.setFontArguments(SkFontArguments().setVariationDesignPosition(position));
    }

    return ts;
}

struct SimpleParagraphStyle {
    bool disableHinting;
    WASMPointerU8 ellipsisPtr;
    size_t ellipsisLen;
    SkScalar heightMultiplier;
    size_t maxLines;
    bool replaceTabCharacters;
    para::TextAlign textAlign;
    para::TextDirection textDirection;
    para::TextHeightBehavior textHeightBehavior;
    SimpleTextStyle textStyle;
    SimpleStrutStyle strutStyle;
};

para::ParagraphStyle toParagraphStyle(const SimpleParagraphStyle& s) {
    para::ParagraphStyle ps;
    if (s.disableHinting) {
        ps.turnHintingOff();
    }

    if (s.ellipsisLen > 0) {
        const char* ellipsisPtr = reinterpret_cast<const char*>(s.ellipsisPtr);
        SkString eStr(ellipsisPtr, s.ellipsisLen);
        ps.setEllipsis(eStr);
    }
    ps.setTextAlign(s.textAlign);
    ps.setTextDirection(s.textDirection);
    auto ts = toTextStyle(s.textStyle);
    ps.setTextStyle(ts);
    auto ss = toStrutStyle(s.strutStyle);
    ps.setStrutStyle(ss);
    if (s.heightMultiplier != 0) {
        ps.setHeight(s.heightMultiplier);
    }
    if (s.maxLines != 0) {
        ps.setMaxLines(s.maxLines);
    }
    ps.setTextHeightBehavior(s.textHeightBehavior);
    ps.setReplaceTabCharacters(s.replaceTabCharacters);
    return ps;
}

struct SimpleTextBox {
    SkRect rect;
    // This isn't the most efficient way to represent this, but it is much easier to keep
    // everything as floats when unpacking on the JS side.
    // 0.0 = RTL, 1.0 = LTr
    SkScalar direction;
};

Float32Array TextBoxesToFloat32Array(std::vector<para::TextBox> boxes) {
    // Pack these text boxes into an array of n groups of 5 SkScalar (floats)
    if (!boxes.size()) {
        return emscripten::val::null();
    }
    SimpleTextBox* rects = new SimpleTextBox[boxes.size()];
    for (size_t i = 0; i < boxes.size(); i++) {
        rects[i].rect = boxes[i].rect;
        if (boxes[i].direction == para::TextDirection::kRtl) {
            rects[i].direction = 0;
        } else {
            rects[i].direction = 1;
        }
    }
    float* fPtr = reinterpret_cast<float*>(rects);
    // Of note: now that we have cast rects to float*, emscripten is smart enough to wrap this
    // into a Float32Array for us.
    return Float32Array(typed_memory_view(boxes.size() * 5, fPtr));
}

Float32Array GetRectsForRange(para::Paragraph& self,
                              unsigned start,
                              unsigned end,
                              para::RectHeightStyle heightStyle,
                              para::RectWidthStyle widthStyle) {
    std::vector<para::TextBox> boxes = self.getRectsForRange(start, end, heightStyle, widthStyle);
    return TextBoxesToFloat32Array(boxes);
}

Float32Array GetRectsForPlaceholders(para::Paragraph& self) {
    std::vector<para::TextBox> boxes = self.getRectsForPlaceholders();
    return TextBoxesToFloat32Array(boxes);
}

JSArray GetLineMetrics(para::Paragraph& self) {
    std::vector<skia::textlayout::LineMetrics> metrics;
    self.getLineMetrics(metrics);
    JSArray result = emscripten::val::array();
    for (auto metric : metrics) {
        JSObject m = emscripten::val::object();
        m.set("startIndex", metric.fStartIndex);
        m.set("endIndex", metric.fEndIndex);
        m.set("endExcludingWhitespaces", metric.fEndExcludingWhitespaces);
        m.set("endIncludingNewline", metric.fEndIncludingNewline);
        m.set("isHardBreak", metric.fHardBreak);
        m.set("ascent", metric.fAscent);
        m.set("descent", metric.fDescent);
        m.set("height", metric.fHeight);
        m.set("width", metric.fWidth);
        m.set("left", metric.fLeft);
        m.set("baseline", metric.fBaseline);
        m.set("lineNumber", metric.fLineNumber);
        result.call<void>("push", m);
    }
    return result;
}

/*
 *  Returns Lines[]
 */
JSArray GetShapedLines(para::Paragraph& self) {
    struct LineAccumulate {
        int         lineNumber  = -1;   // deliberately -1 from starting value
        uint32_t    minOffset   = 0xFFFFFFFF;
        uint32_t    maxOffset   = 0;
        float       minAscent   = 0;
        float       maxDescent  = 0;
        // not really accumulated, but definitely set
        float       baseline    = 0;

        void reset(int newLineNum) {
            new (this) LineAccumulate;
            this->lineNumber = newLineNum;
        }
    };

    // where we accumulate our js output
    JSArray  jlines = emscripten::val::array();
    JSObject jline = emscripten::val::null();
    JSArray  jruns = emscripten::val::null();
    LineAccumulate accum;

    self.visit([&](int lineNumber, const para::Paragraph::VisitorInfo* info) {
        if (!info) {
            if (!jline) return; // how???
            // end of current line
            JSObject range = emscripten::val::object();
            range.set("first", accum.minOffset);
            range.set("last",  accum.maxOffset);
            jline.set("textRange", range);

            jline.set("top", accum.baseline + accum.minAscent);
            jline.set("bottom", accum.baseline + accum.maxDescent);
            jline.set("baseline", accum.baseline);
            return;
        }

        if (lineNumber != accum.lineNumber) {
            SkASSERT(lineNumber == accum.lineNumber + 1);   // assume monotonic

            accum.reset(lineNumber);
            jruns = emscripten::val::array();

            jline = emscripten::val::object();
            jline.set("runs", jruns);
            // will assign textRange and metrics on end-of-line signal

            jlines.call<void>("push", jline);
        }

        // append the run
        const int N = info->count;   // glyphs
        const int N1 = N + 1;       // positions, offsets have 1 extra (trailing) slot

        JSObject jrun = emscripten::val::object();

        jrun.set("flags",    info->flags);

// TODO: figure out how to set a wrapped sk_sp<SkTypeface>
//        jrun.set("typeface", info->font.getTypeface());
        jrun.set("typeface",    emscripten::val::null());
        jrun.set("size",        info->font.getSize());
        if (info->font.getScaleX()) {
            jrun.set("scaleX",  info->font.getScaleX());
        }

        jrun.set("glyphs",   MakeTypedArray(N,  info->glyphs));
        jrun.set("offsets",  MakeTypedArray(N1, info->utf8Starts));

        // we need to modify the positions, so make a temp copy
        SkAutoSTMalloc<32, SkPoint> positions(N1);
        for (int i = 0; i < N; ++i) {
            positions.get()[i] = info->positions[i] + info->origin;
        }
        positions.get()[N] = { info->advanceX, positions.get()[N - 1].fY };
        jrun.set("positions", MakeTypedArray(N1*2, (const float*)positions.get()));

        jruns.call<void>("push", jrun);

        // update accum
        {   SkFontMetrics fm;
            info->font.getMetrics(&fm);

            accum.minAscent  = std::min(accum.minAscent,  fm.fAscent);
            accum.maxDescent = std::max(accum.maxDescent, fm.fDescent);
            accum.baseline   = info->origin.fY;

            accum.minOffset  = std::min(accum.minOffset,  info->utf8Starts[0]);
            accum.maxOffset  = std::max(accum.maxOffset,  info->utf8Starts[N]);
        }

    });
    return jlines;
}

std::vector<SkUnicode::Position> convertArrayU32(WASMPointerU32 array, size_t count) {
    std::vector<size_t> vec;
    vec.resize(count);
    SkUnicode::Position* data = reinterpret_cast<SkUnicode::Position*>(array);
    std::memcpy(vec.data(), data, count * sizeof(size_t));
    return vec;
}

EMSCRIPTEN_BINDINGS(Paragraph) {

    class_<para::Paragraph>("Paragraph")
        .function("didExceedMaxLines", &para::Paragraph::didExceedMaxLines)
        .function("getAlphabeticBaseline", &para::Paragraph::getAlphabeticBaseline)
        .function("getGlyphPositionAtCoordinate", &para::Paragraph::getGlyphPositionAtCoordinate)
        .function("getHeight", &para::Paragraph::getHeight)
        .function("getIdeographicBaseline", &para::Paragraph::getIdeographicBaseline)
        .function("getLineMetrics", &GetLineMetrics)
        .function("getLongestLine", &para::Paragraph::getLongestLine)
        .function("getMaxIntrinsicWidth", &para::Paragraph::getMaxIntrinsicWidth)
        .function("getMaxWidth", &para::Paragraph::getMaxWidth)
        .function("getMinIntrinsicWidth", &para::Paragraph::getMinIntrinsicWidth)
        .function("_getRectsForPlaceholders", &GetRectsForPlaceholders)
        .function("_getRectsForRange", &GetRectsForRange)
        .function("getShapedLines", &GetShapedLines)
        .function("getWordBoundary", &para::Paragraph::getWordBoundary)
        .function("layout", &para::Paragraph::layout);

    class_<para::ParagraphBuilderImpl>("ParagraphBuilder")
            .class_function(
                    "_Make",
                    optional_override([](SimpleParagraphStyle style, sk_sp<SkFontMgr> fontMgr)
                                              -> std::unique_ptr<para::ParagraphBuilderImpl> {
                        auto fc = sk_make_sp<para::FontCollection>();
                        fc->setDefaultFontManager(fontMgr);
                        fc->enableFontFallback();
                        auto ps = toParagraphStyle(style);
                        auto pb = para::ParagraphBuilderImpl::make(ps, fc);
                        return std::unique_ptr<para::ParagraphBuilderImpl>(
                                static_cast<para::ParagraphBuilderImpl*>(pb.release()));
                    }),
                    allow_raw_pointers())
            .class_function(
                    "_MakeFromFontProvider",
                    optional_override([](SimpleParagraphStyle style,
                                         sk_sp<para::TypefaceFontProvider> fontProvider)
                                              -> std::unique_ptr<para::ParagraphBuilderImpl> {
                        auto fc = sk_make_sp<para::FontCollection>();
                        fc->setDefaultFontManager(fontProvider);
                        fc->enableFontFallback();
                        auto ps = toParagraphStyle(style);
                        auto pb = para::ParagraphBuilderImpl::make(ps, fc);
                        return std::unique_ptr<para::ParagraphBuilderImpl>(
                                static_cast<para::ParagraphBuilderImpl*>(pb.release()));
                    }),
                    allow_raw_pointers())
            .class_function(
                    "_ShapeText",
                    optional_override([](JSString jtext, JSArray jruns, float width) -> JSArray {
                std::string textStorage = jtext.as<std::string>();
                const char* text = textStorage.data();
                size_t      textCount = textStorage.size();

                auto fc = sk_make_sp<para::FontCollection>();
                fc->setDefaultFontManager(SkFontMgr::RefDefault());
                fc->enableFontFallback();

                para::ParagraphStyle pstyle;
                {
                    // For the most part this is ignored, since we set an explicit TextStyle
                    // for all of our text runs, but it is required by SkParagraph.
                    para::TextStyle style;
                    style.setFontFamilies({SkString("sans-serif")});
                    style.setFontSize(32);
                    pstyle.setTextStyle(style);
                }

                auto pb = para::ParagraphBuilder::make(pstyle, fc);

                // tease apart the FontBlock runs
                size_t runCount = jruns["length"].as<size_t>();
                for (size_t i = 0; i < runCount; ++i) {
                    emscripten::val r = jruns[i];

                    para::TextStyle style;
                    style.setTypeface(r["typeface"].as< sk_sp<SkTypeface> >());
                    style.setFontSize(r["size"].as<float>());

                    const size_t subTextCount = r["length"].as<size_t>();
                    if (subTextCount > textCount) {
                        return emscripten::val("block runs exceed text length!");
                    }

                    pb->pushStyle(style);
                    pb->addText(text, subTextCount);
                    pb->pop();

                    text += subTextCount;
                    textCount -= subTextCount;
                }
                if (textCount != 0) {
                    return emscripten::val("Didn't have enough block runs to cover text");
                }

                auto pa = pb->Build();
                pa->layout(width);

                // workaround until this is fixed in SkParagraph
                {
                    SkPictureRecorder rec;
                    pa->paint(rec.beginRecording({0,0,9999,9999}), 0, 0);
                }
                return GetShapedLines(*pa);
            }),
            allow_raw_pointers())
            .function("addText",
                      optional_override([](para::ParagraphBuilderImpl& self, std::string text) {
                          return self.addText(text.c_str(), text.length());
                      }))
            .function("build", &para::ParagraphBuilderImpl::Build, allow_raw_pointers())
            .function("pop", &para::ParagraphBuilderImpl::pop)
            .function("reset", &para::ParagraphBuilderImpl::Reset, allow_raw_pointers())
            .function("_pushStyle", optional_override([](para::ParagraphBuilderImpl& self,
                                                         SimpleTextStyle textStyle) {
                          auto ts = toTextStyle(textStyle);
                          self.pushStyle(ts);
                      }))
            // A method of pushing a textStyle with paints instead of colors for foreground and
            // background. Since SimpleTextStyle is a value object, it cannot contain paints, which
            // are not primitives. This binding is here to accept them. Any color that is specified
            // in the textStyle is overridden.
            .function("_pushPaintStyle",
                      optional_override([](para::ParagraphBuilderImpl& self,
                                           SimpleTextStyle textStyle, SkPaint foreground,
                                           SkPaint background) {
                          auto ts = toTextStyle(textStyle);
                          ts.setForegroundColor(foreground);
                          ts.setBackgroundColor(background);
                          self.pushStyle(ts);
                      }))
            .function("_addPlaceholder", optional_override([](para::ParagraphBuilderImpl& self,
                                                              SkScalar width,
                                                              SkScalar height,
                                                              para::PlaceholderAlignment alignment,
                                                              para::TextBaseline baseline,
                                                              SkScalar offset) {
                          para::PlaceholderStyle ps(width, height, alignment, baseline, offset);
                          self.addPlaceholder(ps);
                      }))
            .function("getText",
                      optional_override([](para::ParagraphBuilderImpl& self) -> JSString {
                          auto text = self.getText();
                          return emscripten::val(std::string(text.data(), text.size()).c_str());
                      }))
            .function("_buildWithClientInfo",
                      optional_override([](para::ParagraphBuilderImpl& self,
                                           WASMPointerU32 clientBidis, size_t bidisNum,
                                           WASMPointerU32 clientWords, size_t wordsNum,
                                           WASMPointerU32 clientGraphemes, size_t graphemesNum,
                                           WASMPointerU32 clientLineBreaks, size_t lineBreaksNum) {
                      SkUnicode::Position* bidiData = reinterpret_cast<SkUnicode::Position*>(clientBidis);
                      std::vector<SkUnicode::BidiRegion> bidiRegions;
                      for (size_t i = 0; i < bidisNum; i += 3) {
                          auto start = bidiData[i];
                          auto end = bidiData[i+1];
                          auto direction = SkToU8(bidiData[i+2]);

                          SkUnicode::BidiLevel level = direction == static_cast<int>(para::TextDirection::kLtr)
                                                   ? static_cast<SkUnicode::BidiLevel>(SkUnicode::TextDirection::kLTR)
                                                   : static_cast<SkUnicode::BidiLevel>(SkUnicode::TextDirection::kRTL);
                          bidiRegions.emplace_back(start, end, level);
                      }
                      SkUnicode::Position* lineBreakData = reinterpret_cast<SkUnicode::Position*>(clientLineBreaks);
                      std::vector<SkUnicode::LineBreakBefore> lineBreaks;
                      for (size_t i = 0; i < lineBreaksNum; i += 2) {
                          auto pos = lineBreakData[i];
                          auto breakType = lineBreakData[i+1];
                          if (breakType == 0) {
                              lineBreaks.emplace_back(pos, SkUnicode::LineBreakType::kSoftLineBreak);
                          } else {
                              lineBreaks.emplace_back(pos, SkUnicode::LineBreakType::kHardLineBreak);
                          }
                      }
                      return self.BuildWithClientInfo(
                                        std::move(bidiRegions),
                                        convertArrayU32(clientWords, wordsNum),
                                        convertArrayU32(clientGraphemes, graphemesNum),
                                        std::move(lineBreaks));
                  }));

    class_<para::TypefaceFontProvider, base<SkFontMgr>>("TypefaceFontProvider")
      .smart_ptr<sk_sp<para::TypefaceFontProvider>>("sk_sp<TypefaceFontProvider>")
      .class_function("Make", optional_override([]()-> sk_sp<para::TypefaceFontProvider> {
          return sk_make_sp<para::TypefaceFontProvider>();
      }))
      .function("_registerFont", optional_override([](para::TypefaceFontProvider& self,
                                                      sk_sp<SkTypeface> typeface,
                                                      WASMPointerU8 familyPtr) {
          const char* fPtr = reinterpret_cast<const char*>(familyPtr);
          SkString fStr(fPtr);
          self.registerTypeface(typeface, fStr);
      }), allow_raw_pointers());


    // These value objects make it easier to send data across the wire.
    value_object<para::PositionWithAffinity>("PositionWithAffinity")
        .field("pos",      &para::PositionWithAffinity::position)
        .field("affinity", &para::PositionWithAffinity::affinity);

    value_object<SimpleFontStyle>("FontStyle")
        .field("slant",     &SimpleFontStyle::slant)
        .field("weight",    &SimpleFontStyle::weight)
        .field("width",     &SimpleFontStyle::width);

    value_object<SimpleParagraphStyle>("ParagraphStyle")
        .field("disableHinting",       &SimpleParagraphStyle::disableHinting)
        .field("_ellipsisPtr",         &SimpleParagraphStyle::ellipsisPtr)
        .field("_ellipsisLen",         &SimpleParagraphStyle::ellipsisLen)
        .field("heightMultiplier",     &SimpleParagraphStyle::heightMultiplier)
        .field("maxLines",             &SimpleParagraphStyle::maxLines)
        .field("replaceTabCharacters", &SimpleParagraphStyle::replaceTabCharacters)
        .field("textAlign",            &SimpleParagraphStyle::textAlign)
        .field("textDirection",        &SimpleParagraphStyle::textDirection)
        .field("textHeightBehavior",   &SimpleParagraphStyle::textHeightBehavior)
        .field("textStyle",            &SimpleParagraphStyle::textStyle)
        .field("strutStyle",           &SimpleParagraphStyle::strutStyle);

    value_object<SimpleStrutStyle>("StrutStyle")
        .field("_fontFamiliesPtr", &SimpleStrutStyle::fontFamiliesPtr)
        .field("_fontFamiliesLen", &SimpleStrutStyle::fontFamiliesLen)
        .field("strutEnabled",     &SimpleStrutStyle::strutEnabled)
        .field("fontSize",         &SimpleStrutStyle::fontSize)
        .field("fontStyle",        &SimpleStrutStyle::fontStyle)
        .field("heightMultiplier", &SimpleStrutStyle::heightMultiplier)
        .field("halfLeading",      &SimpleStrutStyle::halfLeading)
        .field("leading",          &SimpleStrutStyle::leading)
        .field("forceStrutHeight", &SimpleStrutStyle::forceStrutHeight);

    value_object<SimpleTextStyle>("TextStyle")
        .field("_colorPtr",             &SimpleTextStyle::colorPtr)
        .field("_foregroundColorPtr",   &SimpleTextStyle::foregroundColorPtr)
        .field("_backgroundColorPtr",   &SimpleTextStyle::backgroundColorPtr)
        .field("decoration",            &SimpleTextStyle::decoration)
        .field("decorationThickness",   &SimpleTextStyle::decorationThickness)
        .field("_decorationColorPtr",   &SimpleTextStyle::decorationColorPtr)
        .field("decorationStyle",       &SimpleTextStyle::decorationStyle)
        .field("_fontFamiliesPtr",      &SimpleTextStyle::fontFamiliesPtr)
        .field("_fontFamiliesLen",      &SimpleTextStyle::fontFamiliesLen)
        .field("fontSize",              &SimpleTextStyle::fontSize)
        .field("letterSpacing",         &SimpleTextStyle::letterSpacing)
        .field("wordSpacing",           &SimpleTextStyle::wordSpacing)
        .field("heightMultiplier",      &SimpleTextStyle::heightMultiplier)
        .field("halfLeading",           &SimpleTextStyle::halfLeading)
        .field("_localePtr",            &SimpleTextStyle::localePtr)
        .field("_localeLen",            &SimpleTextStyle::localeLen)
        .field("fontStyle",             &SimpleTextStyle::fontStyle)
        .field("_shadowLen",            &SimpleTextStyle::shadowLen)
        .field("_shadowColorsPtr",      &SimpleTextStyle::shadowColorsPtr)
        .field("_shadowOffsetsPtr",     &SimpleTextStyle::shadowOffsetsPtr)
        .field("_shadowBlurRadiiPtr",   &SimpleTextStyle::shadowBlurRadiiPtr)
        .field("_fontFeatureLen",       &SimpleTextStyle::fontFeatureLen)
        .field("_fontFeatureNamesPtr",  &SimpleTextStyle::fontFeatureNamesPtr)
        .field("_fontFeatureValuesPtr", &SimpleTextStyle::fontFeatureValuesPtr)
        .field("_fontVariationLen",     &SimpleTextStyle::fontVariationLen)
        .field("_fontVariationAxesPtr", &SimpleTextStyle::fontVariationAxesPtr)
        .field("_fontVariationValuesPtr", &SimpleTextStyle::fontVariationValuesPtr);

    // The U stands for unsigned - we can't bind a generic/template object, so we have to specify it
    // with the type we are using.
    // TODO(kjlubick) make this a typedarray.
    value_object<para::SkRange<size_t>>("URange")
        .field("start",    &para::SkRange<size_t>::start)
        .field("end",      &para::SkRange<size_t>::end);

    // TextDecoration should be a const because they can be combined
    constant("NoDecoration", int(para::TextDecoration::kNoDecoration));
    constant("UnderlineDecoration", int(para::TextDecoration::kUnderline));
    constant("OverlineDecoration", int(para::TextDecoration::kOverline));
    constant("LineThroughDecoration", int(para::TextDecoration::kLineThrough));
}
