1 /*
<lambda>null2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.compose.ui.graphics
18
19 import android.graphics.ColorSpace.get
20 import android.os.Build
21 import androidx.annotation.RequiresApi
22 import androidx.compose.ui.graphics.ColorSpaceVerificationHelper.composeColorSpace
23 import androidx.compose.ui.graphics.colorspace.ColorSpace
24 import androidx.compose.ui.graphics.colorspace.ColorSpaces
25 import androidx.compose.ui.graphics.colorspace.Rgb
26 import androidx.compose.ui.graphics.colorspace.TransferParameters
27 import androidx.compose.ui.graphics.colorspace.WhitePoint
28
29 /** Convert the Compose [ColorSpace] into an Android framework [android.graphics.ColorSpace] */
30 @RequiresApi(Build.VERSION_CODES.O)
31 fun ColorSpace.toAndroidColorSpace(): android.graphics.ColorSpace =
32 with(ColorSpaceVerificationHelper) { androidColorSpace() }
33
34 /** Convert the [android.graphics.ColorSpace] into a Compose [ColorSpace] */
35 @RequiresApi(Build.VERSION_CODES.O)
toComposeColorSpacenull36 fun android.graphics.ColorSpace.toComposeColorSpace() =
37 with(ColorSpaceVerificationHelper) { composeColorSpace() }
38
39 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
40 private object ColorSpaceVerificationHelperV34 {
41
42 @JvmStatic
obtainAndroidColorSpacenull43 fun obtainAndroidColorSpace(colorSpace: ColorSpace): android.graphics.ColorSpace? =
44 when (colorSpace) {
45 ColorSpaces.Bt2020Hlg -> get(android.graphics.ColorSpace.Named.BT2020_HLG)
46 ColorSpaces.Bt2020Pq -> get(android.graphics.ColorSpace.Named.BT2020_PQ)
47 else -> null
48 }
49
50 @JvmStatic
obtainComposeColorSpaceFromIdnull51 fun obtainComposeColorSpaceFromId(id: Int): ColorSpace =
52 when (id) {
53 android.graphics.ColorSpace.Named.BT2020_HLG.ordinal -> ColorSpaces.Bt2020Hlg
54 android.graphics.ColorSpace.Named.BT2020_PQ.ordinal -> ColorSpaces.Bt2020Pq
55 else -> ColorSpaces.Unspecified
56 }
57 }
58
59 @RequiresApi(Build.VERSION_CODES.O)
60 private object ColorSpaceVerificationHelper {
61
62 @JvmStatic
63 @RequiresApi(Build.VERSION_CODES.O)
ColorSpacenull64 fun ColorSpace.androidColorSpace(): android.graphics.ColorSpace {
65 return when (this) {
66 ColorSpaces.Srgb -> get(android.graphics.ColorSpace.Named.SRGB)
67 ColorSpaces.Aces -> get(android.graphics.ColorSpace.Named.ACES)
68 ColorSpaces.Acescg -> get(android.graphics.ColorSpace.Named.ACESCG)
69 ColorSpaces.AdobeRgb -> get(android.graphics.ColorSpace.Named.ADOBE_RGB)
70 ColorSpaces.Bt2020 -> get(android.graphics.ColorSpace.Named.BT2020)
71 ColorSpaces.Bt709 -> get(android.graphics.ColorSpace.Named.BT709)
72 ColorSpaces.CieLab -> get(android.graphics.ColorSpace.Named.CIE_LAB)
73 ColorSpaces.CieXyz -> get(android.graphics.ColorSpace.Named.CIE_XYZ)
74 ColorSpaces.DciP3 -> get(android.graphics.ColorSpace.Named.DCI_P3)
75 ColorSpaces.DisplayP3 -> get(android.graphics.ColorSpace.Named.DISPLAY_P3)
76 ColorSpaces.ExtendedSrgb -> get(android.graphics.ColorSpace.Named.EXTENDED_SRGB)
77 ColorSpaces.LinearExtendedSrgb ->
78 get(android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB)
79 ColorSpaces.LinearSrgb -> get(android.graphics.ColorSpace.Named.LINEAR_SRGB)
80 ColorSpaces.Ntsc1953 -> get(android.graphics.ColorSpace.Named.NTSC_1953)
81 ColorSpaces.ProPhotoRgb -> get(android.graphics.ColorSpace.Named.PRO_PHOTO_RGB)
82 ColorSpaces.SmpteC -> get(android.graphics.ColorSpace.Named.SMPTE_C)
83 else -> {
84 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
85 val v34ColorSpace =
86 ColorSpaceVerificationHelperV34.obtainAndroidColorSpace(this)
87 if (v34ColorSpace != null) {
88 return v34ColorSpace
89 }
90 }
91 if (this is Rgb) {
92 val whitePointArray = this.whitePoint.toXyz()
93 val transferParams = this.transferParameters
94 val androidTransferParams =
95 if (transferParams != null) {
96 android.graphics.ColorSpace.Rgb.TransferParameters(
97 transferParams.a,
98 transferParams.b,
99 transferParams.c,
100 transferParams.d,
101 transferParams.e,
102 transferParams.f,
103 transferParams.gamma
104 )
105 } else {
106 null
107 }
108 if (androidTransferParams != null) {
109 android.graphics.ColorSpace.Rgb(
110 this.name,
111 this.primaries,
112 whitePointArray,
113 androidTransferParams
114 )
115 } else {
116 android.graphics.ColorSpace.Rgb(
117 this.name,
118 this.primaries,
119 whitePointArray,
120 this.oetf,
121 this.eotf,
122 this.getMinValue(0),
123 this.getMaxValue(0)
124 )
125 }
126 } else {
127 get(android.graphics.ColorSpace.Named.SRGB)
128 }
129 }
130 }
131 }
132
133 @JvmStatic
134 @RequiresApi(Build.VERSION_CODES.O)
composeColorSpacenull135 fun android.graphics.ColorSpace.composeColorSpace(): ColorSpace {
136 return when (this.id) {
137 android.graphics.ColorSpace.Named.SRGB.ordinal -> ColorSpaces.Srgb
138 android.graphics.ColorSpace.Named.ACES.ordinal -> ColorSpaces.Aces
139 android.graphics.ColorSpace.Named.ACESCG.ordinal -> ColorSpaces.Acescg
140 android.graphics.ColorSpace.Named.ADOBE_RGB.ordinal -> ColorSpaces.AdobeRgb
141 android.graphics.ColorSpace.Named.BT2020.ordinal -> ColorSpaces.Bt2020
142 android.graphics.ColorSpace.Named.BT709.ordinal -> ColorSpaces.Bt709
143 android.graphics.ColorSpace.Named.CIE_LAB.ordinal -> ColorSpaces.CieLab
144 android.graphics.ColorSpace.Named.CIE_XYZ.ordinal -> ColorSpaces.CieXyz
145 android.graphics.ColorSpace.Named.DCI_P3.ordinal -> ColorSpaces.DciP3
146 android.graphics.ColorSpace.Named.DISPLAY_P3.ordinal -> ColorSpaces.DisplayP3
147 android.graphics.ColorSpace.Named.EXTENDED_SRGB.ordinal -> ColorSpaces.ExtendedSrgb
148 android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB.ordinal ->
149 ColorSpaces.LinearExtendedSrgb
150 android.graphics.ColorSpace.Named.LINEAR_SRGB.ordinal -> ColorSpaces.LinearSrgb
151 android.graphics.ColorSpace.Named.NTSC_1953.ordinal -> ColorSpaces.Ntsc1953
152 android.graphics.ColorSpace.Named.PRO_PHOTO_RGB.ordinal -> ColorSpaces.ProPhotoRgb
153 android.graphics.ColorSpace.Named.SMPTE_C.ordinal -> ColorSpaces.SmpteC
154 else -> {
155 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
156 val v34ColorSpace =
157 ColorSpaceVerificationHelperV34.obtainComposeColorSpaceFromId(this.id)
158 if (v34ColorSpace != ColorSpaces.Unspecified) {
159 return v34ColorSpace
160 }
161 }
162 if (this is android.graphics.ColorSpace.Rgb) {
163 val transferParams = this.transferParameters
164 val whitePoint =
165 if (this.whitePoint.size == 3) {
166 WhitePoint(this.whitePoint[0], this.whitePoint[1], this.whitePoint[2])
167 } else {
168 WhitePoint(this.whitePoint[0], this.whitePoint[1])
169 }
170
171 val composeTransferParams =
172 if (transferParams != null) {
173 TransferParameters(
174 gamma = transferParams.g,
175 a = transferParams.a,
176 b = transferParams.b,
177 c = transferParams.c,
178 d = transferParams.d,
179 e = transferParams.e,
180 f = transferParams.f
181 )
182 } else {
183 null
184 }
185 Rgb(
186 name = this.name,
187 primaries = this.primaries,
188 whitePoint = whitePoint,
189 transform = this.transform,
190 oetf = { x -> this.oetf.applyAsDouble(x) },
191 eotf = { x -> this.eotf.applyAsDouble(x) },
192 min = this.getMinValue(0),
193 max = this.getMaxValue(0),
194 transferParameters = composeTransferParams,
195 id = this.id
196 )
197 } else {
198 ColorSpaces.Srgb
199 }
200 }
201 }
202 }
203 }
204