shared/java/Drawable.java (78 lines of code) (raw):
package org.jetbrains.skija;
import java.lang.ref.*;
import java.io.*;
import org.jetbrains.skija.impl.*;
import org.jetbrains.annotations.*;
/**
* <p>Base class for objects that draw into Canvas.</p>
*
* <p>The object has a generation id, which is guaranteed to be unique across all drawables. To
* allow for clients of the drawable that may want to cache the results, the drawable must
* change its generation id whenever its internal state changes such that it will draw differently.</p>
*/
public abstract class Drawable extends RefCnt {
static { Library.staticLoad(); }
@ApiStatus.Internal
public Rect _bounds = null;
public Drawable() {
super(_nMake());
Stats.onNativeCall();
Stats.onNativeCall();
_nInit(_ptr);
}
/**
* Draws into the specified content. The drawing sequence will be balanced upon return
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
* and the current matrix and clip settings will not be changed.
*/
@ApiStatus.NonExtendable
public Drawable draw(Canvas canvas) {
return draw(canvas, null);
}
/**
* Draws into the specified content. The drawing sequence will be balanced upon return
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
* and the current matrix and clip settings will not be changed.
*/
@ApiStatus.NonExtendable
public Drawable draw(Canvas canvas, float x, float y) {
return draw(canvas, Matrix33.makeTranslate(x, y));
}
/**
* Draws into the specified content. The drawing sequence will be balanced upon return
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
* and the current matrix and clip settings will not be changed.
*/
@ApiStatus.NonExtendable
public Drawable draw(Canvas canvas, @Nullable Matrix33 matrix) {
try {
Stats.onNativeCall();
_nDraw(_ptr, Native.getPtr(canvas), matrix == null ? null : matrix._mat);
return this;
} finally {
Reference.reachabilityFence(canvas);
}
}
@ApiStatus.NonExtendable
public Picture makePictureSnapshot() {
try {
Stats.onNativeCall();
return new Picture(_nMakePictureSnapshot(_ptr));
} finally {
Reference.reachabilityFence(this);
}
}
/**
* <p>Return a unique value for this instance. If two calls to this return the same value,
* it is presumed that calling the draw() method will render the same thing as well.</p>
*
* <p>Subclasses that change their state should call notifyDrawingChanged() to ensure that
* a new value will be returned the next time it is called.</p>
*/
public int getGenerationId() {
try {
Stats.onNativeCall();
return _nGetGenerationId(_ptr);
} finally {
Reference.reachabilityFence(this);
}
}
/**
* Return the (conservative) bounds of what the drawable will draw. If the drawable can
* change what it draws (e.g. animation or in response to some external change), then this
* must return a bounds that is always valid for all possible states.
*/
@ApiStatus.NonExtendable
public @NotNull Rect getBounds() {
if (_bounds == null)
_bounds = onGetBounds();
return _bounds;
}
/**
* Calling this invalidates the previous generation ID, and causes a new one to be computed
* the next time getGenerationId() is called. Typically this is called by the object itself,
* in response to its internal state changing.
*/
@ApiStatus.NonExtendable
public Drawable notifyDrawingChanged() {
Stats.onNativeCall();
_nNotifyDrawingChanged(_ptr);
_bounds = null;
return this;
}
@ApiStatus.OverrideOnly
public abstract void onDraw(Canvas canvas);
@ApiStatus.OverrideOnly
public abstract @NotNull Rect onGetBounds();
@ApiStatus.Internal
public void _onDraw(long canvasPtr) {
onDraw(new Canvas(canvasPtr, false, this));
}
@ApiStatus.Internal public static native long _nMake();
@ApiStatus.Internal public native void _nInit(long ptr);
@ApiStatus.Internal public static native void _nDraw(long ptr, long canvasPtr, float[] matrix);
@ApiStatus.Internal public static native long _nMakePictureSnapshot(long ptr);
@ApiStatus.Internal public static native int _nGetGenerationId(long ptr);
@ApiStatus.Internal public static native void _nNotifyDrawingChanged(long ptr);
}