Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
d73160f5
Unverified
Commit
d73160f5
authored
Apr 22, 2026
by
Konstantin
Committed by
GitHub
Apr 22, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for retrieving unresolved codepoints in `Paragraph` (#1192)
parent
f539b7a1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
85 additions
and
0 deletions
+85
-0
Paragraph.kt
...mmonMain/kotlin/org/jetbrains/skia/paragraph/Paragraph.kt
+27
-0
ParagraphTest.kt
...src/commonTest/kotlin/org/jetbrains/skia/ParagraphTest.kt
+23
-0
Paragraph.cc
skiko/src/jvmMain/cpp/common/paragraph/Paragraph.cc
+18
-0
Paragraph.cc
skiko/src/nativeJsMain/cpp/paragraph/Paragraph.cc
+17
-0
No files found.
skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/Paragraph.kt
View file @
d73160f5
...
@@ -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
)
...
...
skiko/src/commonTest/kotlin/org/jetbrains/skia/ParagraphTest.kt
View file @
d73160f5
...
@@ -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
)
...
...
skiko/src/jvmMain/cpp/common/paragraph/Paragraph.cc
View file @
d73160f5
...
@@ -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
));
...
...
skiko/src/nativeJsMain/cpp/paragraph/Paragraph.cc
View file @
d73160f5
...
@@ -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
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment