Skip to content

Commit 5ff7f24

Browse files
committed
fix: wrong radix multipliers for complex values
1 parent 51b81f8 commit 5ff7f24

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@
2828
public final class ResXmlEncoders {
2929
private static final Logger LOGGER = Logger.getLogger(ResXmlEncoders.class.getName());
3030

31+
private static final String[] DIMENSION_UNIT_STRS = new String[] {
32+
"px", "dp", "sp", "pt", "in", "mm"
33+
};
34+
35+
private static final String[] FRACTION_UNIT_STRS = new String[] {
36+
"%", "%p"
37+
};
38+
39+
private static final float MANTISSA_MULT = 1.0f / (1 << TypedValue.COMPLEX_MANTISSA_SHIFT);
40+
private static final float[] RADIX_MULTS = new float[] {
41+
MANTISSA_MULT,
42+
(1.0f / (1 << 7)) * MANTISSA_MULT,
43+
(1.0f / (1 << 15)) * MANTISSA_MULT,
44+
(1.0f / (1 << 23)) * MANTISSA_MULT
45+
};
46+
3147
private ResXmlEncoders() {
3248
// Private constructor for utility class.
3349
}
@@ -47,9 +63,9 @@ public static String coerceToString(int type, int data) {
4763
case TypedValue.TYPE_FLOAT:
4864
return Float.toString(Float.intBitsToFloat(data));
4965
case TypedValue.TYPE_DIMENSION:
50-
return TypedValue.coerceDimensionToString(data);
66+
return coerceDimensionToString(data);
5167
case TypedValue.TYPE_FRACTION:
52-
return TypedValue.coerceFractionToString(data);
68+
return coerceFractionToString(data);
5369
}
5470

5571
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
@@ -86,6 +102,26 @@ public static String coerceToString(int type, int data) {
86102
return null;
87103
}
88104

105+
private static String coerceDimensionToString(int complex) {
106+
float value = complexToFloat(complex);
107+
int unit = (complex >> TypedValue.COMPLEX_UNIT_SHIFT) & TypedValue.COMPLEX_UNIT_MASK;
108+
String unitStr = unit < DIMENSION_UNIT_STRS.length ? DIMENSION_UNIT_STRS[unit] : "";
109+
return Float.toString(value) + unitStr;
110+
}
111+
112+
private static String coerceFractionToString(int complex) {
113+
float value = complexToFloat(complex) * 100;
114+
int unit = (complex >> TypedValue.COMPLEX_UNIT_SHIFT) & TypedValue.COMPLEX_UNIT_MASK;
115+
String unitStr = unit < FRACTION_UNIT_STRS.length ? FRACTION_UNIT_STRS[unit] : "";
116+
return Float.toString(value) + unitStr;
117+
}
118+
119+
private static float complexToFloat(int complex) {
120+
// AOSP: TypedValue.complexToFloat(int complex)
121+
return (complex & (TypedValue.COMPLEX_MANTISSA_MASK << TypedValue.COMPLEX_MANTISSA_SHIFT))
122+
* RADIX_MULTS[(complex >> TypedValue.COMPLEX_RADIX_SHIFT) & TypedValue.COMPLEX_RADIX_MASK];
123+
}
124+
89125
public static String encodeAsXmlValue(String str) {
90126
if (str == null || str.isEmpty()) {
91127
return str;

0 commit comments

Comments
 (0)