1 /*
2  * Copyright (C) 2024 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 com.android.systemui.shared.clocks
18 
19 import android.content.Context
20 import android.util.TypedValue
21 import java.util.regex.Pattern
22 
23 class DimensionParser(private val ctx: Context) {
convertnull24     fun convert(dimension: String?): Float? {
25         if (dimension == null) {
26             return null
27         }
28         return convert(dimension)
29     }
30 
convertnull31     fun convert(dimension: String): Float {
32         val metrics = ctx.resources.displayMetrics
33         val (value, unit) = parse(dimension)
34         return TypedValue.applyDimension(unit, value, metrics)
35     }
36 
parsenull37     fun parse(dimension: String): Pair<Float, Int> {
38         val matcher = parserPattern.matcher(dimension)
39         if (!matcher.matches()) {
40             throw NumberFormatException("Failed to parse '$dimension'")
41         }
42 
43         val value =
44             matcher.group(1)?.toFloat() ?: throw NumberFormatException("Bad value in '$dimension'")
45         val unit =
46             dimensionMap.get(matcher.group(3) ?: "")
47                 ?: throw NumberFormatException("Bad unit in '$dimension'")
48         return Pair(value, unit)
49     }
50 
51     private companion object {
52         val parserPattern = Pattern.compile("(\\d+(\\.\\d+)?)([a-z]+)")
53         val dimensionMap =
54             mapOf(
55                 "dp" to TypedValue.COMPLEX_UNIT_DIP,
56                 "dip" to TypedValue.COMPLEX_UNIT_DIP,
57                 "sp" to TypedValue.COMPLEX_UNIT_SP,
58                 "px" to TypedValue.COMPLEX_UNIT_PX,
59                 "pt" to TypedValue.COMPLEX_UNIT_PT,
60                 "mm" to TypedValue.COMPLEX_UNIT_MM,
61                 "in" to TypedValue.COMPLEX_UNIT_IN,
62             )
63     }
64 }
65