Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

turn off flutter hack by default, implement methods to control it #997

Merged
merged 9 commits into from
Oct 31, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ class ParagraphStyle : Managed(ParagraphStyle_nMake(), _FinalizerHolder.PTR) {
reachabilityBarrier(this)
}

var isApplyRoundingHackEnabled: Boolean
get() = try {
Stats.onNativeCall()
_nGetApplyRoundingHack(_ptr).not().not()
} finally {
reachabilityBarrier(this)
}
set(value) = try {
Stats.onNativeCall()
_nSetApplyRoundingHack(_ptr, value)
} finally {
reachabilityBarrier(this)
}

var textIndent: TextIndent
get() = try {
Expand Down Expand Up @@ -322,6 +335,14 @@ private external fun _nGetHinting(ptr: NativePointer): Int
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nGetSubpixel")
private external fun _nGetSubpixel(ptr: NativePointer): Boolean

@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack")
private external fun _nGetApplyRoundingHack(ptr: NativePointer): Boolean

@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack")
private external fun _nSetApplyRoundingHack(ptr: NativePointer, value: Boolean)

@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent")
private external fun _nSetTextIndent(ptr: NativePointer, firstLine: Float, restLine: Float)
Expand Down
56 changes: 47 additions & 9 deletions skiko/src/commonTest/kotlin/org/jetbrains/skia/ParagraphTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import org.jetbrains.skia.tests.assertCloseEnough
import org.jetbrains.skia.tests.assertContentCloseEnough
import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.tests.*
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.truncate
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
Expand All @@ -15,6 +18,7 @@ class ParagraphTest {
private val fontCollection = suspend {
FontCollection().setDefaultFontManager(TypefaceFontProvider().apply {
registerTypeface(Typeface.makeFromResource("./fonts/Inter-Hinted-Regular.ttf"), "Inter")
registerTypeface(Typeface.makeFromResource("./fonts/JetBrainsMono_2_304/JetBrainsMono-Regular.ttf"), "JetBrains Mono")
})
}
private val style = ParagraphStyle().apply {
Expand Down Expand Up @@ -47,40 +51,43 @@ class ParagraphTest {

@Test
fun layoutParagraph() = runTest {
val lineMetricsEpsilon = 0.0001f
val lineMetricsEpsilon = 0.001f

assertCloseEnough(
singleLineMetrics("aa"), LineMetrics(
actual = singleLineMetrics("aa"),
expected = LineMetrics(
startIndex = 0,
endIndex = 2,
endExcludingWhitespaces = 2,
endIncludingNewline = 2,
isHardBreak = true,
ascent = 13.5625,
descent = 3.3806817531585693,
descent = 3.380584716796875,
unscaledAscent = 13.5625,
height = 17.0,
width = 15.789999961853027,
width = 15.789764404296875,
left = 0.0,
baseline = 13.619318008422852,
baseline = 13.619415283203125,
lineNumber = 0
), epsilon = lineMetricsEpsilon
)


assertCloseEnough(
singleLineMetrics("яя"), LineMetrics(
actual = singleLineMetrics("яя"),
expected = LineMetrics(
startIndex = 0,
endIndex = 2,
endExcludingWhitespaces = 2,
endIncludingNewline = 2,
isHardBreak = true,
ascent = 13.5625,
descent = 3.3806817531585693,
descent = 3.380584716796875,
unscaledAscent = 13.5625,
height = 17.0,
width = 15.710000038146973,
width = 15.710235595703125,
left = 0.0,
baseline = 13.619318008422852,
baseline = 13.619415283203125,
lineNumber = 0
), epsilon = lineMetricsEpsilon
)
Expand Down Expand Up @@ -172,4 +179,35 @@ class ParagraphTest {
}
}
}

@Test
fun layout_paragraph_with_its_maxIntrinsicWidth_shouldnt_lead_to_wraps() = runTest {
suspend fun testWraps(isApplyRoundingHackEnabled: Boolean, unexpectedWrapsPresent: Boolean) {
val paragraphStyle = ParagraphStyle().apply {
this.isApplyRoundingHackEnabled = isApplyRoundingHackEnabled
textStyle = TextStyle().apply {
fontFamilies = arrayOf("JetBrains Mono")
fontSize = 13.0f * 2f
}
}
val paragraph = ParagraphBuilder(paragraphStyle, fontCollection()).use {
it.addText("x".repeat(104))
it.addText(" ")
it.addText("y".repeat(100))
it.build()
}.layout(Float.POSITIVE_INFINITY)
assertEquals(1, paragraph.lineNumber, "Layout in one line with Inf width")

val maxIntrinsicWidth = paragraph.maxIntrinsicWidth
val expectedLines = if (unexpectedWrapsPresent) 2 else 1

paragraph.layout(paragraph.maxIntrinsicWidth)
assertEquals(expectedLines, paragraph.lineNumber, "Layout with maxIntrinsicWidth " +
"maxIntrinsicWidth: $maxIntrinsicWidth " +
"unexpectedWrapsPresent: $unexpectedWrapsPresent " +
"isApplyRoundingHackEnabled: $isApplyRoundingHackEnabled")
}
testWraps(isApplyRoundingHackEnabled = false, unexpectedWrapsPresent = false)
testWraps(isApplyRoundingHackEnabled = true, unexpectedWrapsPresent = true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,13 @@ class ParagraphStyleTests {
assertEquals(gloriousRasterSettings, paragraphStyle.fontRastrSettings)
}
}

@Test
fun paragraphStyleRoundingHackTests() {
ParagraphStyle().use { paragraphStyle ->
Copy link
Member

@eymar eymar Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this one to this would make k/js happy :D

    @Test
    fun paragraphStyleRoundingHackTests() {
        ParagraphStyle().use { paragraphStyle ->
            assertFalse(paragraphStyle.isApplyRoundingHackEnabled)
            paragraphStyle.isApplyRoundingHackEnabled = true
            assertTrue(paragraphStyle.isApplyRoundingHackEnabled)
        }
    }

_nGetApplyRoundingHack returns 0 (there is no false/true in wasm). And JS equality check fails:
0 === false --> false


Not using "add a suggestion" because new imports are needed anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jfyi: to run the k/js tests locally:

./gradlew :cleanJsBrowserTest :jsBrowserTest -Pskiko.wasm.enabled=true -Pskiko.js.enabled=true

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

assertEquals(false, paragraphStyle.isApplyRoundingHackEnabled)
paragraphStyle.isApplyRoundingHackEnabled = true
assertEquals(true, paragraphStyle.isApplyRoundingHackEnabled)
}
}
}
Binary file not shown.
13 changes: 13 additions & 0 deletions skiko/src/jvmMain/cpp/common/paragraph/ParagraphStyle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_paragraph_ParagraphSt
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt_ParagraphStyle_1nMake
(JNIEnv* env, jclass jclass) {
ParagraphStyle* instance = new ParagraphStyle();
instance->setApplyRoundingHack(false);
return reinterpret_cast<jlong>(instance);
}

Expand Down Expand Up @@ -180,6 +181,18 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphSty
instance->turnHintingOff();
}

extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nGetApplyRoundingHack
(JNIEnv* env, jclass jclass, jlong ptr) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));
return instance->getApplyRoundingHack();
}

extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nSetApplyRoundingHack
(JNIEnv* env, jclass jclass, jlong ptr, jboolean val) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));
instance->setApplyRoundingHack(val);
}

extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nSetTextIndent
(JNIEnv* env, jclass jclass, jlong ptr, jfloat firstLine, jfloat restLine) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));
Expand Down
13 changes: 13 additions & 0 deletions skiko/src/nativeJsMain/cpp/paragraph/ParagraphStyle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_paragraph_ParagraphStyle__1nGetFi
SKIKO_EXPORT KNativePointer org_jetbrains_skia_paragraph_ParagraphStyle__1nMake
() {
ParagraphStyle* instance = new ParagraphStyle();
instance->setApplyRoundingHack(false);
return reinterpret_cast<KNativePointer>(instance);
}

Expand Down Expand Up @@ -177,6 +178,18 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_paragraph_ParagraphStyle__1nGetSubpixel
return fontRastrSettings.fSubpixel;
}

SKIKO_EXPORT KBoolean org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack
(KNativePointer ptr) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(ptr);
return instance->getApplyRoundingHack();
}

SKIKO_EXPORT void org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack
(KNativePointer ptr, KBoolean val) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(ptr);
instance->setApplyRoundingHack(val);
}

SKIKO_EXPORT void org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent
(KNativePointer ptr, KFloat firstLine, KFloat restLine) {
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>((ptr));
Expand Down
Loading