@@ -49,81 +49,97 @@ fun Modifier.outline(
4949 }
5050
5151 is Outline .Rectangle -> {
52- val inset = - offset.toPx()
52+ val geometry = calculateOutlineRectGeometry(
53+ rect = Rect (0f , 0f , size.width, size.height),
54+ strokeWidth = strokeWidth,
55+ offset = offset.toPx(),
56+ )
5357
5458 val path = Path ().apply {
55- addRect(
56- Rect (
57- left = inset - strokeWidth,
58- top = inset - strokeWidth,
59- right = size.width - inset + strokeWidth,
60- bottom = size.height - inset + strokeWidth,
61- ),
62- )
59+ addRect(geometry.outer)
6360 fillType = PathFillType .EvenOdd
64- addRect(
65- Rect (
66- left = inset,
67- top = inset,
68- right = size.width - inset,
69- bottom = size.height - inset,
70- ),
71- )
61+ addRect(geometry.inner)
7262 }
7363
7464 drawPath(path, color)
7565 }
7666
7767 is Outline .Rounded -> {
78- val inset = - offset.toPx()
79- val roundRect = outline.roundRect
80-
81- val topLeftRadius = roundRect.topLeftCornerRadius.x
82- val topRightRadius = roundRect.topRightCornerRadius.x
83- val bottomRightRadius = roundRect.bottomRightCornerRadius.x
84- val bottomLeftRadius = roundRect.bottomLeftCornerRadius.y
85-
86- val topLeftOutlineRadius = topLeftRadius + strokeWidth
87- val topRightOutlineRadius = topRightRadius + strokeWidth
88- val bottomRightOutlineRadius = bottomRightRadius + strokeWidth
89- val bottomLeftOutlineRadius = bottomLeftRadius + strokeWidth
68+ val geometry = calculateOutlineRoundRectGeometry(
69+ roundRect = outline.roundRect,
70+ strokeWidth = strokeWidth,
71+ offset = offset.toPx(),
72+ )
9073
9174 val path = Path ().apply {
92- addRoundRect(
93- RoundRect (
94- left = inset - strokeWidth,
95- top = inset - strokeWidth,
96- right = size.width - inset + strokeWidth,
97- bottom = size.height - inset + strokeWidth,
98- topLeftCornerRadius = CornerRadius (topLeftOutlineRadius, topLeftOutlineRadius),
99- topRightCornerRadius = CornerRadius (topRightOutlineRadius, topRightOutlineRadius),
100- bottomRightCornerRadius = CornerRadius (
101- bottomRightOutlineRadius,
102- bottomRightOutlineRadius,
103- ),
104- bottomLeftCornerRadius = CornerRadius (
105- bottomLeftOutlineRadius,
106- bottomLeftOutlineRadius,
107- ),
108- ),
109- )
75+ addRoundRect(geometry.outer)
11076 fillType = PathFillType .EvenOdd
111- addRoundRect(
112- RoundRect (
113- left = inset,
114- top = inset,
115- right = size.width - inset,
116- bottom = size.height - inset,
117- topLeftCornerRadius = CornerRadius (topLeftRadius, topLeftRadius),
118- topRightCornerRadius = CornerRadius (topRightRadius, topRightRadius),
119- bottomRightCornerRadius = CornerRadius (bottomRightRadius, bottomRightRadius),
120- bottomLeftCornerRadius = CornerRadius (bottomLeftRadius, bottomLeftRadius),
121- ),
122- )
77+ addRoundRect(geometry.inner)
12378 }
12479
12580 drawPath(path, color)
12681 }
12782 }
12883 }
12984}
85+
86+ internal data class OutlineRectGeometry (
87+ val inner : Rect ,
88+ val outer : Rect ,
89+ )
90+
91+ internal data class OutlineRoundRectGeometry (
92+ val inner : RoundRect ,
93+ val outer : RoundRect ,
94+ )
95+
96+ internal fun calculateOutlineRectGeometry (
97+ rect : Rect ,
98+ strokeWidth : Float ,
99+ offset : Float ,
100+ ): OutlineRectGeometry {
101+ return OutlineRectGeometry (
102+ inner = rect.inflate(offset),
103+ outer = rect.inflate(offset + strokeWidth),
104+ )
105+ }
106+
107+ internal fun calculateOutlineRoundRectGeometry (
108+ roundRect : RoundRect ,
109+ strokeWidth : Float ,
110+ offset : Float ,
111+ ): OutlineRoundRectGeometry {
112+ return OutlineRoundRectGeometry (
113+ inner = roundRect.inflate(offset),
114+ outer = roundRect.inflate(offset + strokeWidth),
115+ )
116+ }
117+
118+ private fun Rect.inflate (amount : Float ): Rect {
119+ return Rect (
120+ left = left - amount,
121+ top = top - amount,
122+ right = right + amount,
123+ bottom = bottom + amount,
124+ )
125+ }
126+
127+ private fun RoundRect.inflate (amount : Float ): RoundRect {
128+ return RoundRect (
129+ left = left - amount,
130+ top = top - amount,
131+ right = right + amount,
132+ bottom = bottom + amount,
133+ topLeftCornerRadius = topLeftCornerRadius.inflate(amount),
134+ topRightCornerRadius = topRightCornerRadius.inflate(amount),
135+ bottomRightCornerRadius = bottomRightCornerRadius.inflate(amount),
136+ bottomLeftCornerRadius = bottomLeftCornerRadius.inflate(amount),
137+ )
138+ }
139+
140+ private fun CornerRadius.inflate (amount : Float ): CornerRadius {
141+ return CornerRadius (
142+ x = (x + amount).coerceAtLeast(0f ),
143+ y = (y + amount).coerceAtLeast(0f ),
144+ )
145+ }
0 commit comments