Unverified Commit d73160f5 authored by Konstantin's avatar Konstantin Committed by GitHub

Add support for retrieving unresolved codepoints in `Paragraph` (#1192)

parent f539b7a1
...@@ -188,6 +188,27 @@ class Paragraph internal constructor(ptr: NativePointer, text: ManagedString?) : ...@@ -188,6 +188,27 @@ class Paragraph internal constructor(ptr: NativePointer, text: ManagedString?) :
reachabilityBarrier(this) reachabilityBarrier(this)
} }
val unresolvedCodepointsCount: Int
get() = try {
Stats.onNativeCall()
_nGetUnresolvedCodepointsCount(_ptr)
} finally {
reachabilityBarrier(this)
}
val unresolvedCodepoints: IntArray
get() = try {
Stats.onNativeCall()
val count = _nGetUnresolvedCodepointsCount(_ptr)
val result = IntArray(count)
if (count > 0) {
withResult(result) { _nGetUnresolvedCodepoints(_ptr, it) }
}
result
} finally {
reachabilityBarrier(this)
}
fun updateAlignment(alignment: Alignment): Paragraph { fun updateAlignment(alignment: Alignment): Paragraph {
Stats.onNativeCall() Stats.onNativeCall()
_nUpdateAlignment(_ptr, alignment.ordinal) _nUpdateAlignment(_ptr, alignment.ordinal)
...@@ -357,6 +378,12 @@ private external fun _nMarkDirty(ptr: NativePointer) ...@@ -357,6 +378,12 @@ private external fun _nMarkDirty(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedGlyphsCount") @ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedGlyphsCount")
private external fun _nGetUnresolvedGlyphsCount(ptr: NativePointer): Int private external fun _nGetUnresolvedGlyphsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedCodepointsCount")
private external fun _nGetUnresolvedCodepointsCount(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedCodepoints")
private external fun _nGetUnresolvedCodepoints(ptr: NativePointer, result: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nUpdateAlignment") @ExternalSymbolName("org_jetbrains_skia_paragraph_Paragraph__1nUpdateAlignment")
private external fun _nUpdateAlignment(ptr: NativePointer, Align: Int) private external fun _nUpdateAlignment(ptr: NativePointer, Align: Int)
......
...@@ -132,6 +132,8 @@ class ParagraphTest { ...@@ -132,6 +132,8 @@ class ParagraphTest {
assertEquals(IRange(0, 5), paragraph.getWordBoundary(0)) assertEquals(IRange(0, 5), paragraph.getWordBoundary(0))
assertEquals(IRange(8, 21), paragraph.getWordBoundary(10)) assertEquals(IRange(8, 21), paragraph.getWordBoundary(10))
assertEquals(0, paragraph.unresolvedGlyphsCount) assertEquals(0, paragraph.unresolvedGlyphsCount)
assertEquals(0, paragraph.unresolvedCodepointsCount)
assertContentEquals(IntArray(0), paragraph.unresolvedCodepoints)
assertEquals(2, paragraph.lineNumber) assertEquals(2, paragraph.lineNumber)
assertContentEquals(arrayOf(), paragraph.rectsForPlaceholders) assertContentEquals(arrayOf(), paragraph.rectsForPlaceholders)
...@@ -157,6 +159,27 @@ class ParagraphTest { ...@@ -157,6 +159,27 @@ class ParagraphTest {
) )
} }
@Test
fun unresolvedCodepointsWithUnknownSymbols() = runTest {
// U+E001 is a Private Use Area character not present in Inter.
// It appears twice in the text to verify count-vs-unique-set semantics.
val unknownChar = '\uE001'
val text = "Hello${unknownChar}World${unknownChar}!"
val paragraph = ParagraphBuilder(style, fontCollection()).use {
it.addText(text)
it.build()
}.layout(Float.POSITIVE_INFINITY)
// unresolvedGlyphsCount counts all glyph instances (2 occurrences of U+E001)
assertEquals(2, paragraph.unresolvedGlyphsCount)
// unresolvedCodepoints returns the set of unique unresolved codepoints
assertEquals(1, paragraph.unresolvedCodepointsCount)
val codepoints = paragraph.unresolvedCodepoints
assertEquals(1, codepoints.size)
assertTrue(unknownChar.code in codepoints, "Expected U+E001 to be in unresolvedCodepoints")
}
@Test @Test
fun getRectsForRange() { fun getRectsForRange() {
val fontCollection = FontCollection().setDefaultFontManager(FontMgr.default) val fontCollection = FontCollection().setDefaultFontManager(FontMgr.default)
......
...@@ -177,6 +177,24 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt_ ...@@ -177,6 +177,24 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt_
return instance->unresolvedGlyphs(); return instance->unresolvedGlyphs();
} }
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt__1nGetUnresolvedCodepointsCount
(JNIEnv* env, jclass jclass, jlong ptr) {
Paragraph* instance = reinterpret_cast<Paragraph*>(static_cast<uintptr_t>(ptr));
return instance->unresolvedCodepoints().size();
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt__1nGetUnresolvedCodepoints
(JNIEnv* env, jclass jclass, jlong ptr, jintArray resultArray) {
Paragraph* instance = reinterpret_cast<Paragraph*>(static_cast<uintptr_t>(ptr));
auto codepoints = instance->unresolvedCodepoints();
std::vector<jint> data;
data.reserve(codepoints.size());
for (SkUnichar cp : codepoints) {
data.push_back(static_cast<jint>(cp));
}
env->SetIntArrayRegion(resultArray, 0, static_cast<jsize>(data.size()), data.data());
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt__1nUpdateAlignment extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphKt__1nUpdateAlignment
(JNIEnv* env, jclass jclass, jlong ptr, jint textAlignment) { (JNIEnv* env, jclass jclass, jlong ptr, jint textAlignment) {
Paragraph* instance = reinterpret_cast<Paragraph*>(static_cast<uintptr_t>(ptr)); Paragraph* instance = reinterpret_cast<Paragraph*>(static_cast<uintptr_t>(ptr));
......
...@@ -146,6 +146,23 @@ SKIKO_EXPORT KInt org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedGlyphsC ...@@ -146,6 +146,23 @@ SKIKO_EXPORT KInt org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedGlyphsC
return instance->unresolvedGlyphs(); return instance->unresolvedGlyphs();
} }
SKIKO_EXPORT KInt org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedCodepointsCount
(KNativePointer ptr) {
Paragraph* instance = reinterpret_cast<Paragraph*>(ptr);
return static_cast<KInt>(instance->unresolvedCodepoints().size());
}
SKIKO_EXPORT void org_jetbrains_skia_paragraph_Paragraph__1nGetUnresolvedCodepoints
(KNativePointer ptr, KInteropPointer resultPtr) {
Paragraph* instance = reinterpret_cast<Paragraph*>(ptr);
auto codepoints = instance->unresolvedCodepoints();
KInt* result = reinterpret_cast<KInt*>(resultPtr);
size_t i = 0;
for (SkUnichar cp : codepoints) {
result[i++] = static_cast<KInt>(cp);
}
}
SKIKO_EXPORT void org_jetbrains_skia_paragraph_Paragraph__1nUpdateAlignment SKIKO_EXPORT void org_jetbrains_skia_paragraph_Paragraph__1nUpdateAlignment
(KNativePointer ptr, KInt textAlignment) { (KNativePointer ptr, KInt textAlignment) {
Paragraph* instance = reinterpret_cast<Paragraph*>((ptr)); Paragraph* instance = reinterpret_cast<Paragraph*>((ptr));
......
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