Skip to content

Commit f722906

Browse files
SergeevPaveleymar
andauthored
turn off flutter hack by default, implement methods to control it (JetBrains#997)
Co-authored-by: Oleksandr Karpovich <a.n.karpovich@gmail.com>
1 parent d0b681d commit f722906

6 files changed

Lines changed: 103 additions & 9 deletions

File tree

skiko/src/commonMain/kotlin/org/jetbrains/skia/paragraph/ParagraphStyle.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ class ParagraphStyle : Managed(ParagraphStyle_nMake(), _FinalizerHolder.PTR) {
191191
reachabilityBarrier(this)
192192
}
193193

194+
var isApplyRoundingHackEnabled: Boolean
195+
get() = try {
196+
Stats.onNativeCall()
197+
_nGetApplyRoundingHack(_ptr).not().not()
198+
} finally {
199+
reachabilityBarrier(this)
200+
}
201+
set(value) = try {
202+
Stats.onNativeCall()
203+
_nSetApplyRoundingHack(_ptr, value)
204+
} finally {
205+
reachabilityBarrier(this)
206+
}
194207

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

338+
@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack")
339+
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack")
340+
private external fun _nGetApplyRoundingHack(ptr: NativePointer): Boolean
341+
342+
@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack")
343+
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack")
344+
private external fun _nSetApplyRoundingHack(ptr: NativePointer, value: Boolean)
345+
325346
@ExternalSymbolName("org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent")
326347
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent")
327348
private external fun _nSetTextIndent(ptr: NativePointer, firstLine: Float, restLine: Float)

skiko/src/commonTest/kotlin/org/jetbrains/skia/ParagraphTest.kt

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import org.jetbrains.skia.tests.assertCloseEnough
66
import org.jetbrains.skia.tests.assertContentCloseEnough
77
import org.jetbrains.skia.tests.makeFromResource
88
import org.jetbrains.skiko.tests.*
9+
import kotlin.math.ceil
10+
import kotlin.math.floor
11+
import kotlin.math.truncate
912
import kotlin.test.Test
1013
import kotlin.test.assertContentEquals
1114
import kotlin.test.assertEquals
@@ -15,6 +18,7 @@ class ParagraphTest {
1518
private val fontCollection = suspend {
1619
FontCollection().setDefaultFontManager(TypefaceFontProvider().apply {
1720
registerTypeface(Typeface.makeFromResource("./fonts/Inter-Hinted-Regular.ttf"), "Inter")
21+
registerTypeface(Typeface.makeFromResource("./fonts/JetBrainsMono_2_304/JetBrainsMono-Regular.ttf"), "JetBrains Mono")
1822
})
1923
}
2024
private val style = ParagraphStyle().apply {
@@ -47,40 +51,43 @@ class ParagraphTest {
4751

4852
@Test
4953
fun layoutParagraph() = runTest {
50-
val lineMetricsEpsilon = 0.0001f
54+
val lineMetricsEpsilon = 0.001f
5155

5256
assertCloseEnough(
53-
singleLineMetrics("aa"), LineMetrics(
57+
actual = singleLineMetrics("aa"),
58+
expected = LineMetrics(
5459
startIndex = 0,
5560
endIndex = 2,
5661
endExcludingWhitespaces = 2,
5762
endIncludingNewline = 2,
5863
isHardBreak = true,
5964
ascent = 13.5625,
60-
descent = 3.3806817531585693,
65+
descent = 3.380584716796875,
6166
unscaledAscent = 13.5625,
6267
height = 17.0,
63-
width = 15.789999961853027,
68+
width = 15.789764404296875,
6469
left = 0.0,
65-
baseline = 13.619318008422852,
70+
baseline = 13.619415283203125,
6671
lineNumber = 0
6772
), epsilon = lineMetricsEpsilon
6873
)
6974

75+
7076
assertCloseEnough(
71-
singleLineMetrics("яя"), LineMetrics(
77+
actual = singleLineMetrics("яя"),
78+
expected = LineMetrics(
7279
startIndex = 0,
7380
endIndex = 2,
7481
endExcludingWhitespaces = 2,
7582
endIncludingNewline = 2,
7683
isHardBreak = true,
7784
ascent = 13.5625,
78-
descent = 3.3806817531585693,
85+
descent = 3.380584716796875,
7986
unscaledAscent = 13.5625,
8087
height = 17.0,
81-
width = 15.710000038146973,
88+
width = 15.710235595703125,
8289
left = 0.0,
83-
baseline = 13.619318008422852,
90+
baseline = 13.619415283203125,
8491
lineNumber = 0
8592
), epsilon = lineMetricsEpsilon
8693
)
@@ -172,4 +179,35 @@ class ParagraphTest {
172179
}
173180
}
174181
}
182+
183+
@Test
184+
fun layout_paragraph_with_its_maxIntrinsicWidth_shouldnt_lead_to_wraps() = runTest {
185+
suspend fun testWraps(isApplyRoundingHackEnabled: Boolean, unexpectedWrapsPresent: Boolean) {
186+
val paragraphStyle = ParagraphStyle().apply {
187+
this.isApplyRoundingHackEnabled = isApplyRoundingHackEnabled
188+
textStyle = TextStyle().apply {
189+
fontFamilies = arrayOf("JetBrains Mono")
190+
fontSize = 13.0f * 2f
191+
}
192+
}
193+
val paragraph = ParagraphBuilder(paragraphStyle, fontCollection()).use {
194+
it.addText("x".repeat(104))
195+
it.addText(" ")
196+
it.addText("y".repeat(100))
197+
it.build()
198+
}.layout(Float.POSITIVE_INFINITY)
199+
assertEquals(1, paragraph.lineNumber, "Layout in one line with Inf width")
200+
201+
val maxIntrinsicWidth = paragraph.maxIntrinsicWidth
202+
val expectedLines = if (unexpectedWrapsPresent) 2 else 1
203+
204+
paragraph.layout(paragraph.maxIntrinsicWidth)
205+
assertEquals(expectedLines, paragraph.lineNumber, "Layout with maxIntrinsicWidth " +
206+
"maxIntrinsicWidth: $maxIntrinsicWidth " +
207+
"unexpectedWrapsPresent: $unexpectedWrapsPresent " +
208+
"isApplyRoundingHackEnabled: $isApplyRoundingHackEnabled")
209+
}
210+
testWraps(isApplyRoundingHackEnabled = false, unexpectedWrapsPresent = false)
211+
testWraps(isApplyRoundingHackEnabled = true, unexpectedWrapsPresent = true)
212+
}
175213
}

skiko/src/commonTest/kotlin/org/jetbrains/skiko/paragraph/ParagraphStyleTests.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,13 @@ class ParagraphStyleTests {
5555
assertEquals(gloriousRasterSettings, paragraphStyle.fontRastrSettings)
5656
}
5757
}
58+
59+
@Test
60+
fun paragraphStyleRoundingHackTests() {
61+
ParagraphStyle().use { paragraphStyle ->
62+
assertEquals(false, paragraphStyle.isApplyRoundingHackEnabled)
63+
paragraphStyle.isApplyRoundingHackEnabled = true
64+
assertEquals(true, paragraphStyle.isApplyRoundingHackEnabled)
65+
}
66+
}
5867
}
Binary file not shown.

skiko/src/jvmMain/cpp/common/paragraph/ParagraphStyle.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_paragraph_ParagraphSt
1919
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt_ParagraphStyle_1nMake
2020
(JNIEnv* env, jclass jclass) {
2121
ParagraphStyle* instance = new ParagraphStyle();
22+
instance->setApplyRoundingHack(false);
2223
return reinterpret_cast<jlong>(instance);
2324
}
2425

@@ -180,6 +181,18 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphSty
180181
instance->turnHintingOff();
181182
}
182183

184+
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nGetApplyRoundingHack
185+
(JNIEnv* env, jclass jclass, jlong ptr) {
186+
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));
187+
return instance->getApplyRoundingHack();
188+
}
189+
190+
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nSetApplyRoundingHack
191+
(JNIEnv* env, jclass jclass, jlong ptr, jboolean val) {
192+
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));
193+
instance->setApplyRoundingHack(val);
194+
}
195+
183196
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_paragraph_ParagraphStyleKt__1nSetTextIndent
184197
(JNIEnv* env, jclass jclass, jlong ptr, jfloat firstLine, jfloat restLine) {
185198
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(static_cast<uintptr_t>(ptr));

skiko/src/nativeJsMain/cpp/paragraph/ParagraphStyle.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_paragraph_ParagraphStyle__1nGetFi
1616
SKIKO_EXPORT KNativePointer org_jetbrains_skia_paragraph_ParagraphStyle__1nMake
1717
() {
1818
ParagraphStyle* instance = new ParagraphStyle();
19+
instance->setApplyRoundingHack(false);
1920
return reinterpret_cast<KNativePointer>(instance);
2021
}
2122

@@ -177,6 +178,18 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_paragraph_ParagraphStyle__1nGetSubpixel
177178
return fontRastrSettings.fSubpixel;
178179
}
179180

181+
SKIKO_EXPORT KBoolean org_jetbrains_skia_paragraph_ParagraphStyle__1nGetApplyRoundingHack
182+
(KNativePointer ptr) {
183+
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(ptr);
184+
return instance->getApplyRoundingHack();
185+
}
186+
187+
SKIKO_EXPORT void org_jetbrains_skia_paragraph_ParagraphStyle__1nSetApplyRoundingHack
188+
(KNativePointer ptr, KBoolean val) {
189+
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>(ptr);
190+
instance->setApplyRoundingHack(val);
191+
}
192+
180193
SKIKO_EXPORT void org_jetbrains_skia_paragraph_ParagraphStyle__1nSetTextIndent
181194
(KNativePointer ptr, KFloat firstLine, KFloat restLine) {
182195
ParagraphStyle* instance = reinterpret_cast<ParagraphStyle*>((ptr));

0 commit comments

Comments
 (0)