Unverified Commit cc6f2006 authored by James Morrissey's avatar James Morrissey Committed by GitHub

Introduce SkPathUtils bindings (#815)

* Introduce SkPathUtils bindings

This functionality used to exist elsewhere in Skia, but in m110 it was moved into SkPathUtils. When that change occurred, the functionality was removed from Skiko rather than moved, so this commit is to return the functionality by providing access to SkPathUtils.

* use `assertTrue` instead of `assertEquals`

to make KotlinJS happy

---------
Co-authored-by: 's avatarPavel <sergeev.pavel.al@gmail.com>
parent f9aab263
package org.jetbrains.skia
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.reachabilityBarrier
object PathUtils {
/**
* Returns the filled equivalent of the stroked path using the provided paint attributes.
*
* @param src Path to create a filled version of.
* @param paint Paint from which attributes such as stroke cap, width, miter, join, and
* pathEffect will be used.
* @param cull Optional limit passed to the path effect.
* @param resScale If &gt; 1, increase precision, else if (0 &lt; resScale &lt; 1) reduce precision
* to favor speed and size.
* @return A filled version of the source path.
*/
fun fillPathWithPaint(src: Path, paint: Paint, cull: Rect?, resScale: Float): Path {
return fillPathWithPaint(src, paint, cull, Matrix33.makeScale(resScale))
}
/**
* Returns the filled equivalent of the stroked path using the provided paint attributes.
*
* @param src Path to create a filled version of.
* @param paint Paint from which attributes such as stroke cap, width, miter, join, and
* pathEffect will be used.
* @param cull Optional limit passed to the path effect.
* @param matrix Current transformation matrix.
* @return A filled version of the source path.
*/
fun fillPathWithPaint(src: Path, paint: Paint, cull: Rect?, matrix: Matrix33): Path {
return try {
Stats.onNativeCall()
if (cull == null) org.jetbrains.skia.Path(
interopScope {
_nFillPathWithPaint(
getPtr(src),
getPtr(paint),
toInterop(matrix.mat)
)
}
) else org.jetbrains.skia.Path(
interopScope {
_nFillPathWithPaintCull(
getPtr(src),
getPtr(paint),
cull.left,
cull.top,
cull.right,
cull.bottom,
toInterop(matrix.mat)
)
}
)
} finally {
reachabilityBarrier(src)
reachabilityBarrier(paint)
}
}
/**
* Returns the filled equivalent of the stroked path using the provided paint attributes.
*
* @param src Path to create a filled version of.
* @param paint Paint attributes such as stroke cap, width, miter, join, and pathEffect.
* @return A filled version of the source path.
*/
fun fillPathWithPaint(src: Path, paint: Paint): Path {
return fillPathWithPaint(src, paint, null, 1f)
}
init {
staticLoad()
}
}
@ExternalSymbolName("org_jetbrains_skia_PathUtils__1nFillPathWithPaint")
private external fun _nFillPathWithPaint(
srcPtr: NativePointer,
paintPtr: NativePointer,
matrix: InteropPointer
): NativePointer
@ExternalSymbolName("org_jetbrains_skia_PathUtils__1nFillPathWithPaintCull")
private external fun _nFillPathWithPaintCull(
srcPtr: NativePointer,
paintPtr: NativePointer,
left: Float,
top: Float,
right: Float,
bottom: Float,
matrix: InteropPointer
): NativePointer
package org.jetbrains.skia
import org.jetbrains.skiko.tests.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class PathUtilsTest {
@Test
fun fillPathWithPaint() = runTest {
val paint = Paint().apply {
color = 0xff000000.toInt()
strokeWidth = 10f
mode = PaintMode.STROKE
}
val path = Path().lineTo(40f, 40f)
val fillPath = PathUtils.fillPathWithPaint(path, paint)
assertTrue(fillPath.isLastContourClosed)
assertTrue(fillPath.pointsCount > path.pointsCount)
assertTrue(fillPath.verbsCount > path.verbsCount)
}
@Test
fun fillPathWithPaintScale() = runTest {
val paint = Paint().apply {
color = 0xff000000.toInt()
strokeWidth = 10f
mode = PaintMode.STROKE
}
val path = Path().arcTo(Rect(0f, 0f, 40f, 40f), 0f, 90f, false)
val fillPath1 = PathUtils.fillPathWithPaint(path, paint,null, 1f)
val fillPath001 = PathUtils.fillPathWithPaint(path, paint,null, 0.01f)
// assert 1f scale has higher precision (more points) than 0.01f
assertTrue(fillPath1.pointsCount > fillPath001.pointsCount)
}
}
#include <jni.h>
#include "SkPathUtils.h"
#include "SkPath.h"
#include "SkPaint.h"
#include "interop.hh"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_PathUtilsKt__1nFillPathWithPaint
(JNIEnv* env, jclass jclass, jlong srcPtr, jlong paintPtr, jfloatArray matrixArr) {
std::unique_ptr<SkMatrix> matrix = skMatrix(env, matrixArr);
SkPath* src = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(srcPtr));
SkPaint* paint = reinterpret_cast<SkPaint*>(static_cast<uintptr_t>(paintPtr));
SkPath* dst = new SkPath();
skpathutils::FillPathWithPaint(*src, *paint, dst, nullptr, *matrix);
return reinterpret_cast<jlong>(dst);
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_PathUtilsKt__1nFillPathWithPaintCull
(JNIEnv* env, jclass jclass, jlong srcPtr, jlong paintPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray matrixArr) {
std::unique_ptr<SkMatrix> matrix = skMatrix(env, matrixArr);
SkPath* src = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(srcPtr));
SkPaint* paint = reinterpret_cast<SkPaint*>(static_cast<uintptr_t>(paintPtr));
SkPath* dst = new SkPath();
SkRect cull {left, top, right, bottom};
skpathutils::FillPathWithPaint(*src, *paint, dst, &cull, *matrix);
return reinterpret_cast<jlong>(dst);
}
#include "SkPathUtils.h"
#include "SkPath.h"
#include "SkPaint.h"
#include "common.h"
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PathUtils__1nFillPathWithPaint
(KNativePointer srcPtr, KNativePointer paintPtr, KFloat* matrixArr) {
std::unique_ptr<SkMatrix> matrix = skMatrix(matrixArr);
SkPath* src = reinterpret_cast<SkPath*>((srcPtr));
SkPaint* paint = reinterpret_cast<SkPaint*>((paintPtr));
SkPath* dst = new SkPath();
skpathutils::FillPathWithPaint(*src, *paint, dst, nullptr, *matrix);
return reinterpret_cast<KNativePointer>(dst);
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PathUtils__1nFillPathWithPaintCull
(KNativePointer srcPtr, KNativePointer paintPtr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* matrixArr) {
std::unique_ptr<SkMatrix> matrix = skMatrix(matrixArr);
SkPath* src = reinterpret_cast<SkPath*>((srcPtr));
SkPaint* paint = reinterpret_cast<SkPaint*>((paintPtr));
SkPath* dst = new SkPath();
SkRect cull {left, top, right, bottom};
skpathutils::FillPathWithPaint(*src, *paint, dst, &cull, *matrix);
return reinterpret_cast<KNativePointer>(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