lookupMap;
29 | private final int shortest;
30 | private final int longest;
31 |
32 | /**
33 | * Define the lookup table to be used in translation
34 | *
35 | * Note that, as of Lang 3.1, the key to the lookup table is converted to a
36 | * java.lang.String, while the value remains as a java.lang.CharSequence.
37 | * This is because we need the key to support hashCode and equals(Object),
38 | * allowing it to be the key for a HashMap. See LANG-882.
39 | *
40 | * @param lookup CharSequence[][] table of size [*][2]
41 | */
42 | public LookupTranslator(final CharSequence[]... lookup) {
43 | lookupMap = new HashMap<>();
44 | int _shortest = Integer.MAX_VALUE;
45 | int _longest = 0;
46 | if (lookup != null) {
47 | for (final CharSequence[] seq : lookup) {
48 | this.lookupMap.put(seq[0].toString(), seq[1]);
49 | final int sz = seq[0].length();
50 | if (sz < _shortest) {
51 | _shortest = sz;
52 | }
53 | if (sz > _longest) {
54 | _longest = sz;
55 | }
56 | }
57 | }
58 | shortest = _shortest;
59 | longest = _longest;
60 | }
61 |
62 | /**
63 | * {@inheritDoc}
64 | */
65 | @Override
66 | public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
67 | int max = longest;
68 | if (index + longest > input.length()) {
69 | max = input.length() - index;
70 | }
71 | // descend so as to get a greedy algorithm
72 | for (int i = max; i >= shortest; i--) {
73 | final CharSequence subSeq = input.subSequence(index, index + i);
74 | final CharSequence result = lookupMap.get(subSeq.toString());
75 | if (result != null) {
76 | out.write(result.toString());
77 | return i;
78 | }
79 | }
80 | return 0;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/escaper/NumericEntityEscaper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package mt.modder.hub.axmlTools.escaper;
18 |
19 | import java.io.IOException;
20 | import java.io.Writer;
21 |
22 | /**
23 | * Translates codepoints to their XML numeric entity escaped value.
24 | */
25 | class NumericEntityEscaper extends CodePointTranslator {
26 |
27 | private final int below;
28 | private final int above;
29 | private final boolean between;
30 |
31 | /**
32 | * Constructs a NumericEntityEscaper
for the specified range. This is
33 | * the underlying method for the other constructors/builders. The below
34 | * and above
boundaries are inclusive when between
is
35 | * true
and exclusive when it is false
.
36 | *
37 | * @param below int value representing the lowest codepoint boundary
38 | * @param above int value representing the highest codepoint boundary
39 | * @param between whether to escape between the boundaries or outside them
40 | */
41 | private NumericEntityEscaper(final int below, final int above, final boolean between) {
42 | this.below = below;
43 | this.above = above;
44 | this.between = between;
45 | }
46 |
47 | /**
48 | * Constructs a NumericEntityEscaper
for all characters.
49 | */
50 | public NumericEntityEscaper() {
51 | this(0, Integer.MAX_VALUE, true);
52 | }
53 |
54 | /**
55 | * Constructs a NumericEntityEscaper
below the specified value (exclusive).
56 | *
57 | * @param codepoint below which to escape
58 | * @return the newly created {@code NumericEntityEscaper} instance
59 | */
60 | public static NumericEntityEscaper below(final int codepoint) {
61 | return outsideOf(codepoint, Integer.MAX_VALUE);
62 | }
63 |
64 | /**
65 | * Constructs a NumericEntityEscaper
above the specified value (exclusive).
66 | *
67 | * @param codepoint above which to escape
68 | * @return the newly created {@code NumericEntityEscaper} instance
69 | */
70 | public static NumericEntityEscaper above(final int codepoint) {
71 | return outsideOf(0, codepoint);
72 | }
73 |
74 | /**
75 | * Constructs a NumericEntityEscaper
between the specified values (inclusive).
76 | *
77 | * @param codepointLow above which to escape
78 | * @param codepointHigh below which to escape
79 | * @return the newly created {@code NumericEntityEscaper} instance
80 | */
81 | public static NumericEntityEscaper between(final int codepointLow, final int codepointHigh) {
82 | return new NumericEntityEscaper(codepointLow, codepointHigh, true);
83 | }
84 |
85 | /**
86 | * Constructs a NumericEntityEscaper
outside of the specified values (exclusive).
87 | *
88 | * @param codepointLow below which to escape
89 | * @param codepointHigh above which to escape
90 | * @return the newly created {@code NumericEntityEscaper} instance
91 | */
92 | public static NumericEntityEscaper outsideOf(final int codepointLow, final int codepointHigh) {
93 | return new NumericEntityEscaper(codepointLow, codepointHigh, false);
94 | }
95 |
96 | /**
97 | * {@inheritDoc}
98 | */
99 | @Override
100 | public boolean translate(final int codepoint, final Writer out) throws IOException {
101 | if(between) {
102 | if (codepoint < below || codepoint > above) {
103 | return false;
104 | }
105 | } else {
106 | if (codepoint >= below && codepoint <= above) {
107 | return false;
108 | }
109 | }
110 |
111 | out.write("");
112 | out.write(Integer.toString(codepoint, 10));
113 | out.write(';');
114 | return true;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/escaper/UnicodeUnpairedSurrogateRemover.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package mt.modder.hub.axmlTools.escaper;
18 |
19 | import java.io.IOException;
20 | import java.io.Writer;
21 |
22 | /**
23 | * Helper subclass to CharSequenceTranslator to remove unpaired surrogates.
24 | */
25 | class UnicodeUnpairedSurrogateRemover extends CodePointTranslator {
26 | /**
27 | * Implementation of translate that throws out unpaired surrogates.
28 | * {@inheritDoc}
29 | */
30 | @Override
31 | public boolean translate(int codepoint, Writer out) throws IOException {
32 | if (codepoint >= Character.MIN_SURROGATE && codepoint <= Character.MAX_SURROGATE) {
33 | // It's a surrogate. Write nothing and say we've translated.
34 | return true;
35 | } else {
36 | // It's not a surrogate. Don't translate it.
37 | return false;
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/escaper/XmlEscaper.java:
--------------------------------------------------------------------------------
1 | package mt.modder.hub.axmlTools.escaper;
2 |
3 | /**
4 | * Utils method to escape xml string, copied from apache commons lang3
5 | *
6 | * @author Liu Dong {@literal }
7 | */
8 | public class XmlEscaper {
9 |
10 | /**
11 | * Escapes the characters in a {@code String} using XML entities.
12 | */
13 | public static String escapeXml10(final String input) {
14 | return ESCAPE_XML10.translate(input);
15 | }
16 |
17 | public static final CharSequenceTranslator ESCAPE_XML10 =
18 | new AggregateTranslator(
19 | new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
20 | new LookupTranslator(EntityArrays.APOS_ESCAPE()),
21 | new LookupTranslator(
22 | new String[][]{
23 | {"\u0000", ""},
24 | {"\u0001", ""},
25 | {"\u0002", ""},
26 | {"\u0003", ""},
27 | {"\u0004", ""},
28 | {"\u0005", ""},
29 | {"\u0006", ""},
30 | {"\u0007", ""},
31 | {"\u0008", ""},
32 | {"\u000b", ""},
33 | {"\u000c", ""},
34 | {"\u000e", ""},
35 | {"\u000f", ""},
36 | {"\u0010", ""},
37 | {"\u0011", ""},
38 | {"\u0012", ""},
39 | {"\u0013", ""},
40 | {"\u0014", ""},
41 | {"\u0015", ""},
42 | {"\u0016", ""},
43 | {"\u0017", ""},
44 | {"\u0018", ""},
45 | {"\u0019", ""},
46 | {"\u001a", ""},
47 | {"\u001b", ""},
48 | {"\u001c", ""},
49 | {"\u001d", ""},
50 | {"\u001e", ""},
51 | {"\u001f", ""},
52 | {"\ufffe", ""},
53 | {"\uffff", ""}
54 | }),
55 | NumericEntityEscaper.between(0x7f, 0x84),
56 | NumericEntityEscaper.between(0x86, 0x9f),
57 | new UnicodeUnpairedSurrogateRemover()
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/utils/Attribute.java:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * AxmlPrinter - An Advanced Axml Printer available with proper xml style/format feature
4 | * Copyright 2024, developer-krushna
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are
8 | * met:
9 | *
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above
13 | * copyright notice, this list of conditions and the following disclaimer
14 | * in the documentation and/or other materials provided with the
15 | * distribution.
16 | * * Neither the name of developer-krushna nor the names of its
17 | * contributors may be used to endorse or promote products derived from
18 | * this software without specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 |
33 | * Please contact Krushna by email mt.modder.hub@gmail.com if you need
34 | * additional information or have any questions
35 | */
36 |
37 |
38 | // Idea copied from : https://github.com/hsiafan/apk-parser
39 |
40 | package mt.modder.hub.axmlTools.utils;
41 |
42 | import java.util.*;
43 | import java.io.*;
44 |
45 | public class Attribute {
46 |
47 | public static class AttrIds {
48 |
49 | private static final Map ids = loadSystemAttrIds();
50 |
51 | public static String getString(long id) {
52 | String value = ids.get((int) id);
53 | if (value == null) {
54 | value = "" + id;
55 | }
56 | return value;
57 | }
58 | }
59 |
60 | public static Map loadSystemAttrIds() {
61 | try{
62 | BufferedReader reader = toReader("/assets/r_values.ini");
63 | Map map = new HashMap<>();
64 | String line;
65 | while ((line = reader.readLine()) != null) {
66 | String[] items = line.trim().split("=");
67 | if (items.length != 2) {
68 | continue;
69 | }
70 | String name = items[0].trim();
71 | Integer id = Integer.valueOf(items[1].trim());
72 | map.put(id, name);
73 | }
74 | return map;
75 | } catch (IOException e) {
76 | throw new RuntimeException(e);
77 | }
78 | }
79 |
80 | private static BufferedReader toReader(String path) {
81 | return new BufferedReader(new InputStreamReader(Attribute.class.getResourceAsStream(path)));
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/utils/AttributeSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * AxmlPrinter - An Advanced Axml Printer available with proper xml style/format feature
3 | * Copyright 2024, developer-krushna
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are
7 | * met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above
12 | * copyright notice, this list of conditions and the following disclaimer
13 | * in the documentation and/or other materials provided with the
14 | * distribution.
15 | * * Neither the name of developer-krushna nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 |
32 | * Please contact Krushna by email mt.modder.hub@gmail.com if you need
33 | * additional information or have any questions
34 | */
35 |
36 | package mt.modder.hub.axmlTools.utils;
37 |
38 | public interface AttributeSet {
39 | int getAttributeCount();
40 |
41 | String getAttributeName(int index);
42 |
43 | String getAttributeValue(int index);
44 |
45 | String getPositionDescription();
46 |
47 | int getAttributeNameResource(int index);
48 |
49 | int getAttributeListValue(int index, String options[], int defaultValue);
50 |
51 | boolean getAttributeBooleanValue(int index, boolean defaultValue);
52 |
53 | int getAttributeResourceValue(int index, int defaultValue);
54 |
55 | int getAttributeIntValue(int index, int defaultValue);
56 |
57 | int getAttributeUnsignedIntValue(int index, int defaultValue);
58 |
59 | float getAttributeFloatValue(int index, float defaultValue);
60 |
61 | String getIdAttribute();
62 |
63 | String getClassAttribute();
64 |
65 | int getIdAttributeResourceValue(int index);
66 |
67 | int getStyleAttribute();
68 |
69 | String getAttributeValue(String namespace, String attribute);
70 |
71 | int getAttributeListValue(String namespace, String attribute,
72 | String options[], int defaultValue);
73 |
74 | boolean getAttributeBooleanValue(String namespace, String attribute,
75 | boolean defaultValue);
76 |
77 | int getAttributeResourceValue(String namespace, String attribute,
78 | int defaultValue);
79 |
80 | int getAttributeIntValue(String namespace, String attribute,
81 | int defaultValue);
82 |
83 | int getAttributeUnsignedIntValue(String namespace, String attribute,
84 | int defaultValue);
85 |
86 | float getAttributeFloatValue(String namespace, String attribute,
87 | float defaultValue);
88 |
89 | // TODO: remove
90 | int getAttributeValueType(int index);
91 |
92 | int getAttributeValueData(int index);
93 | }
94 |
--------------------------------------------------------------------------------
/library/src/main/java/mt/modder/hub/axmlTools/utils/TypedValue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * AxmlPrinter - An Advanced Axml Printer available with proper xml style/format feature
3 | * Copyright 2024, developer-krushna
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are
7 | * met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above
12 | * copyright notice, this list of conditions and the following disclaimer
13 | * in the documentation and/or other materials provided with the
14 | * distribution.
15 | * * Neither the name of developer-krushna nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 |
32 | * Please contact Krushna by email mt.modder.hub@gmail.com if you need
33 | * additional information or have any questions
34 | */
35 |
36 | package mt.modder.hub.axmlTools.utils;
37 |
38 | /**
39 | * Container for a dynamically typed data value. Primarily used with
40 | * {@link android.content.res.Resources} for holding resource values.
41 | */
42 | public class TypedValue {
43 | /**
44 | * The value contains no data.
45 | */
46 | public static final int TYPE_NULL = 0x00;
47 |
48 | /**
49 | * The data field holds a resource identifier.
50 | */
51 | public static final int TYPE_REFERENCE = 0x01;
52 | /**
53 | * The data field holds an attribute resource
54 | * identifier (referencing an attribute in the current theme
55 | * style, not a resource entry).
56 | */
57 | public static final int TYPE_ATTRIBUTE = 0x02;
58 | /**
59 | * The string field holds string data. In addition, if
60 | * data is non-zero then it is the string block
61 | * index of the string and assetCookie is the set of
62 | * assets the string came from.
63 | */
64 | public static final int TYPE_STRING = 0x03;
65 | /**
66 | * The data field holds an IEEE 754 floating point number.
67 | */
68 | public static final int TYPE_FLOAT = 0x04;
69 | /**
70 | * The data field holds a complex number encoding a
71 | * dimension value.
72 | */
73 | public static final int TYPE_DIMENSION = 0x05;
74 | /**
75 | * The data field holds a complex number encoding a fraction
76 | * of a container.
77 | */
78 | public static final int TYPE_FRACTION = 0x06;
79 |
80 | /**
81 | * Identifies the start of plain integer values. Any type value
82 | * from this to {@link #TYPE_LAST_INT} means the
83 | * data field holds a generic integer value.
84 | */
85 | public static final int TYPE_FIRST_INT = 0x10;
86 |
87 | /**
88 | * The data field holds a number that was
89 | * originally specified in decimal.
90 | */
91 | public static final int TYPE_INT_DEC = 0x10;
92 | /**
93 | * The data field holds a number that was
94 | * originally specified in hexadecimal (0xn).
95 | */
96 | public static final int TYPE_INT_HEX = 0x11;
97 | /**
98 | * The data field holds 0 or 1 that was originally
99 | * specified as "false" or "true".
100 | */
101 | public static final int TYPE_INT_BOOLEAN = 0x12;
102 |
103 | /**
104 | * Identifies the start of integer values that were specified as
105 | * color constants (starting with '#').
106 | */
107 | public static final int TYPE_FIRST_COLOR_INT = 0x1c;
108 |
109 | /**
110 | * The data field holds a color that was originally
111 | * specified as #aarrggbb.
112 | */
113 | public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
114 | /**
115 | * The data field holds a color that was originally
116 | * specified as #rrggbb.
117 | */
118 | public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
119 | /**
120 | * The data field holds a color that was originally
121 | * specified as #argb.
122 | */
123 | public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
124 | /**
125 | * The data field holds a color that was originally
126 | * specified as #rgb.
127 | */
128 | public static final int TYPE_INT_COLOR_RGB4 = 0x1f;
129 |
130 | /**
131 | * Identifies the end of integer values that were specified as color
132 | * constants.
133 | */
134 | public static final int TYPE_LAST_COLOR_INT = 0x1f;
135 |
136 | /**
137 | * Identifies the end of plain integer values.
138 | */
139 | public static final int TYPE_LAST_INT = 0x1f;
140 |
141 | /* ------------------------------------------------------------ */
142 |
143 | /**
144 | * Complex data: bit location of unit information.
145 | */
146 | public static final int COMPLEX_UNIT_SHIFT = 0;
147 | /**
148 | * Complex data: mask to extract unit information (after shifting by
149 | * {@link #COMPLEX_UNIT_SHIFT}). This gives us 16 possible types, as
150 | * defined below.
151 | */
152 | public static final int COMPLEX_UNIT_MASK = 0xf;
153 |
154 | /**
155 | * {@link #TYPE_DIMENSION} complex unit: Value is raw pixels.
156 | */
157 | public static final int COMPLEX_UNIT_PX = 0;
158 | /**
159 | * {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
160 | * Pixels.
161 | */
162 | public static final int COMPLEX_UNIT_DIP = 1;
163 | /**
164 | * {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel.
165 | */
166 | public static final int COMPLEX_UNIT_SP = 2;
167 | /**
168 | * {@link #TYPE_DIMENSION} complex unit: Value is in points.
169 | */
170 | public static final int COMPLEX_UNIT_PT = 3;
171 | /**
172 | * {@link #TYPE_DIMENSION} complex unit: Value is in inches.
173 | */
174 | public static final int COMPLEX_UNIT_IN = 4;
175 | /**
176 | * {@link #TYPE_DIMENSION} complex unit: Value is in millimeters.
177 | */
178 | public static final int COMPLEX_UNIT_MM = 5;
179 |
180 | /**
181 | * {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
182 | * size.
183 | */
184 | public static final int COMPLEX_UNIT_FRACTION = 0;
185 | /**
186 | * {@link #TYPE_FRACTION} complex unit: A fraction of the parent size.
187 | */
188 | public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;
189 |
190 | /**
191 | * Complex data: where the radix information is, telling where the decimal
192 | * place appears in the mantissa.
193 | */
194 | public static final int COMPLEX_RADIX_SHIFT = 4;
195 | /**
196 | * Complex data: mask to extract radix information (after shifting by
197 | * {@link #COMPLEX_RADIX_SHIFT}). This give us 4 possible fixed point
198 | * representations as defined below.
199 | */
200 | public static final int COMPLEX_RADIX_MASK = 0x3;
201 |
202 | /**
203 | * Complex data: the mantissa is an integral number -- i.e., 0xnnnnnn.0
204 | */
205 | public static final int COMPLEX_RADIX_23p0 = 0;
206 | /**
207 | * Complex data: the mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
208 | */
209 | public static final int COMPLEX_RADIX_16p7 = 1;
210 | /**
211 | * Complex data: the mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
212 | */
213 | public static final int COMPLEX_RADIX_8p15 = 2;
214 | /**
215 | * Complex data: the mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
216 | */
217 | public static final int COMPLEX_RADIX_0p23 = 3;
218 |
219 | /**
220 | * Complex data: bit location of mantissa information.
221 | */
222 | public static final int COMPLEX_MANTISSA_SHIFT = 8;
223 | /**
224 | * Complex data: mask to extract mantissa information (after shifting by
225 | * {@link #COMPLEX_MANTISSA_SHIFT}). This gives us 23 bits of precision;
226 | * the top bit is the sign.
227 | */
228 | public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
229 |
230 | /* ------------------------------------------------------------ */
231 |
232 | /**
233 | * If {@link #density} is equal to this value, then the density should be
234 | * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
235 | */
236 | public static final int DENSITY_DEFAULT = 0;
237 |
238 | /**
239 | * If {@link #density} is equal to this value, then there is no density
240 | * associated with the resource and it should not be scaled.
241 | */
242 | public static final int DENSITY_NONE = 0xffff;
243 |
244 | /* ------------------------------------------------------------ */
245 | private static final float MANTISSA_MULT =
246 | 1.0f / (1 << TypedValue.COMPLEX_MANTISSA_SHIFT);
247 | private static final float[] RADIX_MULTS = new float[]{
248 | 1.0f * MANTISSA_MULT, 1.0f / (1 << 7) * MANTISSA_MULT,
249 | 1.0f / (1 << 15) * MANTISSA_MULT, 1.0f / (1 << 23) * MANTISSA_MULT
250 | };
251 | private static final String[] DIMENSION_UNIT_STRS = new String[]{
252 | "px", "dip", "sp", "pt", "in", "mm"
253 | };
254 | private static final String[] FRACTION_UNIT_STRS = new String[]{
255 | "%", "%p"
256 | };
257 | /**
258 | * The type held by this value, as defined by the constants here.
259 | * This tells you how to interpret the other fields in the object.
260 | */
261 | public int type;
262 |
263 | /**
264 | * Retrieve the base value from a complex data integer. This uses the
265 | * {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of
266 | * the data to compute a floating point representation of the number they
267 | * describe. The units are ignored.
268 | *
269 | * @param complex A complex data value.
270 | * @return A floating point value corresponding to the complex data.
271 | */
272 | public static float complexToFloat(int complex) {
273 | return (complex & (TypedValue.COMPLEX_MANTISSA_MASK
274 | << TypedValue.COMPLEX_MANTISSA_SHIFT))
275 | * RADIX_MULTS[(complex >> TypedValue.COMPLEX_RADIX_SHIFT)
276 | & TypedValue.COMPLEX_RADIX_MASK];
277 | }
278 |
279 | /**
280 | * Perform type conversion as per {@link #coerceToString()} on an
281 | * explicitly supplied type and data.
282 | *
283 | * @param type The data type identifier.
284 | * @param data The data value.
285 | * @return String The coerced string value. If the value is
286 | * null or the type is not known, null is returned.
287 | */
288 | public static final String coerceToString(int type, int data) {
289 | switch (type) {
290 | case TYPE_NULL:
291 | return null;
292 | case TYPE_REFERENCE:
293 | return "@" + data;
294 | case TYPE_ATTRIBUTE:
295 | return "?" + data;
296 | case TYPE_FLOAT:
297 | return Float.toString(Float.intBitsToFloat(data));
298 | case TYPE_DIMENSION:
299 | return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
300 | (data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK];
301 | case TYPE_FRACTION:
302 | return Float.toString(complexToFloat(data) * 100) + FRACTION_UNIT_STRS[
303 | (data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK];
304 | case TYPE_INT_HEX:
305 | return "0x" + Integer.toHexString(data);
306 | case TYPE_INT_BOOLEAN:
307 | return data != 0 ? "true" : "false";
308 | }
309 |
310 | if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
311 | return "#" + Integer.toHexString(data);
312 | } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
313 | return Integer.toString(data);
314 | }
315 |
316 | return null;
317 | }
318 |
319 | };
320 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------