Unverified Commit c24886be authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement native methods of Codec (#346)

parent f1288f35
...@@ -26,10 +26,11 @@ config.webpack.output = Object.assign(config.webpack.output || {}, { ...@@ -26,10 +26,11 @@ config.webpack.output = Object.assign(config.webpack.output || {}, {
config.webpack.module.rules.push( config.webpack.module.rules.push(
{ {
test: /\.(ttf|woff|woff2)$/, test: /\.(ttf|woff|woff2)$/,
type: 'asset/resource', type: 'asset/resource'
generator: { },
filename: "assets/fonts/[name][ext]" {
} test: /\.(png|jpg|gif)$/,
type: 'asset/resource'
}, },
{ {
test: /\.txt$/, test: /\.txt$/,
......
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.InteropPointer
import org.jetbrains.skia.impl.withResult
/** /**
* Information about individual frames in a multi-framed image. * Information about individual frames in a multi-framed image.
*/ */
...@@ -66,6 +69,32 @@ class AnimationFrameInfo( ...@@ -66,6 +69,32 @@ class AnimationFrameInfo(
*/ */
internal var frameRect: IRect internal var frameRect: IRect
) { ) {
companion object {
private const val REPR_SIZE = 11
private fun fromIntArray(repr: IntArray, index: Int = 0): AnimationFrameInfo {
val offset = index * REPR_SIZE
return AnimationFrameInfo(
repr[offset + 0],
repr[offset + 1],
repr[offset + 2] != 0,
repr[offset + 3],
repr[offset + 4] != 0,
repr[offset + 5],
repr[offset + 6],
IRect(repr[offset + 7], repr[offset + 8], repr[offset + 9], repr[offset + 10])
)
}
internal fun fromInteropPointer(block: (InteropPointer) -> Unit): AnimationFrameInfo {
return fromIntArray(withResult(IntArray(REPR_SIZE), block))
}
internal fun fromInteropArrayPointer(size: Int, block: (InteropPointer) -> Unit): Array<AnimationFrameInfo> {
val repr = withResult(IntArray(REPR_SIZE * size), block)
return Array(size) { fromIntArray(repr, it) }
}
}
internal constructor( internal constructor(
requiredFrame: Int, requiredFrame: Int,
duration: Int, duration: Int,
......
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.Managed
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.getPtr
class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR), IHasImageInfo { class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR), IHasImageInfo {
companion object { companion object {
...@@ -48,8 +44,10 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo ...@@ -48,8 +44,10 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo
override val imageInfo: ImageInfo override val imageInfo: ImageInfo
get() = try { get() = try {
if (_imageInfo == null) { if (_imageInfo == null) {
Stats.onNativeCall() _imageInfo = ImageInfo.createUsing(
_imageInfo = Codec_nGetImageInfo(_ptr) _ptr = _ptr,
_nGetImageInfo = ::Codec_nGetImageInfo
)
} }
_imageInfo!! _imageInfo!!
} finally { } finally {
...@@ -289,7 +287,7 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo ...@@ -289,7 +287,7 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo
fun getFrameInfo(frame: Int): AnimationFrameInfo { fun getFrameInfo(frame: Int): AnimationFrameInfo {
return try { return try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetFrameInfo(_ptr, frame) AnimationFrameInfo.fromInteropPointer { _nGetFrameInfo(_ptr, frame, it) }
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -312,7 +310,17 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo ...@@ -312,7 +310,17 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo
val framesInfo: Array<AnimationFrameInfo> val framesInfo: Array<AnimationFrameInfo>
get() = try { get() = try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetFramesInfo(_ptr) val buffer = _nGetFramesInfo(_ptr)
val size = FramesInfo_nGetSize(buffer)
if (size > 0) {
AnimationFrameInfo.fromInteropArrayPointer(size) {
FramesInfo_nGetInfos(buffer, it)
}
} else {
arrayOf()
}.also {
FramesInfo_nDelete(buffer)
}
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -353,7 +361,7 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo ...@@ -353,7 +361,7 @@ class Codec internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHo
private external fun Codec_nGetFinalizer(): NativePointer private external fun Codec_nGetFinalizer(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Codec__1nGetImageInfo") @ExternalSymbolName("org_jetbrains_skia_Codec__1nGetImageInfo")
private external fun Codec_nGetImageInfo(ptr: NativePointer): ImageInfo? private external fun Codec_nGetImageInfo(ptr: NativePointer, imageInfo: InteropPointer, colorSpacePtrs: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Codec__1nReadPixels") @ExternalSymbolName("org_jetbrains_skia_Codec__1nReadPixels")
private external fun Codec_nReadPixels(ptr: NativePointer, bitmapPtr: NativePointer, frame: Int, priorFrame: Int): Int private external fun Codec_nReadPixels(ptr: NativePointer, bitmapPtr: NativePointer, frame: Int, priorFrame: Int): Int
...@@ -374,10 +382,19 @@ private external fun _nGetEncodedImageFormat(ptr: NativePointer): Int ...@@ -374,10 +382,19 @@ private external fun _nGetEncodedImageFormat(ptr: NativePointer): Int
private external fun _nGetFrameCount(ptr: NativePointer): Int private external fun _nGetFrameCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Codec__1nGetFrameInfo") @ExternalSymbolName("org_jetbrains_skia_Codec__1nGetFrameInfo")
private external fun _nGetFrameInfo(ptr: NativePointer, frame: Int): AnimationFrameInfo private external fun _nGetFrameInfo(ptr: NativePointer, frame: Int, result: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Codec__1nGetFramesInfo") @ExternalSymbolName("org_jetbrains_skia_Codec__1nGetFramesInfo")
private external fun _nGetFramesInfo(ptr: NativePointer): Array<AnimationFrameInfo> private external fun _nGetFramesInfo(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Codec__1nGetRepetitionCount") @ExternalSymbolName("org_jetbrains_skia_Codec__1nGetRepetitionCount")
private external fun _nGetRepetitionCount(ptr: NativePointer): Int private external fun _nGetRepetitionCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Codec__1nFramesInfo_Delete")
private external fun FramesInfo_nDelete(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skia_Codec__1nFramesInfo_GetSize")
private external fun FramesInfo_nGetSize(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Codec__1nFramesInfo_GetInfos")
private external fun FramesInfo_nGetInfos(ptr: NativePointer, result: InteropPointer)
package org.jetbrains.skia
import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skia.util.assertContentSame
import org.jetbrains.skiko.tests.runTest
import org.jetbrains.skiko.util.IMAGE_COLORS_8X8
import org.jetbrains.skiko.util.makeSolidColor
import kotlin.test.Test
import kotlin.test.assertEquals
class CodecTest {
@Test
fun decodePNG() = runTest {
val codec = Codec.makeFromData(Data.makeFromResource("./colors_8x8.png"))
assertEquals(1, codec.frameCount)
assertEquals(8, codec.imageInfo.width)
assertEquals(8, codec.imageInfo.height)
assertEquals(EncodedImageFormat.PNG, codec.encodedImageFormat)
val pixels = codec.readPixels()
assertContentSame(IMAGE_COLORS_8X8, Image.makeFromBitmap(pixels), 0.01)
}
@Test
fun decodeGIF() = runTest {
val codec = Codec.makeFromData(Data.makeFromResource("./colored_square.gif"))
assertEquals(5, codec.frameCount)
assertEquals(8, codec.imageInfo.width)
assertEquals(8, codec.imageInfo.height)
assertEquals(EncodedImageFormat.GIF, codec.encodedImageFormat)
val palette = intArrayOf(Color.BLACK, Color.RED, Color.GREEN, Color.BLUE, Color.WHITE)
val pixels = Bitmap()
pixels.allocPixels(codec.imageInfo)
for (frame in 0 until codec.frameCount) {
codec.readPixels(pixels, frame)
val expected = Image.makeSolidColor(palette[frame], 8, 8)
assertContentSame(expected, Image.makeFromBitmap(pixels), 0.01)
}
assertEquals(200, codec.getFrameInfo(3).duration)
val framesInfo = codec.framesInfo
assertEquals(5, framesInfo.size)
for (frameInfo in framesInfo) {
assertEquals(200, frameInfo.duration)
}
}
}
\ No newline at end of file
package org.jetbrains.skiko.util
import org.jetbrains.skia.Image
import org.jetbrains.skia.util.imageFromIntArray
@Suppress("RemoveRedundantCallsOfConversionMethods")
val PIXELS_COLORS_8X8 by lazy { intArrayOf(
0xffff0000.toInt(), 0xffff0000.toInt(), 0xff00ff00.toInt(), 0xff00ff00.toInt(), 0xff0000ff.toInt(), 0xff0000ff.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
0xffff0000.toInt(), 0xffff0000.toInt(), 0xff00ff00.toInt(), 0xff00ff00.toInt(), 0xff0000ff.toInt(), 0xff0000ff.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
0xff00ffff.toInt(), 0xff00ffff.toInt(), 0xffff00ff.toInt(), 0xffff00ff.toInt(), 0xffffff00.toInt(), 0xffffff00.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
0xff00ffff.toInt(), 0xff00ffff.toInt(), 0xffff00ff.toInt(), 0xffff00ff.toInt(), 0xffffff00.toInt(), 0xffffff00.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
0xffffffff.toInt(), 0xffffffff.toInt(), 0xff000000.toInt(), 0xff000000.toInt(), 0x80000000.toInt(), 0x80000000.toInt(), 0x03000000.toInt(), 0x00000000.toInt(),
0xffffffff.toInt(), 0xffffffff.toInt(), 0xff000000.toInt(), 0xff000000.toInt(), 0x80000000.toInt(), 0x80000000.toInt(), 0x03000000.toInt(), 0x00000000.toInt(),
0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(), 0x00000000.toInt(),
) }
val IMAGE_COLORS_8X8 by lazy { imageFromIntArray(PIXELS_COLORS_8X8, 8) }
fun Image.Companion.makeSolidColor(color: Int, width: Int, height: Int)
= imageFromIntArray(IntArray(width * height) { color }, width)
\ No newline at end of file
...@@ -20,10 +20,11 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_CodecKt__1nMakeFromDa ...@@ -20,10 +20,11 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_CodecKt__1nMakeFromDa
return reinterpret_cast<jlong>(instance.release()); return reinterpret_cast<jlong>(instance.release());
} }
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_CodecKt_Codec_1nGetImageInfo extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_CodecKt_Codec_1nGetImageInfo
(JNIEnv* env, jclass jclass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr, jintArray imageInfoResult, jlongArray colorSpaceResultPtr) {
SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr)); auto instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr));
return skija::ImageInfo::toJava(env, instance->getInfo()); SkImageInfo imageInfo = instance->getInfo();
skija::ImageInfo::writeImageInfoForInterop(env, imageInfo, imageInfoResult, colorSpaceResultPtr);
} }
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_CodecKt__1nGetSize extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_CodecKt__1nGetSize
...@@ -61,27 +62,19 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFrameCou ...@@ -61,27 +62,19 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFrameCou
return instance->getFrameCount(); return instance->getFrameCount();
} }
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFrameInfo extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFrameInfo
(JNIEnv* env, jclass jclass, jlong ptr, jint frame) { (JNIEnv* env, jclass jclass, jlong ptr, jint frame, jintArray result) {
SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr)); SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr));
SkCodec::FrameInfo info; SkCodec::FrameInfo info;
instance->getFrameInfo(frame, &info); instance->getFrameInfo(frame, &info);
return skija::AnimationFrameInfo::toJava(env, info); skija::AnimationFrameInfo::copyToInterop(env, info, result);
} }
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFramesInfo extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_CodecKt__1nGetFramesInfo
(JNIEnv* env, jclass jclass, jlong ptr, jint frame) { (JNIEnv* env, jclass jclass, jlong ptr) {
SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr)); SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr));
SkCodec::FrameInfo info; auto* infos = new std::vector<SkCodec::FrameInfo> { instance->getFrameInfo() };
std::vector<SkCodec::FrameInfo> frames = instance->getFrameInfo(); return reinterpret_cast<jlong>(infos);
jobjectArray res = env->NewObjectArray(frames.size(), skija::AnimationFrameInfo::cls, nullptr);
if (java::lang::Throwable::exceptionThrown(env))
return nullptr;
for (int i = 0; i < frames.size(); ++i) {
skija::AutoLocal<jobject> infoObj(env, skija::AnimationFrameInfo::toJava(env, frames[i]));
env->SetObjectArrayElement(res, i, infoObj.get());
}
return res;
} }
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetRepetitionCount extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetRepetitionCount
...@@ -89,3 +82,20 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetRepetiti ...@@ -89,3 +82,20 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt__1nGetRepetiti
SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr)); SkCodec* instance = reinterpret_cast<SkCodec*>(static_cast<uintptr_t>(ptr));
return instance->getRepetitionCount(); return instance->getRepetitionCount();
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_CodecKt_FramesInfo_1nDelete
(JNIEnv* env, jclass jclass, jlong ptr) {
delete reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(static_cast<uintptr_t>(ptr));
}
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_CodecKt_FramesInfo_1nGetSize
(JNIEnv* env, jclass jclass, jlong ptr) {
auto* infos = reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(static_cast<uintptr_t>(ptr));
return infos->size();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_CodecKt_FramesInfo_1nGetInfos
(JNIEnv* env, jclass jclass, jlong ptr, jintArray result) {
auto* infos = reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(static_cast<uintptr_t>(ptr));
skija::AnimationFrameInfo::copyToInterop(env, *infos, result);
}
\ No newline at end of file
...@@ -177,6 +177,34 @@ namespace skija { ...@@ -177,6 +177,34 @@ namespace skija {
IRect::fromSkIRect(env, i.fFrameRect)); IRect::fromSkIRect(env, i.fFrameRect));
return java::lang::Throwable::exceptionThrown(env) ? nullptr : res; return java::lang::Throwable::exceptionThrown(env) ? nullptr : res;
} }
void copyToInteropAtIndex(JNIEnv* env, const SkCodec::FrameInfo& info, jintArray dst, jsize index) {
jint repr[11] {
info.fRequiredFrame,
info.fDuration,
static_cast<jint>(info.fFullyReceived),
static_cast<jint>(info.fAlphaType),
static_cast<jint>(info.fHasAlphaWithinBounds),
static_cast<jint>(info.fDisposalMethod),
static_cast<jint>(info.fBlend),
info.fFrameRect.left(),
info.fFrameRect.top(),
info.fFrameRect.right(),
info.fFrameRect.bottom()
};
env->SetIntArrayRegion(dst, index * 11, 11, repr);
}
void copyToInterop(JNIEnv* env, const SkCodec::FrameInfo& info, jintArray dst) {
copyToInteropAtIndex(env, info, dst, 0);
}
void copyToInterop(JNIEnv* env, const std::vector<SkCodec::FrameInfo>& infos, jintArray dst) {
jsize i = 0;
for (const auto& info : infos) {
copyToInteropAtIndex(env, info, dst, i++);
}
}
} }
namespace Color4f { namespace Color4f {
...@@ -495,11 +523,11 @@ namespace skija { ...@@ -495,11 +523,11 @@ namespace skija {
if (rectInts == nullptr) if (rectInts == nullptr)
return std::unique_ptr<SkIRect>(nullptr); return std::unique_ptr<SkIRect>(nullptr);
else { else {
jint *ints = env->GetIntArrayElements(rectInts, NULL); jint *ints = env->GetIntArrayElements(rectInts, nullptr);
auto result = std::unique_ptr<SkIRect>(new SkIRect{ auto result = std::unique_ptr<SkIRect>(new SkIRect{
ints[0], ints[1], ints[2], ints[3] ints[0], ints[1], ints[2], ints[3]
}); });
env->ReleaseIntArrayElements(rectInts, ints, NULL); env->ReleaseIntArrayElements(rectInts, ints, 0);
return result; return result;
} }
} }
......
...@@ -85,6 +85,8 @@ namespace skija { ...@@ -85,6 +85,8 @@ namespace skija {
void onLoad(JNIEnv* env); void onLoad(JNIEnv* env);
void onUnload(JNIEnv* env); void onUnload(JNIEnv* env);
jobject toJava(JNIEnv* env, const SkCodec::FrameInfo& i); jobject toJava(JNIEnv* env, const SkCodec::FrameInfo& i);
void copyToInterop(JNIEnv* env, const SkCodec::FrameInfo& info, jintArray dst);
void copyToInterop(JNIEnv* env, const std::vector<SkCodec::FrameInfo>& infos, jintArray dst);
} }
template <typename T> template <typename T>
......
...@@ -22,21 +22,13 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Codec__1nMakeFromData ...@@ -22,21 +22,13 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Codec__1nMakeFromData
return reinterpret_cast<KNativePointer>(instance.release()); return reinterpret_cast<KNativePointer>(instance.release());
} }
SKIKO_EXPORT void org_jetbrains_skia_Codec__1nGetImageInfo
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetImageInfo (KNativePointer ptr, KInt* imageInfoResult, KNativePointer* colorSpacePtrsArray) {
(KNativePointer ptr) { auto instance = reinterpret_cast<SkCodec*>(ptr);
TODO("implement org_jetbrains_skia_Codec__1nGetImageInfo"); SkImageInfo imageInfo = instance->getInfo();
skija::ImageInfo::writeImageInfoForInterop(imageInfo, imageInfoResult, colorSpacePtrsArray);
} }
#if 0
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetImageInfo
(KNativePointer ptr) {
SkCodec* instance = reinterpret_cast<SkCodec*>((ptr));
return skija::ImageInfo::toJava(env, instance->getInfo());
}
#endif
SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetSize SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetSize
(KNativePointer ptr) { (KNativePointer ptr) {
SkCodec* instance = reinterpret_cast<SkCodec*>((ptr)); SkCodec* instance = reinterpret_cast<SkCodec*>((ptr));
...@@ -73,45 +65,38 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetFrameCount ...@@ -73,45 +65,38 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetFrameCount
} }
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetFrameInfo SKIKO_EXPORT void org_jetbrains_skia_Codec__1nGetFrameInfo
(KNativePointer ptr, KInt frame) { (KNativePointer ptr, KInt frame, KInteropPointer result) {
TODO("implement org_jetbrains_skia_Codec__1nGetFrameInfo"); auto* instance = reinterpret_cast<SkCodec*>((ptr));
} SkCodec::FrameInfo info{};
#if 0
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetFrameInfo
(KNativePointer ptr, KInt frame) {
SkCodec* instance = reinterpret_cast<SkCodec*>((ptr));
SkCodec::FrameInfo info;
instance->getFrameInfo(frame, &info); instance->getFrameInfo(frame, &info);
return skija::AnimationFrameInfo::toJava(env, info); skija::AnimationFrameInfo::copyToInterop(info, result);
} }
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Codec__1nGetFramesInfo
(KNativePointer ptr) {
SkCodec* instance = reinterpret_cast<SkCodec*>((ptr));
auto* infos = new std::vector<SkCodec::FrameInfo> { instance->getFrameInfo() };
return reinterpret_cast<KNativePointer>(infos);
}
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetFramesInfo SKIKO_EXPORT void org_jetbrains_skia_Codec__1nFramesInfo_Delete
(KNativePointer ptr, KInt frame) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Codec__1nGetFramesInfo"); delete reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(ptr);
} }
#if 0 SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nFramesInfo_GetSize
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Codec__1nGetFramesInfo (KNativePointer ptr) {
(KNativePointer ptr, KInt frame) { auto* infos = reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(ptr);
SkCodec* instance = reinterpret_cast<SkCodec*>((ptr)); return static_cast<KInt>(infos->size());
SkCodec::FrameInfo info;
std::vector<SkCodec::FrameInfo> frames = instance->getFrameInfo();
KInteropPointerArray res = env->NewObjectArray(frames.size(), skija::AnimationFrameInfo::cls, nullptr);
if (java::lang::Throwable::exceptionThrown(env))
return nullptr;
for (int i = 0; i < frames.size(); ++i) {
skija::AutoLocal<KInteropPointer> infoObj(env, skija::AnimationFrameInfo::toJava(env, frames[i]));
env->SetObjectArrayElement(res, i, infoObj.get());
}
return res;
} }
#endif
SKIKO_EXPORT void org_jetbrains_skia_Codec__1nFramesInfo_GetInfos
(KNativePointer ptr, KInteropPointer result) {
auto* infos = reinterpret_cast<std::vector<SkCodec::FrameInfo>*>(ptr);
skija::AnimationFrameInfo::copyToInterop(*infos, result);
}
SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetRepetitionCount SKIKO_EXPORT KInt org_jetbrains_skia_Codec__1nGetRepetitionCount
(KNativePointer ptr) { (KNativePointer ptr) {
......
...@@ -95,6 +95,11 @@ namespace skija { ...@@ -95,6 +95,11 @@ namespace skija {
} }
} }
namespace AnimationFrameInfo {
void copyToInterop(const SkCodec::FrameInfo& info, KInteropPointer dst);
void copyToInterop(const std::vector<SkCodec::FrameInfo>& infos, KInteropPointer dst);
}
namespace svg { namespace svg {
namespace SVGLength { namespace SVGLength {
void copyToInterop(const SkSVGLength& length, KInteropPointer dst); void copyToInterop(const SkSVGLength& length, KInteropPointer dst);
......
...@@ -286,6 +286,37 @@ namespace skija { ...@@ -286,6 +286,37 @@ namespace skija {
} }
} }
namespace AnimationFrameInfo {
static void copyToInteropAtIndex(const SkCodec::FrameInfo& info, KInt* repr, size_t index) {
repr += (index * 11);
repr[0] = info.fRequiredFrame;
repr[1] = info.fDuration;
repr[2] = static_cast<KInt>(info.fFullyReceived);
repr[3] = static_cast<KInt>(info.fAlphaType);
repr[4] = static_cast<KInt>(info.fHasAlphaWithinBounds);
repr[5] = static_cast<KInt>(info.fDisposalMethod);
repr[6] = static_cast<KInt>(info.fBlend);
repr[7] = info.fFrameRect.left();
repr[8] = info.fFrameRect.top();
repr[9] = info.fFrameRect.right();
repr[10] = info.fFrameRect.bottom();
}
void copyToInterop(const SkCodec::FrameInfo& info, KInteropPointer dst) {
KInt* repr = reinterpret_cast<KInt*>(dst);
copyToInteropAtIndex(info, repr, 0);
}
void copyToInterop(const std::vector<SkCodec::FrameInfo>& infos, KInteropPointer dst) {
KInt* repr = reinterpret_cast<KInt*>(dst);
size_t i = 0;
for (const auto& info : infos) {
copyToInteropAtIndex(info, repr, i++);
}
}
}
namespace svg { namespace svg {
namespace SVGLength { namespace SVGLength {
void copyToInterop(const SkSVGLength& length, KInteropPointer dst) { void copyToInterop(const SkSVGLength& length, KInteropPointer dst) {
......
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