Skip to content

Commit e62d095

Browse files
authored
Update skia to m144 (JetBrains#2779)
[SKIKO-1094](https://youtrack.jetbrains.com/issue/SKIKO-1094) Update skia to m144 JetBrains/skiko#1154 ## Release Notes ### Features - Multiple Platforms - Update skia to m144
1 parent d7673d2 commit e62d095

5 files changed

Lines changed: 114 additions & 87 deletions

File tree

compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedPath.skiko.kt

Lines changed: 93 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.compose.ui.geometry.Rect
2121
import androidx.compose.ui.geometry.RoundRect
2222
import org.jetbrains.skia.Matrix33
2323
import org.jetbrains.skia.PathDirection
24+
import org.jetbrains.skia.PathBuilder
2425
import org.jetbrains.skia.PathFillMode
2526
import org.jetbrains.skia.PathOp
2627

@@ -49,6 +50,17 @@ internal class SkiaBackedPath(
4950
) : Path {
5051
var internalPath = internalPath
5152
private set
53+
private var pathBuilder = PathBuilder(internalPath)
54+
55+
private inline fun mutatePath(block: PathBuilder.() -> Unit) {
56+
pathBuilder.apply(block)
57+
internalPath = pathBuilder.snapshot()
58+
}
59+
60+
private fun replacePath(path: org.jetbrains.skia.Path) {
61+
internalPath = path
62+
pathBuilder = PathBuilder(path)
63+
}
5264

5365
override var fillType: PathFillType
5466
get() {
@@ -60,53 +72,63 @@ internal class SkiaBackedPath(
6072
}
6173

6274
set(value) {
63-
internalPath.fillMode =
75+
pathBuilder.setFillType(
6476
if (value == PathFillType.EvenOdd) {
6577
PathFillMode.EVEN_ODD
6678
} else {
6779
PathFillMode.WINDING
6880
}
81+
)
82+
internalPath = pathBuilder.snapshot()
6983
}
7084

71-
override fun moveTo(x: Float, y: Float) {
72-
internalPath.moveTo(x, y)
85+
override fun moveTo(x: Float, y: Float) = mutatePath {
86+
moveTo(x, y)
7387
}
7488

75-
override fun relativeMoveTo(dx: Float, dy: Float) {
76-
internalPath.rMoveTo(dx, dy)
89+
override fun relativeMoveTo(dx: Float, dy: Float) = mutatePath {
90+
rMoveTo(dx, dy)
7791
}
7892

79-
override fun lineTo(x: Float, y: Float) {
80-
internalPath.lineTo(x, y)
93+
override fun lineTo(x: Float, y: Float) = mutatePath {
94+
lineTo(x, y)
8195
}
8296

83-
override fun relativeLineTo(dx: Float, dy: Float) {
84-
internalPath.rLineTo(dx, dy)
97+
override fun relativeLineTo(dx: Float, dy: Float) = mutatePath {
98+
rLineTo(dx, dy)
8599
}
86100

87-
override fun quadraticBezierTo(x1: Float, y1: Float, x2: Float, y2: Float) {
88-
internalPath.quadTo(x1, y1, x2, y2)
89-
}
90-
91-
override fun quadraticTo(x1: Float, y1: Float, x2: Float, y2: Float) {
92-
internalPath.quadTo(x1, y1, x2, y2)
93-
}
94-
95-
override fun relativeQuadraticBezierTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float) {
96-
internalPath.rQuadTo(dx1, dy1, dx2, dy2)
97-
}
101+
@Deprecated(
102+
"Use quadraticTo() for consistency with cubicTo()",
103+
replaceWith = ReplaceWith("quadraticTo(x1, y1, x2, y2)"),
104+
level = DeprecationLevel.WARNING,
105+
)
106+
override fun quadraticBezierTo(x1: Float, y1: Float, x2: Float, y2: Float) =
107+
mutatePath { quadTo(x1, y1, x2, y2) }
108+
109+
override fun quadraticTo(x1: Float, y1: Float, x2: Float, y2: Float) =
110+
mutatePath { quadTo(x1, y1, x2, y2) }
111+
112+
@Deprecated(
113+
"Use relativeQuadraticTo() for consistency with relativeCubicTo()",
114+
replaceWith = ReplaceWith("relativeQuadraticTo(dx1, dy1, dx2, dy2)"),
115+
level = DeprecationLevel.WARNING,
116+
)
117+
override fun relativeQuadraticBezierTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float) =
118+
mutatePath { rQuadTo(dx1, dy1, dx2, dy2) }
98119

99120
override fun relativeQuadraticTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float) {
100-
internalPath.rQuadTo(dx1, dy1, dx2, dy2)
121+
mutatePath { rQuadTo(dx1, dy1, dx2, dy2) }
101122
}
102123

103-
override fun cubicTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) {
104-
internalPath.cubicTo(
105-
x1, y1,
106-
x2, y2,
107-
x3, y3
108-
)
109-
}
124+
override fun cubicTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) =
125+
mutatePath {
126+
cubicTo(
127+
x1, y1,
128+
x2, y2,
129+
x3, y3
130+
)
131+
}
110132

111133
override fun relativeCubicTo(
112134
dx1: Float,
@@ -115,8 +137,8 @@ internal class SkiaBackedPath(
115137
dy2: Float,
116138
dx3: Float,
117139
dy3: Float
118-
) {
119-
internalPath.rCubicTo(
140+
) = mutatePath {
141+
rCubicTo(
120142
dx1, dy1,
121143
dx2, dy2,
122144
dx3, dy3
@@ -128,8 +150,8 @@ internal class SkiaBackedPath(
128150
startAngleDegrees: Float,
129151
sweepAngleDegrees: Float,
130152
forceMoveTo: Boolean
131-
) {
132-
internalPath.arcTo(
153+
) = mutatePath {
154+
arcTo(
133155
rect.left,
134156
rect.top,
135157
rect.right,
@@ -140,8 +162,13 @@ internal class SkiaBackedPath(
140162
)
141163
}
142164

143-
override fun addRect(rect: Rect) {
144-
internalPath.addRect(
165+
@Deprecated(
166+
"Prefer usage of addRect() with a winding direction",
167+
replaceWith = ReplaceWith("addRect(rect)"),
168+
level = DeprecationLevel.HIDDEN,
169+
)
170+
override fun addRect(rect: Rect) = mutatePath {
171+
addRect(
145172
rect.left,
146173
rect.top,
147174
rect.right,
@@ -150,8 +177,8 @@ internal class SkiaBackedPath(
150177
)
151178
}
152179

153-
override fun addRect(rect: Rect, direction: Path.Direction) {
154-
internalPath.addRect(
180+
override fun addRect(rect: Rect, direction: Path.Direction) = mutatePath {
181+
addRect(
155182
rect.left,
156183
rect.top,
157184
rect.right,
@@ -160,8 +187,8 @@ internal class SkiaBackedPath(
160187
)
161188
}
162189

163-
override fun addOval(oval: Rect) {
164-
internalPath.addOval(
190+
override fun addOval(oval: Rect) = mutatePath {
191+
addOval(
165192
oval.left,
166193
oval.top,
167194
oval.right,
@@ -170,8 +197,8 @@ internal class SkiaBackedPath(
170197
)
171198
}
172199

173-
override fun addOval(oval: Rect, direction: Path.Direction) {
174-
internalPath.addOval(
200+
override fun addOval(oval: Rect, direction: Path.Direction) = mutatePath {
201+
addOval(
175202
oval.left,
176203
oval.top,
177204
oval.right,
@@ -180,8 +207,8 @@ internal class SkiaBackedPath(
180207
)
181208
}
182209

183-
override fun addRoundRect(roundRect: RoundRect) {
184-
internalPath.addRRect(
210+
override fun addRoundRect(roundRect: RoundRect) = mutatePath {
211+
addRRect(
185212
roundRect.left,
186213
roundRect.top,
187214
roundRect.right,
@@ -200,8 +227,8 @@ internal class SkiaBackedPath(
200227
)
201228
}
202229

203-
override fun addRoundRect(roundRect: RoundRect, direction: Path.Direction) {
204-
internalPath.addRRect(
230+
override fun addRoundRect(roundRect: RoundRect, direction: Path.Direction) = mutatePath {
231+
addRRect(
205232
roundRect.left,
206233
roundRect.top,
207234
roundRect.right,
@@ -224,42 +251,41 @@ internal class SkiaBackedPath(
224251
addArc(oval, degrees(startAngleRadians), degrees(sweepAngleRadians))
225252
}
226253

227-
override fun addArc(oval: Rect, startAngleDegrees: Float, sweepAngleDegrees: Float) {
228-
internalPath.addArc(
254+
override fun addArc(oval: Rect, startAngleDegrees: Float, sweepAngleDegrees: Float) = mutatePath {
255+
addArc(
229256
oval.left,
230257
oval.top,
231258
oval.right,
232259
oval.bottom,
233-
startAngleDegrees, sweepAngleDegrees
260+
startAngleDegrees,
261+
sweepAngleDegrees
234262
)
235263
}
236264

237-
override fun addPath(path: Path, offset: Offset) {
238-
internalPath.addPath(path.asSkiaPath(), offset.x, offset.y)
239-
}
265+
override fun addPath(path: Path, offset: Offset) =
266+
mutatePath { addPath(path.asSkiaPath(), offset.x, offset.y) }
240267

241-
override fun close() {
242-
internalPath.closePath()
268+
override fun close() = mutatePath {
269+
closePath()
243270
}
244271

245272
override fun reset() {
246-
// preserve fillType to match the Android behavior
247-
// see https://cs.android.com/android/_/android/platform/frameworks/base/+/d0f379c1976c600313f1f4c39f2587a649e3a4fc
248-
val fillType = this.fillType
249-
internalPath.reset()
250-
this.fillType = fillType
251-
}
252-
253-
override fun rewind() {
254-
internalPath.rewind()
273+
val fillMode = internalPath.fillMode
274+
pathBuilder.reset().setFillType(fillMode)
275+
internalPath = pathBuilder.snapshot()
255276
}
256277

257278
override fun translate(offset: Offset) {
258-
internalPath.transform(Matrix33.makeTranslate(offset.x, offset.y))
279+
pathBuilder = PathBuilder(internalPath.fillMode)
280+
.addPath(internalPath, offset.x, offset.y)
281+
internalPath = pathBuilder.snapshot()
259282
}
260283

261284
override fun transform(matrix: Matrix) {
262-
internalPath.transform(Matrix33.makeTranslate(0f, 0f).apply { setFrom(matrix) })
285+
val skiaMatrix = Matrix33.makeTranslate(0f, 0f).apply { setFrom(matrix) }
286+
pathBuilder = PathBuilder(internalPath.fillMode)
287+
.addPath(internalPath, skiaMatrix)
288+
internalPath = pathBuilder.snapshot()
263289
}
264290

265291
override fun getBounds(): Rect {
@@ -283,7 +309,9 @@ internal class SkiaBackedPath(
283309
operation.toSkiaOperation()
284310
)
285311

286-
internalPath = path ?: internalPath
312+
if (path != null) {
313+
replacePath(path)
314+
}
287315
return path != null
288316
}
289317

@@ -304,4 +332,4 @@ internal class SkiaBackedPath(
304332
private fun Path.Direction.toSkiaPathDirection() = when (this) {
305333
Path.Direction.CounterClockwise -> PathDirection.COUNTER_CLOCKWISE
306334
Path.Direction.Clockwise -> PathDirection.CLOCKWISE
307-
}
335+
}

compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/FontRasterizationSettings.skiko.kt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package androidx.compose.ui.text
1818

1919
import androidx.compose.ui.text.platform.Platform
2020
import androidx.compose.ui.text.platform.currentPlatform
21-
import org.jetbrains.skia.paragraph.FontRastrSettings
2221

2322
/**
2423
* Whether edge pixels draw opaque or with partial transparency.
@@ -153,11 +152,3 @@ internal fun FontHinting.toSkFontHinting() = when (this) {
153152
FontHinting.Normal -> org.jetbrains.skia.FontHinting.NORMAL
154153
FontHinting.Full -> org.jetbrains.skia.FontHinting.FULL
155154
}
156-
157-
@OptIn(ExperimentalTextApi::class)
158-
internal fun FontRasterizationSettings.toSkFontRastrSettings() = FontRastrSettings(
159-
edging = smoothing.toSkFontEdging(),
160-
hinting = hinting.toSkFontHinting(),
161-
subpixel = subpixelPositioning
162-
// rasterizationSettings.autoHintingForced is ignored here for now because it's not supported in skia
163-
)

compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import androidx.compose.ui.graphics.Canvas
2626
import androidx.compose.ui.graphics.Color
2727
import androidx.compose.ui.graphics.Path
2828
import androidx.compose.ui.graphics.Shadow
29+
import androidx.compose.ui.graphics.asComposePath
2930
import androidx.compose.ui.graphics.asSkiaPath
3031
import androidx.compose.ui.graphics.drawscope.DrawStyle
3132
import androidx.compose.ui.graphics.nativeCanvas
@@ -43,6 +44,7 @@ import androidx.compose.ui.unit.isUnspecified
4344
import kotlin.math.floor
4445
import org.jetbrains.skia.FontMetrics
4546
import org.jetbrains.skia.IRange
47+
import org.jetbrains.skia.PathBuilder
4648
import org.jetbrains.skia.paragraph.Direction
4749
import org.jetbrains.skia.paragraph.LineMetrics
4850
import org.jetbrains.skia.paragraph.RectHeightMode
@@ -170,11 +172,11 @@ internal class SkiaParagraph(
170172
RectHeightMode.MAX,
171173
RectWidthMode.TIGHT
172174
)
173-
val path = Path()
175+
val pathBuilder = PathBuilder()
174176
for (b in boxes) {
175-
path.asSkiaPath().addRect(b.rect.left, b.rect.top, b.rect.right, b.rect.bottom)
177+
pathBuilder.addRect(b.rect.left, b.rect.top, b.rect.right, b.rect.bottom)
176178
}
177-
return path
179+
return pathBuilder.detach().asComposePath()
178180
}
179181

180182
override fun getCursorRect(offset: Int): Rect {

0 commit comments

Comments
 (0)