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