Unverified Commit ab3e19e4 authored by Shagen Ogandzhanian's avatar Shagen Ogandzhanian Committed by GitHub

Typeface commonization (#356)

* Split TypefaceTest to the part that passes on all platforms and on JVM only

* Breaking for jvm in order to move faster to newer syntax

* org_jetbrains_skia_Typeface__1nGetVariationAxes returns nothing

* Introduce _nGetVariationAxesCount (for JVM only so far)

* Pass count to _nGetVariationAxesCount

* Finally passing the right way

* SOME DEBUG

* org_jetbrains_skia_Typeface__1nGetVariationAxes for native and js

* Restore axis on all platforms

* Passing isHidden boolean flag as a separate int field

* org_jetbrains_skia_Typeface__1nGetVariations on native and js

* Preparations for taming org_jetbrains_skia_Typeface__1nGetTableTags on js and native platforms

* org_jetbrains_skia_Typeface__1nGetTableTags on js and native platforms

* Preparations for commonization of org_jetbrains_skia_Typeface__1nGetUTF32Glyphs

* getUTF32Glyphs commonized

* Minor code rearrangments in preparations of getKerningPairAdjustments commonization

* Passing count to _nGetKerningPairAdjustments

* if (glyphs.size > 0) { _nGetKerningPairAdjustments(_ptr, glyphs, glyphs.size)} else null

* Refactor org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments on JVM and prepare commonization

* cross-platform actual fun String.intCodePoints()

* Uncomment yet another assertion

* Preparations for conquering family names

* Passing variations count separately

* Passing raw value to Java_org_jetbrains_skia_TypefaceKt__1nMakeClone

* org_jetbrains_skia_Typeface__1nMakeClone commonized

* org_jetbrains_skia_Typeface__1nMakeClone commonized-  fix for native

* Wrap _nMakeClone with _nMakeClone rather than wrapping param

* Fix interop scope wrapping at getUTF32Glyphs

* Finally fix org_jetbrains_skia_Typeface__1nMakeClone for js

* Narrow down familyNames to JVM test only

(I want to have a separate PR about Array<String>)

* Explicitely casting so that Typeface.cc compiles on macos and win

* Better intCodePoints() implementation for js/native

* Fix test

* Removed redundant helper array that was a trace of direct jvm port

* Get rid of yet another redundant jvm-copied idiom
Co-authored-by: 's avatarNikolay Igotti <igotti@gmail.com>
parent 734c9f98
...@@ -2,6 +2,7 @@ package org.jetbrains.skia ...@@ -2,6 +2,7 @@ package org.jetbrains.skia
import org.jetbrains.skia.impl.* import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skiko.kotlinBackend
class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object { companion object {
...@@ -88,7 +89,16 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -88,7 +89,16 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val variations: Array<FontVariation>? val variations: Array<FontVariation>?
get() = try { get() = try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetVariations(_ptr) val count = _nGetVariationsCount(_ptr)
if (count > 0) {
val variationsData = withResult(IntArray(count * 2)) {
_nGetVariations(_ptr, it, count)
}
(0 until count).map { i ->
val j = 2 * i
FontVariation(variationsData[j], Float.fromBits(variationsData[j + 1]))
}.toTypedArray()
} else null
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -100,7 +110,18 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -100,7 +110,18 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val variationAxes: Array<FontVariationAxis>? val variationAxes: Array<FontVariationAxis>?
get() = try { get() = try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetVariationAxes(_ptr) val axisCount = _nGetVariationAxesCount(_ptr)
if (axisCount <= 0) {
null
} else {
val axisData = withResult(IntArray(axisCount * 5)) {
_nGetVariationAxes(_ptr, it, axisCount)
}
(0 until axisCount).map { i ->
val j = 5 * i
FontVariationAxis(axisData[j], Float.fromBits(axisData[j + 1]), Float.fromBits(axisData[j + 2]), Float.fromBits(axisData[j + 3]), axisData[j + 4] != 0)
}.toTypedArray()
}
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -156,7 +177,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -156,7 +177,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
return try { return try {
if (variations.size == 0) return this if (variations.size == 0) return this
Stats.onNativeCall() Stats.onNativeCall()
val ptr = _nMakeClone(_ptr, variations, collectionIndex) val variationsData = variations.asList().flatMap { listOf(it._tag, it.value.toRawBits())}.toIntArray()
val ptr = interopScope { _nMakeClone(_ptr, toInterop(variationsData), 2 * variations.size, collectionIndex) }
require(ptr != NullPointer) { require(ptr != NullPointer) {
"Failed to clone Typeface $this with $variations" "Failed to clone Typeface $this with $variations"
} }
...@@ -183,7 +205,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -183,7 +205,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
fun getUTF32Glyphs(uni: IntArray?): ShortArray { fun getUTF32Glyphs(uni: IntArray?): ShortArray {
return try { return try {
Stats.onNativeCall() Stats.onNativeCall()
Typeface_nGetUTF32Glyphs(_ptr, uni) if (uni != null) {
interopScope {
withResult(ShortArray(uni.size)) {
Typeface_nGetUTF32Glyphs(_ptr, toInterop(uni), uni.size, it)
}
}
} else shortArrayOf()
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -230,7 +258,12 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -230,7 +258,12 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val tableTags: Array<String> val tableTags: Array<String>
get() = try { get() = try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetTableTags(_ptr)!!.map { tag -> FourByteTag.toString(tag) }.toTypedArray() val count = _nGetTableTagsCount(_ptr)
if (count > 0) {
withResult(IntArray(count)) {
_nGetTableTags(_ptr, it, count)
}.toList().map { FourByteTag.toString(it) }.toTypedArray()
} else emptyArray()
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -290,7 +323,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -290,7 +323,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
fun getKerningPairAdjustments(glyphs: ShortArray?): IntArray? { fun getKerningPairAdjustments(glyphs: ShortArray?): IntArray? {
return try { return try {
Stats.onNativeCall() Stats.onNativeCall()
_nGetKerningPairAdjustments(_ptr, glyphs) if (glyphs != null) {
if (glyphs.size > 0) {
withNullableResult(IntArray(glyphs.size)) {
_nGetKerningPairAdjustments(_ptr, glyphs, glyphs.size, it)
}
} else null
} else null
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -344,7 +383,7 @@ private external fun Typeface_nEquals(ptr: NativePointer, otherPtr: NativePointe ...@@ -344,7 +383,7 @@ private external fun Typeface_nEquals(ptr: NativePointer, otherPtr: NativePointe
private external fun Typeface_nMakeDefault(): NativePointer private external fun Typeface_nMakeDefault(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUTF32Glyphs") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUTF32Glyphs")
private external fun Typeface_nGetUTF32Glyphs(ptr: NativePointer, uni: IntArray?): ShortArray private external fun Typeface_nGetUTF32Glyphs(ptr: NativePointer, uni: InteropPointer, count: Int, glyphs: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUTF32Glyph") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetUTF32Glyph")
private external fun Typeface_nGetUTF32Glyph(ptr: NativePointer, unichar: Int): Short private external fun Typeface_nGetUTF32Glyph(ptr: NativePointer, unichar: Int): Short
...@@ -358,11 +397,17 @@ private external fun _nGetFontStyle(ptr: NativePointer): Int ...@@ -358,11 +397,17 @@ private external fun _nGetFontStyle(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nIsFixedPitch") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nIsFixedPitch")
private external fun _nIsFixedPitch(ptr: NativePointer): Boolean private external fun _nIsFixedPitch(ptr: NativePointer): Boolean
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariationsCount")
private external fun _nGetVariationsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariations") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariations")
private external fun _nGetVariations(ptr: NativePointer): Array<FontVariation>? private external fun _nGetVariations(ptr: NativePointer, variations: InteropPointer, count: Int)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariationAxesCount")
private external fun _nGetVariationAxesCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariationAxes") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetVariationAxes")
private external fun _nGetVariationAxes(ptr: NativePointer): Array<FontVariationAxis>? private external fun _nGetVariationAxes(ptr: NativePointer, axisData: InteropPointer, axisCount: Int)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nMakeFromName") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nMakeFromName")
private external fun _nMakeFromName(name: String?, fontStyle: Int): NativePointer private external fun _nMakeFromName(name: String?, fontStyle: Int): NativePointer
...@@ -374,7 +419,7 @@ internal external fun _nMakeFromFile(path: InteropPointer, index: Int): NativePo ...@@ -374,7 +419,7 @@ internal external fun _nMakeFromFile(path: InteropPointer, index: Int): NativePo
private external fun _nMakeFromData(dataPtr: NativePointer, index: Int): NativePointer private external fun _nMakeFromData(dataPtr: NativePointer, index: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nMakeClone") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nMakeClone")
private external fun _nMakeClone(ptr: NativePointer, variations: Array<FontVariation>?, collectionIndex: Int): NativePointer private external fun _nMakeClone(ptr: NativePointer, variations: InteropPointer, variationsCount: Int, collectionIndex: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetGlyphsCount") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetGlyphsCount")
private external fun _nGetGlyphsCount(ptr: NativePointer): Int private external fun _nGetGlyphsCount(ptr: NativePointer): Int
...@@ -382,8 +427,11 @@ private external fun _nGetGlyphsCount(ptr: NativePointer): Int ...@@ -382,8 +427,11 @@ private external fun _nGetGlyphsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTablesCount") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTablesCount")
private external fun _nGetTablesCount(ptr: NativePointer): Int private external fun _nGetTablesCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableTagsCount")
private external fun _nGetTableTagsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableTags") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableTags")
private external fun _nGetTableTags(ptr: NativePointer): IntArray? private external fun _nGetTableTags(ptr: NativePointer, tags: InteropPointer, count: Int)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableSize") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableSize")
private external fun _nGetTableSize(ptr: NativePointer, tag: Int): NativePointer private external fun _nGetTableSize(ptr: NativePointer, tag: Int): NativePointer
...@@ -395,7 +443,7 @@ private external fun _nGetTableData(ptr: NativePointer, tag: Int): NativePointer ...@@ -395,7 +443,7 @@ private external fun _nGetTableData(ptr: NativePointer, tag: Int): NativePointer
private external fun _nGetUnitsPerEm(ptr: NativePointer): Int private external fun _nGetUnitsPerEm(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments")
private external fun _nGetKerningPairAdjustments(ptr: NativePointer, glyphs: ShortArray?): IntArray? private external fun _nGetKerningPairAdjustments(ptr: NativePointer, glyphs: ShortArray, count: Int, adjustments: InteropPointer): Boolean
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetFamilyNames") @ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetFamilyNames")
private external fun _nGetFamilyNames(ptr: NativePointer): Array<FontFamilyName> private external fun _nGetFamilyNames(ptr: NativePointer): Array<FontFamilyName>
......
...@@ -2,6 +2,8 @@ package org.jetbrains.skiko ...@@ -2,6 +2,8 @@ package org.jetbrains.skiko
import org.jetbrains.skia.* import org.jetbrains.skia.*
import org.jetbrains.skia.tests.makeFromResource import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.tests.SkipJsTarget
import org.jetbrains.skiko.tests.SkipNativeTarget
import org.jetbrains.skiko.tests.runTest import org.jetbrains.skiko.tests.runTest
import kotlin.test.* import kotlin.test.*
...@@ -9,7 +11,6 @@ class TypefaceTest { ...@@ -9,7 +11,6 @@ class TypefaceTest {
@Test @Test
fun typefaceTest() = runTest { fun typefaceTest() = runTest {
// TODO Commonize array and string results and uncomment
val inter = Typeface.makeFromResource("./fonts/Inter-Hinted-Regular.ttf") val inter = Typeface.makeFromResource("./fonts/Inter-Hinted-Regular.ttf")
val interV = Typeface.makeFromResource("./fonts/Inter-V.ttf") val interV = Typeface.makeFromResource("./fonts/Inter-V.ttf")
val jbMono = Typeface.makeFromResource("./fonts/JetBrainsMono-Regular.ttf") val jbMono = Typeface.makeFromResource("./fonts/JetBrainsMono-Regular.ttf")
...@@ -25,68 +26,70 @@ class TypefaceTest { ...@@ -25,68 +26,70 @@ class TypefaceTest {
assertFalse(inter.isFixedPitch) assertFalse(inter.isFixedPitch)
assertTrue(jbMono.isFixedPitch) assertTrue(jbMono.isFixedPitch)
if (kotlinBackend == KotlinBackend.JVM) {
assertNull(inter.variationAxes)
assertNull(inter.variations)
val axes = arrayOf(
FontVariationAxis("wght", 100f, 400f, 900f),
FontVariationAxis("slnt", -10f, 0f, 0f)
)
assertContentEquals(axes, interV.variationAxes)
val inter500: Typeface = interV.makeClone(FontVariation("wght", 500f))
assertNotEquals(inter500, interV)
assertContentEquals(FontVariation.parse("wght=500 slnt=0"), inter500.variations)
val inter400: Typeface = interV.makeClone(FontVariation("wght", 400f))
}
assertNotEquals(inter.uniqueId, interV.uniqueId) assertNotEquals(inter.uniqueId, interV.uniqueId)
assertNotEquals(inter, interV) assertNotEquals(inter, interV)
assertNotNull(Typeface.makeDefault()) assertNotNull(Typeface.makeDefault())
if (kotlinBackend == KotlinBackend.JVM) {
val Skia = intArrayOf(83, 107, 105, 97)
assertContentEquals(shortArrayOf(394, 713, 677, 503), inter.getUTF32Glyphs(Skia))
assertContentEquals(shortArrayOf(394, 713, 677, 503), inter.getStringGlyphs("Skia"))
}
assertEquals(394, inter.getUTF32Glyph(83)) assertEquals(394, inter.getUTF32Glyph(83))
assertEquals(2548, interV.glyphsCount) assertEquals(2548, interV.glyphsCount)
assertEquals(17, inter.tablesCount) assertEquals(17, inter.tablesCount)
if (kotlinBackend == KotlinBackend.JVM) {
assertContentEquals(
arrayOf(
"GDEF",
"GPOS",
"GSUB",
"OS/2",
"cmap",
"cvt ",
"fpgm",
"gasp",
"glyf",
"head",
"hhea",
"hmtx",
"loca",
"maxp",
"name",
"post",
"prep"
), inter.tableTags
)
}
assertTrue(inter.getTableData("loca")!!.size > 0) assertTrue(inter.getTableData("loca")!!.size > 0)
assertEquals(2816, inter.unitsPerEm) assertEquals(2816, inter.unitsPerEm)
}
if (kotlinBackend == KotlinBackend.JVM) { @Test
assertNull(jbMono.getKerningPairAdjustments(null)) fun fontVariationTest() = runTest {
assertNull(jbMono.getKerningPairAdjustments(jbMono.getStringGlyphs("TAV"))) val inter = Typeface.makeFromResource("./fonts/Inter-Hinted-Regular.ttf")
val interV = Typeface.makeFromResource("./fonts/Inter-V.ttf")
val jbMono = Typeface.makeFromResource("./fonts/JetBrainsMono-Regular.ttf")
assertNull(inter.variationAxes)
assertNull(inter.variations)
val axes = arrayOf(
FontVariationAxis("wght", 100f, 400f, 900f),
FontVariationAxis("slnt", -10f, 0f, 0f)
)
assertContentEquals(axes, interV.variationAxes)
val inter500: Typeface = interV.makeClone(FontVariation("wght", 500f))
assertNotEquals(inter500, interV)
assertContentEquals(FontVariation.parse("wght=500 slnt=0"), inter500.variations)
val Skia = intArrayOf(83, 107, 105, 97)
assertContentEquals(shortArrayOf(394, 713, 677, 503), inter.getUTF32Glyphs(Skia))
assertContentEquals(shortArrayOf(394, 713, 677, 503), inter.getStringGlyphs("Skia"))
assertContentEquals(
arrayOf(
"GDEF",
"GPOS",
"GSUB",
"OS/2",
"cmap",
"cvt ",
"fpgm",
"gasp",
"glyf",
"head",
"hhea",
"hmtx",
"loca",
"maxp",
"name",
"post",
"prep"
), inter.tableTags
)
// TODO: add non-null scenarios
assertNull(jbMono.getKerningPairAdjustments(null))
assertNull(jbMono.getKerningPairAdjustments(jbMono.getStringGlyphs("TAV")))
if (kotlinBackend == KotlinBackend.JVM) {
assertContentEquals(arrayOf(FontFamilyName("Inter", "en-US")), interV.familyNames) assertContentEquals(arrayOf(FontFamilyName("Inter", "en-US")), interV.familyNames)
assertEquals("Inter", interV.familyName)
} }
assertEquals("Inter", interV.familyName)
} }
} }
\ No newline at end of file
...@@ -6,7 +6,7 @@ actual fun <R> commonSynchronized(lock: Any, block: () -> R) { ...@@ -6,7 +6,7 @@ actual fun <R> commonSynchronized(lock: Any, block: () -> R) {
block() block()
} }
actual fun String.intCodePoints(): IntArray = TODO() actual fun String.intCodePoints(): IntArray = IntArray(this.length) { this[it].code }
actual class Pattern constructor(regex: String) { actual class Pattern constructor(regex: String) {
private val _regex = Regex(regex) private val _regex = Regex(regex)
......
...@@ -16,38 +16,43 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_TypefaceKt__1nIsFi ...@@ -16,38 +16,43 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_TypefaceKt__1nIsFi
return instance->isFixedPitch(); return instance->isFixedPitch();
} }
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariations extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationsCount
(JNIEnv* env, jclass jclass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr, jintArray res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
return instance->getVariationDesignPosition(nullptr, 0);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariations
(JNIEnv* env, jclass jclass, jlong ptr, jintArray res, jint count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
int count = instance->getVariationDesignPosition(nullptr, 0);
if (count > 0) { if (count > 0) {
std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count); std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count);
instance->getVariationDesignPosition(coords.data(), count); instance->getVariationDesignPosition(coords.data(), count);
jobjectArray res = env->NewObjectArray(count, skija::FontVariation::cls, nullptr);
for (int i=0; i < count; ++i) { for (int i=0; i < count; ++i) {
jobject var = env->NewObject(skija::FontVariation::cls, skija::FontVariation::ctor, coords[i].axis, coords[i].value); jint r[2] = {static_cast<jint>(coords[i].axis), rawBits(coords[i].value)};
env->SetObjectArrayElement(res, i, var); env->SetIntArrayRegion(res, 2 * i, 2, r);
} }
return res; }
} else
return nullptr;
} }
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationAxes extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationAxesCount
(JNIEnv* env, jclass jclass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr, jfloat* axisData) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
return instance->getVariationDesignParameters(nullptr, 0);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationAxes
(JNIEnv* env, jclass jclass, jlong ptr, jintArray axisData, jint count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
int count = instance->getVariationDesignParameters(nullptr, 0);
if (count > 0) { if (count > 0) {
std::vector<SkFontParameters::Variation::Axis> params(count); std::vector<SkFontParameters::Variation::Axis> params(count);
instance->getVariationDesignParameters(params.data(), count); instance->getVariationDesignParameters(params.data(), count);
jobjectArray res = env->NewObjectArray(count, skija::FontVariationAxis::cls, nullptr); for (int i = 0; i < count; ++i) {
for (int i=0; i < count; ++i) { jint p[5] = { static_cast<jint>(params[i].tag), rawBits(params[i].min), rawBits(params[i].def), rawBits(params[i].max), params[i].isHidden()};
jobject var = env->NewObject(skija::FontVariationAxis::cls, skija::FontVariationAxis::ctor, params[i].tag, params[i].min, params[i].def, params[i].max, params[i].isHidden()); env->SetIntArrayRegion(axisData, 5 * i, 5, p);
env->SetObjectArrayElement(res, i, var);
} }
return res; }
} else
return nullptr;
} }
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUniqueId extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUniqueId
...@@ -94,34 +99,32 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nMakeFro ...@@ -94,34 +99,32 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nMakeFro
} }
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nMakeClone extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nMakeClone
(JNIEnv* env, jclass jclass, jlong typefacePtr, jobjectArray variations, jint collectionIndex) { (JNIEnv* env, jclass jclass, jlong typefacePtr, jintArray variationsArr, jint variationsCount, jint collectionIndex) {
SkTypeface* typeface = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(typefacePtr)); SkTypeface* typeface = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(typefacePtr));
int variationCount = env->GetArrayLength(variations); std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationsCount);
std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationCount); jint* variations = env->GetIntArrayElements(variationsArr, 0);
for (int i=0; i < variationCount; ++i) { for (int i=0; i < variationsCount; i+=2) {
jobject jvar = env->GetObjectArrayElement(variations, i);
coordinates[i] = { coordinates[i] = {
static_cast<SkFourByteTag>(env->GetIntField(jvar, skija::FontVariation::tag)), static_cast<SkFourByteTag>(variations[i]),
env->GetFloatField(jvar, skija::FontVariation::value) fromBits(variations[i+1])
}; };
env->DeleteLocalRef(jvar);
} }
env->ReleaseIntArrayElements(variationsArr, variations, 0);
SkFontArguments arg = SkFontArguments() SkFontArguments arg = SkFontArguments()
.setCollectionIndex(collectionIndex) .setCollectionIndex(collectionIndex)
.setVariationDesignPosition({coordinates.data(), variationCount}); .setVariationDesignPosition({coordinates.data(), variationsCount});
SkTypeface* clone = typeface->makeClone(arg).release(); SkTypeface* clone = typeface->makeClone(arg).release();
return reinterpret_cast<jlong>(clone); return reinterpret_cast<jlong>(clone);
} }
extern "C" JNIEXPORT jshortArray JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyphs extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyphs
(JNIEnv* env, jclass jclass, jlong ptr, jintArray uniArr) { (JNIEnv* env, jclass jclass, jlong ptr, jintArray uniArr, jint count, jshortArray res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
jint count = env->GetArrayLength(uniArr);
std::vector<short> glyphs(count); std::vector<short> glyphs(count);
jint* uni = env->GetIntArrayElements(uniArr, nullptr); jint* uni = env->GetIntArrayElements(uniArr, nullptr);
instance->unicharsToGlyphs(reinterpret_cast<SkUnichar*>(uni), count, reinterpret_cast<SkGlyphID*>(glyphs.data())); instance->unicharsToGlyphs(reinterpret_cast<SkUnichar*>(uni), count, reinterpret_cast<SkGlyphID*>(glyphs.data()));
env->ReleaseIntArrayElements(uniArr, uni, 0); env->ReleaseIntArrayElements(uniArr, uni, 0);
return javaShortArray(env, glyphs); env->SetShortArrayRegion(res, 0, count, glyphs.data());
} }
extern "C" JNIEXPORT jshort JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyph extern "C" JNIEXPORT jshort JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyph
...@@ -142,13 +145,18 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTable ...@@ -142,13 +145,18 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTable
return instance->countTables(); return instance->countTables();
} }
extern "C" JNIEXPORT jintArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTableTags extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTableTagsCount
(JNIEnv* env, jclass jclass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
int count = instance->countTables(); return instance->countTables();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTableTags
(JNIEnv* env, jclass jclass, jlong ptr, jintArray res, jint count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
std::vector<jint> tags(count); std::vector<jint> tags(count);
instance->getTableTags(reinterpret_cast<SkFontTableTag*>(tags.data())); instance->getTableTags(reinterpret_cast<SkFontTableTag*>(tags.data()));
return javaIntArray(env, tags); env->SetIntArrayRegion(res, 0, count, tags.data());
} }
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTableSize extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetTableSize
...@@ -170,22 +178,24 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetUnits ...@@ -170,22 +178,24 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetUnits
return instance->getUnitsPerEm(); return instance->getUnitsPerEm();
} }
extern "C" JNIEXPORT jintArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetKerningPairAdjustments extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetKerningPairAdjustments
(JNIEnv* env, jclass jclass, jlong ptr, jshortArray glyphsArr) { (JNIEnv* env, jclass jclass, jlong ptr, jshortArray glyphsArr, jint count, jintArray res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
int count = glyphsArr == nullptr ? 0 : env->GetArrayLength(glyphsArr);
if (count > 0) { if (count > 0) {
std::vector<jint> adjustments(count); std::vector<jint> adjustments(count);
jshort* glyphs = env->GetShortArrayElements(glyphsArr, nullptr); jshort* glyphs = env->GetShortArrayElements(glyphsArr, nullptr);
bool res = instance->getKerningPairAdjustments( bool hasAdjustments = instance->getKerningPairAdjustments(
reinterpret_cast<SkGlyphID*>(glyphs), count, reinterpret_cast<SkGlyphID*>(glyphs), count,
reinterpret_cast<int32_t*>(adjustments.data())); reinterpret_cast<int32_t*>(adjustments.data())
);
env->ReleaseShortArrayElements(glyphsArr, glyphs, 0); env->ReleaseShortArrayElements(glyphsArr, glyphs, 0);
return res ? javaIntArray(env, adjustments) : nullptr; if (hasAdjustments) {
} else { env->SetIntArrayRegion(res, 0, count, adjustments.data());
bool res = instance->getKerningPairAdjustments(nullptr, 0, nullptr); }
return res ? javaIntArray(env, std::vector<jint>(0)) : nullptr; return hasAdjustments;
} }
return false;
} }
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetFamilyNames extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetFamilyNames
......
...@@ -385,3 +385,12 @@ static inline jint rawBits(jfloat f) { ...@@ -385,3 +385,12 @@ static inline jint rawBits(jfloat f) {
u.f = f; u.f = f;
return u.i; return u.i;
} }
static inline jfloat fromBits(jint i) {
union {
jfloat f;
jint i;
} u;
u.i = i;
return u.f;
}
...@@ -20,58 +20,46 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Typeface__1nIsFixedPitch ...@@ -20,58 +20,46 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Typeface__1nIsFixedPitch
return instance->isFixedPitch(); return instance->isFixedPitch();
} }
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetVariationsCount
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariations
(KNativePointer ptr) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetVariations"); SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
return instance->getVariationDesignPosition(nullptr, 0);
} }
#if 0 SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetVariations
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariations (KNativePointer ptr, KInt* res, KInt count) {
(KNativePointer ptr) { SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
int count = instance->getVariationDesignPosition(nullptr, 0);
if (count > 0) { if (count > 0) {
std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count); std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count);
instance->getVariationDesignPosition(coords.data(), count); instance->getVariationDesignPosition(coords.data(), count);
KInteropPointerArray res = env->NewObjectArray(count, skija::FontVariation::cls, nullptr);
for (int i=0; i < count; ++i) { for (int i=0; i < count; ++i) {
KInteropPointer var = env->NewObject(skija::FontVariation::cls, skija::FontVariation::ctor, coords[i].axis, coords[i].value); res[2*i] = static_cast<KInt>(coords[i].axis);
env->SetObjectArrayElement(res, i, var); res[2*i + 1] = rawBits(coords[i].value);
} }
return res; }
} else
return nullptr;
} }
#endif
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariationAxes SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetVariationAxesCount
(KNativePointer ptr) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetVariationAxes"); SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
return instance->getVariationDesignParameters(nullptr, 0);
} }
#if 0
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariationAxes SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetVariationAxes
(KNativePointer ptr) { (KNativePointer ptr, int* axis, int count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
int count = instance->getVariationDesignParameters(nullptr, 0);
if (count > 0) { if (count > 0) {
std::vector<SkFontParameters::Variation::Axis> params(count); std::vector<SkFontParameters::Variation::Axis> params(count);
instance->getVariationDesignParameters(params.data(), count); instance->getVariationDesignParameters(params.data(), count);
KInteropPointerArray res = env->NewObjectArray(count, skija::FontVariationAxis::cls, nullptr); for (int i = 0, j = 0; i < count; ++i) {
for (int i=0; i < count; ++i) { int p[5] = { static_cast<int>(params[i].tag), rawBits(params[i].min), rawBits(params[i].def), rawBits(params[i].max), params[i].isHidden()};
KInteropPointer var = env->NewObject(skija::FontVariationAxis::cls, skija::FontVariationAxis::ctor, params[i].tag, params[i].min, params[i].def, params[i].max, params[i].isHidden()); memcpy(axis + 5 * i, p, sizeof p);
env->SetObjectArrayElement(res, i, var);
} }
return res; }
} else
return nullptr;
} }
#endif
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUniqueId SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUniqueId
(KNativePointer ptr) { (KNativePointer ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
...@@ -95,19 +83,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromName ...@@ -95,19 +83,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromName
TODO("implement org_jetbrains_skia_Typeface__1nMakeFromName"); TODO("implement org_jetbrains_skia_Typeface__1nMakeFromName");
} }
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromName
(KInteropPointer nameStr, KInt styleValue) {
SkString name = skString(env, nameStr);
SkFontStyle style = skija::FontStyle::fromJava(styleValue);
sk_sp<SkTypeface> instance = SkTypeface::MakeFromName(name.c_str(), style);
SkTypeface* ptr = instance.release();
return reinterpret_cast<KNativePointer>(ptr);
}
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromFile SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromFile
(KInteropPointer pathStr, KInt index) { (KInteropPointer pathStr, KInt index) {
SkString path = skString(pathStr); SkString path = skString(pathStr);
...@@ -127,53 +102,28 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromData ...@@ -127,53 +102,28 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromData
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeClone SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeClone
(KNativePointer typefacePtr, KInteropPointerArray variations, KInt collectionIndex) { (KNativePointer typefacePtr, KInt* variations, KInt variationsCount, KInt collectionIndex) {
TODO("implement org_jetbrains_skia_Typeface__1nMakeClone"); SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefacePtr);
} std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationsCount);
for (int i=0; i < variationsCount; i+=2) {
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeClone
(KNativePointer typefacePtr, KInteropPointerArray variations, KInt collectionIndex) {
SkTypeface* typeface = reinterpret_cast<SkTypeface*>((typefacePtr));
int variationCount = env->GetArrayLength(variations);
std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationCount);
for (int i=0; i < variationCount; ++i) {
KInteropPointer jvar = env->GetObjectArrayElement(variations, i);
coordinates[i] = { coordinates[i] = {
static_cast<SkFourByteTag>(env->GetIntField(jvar, skija::FontVariation::tag)), static_cast<SkFourByteTag>(variations[i]),
env->GetFloatField(jvar, skija::FontVariation::value) fromBits(variations[i+1])
}; };
env->DeleteLocalRef(jvar);
} }
SkFontArguments arg = SkFontArguments() SkFontArguments arg = SkFontArguments()
.setCollectionIndex(collectionIndex) .setCollectionIndex(collectionIndex)
.setVariationDesignPosition({coordinates.data(), variationCount}); .setVariationDesignPosition({coordinates.data(), variationsCount});
SkTypeface* clone = typeface->makeClone(arg).release(); SkTypeface* clone = typeface->makeClone(arg).release();
return reinterpret_cast<KNativePointer>(clone); return reinterpret_cast<KNativePointer>(clone);
} }
#endif
SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetUTF32Glyphs
SKIKO_EXPORT KShort* org_jetbrains_skia_Typeface__1nGetUTF32Glyphs (KNativePointer ptr, KInt* uni, KInt count, KShort* res) {
(KNativePointer ptr, KInt* uniArr) { SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
TODO("implement org_jetbrains_skia_Typeface__1nGetUTF32Glyphs"); instance->unicharsToGlyphs(reinterpret_cast<SkUnichar*>(uni), count, reinterpret_cast<SkGlyphID*>(res));
} }
#if 0
SKIKO_EXPORT KShort* org_jetbrains_skia_Typeface__1nGetUTF32Glyphs
(KNativePointer ptr, KInt* uniArr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
KInt count = env->GetArrayLength(uniArr);
std::vector<short> glyphs(count);
KInt* uni = env->GetIntArrayElements(uniArr, nullptr);
instance->unicharsToGlyphs(reinterpret_cast<SkUnichar*>(uni), count, reinterpret_cast<SkGlyphID*>(glyphs.data()));
env->ReleaseIntArrayElements(uniArr, uni, 0);
return javaShortArray(env, glyphs);
}
#endif
SKIKO_EXPORT KShort org_jetbrains_skia_Typeface__1nGetUTF32Glyph SKIKO_EXPORT KShort org_jetbrains_skia_Typeface__1nGetUTF32Glyph
(KNativePointer ptr, KInt uni) { (KNativePointer ptr, KInt uni) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr)); SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
...@@ -192,23 +142,19 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTablesCount ...@@ -192,23 +142,19 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTablesCount
return instance->countTables(); return instance->countTables();
} }
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTableTagsCount
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetTableTags
(KNativePointer ptr) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetTableTags"); SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
return instance->countTables();
} }
#if 0 SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetTableTags
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetTableTags (KNativePointer ptr, KInt* res, KInt count) {
(KNativePointer ptr) { SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr)); std::vector<int> tags(count);
int count = instance->countTables();
std::vector<KInt> tags(count);
instance->getTableTags(reinterpret_cast<SkFontTableTag*>(tags.data())); instance->getTableTags(reinterpret_cast<SkFontTableTag*>(tags.data()));
return javaIntArray(env, tags); memcpy(res, tags.data(), tags.size() * sizeof(KInt));
} }
#endif
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTableSize SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTableSize
(KNativePointer ptr, KInt tag) { (KNativePointer ptr, KInt tag) {
...@@ -230,33 +176,20 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUnitsPerEm ...@@ -230,33 +176,20 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUnitsPerEm
} }
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments SKIKO_EXPORT bool org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments
(KNativePointer ptr, KShort* glyphsArr) { (KNativePointer ptr, KShort* glyphs, KInt count, KInt* res) {
TODO("implement org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments"); SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
if (count > 0) {
std::vector<int> adjustments(count);
return instance->getKerningPairAdjustments(
reinterpret_cast<SkGlyphID*>(glyphs), count,
reinterpret_cast<int32_t*>(res)
);
}
return false;
} }
#if 0
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments
(KNativePointer ptr, KShort* glyphsArr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
int count = glyphsArr == nullptr ? 0 : env->GetArrayLength(glyphsArr);
if (count > 0) {
std::vector<KInt> adjustments(count);
KShort* glyphs = env->GetShortArrayElements(glyphsArr, nullptr);
bool res = instance->getKerningPairAdjustments(
reinterpret_cast<SkGlyphID*>(glyphs), count,
reinterpret_cast<int32_t*>(adjustments.data()));
env->ReleaseShortArrayElements(glyphsArr, glyphs, 0);
return res ? javaIntArray(env, adjustments) : nullptr;
} else {
bool res = instance->getKerningPairAdjustments(nullptr, 0, nullptr);
return res ? javaIntArray(env, std::vector<KInt>(0)) : nullptr;
}
}
#endif
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetFamilyNames SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetFamilyNames
(KNativePointer ptr) { (KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetFamilyNames"); TODO("implement org_jetbrains_skia_Typeface__1nGetFamilyNames");
......
...@@ -148,5 +148,14 @@ static inline KInt rawBits(KFloat f) { ...@@ -148,5 +148,14 @@ static inline KInt rawBits(KFloat f) {
u.f = f; u.f = f;
return u.i; return u.i;
} }
static inline KFloat fromBits(KInt i) {
union {
KFloat f;
KInt i;
} u;
u.i = i;
return u.f;
}
#endif /* SKIKO_COMMON_H */ #endif /* SKIKO_COMMON_H */
...@@ -6,7 +6,7 @@ actual fun <R> commonSynchronized(lock: Any, block: () -> R) { ...@@ -6,7 +6,7 @@ actual fun <R> commonSynchronized(lock: Any, block: () -> R) {
block() block()
} }
actual fun String.intCodePoints(): IntArray = TODO() actual fun String.intCodePoints(): IntArray = IntArray(this.length) { this[it].code }
actual class Pattern constructor(regex: String) { actual class Pattern constructor(regex: String) {
private val _regex = Regex(regex) private val _regex = Regex(regex)
......
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