Saivignesh S
01/16/2025, 10:23 AMSkiko Native.native.kt
, Native.js.kt
, and Native.wasm.kt
, there is an actual
implementation of the expect
function toInterOp
declared in Native.kt
(CommonMain).
• The function uses convertToZeroTerminatedString()
to convert a String
to a ByteArray
, encoding it to UTF-8.
However, in NativeJsMain/Cpp/Font.cc
, the measureText
function is configured as follows:
SKIKO_EXPORT KFloat org_jetbrains_skia_Font__1nMeasureTextWidth
(KNativePointer ptr, char* str, KInt len, KNativePointer paintPtr) {
SkFont* instance = reinterpret_cast<SkFont*>(ptr);
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
return instance->measureText(str, len * sizeof(KChar), SkTextEncoding::kUTF16, nullptr, paint);
}
The problem: measureText
expects a UTF-16 encoded string, but the input string is in UTF-8
Below Snippet is from jvmMain/cpp/Font.cc
,In this case, Text Measuring returns the correct width ( JVM Environment ), where the String's are processed as UTF-16.
extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skia_FontKt__1nMeasureTextWidth
(JNIEnv* env, jclass jclass, jlong ptr, jstring str, jint len, jlong paintPtr) {
SkFont* instance = reinterpret_cast<SkFont*>(static_cast<uintptr_t>(ptr));
SkPaint* paint = reinterpret_cast<SkPaint*>(static_cast<uintptr_t>(paintPtr));
const jchar* chars = env->GetStringCritical(str, nullptr);
jfloat result = instance->measureText(chars, len * sizeof(jchar), SkTextEncoding::kUTF16, nullptr, paint);
env->ReleaseStringCritical(str, chars);
return result;
}
Workaround:
Changing the encoding to UTF-8 in the measureText
function gives the correct text width:
SKIKO_EXPORT KFloat org_jetbrains_skia_Font__1nMeasureTextWidth
(KNativePointer ptr, char* str, KInt len, KNativePointer paintPtr) {
SkFont* instance = reinterpret_cast<SkFont*>(ptr);
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
return instance->measureText(str, len, SkTextEncoding::kUTF8, nullptr, paint);
}
Question:
Is this workaround correct, or am I addressing the issue incorrectly? If there’s a better way to ensure proper font measurement, I’d appreciate any guidance.
Thanks in advance for your help!Artem Kobzar
01/16/2025, 1:18 PMOleksandr Karpovich [JB]
01/17/2025, 11:05 AMOleksandr Karpovich [JB]
01/17/2025, 11:11 AMSaivignesh S
01/17/2025, 12:18 PMFont.measureTextWidth()
directly in my code. I also tried using ParagraphBuilder,
add text and retrieve the bounds, and it does return the correct text width. However, I needed a more straightforward approach, which is why I relied on Font.measureTextWidth()
.
Thanks again 😀Saivignesh S
02/26/2025, 9:47 AMOleksandr Karpovich [JB]
02/26/2025, 9:51 AM