Skip to content

Commit 99b7098

Browse files
aklm11facebook-github-bot
authored andcommitted
Add mul/div by scaler to Dimen
Summary: Support multiplication/division of `Dimen` by non-dimensional scaler: ```Kotlin 1.px * 42.0 // 42.px val padding = component.gap / 2.0 ``` Reviewed By: zielinskimz Differential Revision: D59061617 fbshipit-source-id: 6c551cfce034cba58a17e8c9612965943b8d3624
1 parent ac6db37 commit 99b7098

File tree

2 files changed

+118
-0
lines changed
  • litho-rendercore/src

2 files changed

+118
-0
lines changed

litho-rendercore/src/main/java/com/facebook/rendercore/Dimen.kt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,86 @@ value class Dimen @PublishedApi internal constructor(val encodedValue: Long) {
4949
else -> "NaN"
5050
}
5151
}
52+
53+
operator fun times(other: Double): Dimen {
54+
return Dimen(
55+
when {
56+
// DP case
57+
encodedValue and NAN_MASK != NAN_MASK ->
58+
doubleToRawLongBits(longBitsToDouble(encodedValue) * other)
59+
// PX case
60+
encodedValue and PX_FLAG == PX_FLAG ->
61+
encodePxInt(((encodedValue and PAYLOAD_MASK).toInt() * other).toInt())
62+
// SP case
63+
encodedValue and SP_FLAG == SP_FLAG ->
64+
encodeSpFloat(
65+
(intBitsToFloat((encodedValue and PAYLOAD_MASK).toInt()) * other).toFloat())
66+
else -> doubleToRawLongBits(Double.NaN)
67+
})
68+
}
69+
70+
operator fun times(other: Float): Dimen {
71+
return Dimen(
72+
when {
73+
// DP case
74+
encodedValue and NAN_MASK != NAN_MASK ->
75+
doubleToRawLongBits(longBitsToDouble(encodedValue) * other)
76+
// PX case
77+
encodedValue and PX_FLAG == PX_FLAG ->
78+
encodePxInt(((encodedValue and PAYLOAD_MASK).toInt() * other).toInt())
79+
// SP case
80+
encodedValue and SP_FLAG == SP_FLAG ->
81+
encodeSpFloat(
82+
(intBitsToFloat((encodedValue and PAYLOAD_MASK).toInt()) * other).toFloat())
83+
else -> doubleToRawLongBits(Double.NaN)
84+
})
85+
}
86+
87+
operator fun times(other: Int): Dimen {
88+
return Dimen(
89+
when {
90+
// DP case
91+
encodedValue and NAN_MASK != NAN_MASK ->
92+
doubleToRawLongBits(longBitsToDouble(encodedValue) * other)
93+
// PX case
94+
encodedValue and PX_FLAG == PX_FLAG ->
95+
encodePxInt((encodedValue and PAYLOAD_MASK).toInt() * other)
96+
// SP case
97+
encodedValue and SP_FLAG == SP_FLAG ->
98+
encodeSpFloat(intBitsToFloat(encodedValue.and(PAYLOAD_MASK).toInt()) * other)
99+
else -> doubleToRawLongBits(Double.NaN)
100+
})
101+
}
102+
103+
operator fun div(other: Double): Dimen = this * (1.0 / other)
104+
105+
operator fun div(other: Float): Dimen = this * (1f / other)
106+
107+
operator fun div(other: Int): Dimen {
108+
return Dimen(
109+
when {
110+
// DP case
111+
encodedValue and NAN_MASK != NAN_MASK ->
112+
doubleToRawLongBits(longBitsToDouble(encodedValue) / other)
113+
// PX case
114+
encodedValue and PX_FLAG == PX_FLAG ->
115+
encodePxInt((encodedValue and PAYLOAD_MASK).toInt() / other)
116+
// SP case
117+
encodedValue and SP_FLAG == SP_FLAG ->
118+
encodeSpFloat(intBitsToFloat(encodedValue.and(PAYLOAD_MASK).toInt()) / other)
119+
else -> doubleToRawLongBits(Double.NaN)
120+
})
121+
}
122+
123+
operator fun unaryMinus(): Dimen = this * -1
52124
}
53125

126+
operator fun Double.times(other: Dimen): Dimen = other * this
127+
128+
operator fun Float.times(other: Dimen): Dimen = other * this
129+
130+
operator fun Int.times(other: Dimen): Dimen = other * this
131+
54132
/** Creates a Dimen with a constant dp (density-independent pixels) value. */
55133
inline val Int.dp: Dimen
56134
get() = Dimen(doubleToRawLongBits(this.toDouble()))

litho-rendercore/src/test/java/com/facebook/rendercore/DimenTest.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,46 @@ class DimenTest {
197197
Dimen(Double.NaN.toRawBits()).toPixels(resourceResolver)
198198
}
199199

200+
@Test
201+
fun `dimen mul div`() {
202+
assertThat(10.sp * 5.0).isEqualTo(50.sp)
203+
assertThat(10.dp * 5.0).isEqualTo(50.dp)
204+
assertThat(10.px * 5.0).isEqualTo(50.px)
205+
assertThat(5.0 * 10.sp).isEqualTo(50.sp)
206+
assertThat(5.0 * 10.dp).isEqualTo(50.dp)
207+
assertThat(5.0 * 10.px).isEqualTo(50.px)
208+
209+
assertThat(10.sp / 2.0).isEqualTo(5.sp)
210+
assertThat(10.dp / 2.0).isEqualTo(5.dp)
211+
assertThat(10.px / 2.0).isEqualTo(5.px)
212+
213+
assertThat(10.sp * 5f).isEqualTo(50.sp)
214+
assertThat(10.dp * 5f).isEqualTo(50.dp)
215+
assertThat(10.px * 5f).isEqualTo(50.px)
216+
assertThat(5f * 10.sp).isEqualTo(50.sp)
217+
assertThat(5f * 10.dp).isEqualTo(50.dp)
218+
assertThat(5f * 10.px).isEqualTo(50.px)
219+
220+
assertThat(10.sp / 2f).isEqualTo(5.sp)
221+
assertThat(10.dp / 2f).isEqualTo(5.dp)
222+
assertThat(10.px / 2f).isEqualTo(5.px)
223+
224+
assertThat(10.sp * 5).isEqualTo(50.sp)
225+
assertThat(10.dp * 5).isEqualTo(50.dp)
226+
assertThat(10.px * 5).isEqualTo(50.px)
227+
assertThat(5 * 10.sp).isEqualTo(50.sp)
228+
assertThat(5 * 10.dp).isEqualTo(50.dp)
229+
assertThat(5 * 10.px).isEqualTo(50.px)
230+
231+
assertThat(10.sp / 2).isEqualTo(5.sp)
232+
assertThat(10.dp / 2).isEqualTo(5.dp)
233+
assertThat(10.px / 2).isEqualTo(5.px)
234+
235+
assertThat(-(10.sp)).isEqualTo((-10).sp)
236+
assertThat(-(10.dp)).isEqualTo((-10).dp)
237+
assertThat(-(10.px)).isEqualTo((-10).px)
238+
}
239+
200240
private class MockResourceResolver(val density: Float, val scaledDensity: Float) :
201241
ResourceResolver(
202242
ApplicationProvider.getApplicationContext<Context>(),

0 commit comments

Comments
 (0)