Unverified Commit 09dae793 authored by Ivan Matkov's avatar Ivan Matkov Committed by GitHub

Adoption of `RenderNode` approach (#1014)

It is a simplified adoption of Android's `RenderNode`.

```kt
/**
 * <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
 * contains both a display list as well as a set of properties that affect the rendering of the
 * display list. RenderNodes are used internally for all Views by default and are not typically
 * used directly.</p>
 *
 * <p>RenderNodes are used to divide up the rendering content of a complex scene into smaller
 * pieces that can then be updated individually more cheaply. Updating part of the scene only needs
 * to update the display list or properties of a small number of RenderNode instead of redrawing
 * everything from scratch. A RenderNode only needs its display list re-recorded when its content
 * alone should be changed. RenderNodes can also be transformed without re-recording the display
 * list through the transform properties.</p>
 ```
 
 This is a more correct approach to make `GraphicsLayer` in Compose invalidation independently.
 - Moved drawing callback to C++ side to avoid extra interop costs
 - Switched from `SkPicture` placeholder to custom `SkDrawable` implementation
parent 1af72c1c
This project contains code adapted from "The Android Open Source Project" licensed under the Apache License, Version 2.0 (the "License"):
https://android.googlesource.com/platform/frameworks/base
...@@ -19,7 +19,7 @@ import kotlin.collections.HashSet ...@@ -19,7 +19,7 @@ import kotlin.collections.HashSet
abstract class CompileSkikoCppTask() : AbstractSkikoNativeToolTask() { abstract class CompileSkikoCppTask() : AbstractSkikoNativeToolTask() {
@get:Internal @get:Internal
open val srcExtensions: Array<String> = arrayOf("cc") open val srcExtensions: Array<String> = arrayOf("cc", "cpp")
@get:Internal @get:Internal
open val headerExtensions: Array<String> = arrayOf("h", "hh") open val headerExtensions: Array<String> = arrayOf("h", "hh")
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
namespace skikoMpp { namespace skikoMpp {
namespace skrect { namespace skrect {
// TODO: Combine with skija::Rect::copyToInterop
void serializeAs4Floats(const SkRect& rect, float* result); void serializeAs4Floats(const SkRect& rect, float* result);
std::unique_ptr<SkRect> toSkRect(float* topLeftRightBottom); std::unique_ptr<SkRect> toSkRect(float* topLeftRightBottom);
} }
......
#pragma once
#include <SkPoint3.h>
// Adoption of frameworks/base/libs/hwui/Lighting.h
namespace skiko {
namespace node {
struct LightGeometry {
SkPoint3 center;
float radius;
};
struct LightInfo {
float ambientShadowAlpha;
float spotShadowAlpha;
};
} // namespace node
} // namespace skiko
#pragma once
#include <optional>
#include <SkBBHFactory.h>
#include <SkCamera.h>
#include <SkCanvas.h>
#include <SkColor.h>
#include <SkDrawable.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkPictureRecorder.h>
#include <SkPoint.h>
#include <SkRRect.h>
#include <SkRect.h>
#include <SkRefCnt.h>
#include "Lighting.h"
namespace skiko {
namespace node {
class RenderNodeContext;
class RenderNode : public SkDrawable {
public:
RenderNode(const sk_sp<RenderNodeContext>& context);
~RenderNode();
std::optional<SkPaint>& getLayerPaint() { return this->layerPaint; }
void setLayerPaint(const std::optional<SkPaint>& layerPaint);
const SkRect& getBounds() const { return this->bounds; }
void setBounds(const SkRect& bounds);
const SkPoint& getPivot() const { return this->pivot; }
void setPivot(const SkPoint& pivot);
float getAlpha() const { return this->alpha; }
void setAlpha(float alpha);
float getScaleX() const { return this->scaleX; }
void setScaleX(float scaleX);
float getScaleY() const { return this->scaleY; }
void setScaleY(float scaleY);
float getTranslationX() const { return this->translationX; }
void setTranslationX(float translationX);
float getTranslationY() const { return this->translationY; }
void setTranslationY(float translationY);
float getShadowElevation() const { return this->shadowElevation; }
void setShadowElevation(float shadowElevation);
SkColor getAmbientShadowColor() const { return this->ambientShadowColor; }
void setAmbientShadowColor(SkColor ambientShadowColor);
SkColor getSpotShadowColor() const { return this->spotShadowColor; }
void setSpotShadowColor(SkColor spotShadowColor);
float getRotationX() const { return this->rotationX; }
void setRotationX(float rotationX);
float getRotationY() const { return this->rotationY; }
void setRotationY(float rotationY);
float getRotationZ() const { return this->rotationZ; }
void setRotationZ(float rotationZ);
float getCameraDistance() const;
void setCameraDistance(float cameraDistance);
void setClipRect(const std::optional<SkRect>& clipRect);
void setClipRRect(const std::optional<SkRRect>& clipRRect);
void setClipPath(const std::optional<SkPath>& clipPath);
bool getClip() const { return this->clip; }
void setClip(bool clip);
const SkMatrix& getMatrix();
SkCanvas * beginRecording();
void endRecording();
void drawInto(SkCanvas *canvas);
// SkDrawable
void onDraw(SkCanvas* canvas) override;
SkRect onGetBounds() override;
protected:
sk_sp<SkPicture> onMakePictureSnapshot() override;
private:
void updateMatrix();
void drawShadow(SkCanvas *canvas, const LightGeometry& lightGeometry, const LightInfo& lightInfo);
void setCameraLocation(float x, float y, float z);
sk_sp<RenderNodeContext> context;
SkBBHFactory *bbhFactory;
SkPictureRecorder recorder;
sk_sp<SkDrawable> contentCache;
std::optional<SkPaint> layerPaint;
SkRect bounds;
SkPoint pivot;
float alpha;
float scaleX, scaleY;
float translationX, translationY;
float shadowElevation;
SkColor ambientShadowColor;
SkColor spotShadowColor;
float rotationX, rotationY, rotationZ;
std::optional<SkRect> clipRect;
std::optional<SkRRect> clipRRect;
std::optional<SkPath> clipPath;
bool clip;
SkMatrix transformMatrix;
SkCamera3D transformCamera;
bool matrixIdentity;
bool matrixDirty;
};
} // namespace node
} // namespace skiko
#pragma once
#include <SkRefCnt.h>
#include "Lighting.h"
namespace skiko {
namespace node {
class RenderNode;
class RenderNodeContext : public SkRefCnt {
public:
RenderNodeContext(bool measureDrawBounds);
bool shouldMeasureDrawBounds() const { return this->measureDrawBounds; }
const LightGeometry& getLightGeometry() const { return this->lightGeometry; }
const LightInfo& getLightInfo() const { return this->lightInfo; }
void setLightingInfo(
const LightGeometry& lightGeometry,
const LightInfo& lightInfo
);
private:
LightGeometry lightGeometry;
LightInfo lightInfo;
bool measureDrawBounds;
};
} // namespace node
} // namespace skiko
#include <SkNWayCanvas.h>
#include <SkPicture.h>
#include <SkShadowUtils.h>
#include "node/RenderNode.h"
#include "node/RenderNodeContext.h"
namespace skiko {
namespace node {
// The goal with selecting the size of the rectangle here is to avoid limiting the
// drawable area as much as possible.
// Due to https://issuetracker.google.com/issues/324465764 we have to
// leave room for scale between the values we specify here and Float.MAX_VALUE.
// The maximum possible scale that can be applied to the canvas will be
// Float.MAX_VALUE divided by the largest value below.
// 2^30 was chosen because it's big enough, leaves quite a lot of room between it
// and Float.MAX_VALUE, and also lets the width and height fit into int32 (just in
// case).
static const float PICTURE_MIN_VALUE = static_cast<float>(-(1L << 30));
static const float PICTURE_MAX_VALUE = static_cast<float>((1L << 30) - 1);
static SkRect PICTURE_BOUNDS {
PICTURE_MIN_VALUE,
PICTURE_MIN_VALUE,
PICTURE_MAX_VALUE,
PICTURE_MAX_VALUE
};
static const float DEFAULT_CAMERA_DISTANCE = 8.0f;
static const float NON_ZERO_EPSILON = 0.001f;
/**
* Check for floats that are close enough to zero.
*/
inline static bool isZero(float value) {
// Using fabsf is more performant as ARM computes
// fabsf in a single instruction.
return fabsf(value) <= NON_ZERO_EPSILON;
}
static SkColor multiplyAlpha(SkColor color, float alpha) {
return SkColorSetA(color, alpha * SkColorGetA(color));
}
class UnrollDrawableCanvas : public SkNWayCanvas {
public:
UnrollDrawableCanvas(SkCanvas* canvas)
: SkNWayCanvas(canvas->imageInfo().width(), canvas->imageInfo().height()) {
this->addCanvas(canvas);
}
protected:
void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
drawable->draw(this, matrix);
}
};
RenderNode::RenderNode(const sk_sp<RenderNodeContext>& context)
: context(context),
bbhFactory(context->shouldMeasureDrawBounds() ? new SkRTreeFactory() : nullptr),
recorder(),
contentCache(),
layerPaint(),
bounds { 0.0f, 0.0f, 0.0f, 0.0f },
pivot { SK_FloatNaN, SK_FloatNaN },
alpha(1.0f),
scaleX(1.0f),
scaleY(1.0f),
translationX(0.0f),
translationY(0.0f),
shadowElevation(0.0f),
ambientShadowColor(SK_ColorBLACK),
spotShadowColor(SK_ColorBLACK),
rotationX(0.0f),
rotationY(0.0f),
rotationZ(0.0f),
clipRect(),
clipRRect(),
clipPath(),
clip(false),
transformMatrix(),
transformCamera(),
matrixIdentity(true),
matrixDirty(false) {
this->setCameraLocation(0.0f, 0.0f, DEFAULT_CAMERA_DISTANCE);
}
RenderNode::~RenderNode() {
if (this->bbhFactory) {
delete this->bbhFactory;
this->bbhFactory = nullptr;
}
}
void RenderNode::setLayerPaint(const std::optional<SkPaint>& layerPaint) {
this->layerPaint = layerPaint;
}
void RenderNode::setBounds(const SkRect& bounds) {
this->bounds = bounds;
this->matrixDirty = true;
}
void RenderNode::setPivot(const SkPoint& pivot) {
this->pivot = pivot;
this->matrixDirty = true;
}
void RenderNode::setAlpha(float alpha) {
this->alpha = alpha;
}
void RenderNode::setScaleX(float scaleX) {
this->scaleX = scaleX;
this->matrixDirty = true;
}
void RenderNode::setScaleY(float scaleY) {
this->scaleY = scaleY;
this->matrixDirty = true;
}
void RenderNode::setTranslationX(float translationX) {
this->translationX = translationX;
this->matrixDirty = true;
}
void RenderNode::setTranslationY(float translationY) {
this->translationY = translationY;
this->matrixDirty = true;
}
void RenderNode::setShadowElevation(float shadowElevation) {
this->shadowElevation = shadowElevation;
}
void RenderNode::setAmbientShadowColor(SkColor ambientShadowColor) {
this->ambientShadowColor = ambientShadowColor;
}
void RenderNode::setSpotShadowColor(SkColor spotShadowColor) {
this->spotShadowColor = spotShadowColor;
}
void RenderNode::setRotationX(float rotationX) {
this->rotationX = rotationX;
this->matrixDirty = true;
}
void RenderNode::setRotationY(float rotationY) {
this->rotationY = rotationY;
this->matrixDirty = true;
}
void RenderNode::setRotationZ(float rotationZ) {
this->rotationZ = rotationZ;
this->matrixDirty = true;
}
float RenderNode::getCameraDistance() const {
return this->transformCamera.fLocation.z / 72.0f;
}
void RenderNode::setCameraDistance(float cameraDistance) {
this->setCameraLocation(0.0f, 0.0f, cameraDistance);
this->matrixDirty = true;
}
void RenderNode::setClipRect(const std::optional<SkRect>& clipRect) {
this->clipRect = clipRect;
this->clipRRect.reset();
this->clipPath.reset();
}
void RenderNode::setClipRRect(const std::optional<SkRRect>& clipRRect) {
this->clipRect.reset();
this->clipRRect = clipRRect;
this->clipPath.reset();
}
void RenderNode::setClipPath(const std::optional<SkPath>& clipPath) {
this->clipRect.reset();
this->clipRRect.reset();
this->clipPath = clipPath;
}
void RenderNode::setClip(bool clip) {
this->clip = clip;
}
const SkMatrix& RenderNode::getMatrix() {
this->updateMatrix();
return this->transformMatrix;
}
SkCanvas *RenderNode::beginRecording() {
bool measureDrawBounds = !clip || shadowElevation > 0.0f;
const SkRect& bounds = measureDrawBounds ? PICTURE_BOUNDS : SkRect::MakeWH(this->bounds.width(), this->bounds.height());
SkBBHFactory* bbhFactory = measureDrawBounds ? this->bbhFactory : nullptr;
return this->recorder.beginRecording(bounds, bbhFactory);
}
void RenderNode::endRecording() {
this->contentCache = this->recorder.finishRecordingAsDrawable();
}
void RenderNode::drawInto(SkCanvas* canvas) {
canvas->drawDrawable(this);
}
void RenderNode::onDraw(SkCanvas* canvas) {
this->updateMatrix();
canvas->translate(this->bounds.left(), this->bounds.top());
if (!this->matrixIdentity) {
canvas->concat(this->transformMatrix);
}
if (this->shadowElevation > 0) {
auto lightGeometry = this->context->getLightGeometry();
auto lightInfo = this->context->getLightInfo();
this->drawShadow(canvas, lightGeometry, lightInfo);
}
if (this->clip) {
canvas->save();
if (this->clipRect) {
canvas->clipRect(*this->clipRect);
} else if (this->clipRRect) {
canvas->clipRRect(*this->clipRRect);
} else if (this->clipPath) {
canvas->clipPath(*this->clipPath);
} else {
canvas->clipRect(SkRect::MakeWH(this->bounds.width(), this->bounds.height()));
}
}
if (this->layerPaint) {
canvas->saveLayer(SkRect::MakeWH(this->bounds.width(), this->bounds.height()), &*this->layerPaint);
} else {
canvas->save();
}
canvas->drawDrawable(this->contentCache.get());
}
SkRect RenderNode::onGetBounds() {
return this->bounds;
}
sk_sp<SkPicture> RenderNode::onMakePictureSnapshot() {
const SkRect bounds = this->getBounds();
SkCanvas* canvas = this->recorder.beginRecording(bounds);
UnrollDrawableCanvas unrollCanvas(canvas);
this->draw(&unrollCanvas);
return this->recorder.finishRecordingAsPicture();
}
// Adoption from frameworks/base/libs/hwui/RenderProperties.cpp
void RenderNode::updateMatrix() {
if (!this->matrixDirty) {
return;
}
float pivotX, pivotY;
if (this->pivot.isFinite()) {
pivotX = this->pivot.fX;
pivotY = this->pivot.fY;
} else {
pivotX = this->bounds.width() / 2.0f;
pivotY = this->bounds.height() / 2.0f;
}
this->transformMatrix.reset();
if (isZero(this->rotationX) && isZero(this->rotationY)) {
this->transformMatrix.setTranslate(this->translationX, this->translationY);
this->transformMatrix.preRotate(this->rotationZ, pivotX, pivotY);
this->transformMatrix.preScale(this->scaleX, this->scaleY, pivotX, pivotY);
} else {
this->transformMatrix.preScale(this->scaleX, this->scaleY, pivotX, pivotY);
SkM44 transform3D;
transform3D.preConcat(SkM44::Rotate({1, 0, 0}, -this->rotationX * SK_ScalarPI / 180));
transform3D.preConcat(SkM44::Rotate({0,-1, 0}, -this->rotationY * SK_ScalarPI / 180));
transform3D.preConcat(SkM44::Rotate({0, 0, 1}, -this->rotationZ * SK_ScalarPI / 180));
SkPatch3D patch3D;
patch3D.transform(transform3D);
SkMatrix transform;
this->transformCamera.patchToMatrix(patch3D, &transform);
transform.preTranslate(-pivotX, -pivotY);
transform.postTranslate(pivotX + this->translationX, pivotY + this->translationY);
this->transformMatrix.postConcat(transform);
}
this->matrixDirty = false;
this->matrixIdentity = this->transformMatrix.isIdentity();
}
void RenderNode::drawShadow(SkCanvas *canvas, const LightGeometry& lightGeometry, const LightInfo& lightInfo) {
SkPath tmpPath, *path = &tmpPath;
if (this->clipRect) {
tmpPath.addRect(*this->clipRect);
} else if (this->clipRRect) {
tmpPath.addRRect(*this->clipRRect);
} else if (this->clipPath) {
path = &*this->clipPath;
} else {
return;
}
SkPoint3 zParams{0.0f, 0.0f, this->shadowElevation};
float ambientAlpha = lightInfo.ambientShadowAlpha * this->alpha;
float spotAlpha = lightInfo.spotShadowAlpha * this->alpha;
SkColor ambientColor = multiplyAlpha(this->ambientShadowColor, ambientAlpha);
SkColor spotColor = multiplyAlpha(this->spotShadowColor, spotAlpha);
SkShadowUtils::DrawShadow(
canvas,
*path,
zParams,
lightGeometry.center,
lightGeometry.radius,
ambientColor,
spotColor,
this->alpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : SkShadowFlags::kNone_ShadowFlag
);
}
// Adoption from frameworks/base/libs/hwui/RenderProperties.cpp
void RenderNode::setCameraLocation(float x, float y, float z) {
// the camera location is passed in inches, set in pt
SkScalar lz = z * 72.0f;
this->transformCamera.fLocation = {x * 72.0f, y * 72.0f, lz};
this->transformCamera.fObserver = {0, 0, lz};
this->transformCamera.update();
}
} // namespace node
} // namespace skiko
#include "node/RenderNodeContext.h"
namespace skiko {
namespace node {
RenderNodeContext::RenderNodeContext(bool measureDrawBounds)
: measureDrawBounds(measureDrawBounds) {
}
void RenderNodeContext::setLightingInfo(
const LightGeometry& lightGeometry,
const LightInfo& lightInfo
) {
this->lightGeometry = lightGeometry;
this->lightInfo = lightInfo;
}
} // namespace node
} // namespace skiko
package org.jetbrains.skiko.node
import org.jetbrains.skia.*
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
/**
* <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
* contains both a display list as well as a set of properties that affect the rendering of the
* display list. RenderNodes are used internally for all Views by default and are not typically
* used directly.</p>
*
* <p>RenderNodes are used to divide up the rendering content of a complex scene into smaller
* pieces that can then be updated individually more cheaply. Updating part of the scene only needs
* to update the display list or properties of a small number of RenderNode instead of redrawing
* everything from scratch. A RenderNode only needs its display list re-recorded when its content
* alone should be changed. RenderNodes can also be transformed without re-recording the display
* list through the transform properties.</p>
*/
class RenderNode internal constructor(ptr: NativePointer, managed: Boolean = true) : RefCnt(ptr, managed) {
private companion object {
init {
staticLoad()
}
}
constructor(context: RenderNodeContext) : this(RenderNode_nMake(getPtr(context))) {
Stats.onNativeCall()
}
var layerPaint: Paint?
get() = try {
Stats.onNativeCall()
val ptr = RenderNode_nGetLayerPaint(_ptr)
if (ptr == NullPointer) null else Paint(ptr, false)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetLayerPaint(_ptr, getPtr(value))
} finally {
reachabilityBarrier(this)
reachabilityBarrier(value)
}
var bounds: Rect
get() = try {
Stats.onNativeCall()
Rect.fromInteropPointer { RenderNode_nGetBounds(_ptr, it) }
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetBounds(_ptr, value.left, value.top, value.right, value.bottom)
} finally {
reachabilityBarrier(this)
}
var pivot: Point
get() = try {
Stats.onNativeCall()
Point.fromInteropPointer { RenderNode_nGetPivot(_ptr, it) }
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetPivot(_ptr, value.x, value.y)
} finally {
reachabilityBarrier(this)
}
var alpha: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetAlpha(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetAlpha(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var scaleX: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetScaleX(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetScaleX(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var scaleY: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetScaleY(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetScaleY(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var translationX: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetTranslationX(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetTranslationX(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var translationY: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetTranslationY(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetTranslationY(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var shadowElevation: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetShadowElevation(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetShadowElevation(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var ambientShadowColor: Int
get() = try {
Stats.onNativeCall()
RenderNode_nGetAmbientShadowColor(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetAmbientShadowColor(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var spotShadowColor: Int
get() = try {
Stats.onNativeCall()
RenderNode_nGetSpotShadowColor(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetSpotShadowColor(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var rotationX: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetRotationX(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetRotationX(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var rotationY: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetRotationY(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetRotationY(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var rotationZ: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetRotationZ(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetRotationZ(_ptr, value)
} finally {
reachabilityBarrier(this)
}
var cameraDistance: Float
get() = try {
Stats.onNativeCall()
RenderNode_nGetCameraDistance(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetCameraDistance(_ptr, value)
} finally {
reachabilityBarrier(this)
}
fun setClipRect(r: Rect) {
Stats.onNativeCall()
RenderNode_nSetClipRect(_ptr, r.left, r.top, r.right, r.bottom)
}
fun setClipRRect(r: RRect) {
Stats.onNativeCall()
interopScope {
RenderNode_nSetClipRRect(_ptr, r.left, r.top, r.right, r.bottom, toInterop(r.radii), r.radii.size)
}
}
fun setClipPath(p: Path?) {
try {
Stats.onNativeCall()
RenderNode_nSetClipPath(_ptr, getPtr(p))
} finally {
reachabilityBarrier(this)
reachabilityBarrier(p)
}
}
var clip: Boolean
get() = try {
Stats.onNativeCall()
RenderNode_nGetClip(_ptr)
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
RenderNode_nSetClip(_ptr, value)
} finally {
reachabilityBarrier(this)
}
fun beginRecording(): Canvas {
return try {
Stats.onNativeCall()
Canvas(
ptr = RenderNode_nBeginRecording(_ptr),
managed = false,
_owner = this
)
} finally {
reachabilityBarrier(this)
}
}
fun endRecording() {
try {
Stats.onNativeCall()
RenderNode_nEndRecording(_ptr)
} finally {
reachabilityBarrier(this)
}
}
fun drawInto(canvas: Canvas) {
try {
Stats.onNativeCall()
RenderNode_nDrawInto(_ptr, getPtr(canvas))
} finally {
reachabilityBarrier(this)
}
}
}
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nMake")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nMake")
private external fun RenderNode_nMake(context: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetLayerPaint")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetLayerPaint")
private external fun RenderNode_nGetLayerPaint(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetLayerPaint")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetLayerPaint")
private external fun RenderNode_nSetLayerPaint(ptr: NativePointer, paint: NativePointer)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetBounds")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetBounds")
private external fun RenderNode_nGetBounds(ptr: NativePointer, result: InteropPointer)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetBounds")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetBounds")
private external fun RenderNode_nSetBounds(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetPivot")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetPivot")
private external fun RenderNode_nGetPivot(ptr: NativePointer, result: InteropPointer)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetPivot")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetPivot")
private external fun RenderNode_nSetPivot(ptr: NativePointer, x: Float, y: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAlpha")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAlpha")
private external fun RenderNode_nGetAlpha(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAlpha")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAlpha")
private external fun RenderNode_nSetAlpha(ptr: NativePointer, alpha: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleX")
private external fun RenderNode_nGetScaleX(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleX")
private external fun RenderNode_nSetScaleX(ptr: NativePointer, scaleX: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleY")
private external fun RenderNode_nGetScaleY(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleY")
private external fun RenderNode_nSetScaleY(ptr: NativePointer, scaleY: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationX")
private external fun RenderNode_nGetTranslationX(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationX")
private external fun RenderNode_nSetTranslationX(ptr: NativePointer, translationX: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationY")
private external fun RenderNode_nGetTranslationY(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationY")
private external fun RenderNode_nSetTranslationY(ptr: NativePointer, translationY: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetShadowElevation")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetShadowElevation")
private external fun RenderNode_nGetShadowElevation(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetShadowElevation")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetShadowElevation")
private external fun RenderNode_nSetShadowElevation(ptr: NativePointer, elevation: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAmbientShadowColor")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAmbientShadowColor")
private external fun RenderNode_nGetAmbientShadowColor(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAmbientShadowColor")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAmbientShadowColor")
private external fun RenderNode_nSetAmbientShadowColor(ptr: NativePointer, color: Int)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetSpotShadowColor")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetSpotShadowColor")
private external fun RenderNode_nGetSpotShadowColor(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetSpotShadowColor")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetSpotShadowColor")
private external fun RenderNode_nSetSpotShadowColor(ptr: NativePointer, color: Int)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationX")
private external fun RenderNode_nGetRotationX(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationX")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationX")
private external fun RenderNode_nSetRotationX(ptr: NativePointer, rotationX: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationY")
private external fun RenderNode_nGetRotationY(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationY")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationY")
private external fun RenderNode_nSetRotationY(ptr: NativePointer, rotationY: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationZ")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationZ")
private external fun RenderNode_nGetRotationZ(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationZ")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationZ")
private external fun RenderNode_nSetRotationZ(ptr: NativePointer, rotationZ: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetCameraDistance")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetCameraDistance")
private external fun RenderNode_nGetCameraDistance(ptr: NativePointer): Float
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDistance")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDistance")
private external fun RenderNode_nSetCameraDistance(ptr: NativePointer, distance: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
private external fun RenderNode_nSetClipRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
private external fun RenderNode_nSetClipRRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, radii: InteropPointer, radiiSize: Int)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
private external fun RenderNode_nSetClipPath(ptr: NativePointer, pathPtr: NativePointer)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")
private external fun RenderNode_nGetClip(ptr: NativePointer): Boolean
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClip")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClip")
private external fun RenderNode_nSetClip(ptr: NativePointer, clip: Boolean)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nBeginRecording")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nBeginRecording")
private external fun RenderNode_nBeginRecording(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nEndRecording")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nEndRecording")
private external fun RenderNode_nEndRecording(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nDrawInto")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nDrawInto")
private external fun RenderNode_nDrawInto(ptr: NativePointer, canvas: NativePointer)
package org.jetbrains.skiko.node
import org.jetbrains.skia.*
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
class RenderNodeContext internal constructor(ptr: NativePointer, managed: Boolean = true) : RefCnt(ptr, managed) {
private companion object {
init {
staticLoad()
}
}
constructor(
measureDrawBounds: Boolean = false,
) : this(RenderNodeContext_nMake(measureDrawBounds)) {
Stats.onNativeCall()
}
fun setLightingInfo(
centerX: Float = Float.MIN_VALUE,
centerY: Float = Float.MIN_VALUE,
centerZ: Float = Float.MIN_VALUE,
radius: Float = 0f,
ambientShadowAlpha: Float = 0f,
spotShadowAlpha: Float = 0f
) {
try {
Stats.onNativeCall()
RenderNodeContext_nSetLightingInfo(
ptr = _ptr,
centerX = centerX,
centerY = centerY,
centerZ = centerZ,
radius = radius,
ambientShadowAlpha = ambientShadowAlpha,
spotShadowAlpha = spotShadowAlpha
)
} finally {
reachabilityBarrier(this)
}
}
}
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nMake")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nMake")
private external fun RenderNodeContext_nMake(measureDrawBounds: Boolean): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nSetLightingInfo")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nSetLightingInfo")
private external fun RenderNodeContext_nSetLightingInfo(ptr: NativePointer, centerX: Float, centerY: Float, centerZ: Float, radius: Float, ambientShadowAlpha: Float, spotShadowAlpha: Float)
package org.jetbrains.skiko.node
import org.jetbrains.skia.*
import org.jetbrains.skia.tests.assertCloseEnough
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class RenderNodeTest {
@Test
fun verifyInterop() {
val surface = Surface.Companion.makeRasterN32Premul(16, 16)
val context = RenderNodeContext()
val node = RenderNode(context)
context.setLightingInfo(0f, 0f, 10f, 1f, 1f, 1f)
node.layerPaint = Paint().apply { color = Color.RED }
assertTrue(node.layerPaint != null)
node.bounds = Rect(1f, 2f, 3f, 4f)
assertCloseEnough(Rect(1f, 2f, 3f, 4f), node.bounds)
node.pivot = Point(5f, 6f)
assertCloseEnough(Point(5f, 6f), node.pivot)
node.alpha = 0.42f
assertCloseEnough(0.42f, node.alpha)
node.scaleX = 2f
assertCloseEnough(2f, node.scaleX)
node.scaleY = 3f
assertCloseEnough(3f, node.scaleY)
node.translationX = 7f
assertCloseEnough(7f, node.translationX)
node.translationY = 8f
assertCloseEnough(8f, node.translationY)
node.rotationX = 9f
assertCloseEnough(9f, node.rotationX)
node.rotationY = 10f
assertCloseEnough(10f, node.rotationY)
node.rotationZ = 11f
assertCloseEnough(11f, node.rotationZ)
node.shadowElevation = 1f
assertCloseEnough(1f, node.shadowElevation)
node.ambientShadowColor = Color.GREEN
assertEquals(Color.GREEN, node.ambientShadowColor)
node.spotShadowColor = Color.BLUE
assertEquals(Color.BLUE, node.spotShadowColor)
node.cameraDistance = 12f
assertCloseEnough(12f, node.cameraDistance)
node.setClipRect(Rect(0f, 0f, 16f, 16f))
node.setClipRRect(RRect.makeLTRB(0f, 0f, 16f, 16f, 1f))
node.setClipPath(Path())
node.setClipPath(null)
node.clip = true
assertTrue(node.clip)
val recordCanvas = node.beginRecording()
recordCanvas.drawRect(Rect(0f,0f,16f,16f), Paint().apply { color = Color.BLACK })
node.endRecording()
node.drawInto(surface.canvas)
surface.close()
node.close()
context.close()
}
}
\ No newline at end of file
#include <jni.h>
#include "../interop.hh"
#include "node/RenderNode.h"
#include "node/RenderNodeContext.h"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nMake
(JNIEnv *env, jclass jclass, skiko::node::RenderNodeContext *context) {
auto instance = sk_make_sp<skiko::node::RenderNode>(sk_ref_sp(context));
return reinterpret_cast<jlong>(instance.release());
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetLayerPaint
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
std::optional<SkPaint>& layerPaint = instance->getLayerPaint();
return reinterpret_cast<jlong>(layerPaint ? &*layerPaint : nullptr);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetLayerPaint
(JNIEnv *env, jclass jclass, jlong ptr, jlong paintPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
auto paint = reinterpret_cast<SkPaint *>(paintPtr);
instance->setLayerPaint(paint ? std::optional<SkPaint>{*paint} : std::nullopt);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetBounds
(JNIEnv *env, jclass jclass, jlong ptr, jfloatArray resultRect) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkRect bounds = instance->getBounds();
jfloat* floats = env->GetFloatArrayElements(resultRect, 0);
skikoMpp::skrect::serializeAs4Floats(bounds, floats);
env->ReleaseFloatArrayElements(resultRect, floats, 0);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetBounds
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setBounds(SkRect::MakeLTRB(left, top, right, bottom));
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetPivot
(JNIEnv *env, jclass jclass, jlong ptr, jfloatArray resultPoint) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPoint pivot = instance->getPivot();
skija::Point::copyToInterop(env, pivot, resultPoint);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetPivot
(JNIEnv *env, jclass jclass, jlong ptr, jfloat x, jfloat y) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setPivot(SkPoint::Make(x, y));
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAlpha
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getAlpha();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAlpha
(JNIEnv *env, jclass jclass, jlong ptr, jfloat alpha) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setAlpha(alpha);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleX
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getScaleX();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleX
(JNIEnv *env, jclass jclass, jlong ptr, jfloat scaleX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setScaleX(scaleX);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleY
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getScaleY();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleY
(JNIEnv *env, jclass jclass, jlong ptr, jfloat scaleY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setScaleY(scaleY);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationX
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getTranslationX();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationX
(JNIEnv *env, jclass jclass, jlong ptr, jfloat translationX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setTranslationX(translationX);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationY
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getTranslationY();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationY
(JNIEnv *env, jclass jclass, jlong ptr, jfloat translationY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setTranslationY(translationY);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetShadowElevation
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getShadowElevation();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetShadowElevation
(JNIEnv *env, jclass jclass, jlong ptr, jfloat elevation) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setShadowElevation(elevation);
}
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAmbientShadowColor
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getAmbientShadowColor();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAmbientShadowColor
(JNIEnv *env, jclass jclass, jlong ptr, jint color) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setAmbientShadowColor(static_cast<uint32_t>(color));
}
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetSpotShadowColor
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getSpotShadowColor();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetSpotShadowColor
(JNIEnv *env, jclass jclass, jlong ptr, jint color) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setSpotShadowColor(static_cast<uint32_t>(color));
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationX
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationX();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationX
(JNIEnv *env, jclass jclass, jlong ptr, jfloat rotationX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationX(rotationX);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationY
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationY();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationY
(JNIEnv *env, jclass jclass, jlong ptr, jfloat rotationY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationY(rotationY);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationZ
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationZ();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationZ
(JNIEnv *env, jclass jclass, jlong ptr, jfloat rotationZ) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationZ(rotationZ);
}
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetCameraDistance
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getCameraDistance();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDistance
(JNIEnv *env, jclass jclass, jlong ptr, jfloat distance) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setCameraDistance(distance);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom));
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray radii, jint radiiSize) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRRect(skija::RRect::toSkRRect(env, left, top, right, bottom, radii));
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
(JNIEnv *env, jclass jclass, jlong ptr, jlong pathPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPath* path = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(pathPtr));
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt);
}
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getClip();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClip
(JNIEnv *env, jclass jclass, jlong ptr, jboolean clip) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClip(clip);
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nBeginRecording
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkCanvas *canvas = instance->beginRecording();
return reinterpret_cast<jlong>(canvas);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nEndRecording
(JNIEnv *env, jclass jclass, jlong ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->endRecording();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nDrawInto
(JNIEnv *env, jclass jclass, jlong ptr, jlong canvasPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
auto canvas = reinterpret_cast<SkCanvas *>(canvasPtr);
instance->drawInto(canvas);
}
#include <jni.h>
#include "../interop.hh"
#include "node/RenderNodeContext.h"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nMake
(JNIEnv *env, jclass jclass, jboolean measureDrawBounds) {
auto instance = sk_make_sp<skiko::node::RenderNodeContext>(measureDrawBounds);
return reinterpret_cast<jlong>(instance.release());
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nSetLightingInfo
(JNIEnv *env, jclass jclass, jlong ptr, jfloat centerX, jfloat centerY, jfloat centerZ, jfloat radius, jfloat ambientShadowAlpha, jfloat spotShadowAlpha) {
auto instance = reinterpret_cast<skiko::node::RenderNodeContext *>(ptr);
skiko::node::LightGeometry lightGeometry {
SkPoint3{centerX, centerY, centerZ},
radius
};
skiko::node::LightInfo lightInfo {
ambientShadowAlpha,
spotShadowAlpha
};
instance->setLightingInfo(lightGeometry, lightInfo);
}
#include "common.h"
#include "node/RenderNode.h"
#include "node/RenderNodeContext.h"
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nMake
(KNativePointer contextPtr) {
auto context = reinterpret_cast<skiko::node::RenderNodeContext *>(contextPtr);
auto instance = sk_make_sp<skiko::node::RenderNode>(sk_ref_sp(context));
return reinterpret_cast<KNativePointer>(instance.release());
}
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetLayerPaint
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
std::optional<SkPaint>& layerPaint = instance->getLayerPaint();
return reinterpret_cast<KNativePointer>(layerPaint ? &*layerPaint : nullptr);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetLayerPaint
(KNativePointer ptr, KNativePointer paintPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
auto paint = reinterpret_cast<SkPaint *>(paintPtr);
instance->setLayerPaint(paint ? std::optional<SkPaint>{*paint} : std::nullopt);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetBounds
(KNativePointer ptr, KInteropPointer resultRect) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkRect bounds = instance->getBounds();
skija::Rect::copyToInterop(bounds, resultRect);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetBounds
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setBounds(SkRect::MakeLTRB(left, top, right, bottom));
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetPivot
(KNativePointer ptr, KFloat* resultPoint) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPoint pivot = instance->getPivot();
skija::Point::copyToInterop(pivot, resultPoint);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetPivot
(KNativePointer ptr, KFloat x, KFloat y) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setPivot(SkPoint::Make(x, y));
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAlpha
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getAlpha();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAlpha
(KNativePointer ptr, KFloat alpha) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setAlpha(alpha);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleX
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getScaleX();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleX
(KNativePointer ptr, KFloat scaleX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setScaleX(scaleX);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetScaleY
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getScaleY();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetScaleY
(KNativePointer ptr, KFloat scaleY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setScaleY(scaleY);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationX
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getTranslationX();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationX
(KNativePointer ptr, KFloat translationX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setTranslationX(translationX);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetTranslationY
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getTranslationY();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetTranslationY
(KNativePointer ptr, KFloat translationY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setTranslationY(translationY);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetShadowElevation
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getShadowElevation();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetShadowElevation
(KNativePointer ptr, KFloat elevation) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setShadowElevation(elevation);
}
SKIKO_EXPORT KInt org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetAmbientShadowColor
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getAmbientShadowColor();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetAmbientShadowColor
(KNativePointer ptr, KInt color) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setAmbientShadowColor(static_cast<uint32_t>(color));
}
SKIKO_EXPORT KInt org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetSpotShadowColor
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getSpotShadowColor();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetSpotShadowColor
(KNativePointer ptr, KInt color) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setSpotShadowColor(static_cast<uint32_t>(color));
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationX
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationX();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationX
(KNativePointer ptr, KFloat rotationX) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationX(rotationX);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationY
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationY();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationY
(KNativePointer ptr, KFloat rotationY) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationY(rotationY);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetRotationZ
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getRotationZ();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetRotationZ
(KNativePointer ptr, KFloat rotationZ) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setRotationZ(rotationZ);
}
SKIKO_EXPORT KFloat org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetCameraDistance
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getCameraDistance();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDistance
(KNativePointer ptr, KFloat distance) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setCameraDistance(distance);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom));
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* radii, KInt radiiSize) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRRect(skija::RRect::toSkRRect(left, top, right, bottom, radii, radiiSize));
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
(KNativePointer ptr, KNativePointer pathPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt);
}
SKIKO_EXPORT KBoolean org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
return instance->getClip();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClip
(KNativePointer ptr, KBoolean clip) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClip(clip);
}
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nBeginRecording
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkCanvas *canvas = instance->beginRecording();
return reinterpret_cast<KNativePointer>(canvas);
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nEndRecording
(KNativePointer ptr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->endRecording();
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nDrawInto
(KNativePointer ptr, KNativePointer canvasPtr) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
auto canvas = reinterpret_cast<SkCanvas *>(canvasPtr);
instance->drawInto(canvas);
}
#include "common.h"
#include "node/RenderNodeContext.h"
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nMake
(KBoolean measureDrawBounds) {
auto instance = sk_make_sp<skiko::node::RenderNodeContext>(measureDrawBounds);
return reinterpret_cast<KNativePointer>(instance.release());
}
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeContextKt_RenderNodeContext_1nSetLightingInfo
(KNativePointer ptr, KFloat centerX, KFloat centerY, KFloat centerZ, KFloat radius, KFloat ambientShadowAlpha, KFloat spotShadowAlpha) {
auto instance = reinterpret_cast<skiko::node::RenderNodeContext *>(ptr);
skiko::node::LightGeometry lightGeometry {
SkPoint3{centerX, centerY, centerZ},
radius
};
skiko::node::LightInfo lightInfo {
ambientShadowAlpha,
spotShadowAlpha
};
instance->setLightingInfo(lightGeometry, lightInfo);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment