diff --git a/packages/skia/cpp/api/JsiNativeBuffer.h b/packages/skia/cpp/api/JsiNativeBuffer.h index 109ecaaae9..ce83389c8b 100644 --- a/packages/skia/cpp/api/JsiNativeBuffer.h +++ b/packages/skia/cpp/api/JsiNativeBuffer.h @@ -21,36 +21,30 @@ class JsiNativeBufferFactory public: static constexpr const char *CLASS_NAME = "NativeBufferFactory"; - JSI_HOST_FUNCTION(MakeFromImage) { - auto image = JsiSkImage::fromValue(runtime, arguments[0]); + // Native buffer pointers travel as BigInts, which the void* converter + // produces/consumes. + void *MakeFromImage(sk_sp image) { image->makeNonTextureImage(); uint64_t pointer = getContext()->makeNativeBuffer(image); - return jsi::BigInt::fromUint64(runtime, pointer); + return reinterpret_cast(pointer); } - JSI_HOST_FUNCTION(MakeTestBuffer) { - auto width = static_cast(arguments[0].asNumber()); - auto height = static_cast(arguments[1].asNumber()); + void *MakeTestBuffer(int width, int height) { uint64_t pointer = getContext()->makeTestNativeBuffer(width, height); - return jsi::BigInt::fromUint64(runtime, pointer); + return reinterpret_cast(pointer); } - JSI_HOST_FUNCTION(Release) { - - jsi::BigInt pointer = arguments[0].asBigInt(runtime); - const uintptr_t nativeBufferPointer = pointer.asUint64(runtime); - - getContext()->releaseNativeBuffer(nativeBufferPointer); - return jsi::Value::undefined(); + void Release(void *pointer) { + getContext()->releaseNativeBuffer(reinterpret_cast(pointer)); } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { - installHostMethod(runtime, prototype, "Release", - &JsiNativeBufferFactory::Release); - installHostMethod(runtime, prototype, "MakeFromImage", - &JsiNativeBufferFactory::MakeFromImage); - installHostMethod(runtime, prototype, "MakeTestBuffer", - &JsiNativeBufferFactory::MakeTestBuffer); + installMethod(runtime, prototype, "Release", + &JsiNativeBufferFactory::Release); + installMethod(runtime, prototype, "MakeFromImage", + &JsiNativeBufferFactory::MakeFromImage); + installMethod(runtime, prototype, "MakeTestBuffer", + &JsiNativeBufferFactory::MakeTestBuffer); } size_t getMemoryPressure() override { return 1024; } diff --git a/packages/skia/cpp/api/JsiSkApi.h b/packages/skia/cpp/api/JsiSkApi.h index b71ef9bab4..675935bba3 100644 --- a/packages/skia/cpp/api/JsiSkApi.h +++ b/packages/skia/cpp/api/JsiSkApi.h @@ -178,11 +178,11 @@ class JsiSkApi : public JsiSkNativeObject { count); } - JSI_HOST_FUNCTION(hasDevice) { + bool hasDevice() { #ifdef SK_GRAPHITE - return jsi::Value(true); + return true; #else - return jsi::Value(false); + return false; #endif } @@ -206,50 +206,63 @@ class JsiSkApi : public JsiSkNativeObject { // Factory properties: like the legacy HostObject implementation, each // property access returns a fresh JS wrapper around the shared factory // instance. - JSI_PROPERTY_GET(SVG) { return makeJsiObject(runtime, _svgFactory); } - JSI_PROPERTY_GET(Image) { return makeJsiObject(runtime, _imageFactory); } - JSI_PROPERTY_GET(AnimatedImage) { - return makeJsiObject(runtime, _animatedImageFactory); + std::shared_ptr getSVGFactory() { return _svgFactory; } + std::shared_ptr getImageFactory() { + return _imageFactory; } - JSI_PROPERTY_GET(Typeface) { - return makeJsiObject(runtime, _typefaceFactory); + std::shared_ptr getAnimatedImageFactory() { + return _animatedImageFactory; } - JSI_PROPERTY_GET(Data) { return makeJsiObject(runtime, _dataFactory); } - JSI_PROPERTY_GET(ImageFilter) { - return makeJsiObject(runtime, _imageFilterFactory); + std::shared_ptr getTypefaceFactory() { + return _typefaceFactory; } - JSI_PROPERTY_GET(PathEffect) { - return makeJsiObject(runtime, _pathEffectFactory); + std::shared_ptr getDataFactory() { return _dataFactory; } + std::shared_ptr getImageFilterFactory() { + return _imageFilterFactory; } - JSI_PROPERTY_GET(Path) { return makeJsiObject(runtime, _pathFactory); } - JSI_PROPERTY_GET(PathBuilder) { - return makeJsiObject(runtime, _pathBuilderFactory); + std::shared_ptr getPathEffectFactory() { + return _pathEffectFactory; } - JSI_PROPERTY_GET(ColorFilter) { - return makeJsiObject(runtime, _colorFilterFactory); + std::shared_ptr getPathFactory() { return _pathFactory; } + std::shared_ptr getPathBuilderFactory() { + return _pathBuilderFactory; } - JSI_PROPERTY_GET(MaskFilter) { - return makeJsiObject(runtime, _maskFilterFactory); + std::shared_ptr getColorFilterFactory() { + return _colorFilterFactory; } - JSI_PROPERTY_GET(RuntimeEffect) { - return makeJsiObject(runtime, _runtimeEffectFactory); + std::shared_ptr getMaskFilterFactory() { + return _maskFilterFactory; } - JSI_PROPERTY_GET(Shader) { return makeJsiObject(runtime, _shaderFactory); } - JSI_PROPERTY_GET(TextBlob) { - return makeJsiObject(runtime, _textBlobFactory); + std::shared_ptr getRuntimeEffectFactory() { + return _runtimeEffectFactory; } - JSI_PROPERTY_GET(Surface) { return makeJsiObject(runtime, _surfaceFactory); } - JSI_PROPERTY_GET(Picture) { return makeJsiObject(runtime, _pictureFactory); } - JSI_PROPERTY_GET(FontMgr) { return makeJsiObject(runtime, _fontMgrFactory); } - JSI_PROPERTY_GET(Skottie) { return makeJsiObject(runtime, _skottieFactory); } - JSI_PROPERTY_GET(TypefaceFontProvider) { - return makeJsiObject(runtime, _typefaceFontProviderFactory); + std::shared_ptr getShaderFactory() { + return _shaderFactory; } - JSI_PROPERTY_GET(ParagraphBuilder) { - return makeJsiObject(runtime, _paragraphBuilderFactory); + std::shared_ptr getTextBlobFactory() { + return _textBlobFactory; } - JSI_PROPERTY_GET(NativeBuffer) { - return makeJsiObject(runtime, _nativeBufferFactory); + std::shared_ptr getSurfaceFactory() { + return _surfaceFactory; + } + std::shared_ptr getPictureFactory() { + return _pictureFactory; + } + std::shared_ptr getFontMgrFactory() { + return _fontMgrFactory; + } + std::shared_ptr getSkottieFactory() { + return _skottieFactory; + } + std::shared_ptr + getTypefaceFontProviderFactory() { + return _typefaceFontProviderFactory; + } + std::shared_ptr getParagraphBuilderFactory() { + return _paragraphBuilderFactory; + } + std::shared_ptr getNativeBufferFactory() { + return _nativeBufferFactory; } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { @@ -274,39 +287,41 @@ class JsiSkApi : public JsiSkNativeObject { &JsiSkApi::PictureRecorder); installHostMethod(runtime, prototype, "Color", &JsiSkApi::Color); installHostMethod(runtime, prototype, "Recorder", &JsiSkApi::Recorder); - installHostMethod(runtime, prototype, "hasDevice", &JsiSkApi::hasDevice); + installMethod(runtime, prototype, "hasDevice", &JsiSkApi::hasDevice); installHostMethod(runtime, prototype, "getDevice", &JsiSkApi::getDevice); - installHostGetter(runtime, prototype, "SVG", &JsiSkApi::get_SVG); - installHostGetter(runtime, prototype, "Image", &JsiSkApi::get_Image); - installHostGetter(runtime, prototype, "AnimatedImage", - &JsiSkApi::get_AnimatedImage); - installHostGetter(runtime, prototype, "Typeface", &JsiSkApi::get_Typeface); - installHostGetter(runtime, prototype, "Data", &JsiSkApi::get_Data); - installHostGetter(runtime, prototype, "ImageFilter", - &JsiSkApi::get_ImageFilter); - installHostGetter(runtime, prototype, "PathEffect", - &JsiSkApi::get_PathEffect); - installHostGetter(runtime, prototype, "Path", &JsiSkApi::get_Path); - installHostGetter(runtime, prototype, "PathBuilder", - &JsiSkApi::get_PathBuilder); - installHostGetter(runtime, prototype, "ColorFilter", - &JsiSkApi::get_ColorFilter); - installHostGetter(runtime, prototype, "MaskFilter", - &JsiSkApi::get_MaskFilter); - installHostGetter(runtime, prototype, "RuntimeEffect", - &JsiSkApi::get_RuntimeEffect); - installHostGetter(runtime, prototype, "Shader", &JsiSkApi::get_Shader); - installHostGetter(runtime, prototype, "TextBlob", &JsiSkApi::get_TextBlob); - installHostGetter(runtime, prototype, "Surface", &JsiSkApi::get_Surface); - installHostGetter(runtime, prototype, "Picture", &JsiSkApi::get_Picture); - installHostGetter(runtime, prototype, "FontMgr", &JsiSkApi::get_FontMgr); - installHostGetter(runtime, prototype, "Skottie", &JsiSkApi::get_Skottie); - installHostGetter(runtime, prototype, "TypefaceFontProvider", - &JsiSkApi::get_TypefaceFontProvider); - installHostGetter(runtime, prototype, "ParagraphBuilder", - &JsiSkApi::get_ParagraphBuilder); - installHostGetter(runtime, prototype, "NativeBuffer", - &JsiSkApi::get_NativeBuffer); + installGetter(runtime, prototype, "SVG", &JsiSkApi::getSVGFactory); + installGetter(runtime, prototype, "Image", &JsiSkApi::getImageFactory); + installGetter(runtime, prototype, "AnimatedImage", + &JsiSkApi::getAnimatedImageFactory); + installGetter(runtime, prototype, "Typeface", + &JsiSkApi::getTypefaceFactory); + installGetter(runtime, prototype, "Data", &JsiSkApi::getDataFactory); + installGetter(runtime, prototype, "ImageFilter", + &JsiSkApi::getImageFilterFactory); + installGetter(runtime, prototype, "PathEffect", + &JsiSkApi::getPathEffectFactory); + installGetter(runtime, prototype, "Path", &JsiSkApi::getPathFactory); + installGetter(runtime, prototype, "PathBuilder", + &JsiSkApi::getPathBuilderFactory); + installGetter(runtime, prototype, "ColorFilter", + &JsiSkApi::getColorFilterFactory); + installGetter(runtime, prototype, "MaskFilter", + &JsiSkApi::getMaskFilterFactory); + installGetter(runtime, prototype, "RuntimeEffect", + &JsiSkApi::getRuntimeEffectFactory); + installGetter(runtime, prototype, "Shader", &JsiSkApi::getShaderFactory); + installGetter(runtime, prototype, "TextBlob", + &JsiSkApi::getTextBlobFactory); + installGetter(runtime, prototype, "Surface", &JsiSkApi::getSurfaceFactory); + installGetter(runtime, prototype, "Picture", &JsiSkApi::getPictureFactory); + installGetter(runtime, prototype, "FontMgr", &JsiSkApi::getFontMgrFactory); + installGetter(runtime, prototype, "Skottie", &JsiSkApi::getSkottieFactory); + installGetter(runtime, prototype, "TypefaceFontProvider", + &JsiSkApi::getTypefaceFontProviderFactory); + installGetter(runtime, prototype, "ParagraphBuilder", + &JsiSkApi::getParagraphBuilderFactory); + installGetter(runtime, prototype, "NativeBuffer", + &JsiSkApi::getNativeBufferFactory); } private: diff --git a/packages/skia/cpp/api/JsiSkCanvas.h b/packages/skia/cpp/api/JsiSkCanvas.h index 3376463d15..19be01b60a 100644 --- a/packages/skia/cpp/api/JsiSkCanvas.h +++ b/packages/skia/cpp/api/JsiSkCanvas.h @@ -1,9 +1,11 @@ #pragma once #include +#include #include #include +#include "JsiSkConverters.h" #include "JsiSkFont.h" #include "JsiSkImage.h" #include "JsiSkImageInfo.h" @@ -53,29 +55,21 @@ class JsiSkCanvas : public JsiSkNativeObject { public: static constexpr const char *CLASS_NAME = "Canvas"; - JSI_HOST_FUNCTION(drawPaint) { - auto paint = JsiSkPaint::fromValue(runtime, arguments[0]); + void drawPaint(std::shared_ptr paint) { _canvas->drawPaint(*paint); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawLine) { - SkScalar x1 = arguments[0].asNumber(); - SkScalar y1 = arguments[1].asNumber(); - SkScalar x2 = arguments[2].asNumber(); - SkScalar y2 = arguments[3].asNumber(); - auto paint = JsiSkPaint::fromValue(runtime, arguments[4]); + void drawLine(double x1, double y1, double x2, double y2, + std::shared_ptr paint) { _canvas->drawLine(x1, y1, x2, y2, *paint); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawRect) { - auto rect = JsiSkRect::fromValue(runtime, arguments[0]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); + void drawRect(std::shared_ptr rect, std::shared_ptr paint) { _canvas->drawRect(*rect, *paint); - return jsi::Value::undefined(); } + // The drawImage* variants stay raw: they dispatch on exact argument counts + // (count == 4 / count == 6) with null-tolerant trailing paints. JSI_HOST_FUNCTION(drawImage) { auto image = JsiSkImage::fromValue(runtime, arguments[0]); auto x = arguments[1].asNumber(); @@ -185,106 +179,55 @@ class JsiSkCanvas : public JsiSkNativeObject { return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawCircle) { - SkScalar cx = arguments[0].asNumber(); - SkScalar cy = arguments[1].asNumber(); - SkScalar radius = arguments[2].asNumber(); - - auto paint = JsiSkPaint::fromValue(runtime, arguments[3]); + void drawCircle(double cx, double cy, double radius, + std::shared_ptr paint) { _canvas->drawCircle(cx, cy, radius, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawArc) { - auto oval = JsiSkRect::fromValue(runtime, arguments[0]); - - SkScalar startAngle = arguments[1].asNumber(); - SkScalar sweepAngle = arguments[2].asNumber(); - bool useCenter = arguments[3].getBool(); - - auto paint = JsiSkPaint::fromValue(runtime, arguments[4]); + void drawArc(std::shared_ptr oval, double startAngle, + double sweepAngle, bool useCenter, + std::shared_ptr paint) { _canvas->drawArc(*oval, startAngle, sweepAngle, useCenter, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawRRect) { - auto rect = JsiSkRRect::fromValue(runtime, arguments[0]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); - + void drawRRect(std::shared_ptr rect, + std::shared_ptr paint) { _canvas->drawRRect(*rect, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawDRRect) { - auto outer = JsiSkRRect::fromValue(runtime, arguments[0]); - auto inner = JsiSkRRect::fromValue(runtime, arguments[1]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[2]); - + void drawDRRect(std::shared_ptr outer, + std::shared_ptr inner, + std::shared_ptr paint) { _canvas->drawDRRect(*outer, *inner, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawOval) { - auto rect = JsiSkRect::fromValue(runtime, arguments[0]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); - + void drawOval(std::shared_ptr rect, std::shared_ptr paint) { _canvas->drawOval(*rect, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(restoreToCount) { - auto c = arguments[0].asNumber(); - _canvas->restoreToCount(c); - return jsi::Value::undefined(); - } + void restoreToCount(double c) { _canvas->restoreToCount(c); } - JSI_HOST_FUNCTION(getSaveCount) { - return static_cast(_canvas->getSaveCount()); - } + int getSaveCount() { return static_cast(_canvas->getSaveCount()); } - JSI_HOST_FUNCTION(getTotalMatrix) { - return makeJsiObject(runtime, std::make_shared( - getContext(), _canvas->getTotalMatrix())); + std::shared_ptr getTotalMatrix() { + return std::make_shared(getContext(), + _canvas->getTotalMatrix()); } - JSI_HOST_FUNCTION(drawPoints) { - auto pointMode = arguments[0].asNumber(); - std::vector points; - - auto jsiPoints = arguments[1].asObject(runtime).asArray(runtime); - auto pointsSize = jsiPoints.size(runtime); - + void drawPoints(double pointMode, std::vector points, + std::shared_ptr paint) { // Check if we have at least one point - if (pointsSize == 0) { + if (points.empty()) { throw std::invalid_argument("Points array must not be empty"); } - - points.reserve(pointsSize); - - for (int i = 0; i < pointsSize; i++) { - std::shared_ptr point = JsiSkPoint::fromValue( - runtime, jsiPoints.getValueAtIndex(runtime, i).asObject(runtime)); - points.push_back(*point.get()); - } - - auto paint = JsiSkPaint::fromValue(runtime, arguments[2]); auto p = SkSpan(points.data(), points.size()); - _canvas->drawPoints((SkCanvas::PointMode)pointMode, p, *paint); - - return jsi::Value::undefined(); + _canvas->drawPoints(static_cast(pointMode), p, *paint); } - JSI_HOST_FUNCTION(drawVertices) { - auto vertices = JsiSkVertices::fromValue(runtime, arguments[0]); - auto blendMode = (SkBlendMode)arguments[1].getNumber(); - auto paint = JsiSkPaint::fromValue(runtime, arguments[2]); - _canvas->drawVertices(vertices, blendMode, *paint); - return jsi::Value::undefined(); + void drawVertices(sk_sp vertices, double blendMode, + std::shared_ptr paint) { + _canvas->drawVertices(vertices, static_cast(blendMode), + *paint); } JSI_HOST_FUNCTION(drawPatch) { @@ -352,118 +295,71 @@ class JsiSkCanvas : public JsiSkNativeObject { return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawPath) { - auto path = JsiSkPath::fromValue(runtime, arguments[0]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); - + void drawPath(std::shared_ptr path, + std::shared_ptr paint) { _canvas->drawPath(path->snapshot(), *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawText) { - auto textVal = arguments[0].asString(runtime).utf8(runtime); + void drawText(std::string textVal, double x, double y, + std::shared_ptr paint, std::shared_ptr font) { auto text = textVal.c_str(); - SkScalar x = arguments[1].asNumber(); - SkScalar y = arguments[2].asNumber(); - - auto paint = JsiSkPaint::fromValue(runtime, arguments[3]); - auto font = JsiSkFont::fromValue(runtime, arguments[4]); - _canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, x, y, *font, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawTextBlob) { - auto blob = JsiSkTextBlob::fromValue(runtime, arguments[0]); - SkScalar x = arguments[1].asNumber(); - SkScalar y = arguments[2].asNumber(); - auto paint = JsiSkPaint::fromValue(runtime, arguments[3]); + void drawTextBlob(sk_sp blob, double x, double y, + std::shared_ptr paint) { _canvas->drawTextBlob(blob, x, y, *paint); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawGlyphs) { - auto jsiGlyphs = arguments[0].asObject(runtime).asArray(runtime); - auto jsiPositions = arguments[1].asObject(runtime).asArray(runtime); - auto x = arguments[2].asNumber(); - auto y = arguments[3].asNumber(); - auto font = JsiSkFont::fromValue(runtime, arguments[4]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[5]); + void drawGlyphs(std::vector glyphIds, std::vector positions, + double x, double y, std::shared_ptr font, + std::shared_ptr paint) { SkPoint origin = SkPoint::Make(x, y); - std::vector positions; - int pointsSize = static_cast(jsiPositions.size(runtime)); - positions.reserve(pointsSize); - for (int i = 0; i < pointsSize; i++) { - std::shared_ptr point = JsiSkPoint::fromValue( - runtime, jsiPositions.getValueAtIndex(runtime, i).asObject(runtime)); - positions.push_back(*point.get()); - } - - std::vector glyphs; - int glyphsSize = static_cast(jsiGlyphs.size(runtime)); - // Validate that glyphs and positions arrays have the same size - if (glyphsSize != pointsSize) { + if (glyphIds.size() != positions.size()) { throw std::invalid_argument( "Glyphs and positions arrays must have the same length"); } - glyphs.reserve(glyphsSize); - for (int i = 0; i < glyphsSize; i++) { - glyphs.push_back(jsiGlyphs.getValueAtIndex(runtime, i).asNumber()); + std::vector glyphs; + glyphs.reserve(glyphIds.size()); + for (auto glyph : glyphIds) { + glyphs.push_back(static_cast(glyph)); } auto g = SkSpan(glyphs.data(), glyphs.size()); auto p = SkSpan(positions.data(), positions.size()); _canvas->drawGlyphs(g, p, origin, *font, *paint); - - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(drawSvg) { - auto svgdom = JsiSkSVG::fromValue(runtime, arguments[0]); - if (count == 3 && arguments[1].isNumber() && arguments[2].isNumber()) { - // read size - auto w = arguments[1].asNumber(); - auto h = arguments[2].asNumber(); - svgdom->setContainerSize(SkSize::Make(w, h)); + void drawSvg(sk_sp svgdom, JsiOptional w, + JsiOptional h) { + if (w.has_value() && h.has_value()) { + svgdom->setContainerSize(SkSize::Make(*w, *h)); } else { auto canvasSize = _canvas->getBaseLayerSize(); svgdom->setContainerSize(SkSize::Make(canvasSize)); } svgdom->render(_canvas); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(clipPath) { - auto path = JsiSkPath::fromValue(runtime, arguments[0]); - auto op = (SkClipOp)arguments[1].asNumber(); - auto doAntiAlias = arguments[2].getBool(); - _canvas->clipPath(path->snapshot(), op, doAntiAlias); - return jsi::Value::undefined(); + void clipPath(std::shared_ptr path, double op, + bool doAntiAlias) { + _canvas->clipPath(path->snapshot(), static_cast(op), + doAntiAlias); } - JSI_HOST_FUNCTION(clipRect) { - auto rect = JsiSkRect::fromValue(runtime, arguments[0]); - auto op = (SkClipOp)arguments[1].asNumber(); - auto doAntiAlias = arguments[2].getBool(); - _canvas->clipRect(*rect, op, doAntiAlias); - return jsi::Value::undefined(); + void clipRect(std::shared_ptr rect, double op, bool doAntiAlias) { + _canvas->clipRect(*rect, static_cast(op), doAntiAlias); } - JSI_HOST_FUNCTION(clipRRect) { - auto rrect = JsiSkRRect::fromValue(runtime, arguments[0]); - auto op = (SkClipOp)arguments[1].asNumber(); - auto doAntiAlias = arguments[2].getBool(); - _canvas->clipRRect(*rrect, op, doAntiAlias); - return jsi::Value::undefined(); + void clipRRect(std::shared_ptr rrect, double op, bool doAntiAlias) { + _canvas->clipRRect(*rrect, static_cast(op), doAntiAlias); } - JSI_HOST_FUNCTION(save) { return jsi::Value(_canvas->save()); } + int save() { return _canvas->save(); } JSI_HOST_FUNCTION(saveLayer) { SkPaint *paint = (count >= 1 && !arguments[0].isUndefined()) @@ -482,67 +378,32 @@ class JsiSkCanvas : public JsiSkNativeObject { SkCanvas::SaveLayerRec(bounds, paint, backdrop, flags))); } - JSI_HOST_FUNCTION(restore) { - _canvas->restore(); - return jsi::Value::undefined(); - } + void restore() { _canvas->restore(); } - JSI_HOST_FUNCTION(rotate) { - SkScalar degrees = arguments[0].asNumber(); - SkScalar rx = arguments[1].asNumber(); - SkScalar ry = arguments[2].asNumber(); + void rotate(double degrees, double rx, double ry) { _canvas->rotate(degrees, rx, ry); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(translate) { - SkScalar dx = arguments[0].asNumber(); - SkScalar dy = arguments[1].asNumber(); - _canvas->translate(dx, dy); - return jsi::Value::undefined(); - } + void translate(double dx, double dy) { _canvas->translate(dx, dy); } - JSI_HOST_FUNCTION(scale) { - SkScalar sx = arguments[0].asNumber(); - SkScalar sy = arguments[1].asNumber(); - _canvas->scale(sx, sy); - return jsi::Value::undefined(); - } + void scale(double sx, double sy) { _canvas->scale(sx, sy); } - JSI_HOST_FUNCTION(skew) { - SkScalar sx = arguments[0].asNumber(); - SkScalar sy = arguments[1].asNumber(); - _canvas->skew(sx, sy); - return jsi::Value::undefined(); - } + void skew(double sx, double sy) { _canvas->skew(sx, sy); } - JSI_HOST_FUNCTION(drawColor) { - SkColor cl = JsiSkColor::fromValue(runtime, arguments[0]); - if (count == 1) { - _canvas->drawColor(cl); + void drawColor(JsiColor cl, JsiOptional mode) { + if (mode.has_value()) { + _canvas->drawColor(cl, static_cast(*mode)); } else { - auto mode = static_cast(arguments[1].asNumber()); - _canvas->drawColor(cl, mode); + _canvas->drawColor(cl); } - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(clear) { - SkColor cl = JsiSkColor::fromValue(runtime, arguments[0]); - _canvas->clear(cl); - return jsi::Value::undefined(); - } + void clear(JsiColor cl) { _canvas->clear(cl); } - JSI_HOST_FUNCTION(concat) { - auto matrix = JsiSkMatrix::fromValue(runtime, arguments[0]); - _canvas->concat(*matrix.get()); - return jsi::Value::undefined(); - } + void concat(std::shared_ptr matrix) { _canvas->concat(*matrix); } - JSI_HOST_FUNCTION(drawPicture) { - auto picture = JsiSkPicture::fromValue(runtime, arguments[0]); + void drawPicture(sk_sp picture) { _canvas->drawPicture(picture); - return jsi::Value::undefined(); } JSI_HOST_FUNCTION(drawAtlas) { @@ -679,9 +540,9 @@ class JsiSkCanvas : public JsiSkNativeObject { } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { - installHostMethod(runtime, prototype, "drawPaint", &JsiSkCanvas::drawPaint); - installHostMethod(runtime, prototype, "drawLine", &JsiSkCanvas::drawLine); - installHostMethod(runtime, prototype, "drawRect", &JsiSkCanvas::drawRect); + installMethod(runtime, prototype, "drawPaint", &JsiSkCanvas::drawPaint); + installMethod(runtime, prototype, "drawLine", &JsiSkCanvas::drawLine); + installMethod(runtime, prototype, "drawRect", &JsiSkCanvas::drawRect); installHostMethod(runtime, prototype, "drawImage", &JsiSkCanvas::drawImage); installHostMethod(runtime, prototype, "drawImageRect", &JsiSkCanvas::drawImageRect); @@ -695,46 +556,42 @@ class JsiSkCanvas : public JsiSkNativeObject { &JsiSkCanvas::drawImageRectCubic); installHostMethod(runtime, prototype, "drawImageRectOptions", &JsiSkCanvas::drawImageRectOptions); - installHostMethod(runtime, prototype, "drawCircle", - &JsiSkCanvas::drawCircle); - installHostMethod(runtime, prototype, "drawArc", &JsiSkCanvas::drawArc); - installHostMethod(runtime, prototype, "drawRRect", &JsiSkCanvas::drawRRect); - installHostMethod(runtime, prototype, "drawDRRect", - &JsiSkCanvas::drawDRRect); - installHostMethod(runtime, prototype, "drawOval", &JsiSkCanvas::drawOval); - installHostMethod(runtime, prototype, "restoreToCount", - &JsiSkCanvas::restoreToCount); - installHostMethod(runtime, prototype, "getSaveCount", - &JsiSkCanvas::getSaveCount); - installHostMethod(runtime, prototype, "getTotalMatrix", - &JsiSkCanvas::getTotalMatrix); - installHostMethod(runtime, prototype, "drawPoints", - &JsiSkCanvas::drawPoints); + installMethod(runtime, prototype, "drawCircle", &JsiSkCanvas::drawCircle); + installMethod(runtime, prototype, "drawArc", &JsiSkCanvas::drawArc); + installMethod(runtime, prototype, "drawRRect", &JsiSkCanvas::drawRRect); + installMethod(runtime, prototype, "drawDRRect", &JsiSkCanvas::drawDRRect); + installMethod(runtime, prototype, "drawOval", &JsiSkCanvas::drawOval); + installMethod(runtime, prototype, "restoreToCount", + &JsiSkCanvas::restoreToCount); + installMethod(runtime, prototype, "getSaveCount", + &JsiSkCanvas::getSaveCount); + installMethod(runtime, prototype, "getTotalMatrix", + &JsiSkCanvas::getTotalMatrix); + installMethod(runtime, prototype, "drawPoints", &JsiSkCanvas::drawPoints); installHostMethod(runtime, prototype, "drawPatch", &JsiSkCanvas::drawPatch); - installHostMethod(runtime, prototype, "drawPath", &JsiSkCanvas::drawPath); - installHostMethod(runtime, prototype, "drawVertices", - &JsiSkCanvas::drawVertices); - installHostMethod(runtime, prototype, "drawText", &JsiSkCanvas::drawText); - installHostMethod(runtime, prototype, "drawTextBlob", - &JsiSkCanvas::drawTextBlob); - installHostMethod(runtime, prototype, "drawGlyphs", - &JsiSkCanvas::drawGlyphs); - installHostMethod(runtime, prototype, "drawSvg", &JsiSkCanvas::drawSvg); - installHostMethod(runtime, prototype, "clipPath", &JsiSkCanvas::clipPath); - installHostMethod(runtime, prototype, "clipRect", &JsiSkCanvas::clipRect); - installHostMethod(runtime, prototype, "clipRRect", &JsiSkCanvas::clipRRect); - installHostMethod(runtime, prototype, "save", &JsiSkCanvas::save); + installMethod(runtime, prototype, "drawPath", &JsiSkCanvas::drawPath); + installMethod(runtime, prototype, "drawVertices", + &JsiSkCanvas::drawVertices); + installMethod(runtime, prototype, "drawText", &JsiSkCanvas::drawText); + installMethod(runtime, prototype, "drawTextBlob", + &JsiSkCanvas::drawTextBlob); + installMethod(runtime, prototype, "drawGlyphs", &JsiSkCanvas::drawGlyphs); + installMethod(runtime, prototype, "drawSvg", &JsiSkCanvas::drawSvg); + installMethod(runtime, prototype, "clipPath", &JsiSkCanvas::clipPath); + installMethod(runtime, prototype, "clipRect", &JsiSkCanvas::clipRect); + installMethod(runtime, prototype, "clipRRect", &JsiSkCanvas::clipRRect); + installMethod(runtime, prototype, "save", &JsiSkCanvas::save); installHostMethod(runtime, prototype, "saveLayer", &JsiSkCanvas::saveLayer); - installHostMethod(runtime, prototype, "restore", &JsiSkCanvas::restore); - installHostMethod(runtime, prototype, "rotate", &JsiSkCanvas::rotate); - installHostMethod(runtime, prototype, "translate", &JsiSkCanvas::translate); - installHostMethod(runtime, prototype, "scale", &JsiSkCanvas::scale); - installHostMethod(runtime, prototype, "skew", &JsiSkCanvas::skew); - installHostMethod(runtime, prototype, "drawColor", &JsiSkCanvas::drawColor); - installHostMethod(runtime, prototype, "clear", &JsiSkCanvas::clear); - installHostMethod(runtime, prototype, "concat", &JsiSkCanvas::concat); - installHostMethod(runtime, prototype, "drawPicture", - &JsiSkCanvas::drawPicture); + installMethod(runtime, prototype, "restore", &JsiSkCanvas::restore); + installMethod(runtime, prototype, "rotate", &JsiSkCanvas::rotate); + installMethod(runtime, prototype, "translate", &JsiSkCanvas::translate); + installMethod(runtime, prototype, "scale", &JsiSkCanvas::scale); + installMethod(runtime, prototype, "skew", &JsiSkCanvas::skew); + installMethod(runtime, prototype, "drawColor", &JsiSkCanvas::drawColor); + installMethod(runtime, prototype, "clear", &JsiSkCanvas::clear); + installMethod(runtime, prototype, "concat", &JsiSkCanvas::concat); + installMethod(runtime, prototype, "drawPicture", + &JsiSkCanvas::drawPicture); installHostMethod(runtime, prototype, "drawAtlas", &JsiSkCanvas::drawAtlas); installHostMethod(runtime, prototype, "readPixels", &JsiSkCanvas::readPixels); diff --git a/packages/skia/cpp/api/JsiSkConverters.h b/packages/skia/cpp/api/JsiSkConverters.h index 39ac425f77..1863d501a2 100644 --- a/packages/skia/cpp/api/JsiSkConverters.h +++ b/packages/skia/cpp/api/JsiSkConverters.h @@ -48,6 +48,14 @@ class SkFontStyle; struct SkImageInfo; struct SkRSXform; +namespace skia { +namespace textlayout { +class TextStyle; +struct ParagraphStyle; +class TypefaceFontProvider; +} // namespace textlayout +} // namespace skia + namespace RNSkia { namespace jsi = facebook::jsi; @@ -77,6 +85,9 @@ class JsiSkRRect; class JsiSkFontStyle; class JsiSkImageInfo; class JsiSkRSXform; +class JsiSkTextStyle; +class JsiSkParagraphStyle; +class JsiSkTypefaceFontProvider; /** * Maps a wrapped Skia type to the JsiSk* class whose `fromValue` knows how to @@ -162,6 +173,15 @@ template <> struct JsiSkWrapperFor { template <> struct JsiSkWrapperFor { using type = JsiSkRSXform; }; +template <> struct JsiSkWrapperFor { + using type = JsiSkTextStyle; +}; +template <> struct JsiSkWrapperFor { + using type = JsiSkParagraphStyle; +}; +template <> struct JsiSkWrapperFor { + using type = JsiSkTypefaceFontProvider; +}; template using JsiSkWrapperFor_t = typename JsiSkWrapperFor::type; @@ -286,6 +306,18 @@ struct JSIConverter>> { } }; +// Paragraph style values — their fromValue helpers return by value and read +// plain JS style objects. +template +struct JSIConverter< + T, std::enable_if_t || + std::is_same_v>> { + static T fromJSI(jsi::Runtime &runtime, const jsi::Value &arg, + bool outOfBound) { + return RNSkia::JsiSkWrapperFor_t::fromValue(runtime, arg); + } +}; + // Colors via the JsiColor strong typedef (see above). template struct JSIConverter>> { diff --git a/packages/skia/cpp/api/JsiSkNativeObjects.h b/packages/skia/cpp/api/JsiSkNativeObjects.h index 413d80fe5a..27ea218f26 100644 --- a/packages/skia/cpp/api/JsiSkNativeObjects.h +++ b/packages/skia/cpp/api/JsiSkNativeObjects.h @@ -11,11 +11,6 @@ #include "rnskia/RNSkPlatformContext.h" #include "utils/RNSkLog.h" -#define STR_CAT_NX(A, B) A##B -#define STR_CAT(A, B) STR_CAT_NX(A, B) -#define STR_GET get_ -#define STR_SET set_ - /** * Creates a new Host function declaration as a lambda with all deps passed * with implicit lambda capture clause @@ -25,24 +20,16 @@ const jsi::Value *arguments, size_t count) -> jsi::Value /** - * Creates a new Host function declaration + * Creates a new Host function declaration. Only used for methods that cannot + * be expressed as typed signatures (heterogeneous argument dispatch, typed + * array construction, lenient options objects, promises) — everything else + * uses installMethod/installGetter/installChainableMethod with typed C++ + * signatures converted through rnwgpu::JSIConverter. */ #define JSI_HOST_FUNCTION(NAME) \ jsi::Value NAME(jsi::Runtime &runtime, const jsi::Value &thisValue, \ const jsi::Value *arguments, size_t count) -/** - * Creates a new property setter function declaration - */ -#define JSI_PROPERTY_SET(NAME) \ - void STR_CAT(STR_SET, NAME)(jsi::Runtime & runtime, const jsi::Value &value) - -/** - * Creates a new property getter function declaration - */ -#define JSI_PROPERTY_GET(NAME) \ - jsi::Value STR_CAT(STR_GET, NAME)(jsi::Runtime & runtime) - namespace RNSkia { namespace jsi = facebook::jsi; @@ -113,10 +100,12 @@ std::shared_ptr getJsiObject(jsi::Runtime &runtime, * NativeObject::installPrototype; wrapping classes additionally call * `installCommon(runtime, proto)` to install dispose(). * - * The existing JSI_HOST_FUNCTION / JSI_PROPERTY_GET / JSI_PROPERTY_SET method - * bodies keep working unchanged; they are installed on the prototype with the - * installHostMethod / installHostGetter / installHostSetter helpers below, - * which resolve the C++ instance from `this` via native state. + * Most methods use typed C++ signatures installed with installMethod / + * installGetter / installChainableMethod (arguments and results converted + * through rnwgpu::JSIConverter, see JsiSkConverters.h). Methods that cannot + * be typed keep the classic JSI_HOST_FUNCTION signature and are installed + * with installHostMethod, which resolves the C++ instance from `this` via + * native state. */ template class JsiSkNativeObject : public rnwgpu::NativeObject { @@ -213,8 +202,6 @@ class JsiSkNativeObject : public rnwgpu::NativeObject { using HostMethod = jsi::Value (Derived::*)(jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t); - using HostGetter = jsi::Value (Derived::*)(jsi::Runtime &); - using HostSetter = void (Derived::*)(jsi::Runtime &, const jsi::Value &); /** * Installs a method with the classic host-function signature @@ -232,54 +219,6 @@ class JsiSkNativeObject : public rnwgpu::NativeObject { prototype.setProperty(runtime, name, func); } - /** - * Installs a property getter with the classic JSI_PROPERTY_GET signature on - * the prototype. - */ - static void installHostGetter(jsi::Runtime &runtime, jsi::Object &prototype, - const char *name, HostGetter getter) { - auto getterFunc = jsi::Function::createFromHostFunction( - runtime, jsi::PropNameID::forUtf8(runtime, std::string("get_") + name), - 0, - [getter](jsi::Runtime &rt, const jsi::Value &thisValue, - const jsi::Value *, size_t) -> jsi::Value { - auto native = fromThis(rt, thisValue); - return ((*native).*getter)(rt); - }); - defineProperty(runtime, prototype, name, &getterFunc, nullptr); - } - - /** - * Installs a property setter with the classic JSI_PROPERTY_SET signature on - * the prototype, preserving a previously installed getter. - */ - static void installHostSetter(jsi::Runtime &runtime, jsi::Object &prototype, - const char *name, HostSetter setter) { - auto setterFunc = jsi::Function::createFromHostFunction( - runtime, jsi::PropNameID::forUtf8(runtime, std::string("set_") + name), - 1, - [setter](jsi::Runtime &rt, const jsi::Value &thisValue, - const jsi::Value *arguments, size_t count) -> jsi::Value { - if (count < 1) { - throw jsi::JSError(rt, "Setter requires a value argument"); - } - auto native = fromThis(rt, thisValue); - ((*native).*setter)(rt, arguments[0]); - return jsi::Value::undefined(); - }); - defineProperty(runtime, prototype, name, nullptr, &setterFunc); - } - - /** - * Installs both getter and setter for a property on the prototype. - */ - static void installHostProperty(jsi::Runtime &runtime, jsi::Object &prototype, - const char *name, HostGetter getter, - HostSetter setter) { - installHostGetter(runtime, prototype, name, getter); - installHostSetter(runtime, prototype, name, setter); - } - /** * Installs a typed mutating method that returns `this` for chaining * (e.g. path.moveTo(...).lineTo(...)). Arguments are converted through @@ -345,41 +284,6 @@ class JsiSkNativeObject : public rnwgpu::NativeObject { runtime, args[Is], Is >= count)...); } - static void defineProperty(jsi::Runtime &runtime, jsi::Object &prototype, - const char *name, jsi::Function *getter, - jsi::Function *setter) { - auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object"); - auto defineProp = - objectCtor.getPropertyAsFunction(runtime, "defineProperty"); - auto getOwnPropertyDescriptor = - objectCtor.getPropertyAsFunction(runtime, "getOwnPropertyDescriptor"); - auto existing = getOwnPropertyDescriptor.call( - runtime, prototype, jsi::String::createFromUtf8(runtime, name)); - - jsi::Object descriptor(runtime); - if (existing.isObject()) { - auto existingObj = existing.getObject(runtime); - if (existingObj.hasProperty(runtime, "get")) { - descriptor.setProperty(runtime, "get", - existingObj.getProperty(runtime, "get")); - } - if (existingObj.hasProperty(runtime, "set")) { - descriptor.setProperty(runtime, "set", - existingObj.getProperty(runtime, "set")); - } - } - if (getter != nullptr) { - descriptor.setProperty(runtime, "get", *getter); - } - if (setter != nullptr) { - descriptor.setProperty(runtime, "set", *setter); - } - descriptor.setProperty(runtime, "enumerable", true); - descriptor.setProperty(runtime, "configurable", true); - defineProp.call(runtime, prototype, - jsi::String::createFromUtf8(runtime, name), descriptor); - } - std::shared_ptr _context; }; diff --git a/packages/skia/cpp/api/JsiSkParagraph.h b/packages/skia/cpp/api/JsiSkParagraph.h index fbc6d31841..81f2a8decd 100644 --- a/packages/skia/cpp/api/JsiSkParagraph.h +++ b/packages/skia/cpp/api/JsiSkParagraph.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -36,61 +37,46 @@ class JsiSkParagraph public: static constexpr const char *CLASS_NAME = "Paragraph"; - JSI_HOST_FUNCTION(layout) { - auto width = getArgumentAsNumber(runtime, arguments, count, 0); - getObject()->layout(width); - return jsi::Value::undefined(); - } + void layout(double width) { getObject()->layout(width); } - JSI_HOST_FUNCTION(paint) { - auto jsiCanvas = getJsiObject( - runtime, getArgument(runtime, arguments, count, 0)); - auto x = getArgumentAsNumber(runtime, arguments, count, 1); - auto y = getArgumentAsNumber(runtime, arguments, count, 2); + void paint(std::shared_ptr jsiCanvas, double x, double y) { getObject()->paint(jsiCanvas->getCanvas(), x, y); - return jsi::Value::undefined(); } - JSI_HOST_FUNCTION(getHeight) { - return static_cast(getObject()->getHeight()); - } + double getHeight() { return static_cast(getObject()->getHeight()); } - JSI_HOST_FUNCTION(getMaxWidth) { + double getMaxWidth() { return static_cast(getObject()->getMaxWidth()); } - JSI_HOST_FUNCTION(getMaxIntrinsicWidth) { + double getMaxIntrinsicWidth() { return static_cast(getObject()->getMaxIntrinsicWidth()); } - JSI_HOST_FUNCTION(getMinIntrinsicWidth) { + double getMinIntrinsicWidth() { return static_cast(getObject()->getMinIntrinsicWidth()); } - JSI_HOST_FUNCTION(getLongestLine) { + double getLongestLine() { return static_cast(getObject()->getLongestLine()); } - JSI_HOST_FUNCTION(getGlyphPositionAtCoordinate) { - auto dx = getArgumentAsNumber(runtime, arguments, count, 0); - auto dy = getArgumentAsNumber(runtime, arguments, count, 1); + int getGlyphPositionAtCoordinate(double dx, double dy) { auto result = getObject()->getGlyphPositionAtCoordinate(dx, dy); return result.position; } - JSI_HOST_FUNCTION(getRectsForRange) { - auto start = getArgumentAsNumber(runtime, arguments, count, 0); - auto end = getArgumentAsNumber(runtime, arguments, count, 1); + std::vector> getRectsForRange(double start, + double end) { auto result = getObject()->getRectsForRange(start, end, para::RectHeightStyle::kTight, para::RectWidthStyle::kTight); - auto returnValue = jsi::Array(runtime, result.size()); - for (size_t i = 0; i < result.size(); ++i) { - returnValue.setValueAtIndex( - runtime, i, - JsiSkRect::toValue(runtime, getContext(), result[i].rect)); + std::vector> rects; + rects.reserve(result.size()); + for (const auto &box : result) { + rects.push_back(std::make_shared(getContext(), box.rect)); } - return returnValue; + return rects; } JSI_HOST_FUNCTION(getLineMetrics) { @@ -143,14 +129,13 @@ class JsiSkParagraph return returnValue; } - JSI_HOST_FUNCTION(getPath) { - auto lineNumber = - static_cast(getArgumentAsNumber(runtime, arguments, count, 0)); + std::variant> + getPath(int lineNumber) { auto paragraph = getObject(); // Paragraph::getPath does not bounds-check the line number. if (lineNumber < 0 || static_cast(lineNumber) >= paragraph->lineNumber()) { - return jsi::Value::null(); + return nullptr; } // Paragraph::getPath resets its path builder after every visual run, so // for lines shaped as multiple runs (e.g. through font fallback) it only @@ -183,8 +168,7 @@ class JsiSkParagraph &rec); }); SkPath path = builder.detach(); - return makeJsiObject( - runtime, std::make_shared(getContext(), std::move(path))); + return std::make_shared(getContext(), std::move(path)); } JSI_HOST_FUNCTION(extendedVisit) { @@ -269,27 +253,26 @@ class JsiSkParagraph static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { installCommon(runtime, prototype); - installHostMethod(runtime, prototype, "layout", &JsiSkParagraph::layout); - installHostMethod(runtime, prototype, "paint", &JsiSkParagraph::paint); - installHostMethod(runtime, prototype, "getMaxWidth", - &JsiSkParagraph::getMaxWidth); - installHostMethod(runtime, prototype, "getMinIntrinsicWidth", - &JsiSkParagraph::getMinIntrinsicWidth); - installHostMethod(runtime, prototype, "getMaxIntrinsicWidth", - &JsiSkParagraph::getMaxIntrinsicWidth); - installHostMethod(runtime, prototype, "getLongestLine", - &JsiSkParagraph::getLongestLine); - installHostMethod(runtime, prototype, "getHeight", - &JsiSkParagraph::getHeight); + installMethod(runtime, prototype, "layout", &JsiSkParagraph::layout); + installMethod(runtime, prototype, "paint", &JsiSkParagraph::paint); + installMethod(runtime, prototype, "getMaxWidth", + &JsiSkParagraph::getMaxWidth); + installMethod(runtime, prototype, "getMinIntrinsicWidth", + &JsiSkParagraph::getMinIntrinsicWidth); + installMethod(runtime, prototype, "getMaxIntrinsicWidth", + &JsiSkParagraph::getMaxIntrinsicWidth); + installMethod(runtime, prototype, "getLongestLine", + &JsiSkParagraph::getLongestLine); + installMethod(runtime, prototype, "getHeight", &JsiSkParagraph::getHeight); installHostMethod(runtime, prototype, "getRectsForPlaceholders", &JsiSkParagraph::getRectsForPlaceholders); - installHostMethod(runtime, prototype, "getGlyphPositionAtCoordinate", - &JsiSkParagraph::getGlyphPositionAtCoordinate); - installHostMethod(runtime, prototype, "getRectsForRange", - &JsiSkParagraph::getRectsForRange); + installMethod(runtime, prototype, "getGlyphPositionAtCoordinate", + &JsiSkParagraph::getGlyphPositionAtCoordinate); + installMethod(runtime, prototype, "getRectsForRange", + &JsiSkParagraph::getRectsForRange); installHostMethod(runtime, prototype, "getLineMetrics", &JsiSkParagraph::getLineMetrics); - installHostMethod(runtime, prototype, "getPath", &JsiSkParagraph::getPath); + installMethod(runtime, prototype, "getPath", &JsiSkParagraph::getPath); installHostMethod(runtime, prototype, "extendedVisit", &JsiSkParagraph::extendedVisit); } diff --git a/packages/skia/cpp/api/JsiSkParagraphBuilder.h b/packages/skia/cpp/api/JsiSkParagraphBuilder.h index c8a938bf1b..817e917a30 100644 --- a/packages/skia/cpp/api/JsiSkParagraphBuilder.h +++ b/packages/skia/cpp/api/JsiSkParagraphBuilder.h @@ -1,10 +1,12 @@ #pragma once #include +#include #include #include +#include "JsiSkConverters.h" #include "JsiSkFont.h" #include "JsiSkFontMgr.h" #include "JsiSkFontMgrFactory.h" @@ -40,85 +42,55 @@ class JsiSkParagraphBuilder : public JsiSkNativeObject { public: static constexpr const char *CLASS_NAME = "ParagraphBuilder"; - JSI_HOST_FUNCTION(build) { - return makeJsiObject(runtime, std::make_shared( - getContext(), _builder.get())); + std::shared_ptr build() { + return std::make_shared(getContext(), _builder.get()); } - JSI_HOST_FUNCTION(reset) { - _builder->Reset(); - return jsi::Value::undefined(); - } + void reset() { _builder->Reset(); } - JSI_HOST_FUNCTION(addText) { - auto text = getArgumentAsString(runtime, arguments, count, 0).utf8(runtime); - _builder->addText(text.c_str()); - return thisValue.asObject(runtime); - } + void addText(std::string text) { _builder->addText(text.c_str()); } - JSI_HOST_FUNCTION(addPlaceholder) { - auto width = - count >= 1 ? getArgumentAsNumber(runtime, arguments, count, 0) : 0; - auto height = - count >= 2 ? getArgumentAsNumber(runtime, arguments, count, 1) : 0; - auto alignment = - count >= 3 ? static_cast( - getArgumentAsNumber(runtime, arguments, count, 2)) - : para::PlaceholderAlignment::kBaseline; - auto baseline = count >= 4 - ? static_cast( - getArgumentAsNumber(runtime, arguments, count, 3)) + void addPlaceholder(JsiOptional width, JsiOptional height, + JsiOptional alignmentParam, + JsiOptional baselineParam, + JsiOptional offset) { + auto alignment = alignmentParam.has_value() + ? static_cast( + *alignmentParam) + : para::PlaceholderAlignment::kBaseline; + auto baseline = baselineParam.has_value() + ? static_cast(*baselineParam) : para::TextBaseline::kAlphabetic; - auto offset = - count >= 5 ? getArgumentAsNumber(runtime, arguments, count, 4) : 0; - - para::PlaceholderStyle style(width, height, alignment, baseline, offset); + para::PlaceholderStyle style(width.value_or(0), height.value_or(0), + alignment, baseline, offset.value_or(0)); _builder->addPlaceholder(style); - - return thisValue.asObject(runtime); } - JSI_HOST_FUNCTION(pushStyle) { - auto textStyle = JsiSkTextStyle::fromValue(runtime, arguments[0]); - // Foreground paint - if (count >= 2) { - auto foreground = tryGetJsiObject( - runtime, getArgument(runtime, arguments, count, 1)); - if (foreground) { - textStyle.setForegroundPaint(*foreground->getObject().get()); - } + void pushStyle(para::TextStyle textStyle, + JsiOptional> foreground, + JsiOptional> background) { + if (foreground.has_value()) { + textStyle.setForegroundPaint(**foreground); } - // Background paint - if (count >= 3) { - auto background = tryGetJsiObject( - runtime, getArgument(runtime, arguments, count, 2)); - if (background) { - textStyle.setBackgroundPaint(*background->getObject().get()); - } + if (background.has_value()) { + textStyle.setBackgroundPaint(**background); } - _builder->pushStyle(textStyle); - - return thisValue.asObject(runtime); } - JSI_HOST_FUNCTION(pop) { - _builder->pop(); - return thisValue.asObject(runtime); - } + void pop() { _builder->pop(); } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { - installHostMethod(runtime, prototype, "build", - &JsiSkParagraphBuilder::build); - installHostMethod(runtime, prototype, "reset", - &JsiSkParagraphBuilder::reset); - installHostMethod(runtime, prototype, "addText", - &JsiSkParagraphBuilder::addText); - installHostMethod(runtime, prototype, "addPlaceholder", - &JsiSkParagraphBuilder::addPlaceholder); - installHostMethod(runtime, prototype, "pushStyle", - &JsiSkParagraphBuilder::pushStyle); - installHostMethod(runtime, prototype, "pop", &JsiSkParagraphBuilder::pop); + installMethod(runtime, prototype, "build", &JsiSkParagraphBuilder::build); + installMethod(runtime, prototype, "reset", &JsiSkParagraphBuilder::reset); + installChainableMethod(runtime, prototype, "addText", + &JsiSkParagraphBuilder::addText); + installChainableMethod(runtime, prototype, "addPlaceholder", + &JsiSkParagraphBuilder::addPlaceholder); + installChainableMethod(runtime, prototype, "pushStyle", + &JsiSkParagraphBuilder::pushStyle); + installChainableMethod(runtime, prototype, "pop", + &JsiSkParagraphBuilder::pop); } size_t getMemoryPressure() override { return 1024 * 1024; } diff --git a/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h b/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h index 8ccbbc279a..cea3190522 100644 --- a/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h +++ b/packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h @@ -5,9 +5,11 @@ #include +#include "JsiSkConverters.h" #include "JsiSkNativeObjects.h" #include "JsiSkParagraphBuilder.h" #include "JsiSkParagraphStyle.h" +#include "JsiSkTypefaceFontProvider.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -31,25 +33,18 @@ class JsiSkParagraphBuilderFactory public: static constexpr const char *CLASS_NAME = "ParagraphBuilderFactory"; - JSI_HOST_FUNCTION(Make) { - // Get paragraph style from params - auto paragraphStyle = - count > 0 ? JsiSkParagraphStyle::fromValue(runtime, arguments[0]) - : para::ParagraphStyle(); - - // get font manager - auto fontMgr = - count > 1 ? JsiSkTypefaceFontProvider::fromValue(runtime, arguments[1]) - : nullptr; - - // Create the paragraph builder - return makeJsiObject(runtime, std::make_shared( - getContext(), paragraphStyle, fontMgr)); + std::shared_ptr + Make(JsiOptional paragraphStyle, + JsiOptional> fontMgr) { + return std::make_shared( + getContext(), + paragraphStyle.has_value() ? *paragraphStyle : para::ParagraphStyle(), + fontMgr.has_value() ? *fontMgr : nullptr); } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { - installHostMethod(runtime, prototype, "Make", - &JsiSkParagraphBuilderFactory::Make); + installMethod(runtime, prototype, "Make", + &JsiSkParagraphBuilderFactory::Make); } size_t getMemoryPressure() override { return 1024 * 1024; } diff --git a/packages/skia/cpp/api/JsiSkPictureRecorder.h b/packages/skia/cpp/api/JsiSkPictureRecorder.h index 7e1a5ef136..42b6121efb 100644 --- a/packages/skia/cpp/api/JsiSkPictureRecorder.h +++ b/packages/skia/cpp/api/JsiSkPictureRecorder.h @@ -3,6 +3,7 @@ #include #include "JsiSkCanvas.h" +#include "JsiSkConverters.h" #include "JsiSkNativeObjects.h" #include "JsiSkPicture.h" #include "JsiSkRect.h" @@ -30,33 +31,31 @@ class JsiSkPictureRecorder SkPictureRecorder>( context, std::make_shared()) {} - JSI_HOST_FUNCTION(beginRecording) { + std::shared_ptr + beginRecording(JsiOptional> rect) { SkCanvas *canvas; - if (count > 0 && !arguments[0].isUndefined()) { - auto rect = JsiSkRect::fromValue(runtime, arguments[0]); + if (rect.has_value()) { SkRTreeFactory factory; - canvas = getObject()->beginRecording(*rect, &factory); + canvas = getObject()->beginRecording(**rect, &factory); } else { SkISize size = SkISize::Make(2'000'000, 2'000'000); - SkRect rect = SkRect::Make(size); - canvas = getObject()->beginRecording(rect, nullptr); + SkRect bounds = SkRect::Make(size); + canvas = getObject()->beginRecording(bounds, nullptr); } - return makeJsiObject(runtime, - std::make_shared(getContext(), canvas)); + return std::make_shared(getContext(), canvas); } - JSI_HOST_FUNCTION(finishRecordingAsPicture) { + std::shared_ptr finishRecordingAsPicture() { auto picture = getObject()->finishRecordingAsPicture(); - return makeJsiObject(runtime, std::make_shared( - getContext(), std::move(picture))); + return std::make_shared(getContext(), std::move(picture)); } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { installCommon(runtime, prototype); - installHostMethod(runtime, prototype, "beginRecording", - &JsiSkPictureRecorder::beginRecording); - installHostMethod(runtime, prototype, "finishRecordingAsPicture", - &JsiSkPictureRecorder::finishRecordingAsPicture); + installMethod(runtime, prototype, "beginRecording", + &JsiSkPictureRecorder::beginRecording); + installMethod(runtime, prototype, "finishRecordingAsPicture", + &JsiSkPictureRecorder::finishRecordingAsPicture); } size_t getMemoryPressure() override { return 1024 * 1024; } diff --git a/packages/skia/cpp/api/JsiSkiaContext.h b/packages/skia/cpp/api/JsiSkiaContext.h index 75bb2b539a..af9a4db9a1 100644 --- a/packages/skia/cpp/api/JsiSkiaContext.h +++ b/packages/skia/cpp/api/JsiSkiaContext.h @@ -3,8 +3,10 @@ #include #include #include +#include #include +#include "JsiSkConverters.h" #include "JsiSkNativeObjects.h" #include "utils/RNSkLog.h" #include @@ -12,6 +14,7 @@ #include "JsiSkPaint.h" #include "JsiSkPoint.h" #include "JsiSkRect.h" +#include "JsiSkSurface.h" #include "JsiSkTypeface.h" #include "rnskia/RNWindowContext.h" @@ -33,25 +36,21 @@ class JsiSkiaContext public: static constexpr const char *CLASS_NAME = "SkiaContext"; - JSI_HOST_FUNCTION(getSurface) { + std::variant> getSurface() { auto surface = getObject()->getSurface(); if (surface == nullptr) { - return jsi::Value::null(); + return nullptr; } - return makeJsiObject(runtime, std::make_shared( - getContext(), std::move(surface))); + return std::make_shared(getContext(), std::move(surface)); } - JSI_HOST_FUNCTION(present) { - getObject()->present(); - return jsi::Value::undefined(); - } + void present() { getObject()->present(); } static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) { installCommon(runtime, prototype); - installHostMethod(runtime, prototype, "getSurface", - &JsiSkiaContext::getSurface); - installHostMethod(runtime, prototype, "present", &JsiSkiaContext::present); + installMethod(runtime, prototype, "getSurface", + &JsiSkiaContext::getSurface); + installMethod(runtime, prototype, "present", &JsiSkiaContext::present); } JsiSkiaContext(std::shared_ptr context,