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
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skiko.kotlinBackend
class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object {
......@@ -88,7 +89,16 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val variations: Array<FontVariation>?
get() = try {
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 {
reachabilityBarrier(this)
}
......@@ -100,7 +110,18 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val variationAxes: Array<FontVariationAxis>?
get() = try {
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 {
reachabilityBarrier(this)
}
......@@ -156,7 +177,8 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
return try {
if (variations.size == 0) return this
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) {
"Failed to clone Typeface $this with $variations"
}
......@@ -183,7 +205,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
fun getUTF32Glyphs(uni: IntArray?): ShortArray {
return try {
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 {
reachabilityBarrier(this)
}
......@@ -230,7 +258,12 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
val tableTags: Array<String>
get() = try {
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 {
reachabilityBarrier(this)
}
......@@ -290,7 +323,13 @@ class Typeface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
fun getKerningPairAdjustments(glyphs: ShortArray?): IntArray? {
return try {
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 {
reachabilityBarrier(this)
}
......@@ -344,7 +383,7 @@ private external fun Typeface_nEquals(ptr: NativePointer, otherPtr: NativePointe
private external fun Typeface_nMakeDefault(): NativePointer
@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")
private external fun Typeface_nGetUTF32Glyph(ptr: NativePointer, unichar: Int): Short
......@@ -358,11 +397,17 @@ private external fun _nGetFontStyle(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nIsFixedPitch")
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")
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")
private external fun _nGetVariationAxes(ptr: NativePointer): Array<FontVariationAxis>?
private external fun _nGetVariationAxes(ptr: NativePointer, axisData: InteropPointer, axisCount: Int)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nMakeFromName")
private external fun _nMakeFromName(name: String?, fontStyle: Int): NativePointer
......@@ -374,7 +419,7 @@ internal external fun _nMakeFromFile(path: InteropPointer, index: Int): NativePo
private external fun _nMakeFromData(dataPtr: NativePointer, index: Int): NativePointer
@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")
private external fun _nGetGlyphsCount(ptr: NativePointer): Int
......@@ -382,8 +427,11 @@ private external fun _nGetGlyphsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTablesCount")
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")
private external fun _nGetTableTags(ptr: NativePointer): IntArray?
private external fun _nGetTableTags(ptr: NativePointer, tags: InteropPointer, count: Int)
@ExternalSymbolName("org_jetbrains_skia_Typeface__1nGetTableSize")
private external fun _nGetTableSize(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
@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")
private external fun _nGetFamilyNames(ptr: NativePointer): Array<FontFamilyName>
......
......@@ -2,6 +2,8 @@ package org.jetbrains.skiko
import org.jetbrains.skia.*
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 kotlin.test.*
......@@ -9,7 +11,6 @@ class TypefaceTest {
@Test
fun typefaceTest() = runTest {
// TODO Commonize array and string results and uncomment
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")
......@@ -25,68 +26,70 @@ class TypefaceTest {
assertFalse(inter.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, interV)
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(2548, interV.glyphsCount)
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)
assertEquals(2816, inter.unitsPerEm)
}
if (kotlinBackend == KotlinBackend.JVM) {
assertNull(jbMono.getKerningPairAdjustments(null))
assertNull(jbMono.getKerningPairAdjustments(jbMono.getStringGlyphs("TAV")))
@Test
fun fontVariationTest() = runTest {
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)
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) {
block()
}
actual fun String.intCodePoints(): IntArray = TODO()
actual fun String.intCodePoints(): IntArray = IntArray(this.length) { this[it].code }
actual class Pattern constructor(regex: String) {
private val _regex = Regex(regex)
......
......@@ -16,38 +16,43 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_TypefaceKt__1nIsFi
return instance->isFixedPitch();
}
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariations
(JNIEnv* env, jclass jclass, jlong ptr) {
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationsCount
(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));
int count = instance->getVariationDesignPosition(nullptr, 0);
if (count > 0) {
std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count);
instance->getVariationDesignPosition(coords.data(), count);
jobjectArray res = env->NewObjectArray(count, skija::FontVariation::cls, nullptr);
for (int i=0; i < count; ++i) {
jobject var = env->NewObject(skija::FontVariation::cls, skija::FontVariation::ctor, coords[i].axis, coords[i].value);
env->SetObjectArrayElement(res, i, var);
jint r[2] = {static_cast<jint>(coords[i].axis), rawBits(coords[i].value)};
env->SetIntArrayRegion(res, 2 * i, 2, r);
}
return res;
} else
return nullptr;
}
}
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationAxes
(JNIEnv* env, jclass jclass, jlong ptr) {
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetVariationAxesCount
(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));
int count = instance->getVariationDesignParameters(nullptr, 0);
if (count > 0) {
std::vector<SkFontParameters::Variation::Axis> params(count);
instance->getVariationDesignParameters(params.data(), count);
jobjectArray res = env->NewObjectArray(count, skija::FontVariationAxis::cls, nullptr);
for (int i=0; i < count; ++i) {
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->SetObjectArrayElement(res, i, var);
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()};
env->SetIntArrayRegion(axisData, 5 * i, 5, p);
}
return res;
} else
return nullptr;
}
}
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
}
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));
int variationCount = env->GetArrayLength(variations);
std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationCount);
for (int i=0; i < variationCount; ++i) {
jobject jvar = env->GetObjectArrayElement(variations, i);
std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationsCount);
jint* variations = env->GetIntArrayElements(variationsArr, 0);
for (int i=0; i < variationsCount; i+=2) {
coordinates[i] = {
static_cast<SkFourByteTag>(env->GetIntField(jvar, skija::FontVariation::tag)),
env->GetFloatField(jvar, skija::FontVariation::value)
static_cast<SkFourByteTag>(variations[i]),
fromBits(variations[i+1])
};
env->DeleteLocalRef(jvar);
}
env->ReleaseIntArrayElements(variationsArr, variations, 0);
SkFontArguments arg = SkFontArguments()
.setCollectionIndex(collectionIndex)
.setVariationDesignPosition({coordinates.data(), variationCount});
.setVariationDesignPosition({coordinates.data(), variationsCount});
SkTypeface* clone = typeface->makeClone(arg).release();
return reinterpret_cast<jlong>(clone);
}
extern "C" JNIEXPORT jshortArray JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyphs
(JNIEnv* env, jclass jclass, jlong ptr, jintArray uniArr) {
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_TypefaceKt_Typeface_1nGetUTF32Glyphs
(JNIEnv* env, jclass jclass, jlong ptr, jintArray uniArr, jint count, jshortArray res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
jint count = env->GetArrayLength(uniArr);
std::vector<short> glyphs(count);
jint* 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);
env->SetShortArrayRegion(res, 0, count, glyphs.data());
}
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
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) {
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);
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
......@@ -170,22 +178,24 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetUnits
return instance->getUnitsPerEm();
}
extern "C" JNIEXPORT jintArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetKerningPairAdjustments
(JNIEnv* env, jclass jclass, jlong ptr, jshortArray glyphsArr) {
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetKerningPairAdjustments
(JNIEnv* env, jclass jclass, jlong ptr, jshortArray glyphsArr, jint count, jintArray res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(static_cast<uintptr_t>(ptr));
int count = glyphsArr == nullptr ? 0 : env->GetArrayLength(glyphsArr);
if (count > 0) {
std::vector<jint> adjustments(count);
jshort* glyphs = env->GetShortArrayElements(glyphsArr, nullptr);
bool res = instance->getKerningPairAdjustments(
bool hasAdjustments = instance->getKerningPairAdjustments(
reinterpret_cast<SkGlyphID*>(glyphs), count,
reinterpret_cast<int32_t*>(adjustments.data()));
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<jint>(0)) : nullptr;
if (hasAdjustments) {
env->SetIntArrayRegion(res, 0, count, adjustments.data());
}
return hasAdjustments;
}
return false;
}
extern "C" JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_skia_TypefaceKt__1nGetFamilyNames
......
......@@ -385,3 +385,12 @@ static inline jint rawBits(jfloat f) {
u.f = f;
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
return instance->isFixedPitch();
}
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariations
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetVariationsCount
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetVariations");
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
return instance->getVariationDesignPosition(nullptr, 0);
}
#if 0
SKIKO_EXPORT KInteropPointerArray org_jetbrains_skia_Typeface__1nGetVariations
(KNativePointer ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
int count = instance->getVariationDesignPosition(nullptr, 0);
SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetVariations
(KNativePointer ptr, KInt* res, KInt count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
if (count > 0) {
std::vector<SkFontArguments::VariationPosition::Coordinate> coords(count);
instance->getVariationDesignPosition(coords.data(), count);
KInteropPointerArray res = env->NewObjectArray(count, skija::FontVariation::cls, nullptr);
for (int i=0; i < count; ++i) {
KInteropPointer var = env->NewObject(skija::FontVariation::cls, skija::FontVariation::ctor, coords[i].axis, coords[i].value);
env->SetObjectArrayElement(res, i, var);
res[2*i] = static_cast<KInt>(coords[i].axis);
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) {
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
(KNativePointer ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
int count = instance->getVariationDesignParameters(nullptr, 0);
SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetVariationAxes
(KNativePointer ptr, int* axis, int count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
if (count > 0) {
std::vector<SkFontParameters::Variation::Axis> params(count);
instance->getVariationDesignParameters(params.data(), count);
KInteropPointerArray res = env->NewObjectArray(count, skija::FontVariationAxis::cls, nullptr);
for (int i=0; i < count; ++i) {
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());
env->SetObjectArrayElement(res, i, var);
for (int i = 0, j = 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()};
memcpy(axis + 5 * i, p, sizeof p);
}
return res;
} else
return nullptr;
}
}
#endif
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUniqueId
(KNativePointer ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
......@@ -95,19 +83,6 @@ SKIKO_EXPORT KNativePointer 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
(KInteropPointer pathStr, KInt index) {
SkString path = skString(pathStr);
......@@ -127,53 +102,28 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeFromData
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Typeface__1nMakeClone
(KNativePointer typefacePtr, KInteropPointerArray variations, KInt collectionIndex) {
TODO("implement org_jetbrains_skia_Typeface__1nMakeClone");
}
#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);
(KNativePointer typefacePtr, KInt* variations, KInt variationsCount, KInt collectionIndex) {
SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefacePtr);
std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates(variationsCount);
for (int i=0; i < variationsCount; i+=2) {
coordinates[i] = {
static_cast<SkFourByteTag>(env->GetIntField(jvar, skija::FontVariation::tag)),
env->GetFloatField(jvar, skija::FontVariation::value)
static_cast<SkFourByteTag>(variations[i]),
fromBits(variations[i+1])
};
env->DeleteLocalRef(jvar);
}
SkFontArguments arg = SkFontArguments()
.setCollectionIndex(collectionIndex)
.setVariationDesignPosition({coordinates.data(), variationCount});
.setVariationDesignPosition({coordinates.data(), variationsCount});
SkTypeface* clone = typeface->makeClone(arg).release();
return reinterpret_cast<KNativePointer>(clone);
}
#endif
SKIKO_EXPORT KShort* org_jetbrains_skia_Typeface__1nGetUTF32Glyphs
(KNativePointer ptr, KInt* uniArr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetUTF32Glyphs");
SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetUTF32Glyphs
(KNativePointer ptr, KInt* uni, KInt count, KShort* res) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
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
(KNativePointer ptr, KInt uni) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
......@@ -192,23 +142,19 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTablesCount
return instance->countTables();
}
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetTableTags
SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetTableTagsCount
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetTableTags");
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
return instance->countTables();
}
#if 0
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetTableTags
(KNativePointer ptr) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>((ptr));
int count = instance->countTables();
std::vector<KInt> tags(count);
SKIKO_EXPORT void org_jetbrains_skia_Typeface__1nGetTableTags
(KNativePointer ptr, KInt* res, KInt count) {
SkTypeface* instance = reinterpret_cast<SkTypeface*>(ptr);
std::vector<int> tags(count);
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
(KNativePointer ptr, KInt tag) {
......@@ -230,33 +176,20 @@ SKIKO_EXPORT KInt org_jetbrains_skia_Typeface__1nGetUnitsPerEm
}
SKIKO_EXPORT KInt* org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments
(KNativePointer ptr, KShort* glyphsArr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments");
SKIKO_EXPORT bool org_jetbrains_skia_Typeface__1nGetKerningPairAdjustments
(KNativePointer ptr, KShort* glyphs, KInt count, KInt* res) {
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
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Typeface__1nGetFamilyNames");
......
......@@ -148,5 +148,14 @@ static inline KInt rawBits(KFloat f) {
u.f = f;
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 */
......@@ -6,7 +6,7 @@ actual fun <R> commonSynchronized(lock: Any, block: () -> R) {
block()
}
actual fun String.intCodePoints(): IntArray = TODO()
actual fun String.intCodePoints(): IntArray = IntArray(this.length) { this[it].code }
actual class Pattern constructor(regex: String) {
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