From 3d4fe269a50d7c1561b5cd6e338965baf3bd5618 Mon Sep 17 00:00:00 2001 From: REAndroid Date: Sun, 19 Mar 2023 08:04:47 -0400 Subject: [PATCH] fix: encode and decode DIMENSION/FRACTION values correctly --- .../reandroid/arsc/decoder/ComplexUtil.java | 206 ++++++++++++++++++ .../reandroid/arsc/decoder/ValueDecoder.java | 122 +---------- 2 files changed, 216 insertions(+), 112 deletions(-) create mode 100644 src/main/java/com/reandroid/arsc/decoder/ComplexUtil.java diff --git a/src/main/java/com/reandroid/arsc/decoder/ComplexUtil.java b/src/main/java/com/reandroid/arsc/decoder/ComplexUtil.java new file mode 100644 index 0000000..fdbe9d8 --- /dev/null +++ b/src/main/java/com/reandroid/arsc/decoder/ComplexUtil.java @@ -0,0 +1,206 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.reandroid.arsc.decoder; + +public class ComplexUtil { + + public static String decodeComplex(boolean fraction, int complex_value){ + int radixFlag = (complex_value >> COMPLEX_RADIX_SHIFT) & COMPLEX_RADIX_MASK; + Radix radix = Radix.forFlag(radixFlag); + long mantissa = (complex_value >> COMPLEX_MANTISSA_SHIFT) & COMPLEX_MANTISSA_MASK; + mantissa = mantissa << radix.getShift(); + float value = mantissa * MANTISSA_MULTIPLIER; + int unit_type = (complex_value >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK; + Unit unit = Unit.fromFlag(fraction, unit_type); + return radix.formatFloat(fraction, value) + unit.getSymbol(); + } + public static int encodeComplex(float value, String unit){ + return encodeComplex(value, Unit.fromSymbol(unit)); + } + public static int encodeComplex(float value, Unit unit){ + boolean neg = value < 0; + if (neg) { + value = -value; + } + long bits = (long)(value*(1<<23) + 0.5f); + + Radix radix = Radix.getRadix(bits); + int mantissa = (int)((bits>>radix.getShift()) & COMPLEX_MANTISSA_MASK); + if (neg) { + mantissa = (-mantissa) & COMPLEX_MANTISSA_MASK; + } + int result = (radix.getFlag()<> 4) & 0x3; - float result=complex & 0xffffff00; - float y2=RADIX_MULTS[y]; - result=result * y2; - return result; - } - static String getDimensionUnit(int index){ - if(index<0 || index>DIMENSION_UNIT_STRS.length){ - index=1; - } - return DIMENSION_UNIT_STRS[index]; - } - private static int getDimensionIndex(String unit){ - if("%".equals(unit)){ - return 0; - } - if("%p".equals(unit)){ - return 1; - } - if("dip".equals(unit)){ - unit = "dp"; - } - String[] dims=DIMENSION_UNIT_STRS; - for(int i=0;i foundGroups = store.getEntryGroups(resourceId); - return pickResourceName(foundGroups); - } - private static String pickResourceName(Collection groups){ - if(groups==null){ - return null; - } - for(EntryGroup entryGroup:groups){ - String name=entryGroup.getSpecName(); - if(name!=null){ - return name; - } - } - return null; + return ComplexUtil.decodeComplex(valueType == ValueType.FRACTION, rawVal); } private static AttributeBag getAttributeBag(EntryStore store, int resourceId){ ResTableMapEntry mapEntry=getAttributeValueBag(store, resourceId); @@ -884,11 +787,6 @@ import java.util.regex.Pattern; return valueType+": "+String.format("0x%08x", value); } } - private static final String[] DIMENSION_UNIT_STRS = new String[] { "px", "dp", "sp", "pt", "in", "mm" }; - private static final float MANTISSA_MULT = 1.0f / (1 << 8); - static final float[] RADIX_MULTS = new float[] { - 1.0f * MANTISSA_MULT, 1.0f / (1 << 7) * MANTISSA_MULT, - 1.0f / (1 << 15) * MANTISSA_MULT, 1.0f / (1 << 23) * MANTISSA_MULT }; public static final Pattern PATTERN_COLOR = Pattern.compile("^#([0-9a-fA-F]{6,8})$"); public static final Pattern PATTERN_DIMEN = Pattern.compile("^([+\\-]?[0-9]+(\\.[0-9]+(E\\+?-?[0-9]+)?)?)(px|di?p|sp|pt|in|mm|%p?)$");