diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f10d030..b50e0f567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ All notable changes to this project will be documented in this file. - Generic tag editor - display of color values in arrays (filters, etc.) - Generic tag editor - display of array brackets - Generic tag editor - GRADIENT filters fields +- [#2099] Smart number formatting precedence ### Changed - AS1/2 P-code action parameters are now separated by commas, code without commas is still accepted @@ -3177,6 +3178,7 @@ Major version of SWF to XML export changed to 2. [#2094]: https://www.free-decompiler.com/flash/issues/2094 [#2095]: https://www.free-decompiler.com/flash/issues/2095 [#223]: https://www.free-decompiler.com/flash/issues/223 +[#2099]: https://www.free-decompiler.com/flash/issues/2099 [#1449]: https://www.free-decompiler.com/flash/issues/1449 [#2070]: https://www.free-decompiler.com/flash/issues/2070 [#2073]: https://www.free-decompiler.com/flash/issues/2073 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java index e2ee25a5f..a39c9928d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java @@ -43,82 +43,95 @@ public class IntegerValueAVM2Item extends NumberValueAVM2Item implements Integer public Integer value; + private String formatted; + public IntegerValueAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Integer value) { super(instruction, lineStartIns); this.value = value; + detectFormat(); + } + + /** + * Should be called after value change + */ + public void detectFormat() { + precedence = PRECEDENCE_PRIMARY; + if (value >= 256 && value <= 0xffffffffL) { + int intVal = (int) (long) (value & 0xffffff); + int r = (intVal >> 16) & 0xff; + int g = (intVal >> 8) & 0xff; + int b = intVal & 0xff; + if ((r == b && b == g) // gray + || (((intVal & 0x0f0000) == 0 || (intVal & 0x0f0000) == 0x0f0000) // a(0/F)b(0/F)c(0/F) + && ((intVal & 0x000f00) == 0 || (intVal & 0x000f00) == 0x000f00) + && ((intVal & 0x00000f) == 0 || (intVal & 0x00000f) == 0x00000f)) + || ((((intVal & 0xf00000) >> 20) == ((intVal & 0x0f0000) >> 16)) // aabbcc + && (((intVal & 0x00f000) >> 12) == ((intVal & 0x000f00) >> 8)) + && (((intVal & 0x0000f0) >> 4) == ((intVal & 0x00000f))))) { + this.formatted = "0x" + Long.toHexString(value); + return; + } + } + + long value2 = (long) value; + if (value2 > 0 && value2 % 60 == 0) { + int thousandCount = 0; + value2 /= 60; + boolean isHour = false; + boolean isDay = false; + if (value2 % 60 == 0) { + value2 /= 60; + isHour = true; + if (value2 % 24 == 0) { + value2 /= 24; + isDay = true; + } + } + + // check milli, micro and nanoseconds + while (thousandCount < 3) { + if (value2 % 1000 == 0) { + thousandCount++; + value2 /= 1000; + } else { + break; + } + } + + if (value2 < 1000) { + List factors = new ArrayList<>(); + if (value2 > 1) { + factors.add((int) value2); + } + if (isDay) { + factors.add(24); + } + if (isHour) { + factors.add(60); + } + factors.add(60); + for (int i = 0; i < thousandCount; i++) { + factors.add(1000); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < factors.size(); i++) { + if (i != 0) { + sb.append(" * "); + } + sb.append(factors.get(i)); + } + precedence = PRECEDENCE_MULTIPLICATIVE; + + this.formatted = sb.toString(); + return; + } + } + this.formatted = EcmaScript.toString(value); } @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { - if (Configuration.smartNumberFormatting.get()) { - if (value >= 256 && value <= 0xffffffffL) { - int intVal = (int) (long) (value & 0xffffff); - int r = (intVal >> 16) & 0xff; - int g = (intVal >> 8) & 0xff; - int b = intVal & 0xff; - if ((r == b && b == g) // gray - || (((intVal & 0x0f0000) == 0 || (intVal & 0x0f0000) == 0x0f0000) // a(0/F)b(0/F)c(0/F) - && ((intVal & 0x000f00) == 0 || (intVal & 0x000f00) == 0x000f00) - && ((intVal & 0x00000f) == 0 || (intVal & 0x00000f) == 0x00000f)) - || ((((intVal & 0xf00000) >> 20) == ((intVal & 0x0f0000) >> 16)) // aabbcc - && (((intVal & 0x00f000) >> 12) == ((intVal & 0x000f00) >> 8)) - && (((intVal & 0x0000f0) >> 4) == ((intVal & 0x00000f))))) { - return writer.append("0x").append(Long.toHexString(value)); - } - } - - long value2 = (long) value; - if (value2 > 0 && value2 % 60 == 0) { - int thousandCount = 0; - value2 /= 60; - boolean isHour = false; - boolean isDay = false; - if (value2 % 60 == 0) { - value2 /= 60; - isHour = true; - if (value2 % 24 == 0) { - value2 /= 24; - isDay = true; - } - } - - // check milli, micro and nanoseconds - while (thousandCount < 3) { - if (value2 % 1000 == 0) { - thousandCount++; - value2 /= 1000; - } else { - break; - } - } - - if (value2 < 1000) { - List factors = new ArrayList<>(); - if (value2 > 1) { - factors.add((int) value2); - } - if (isDay) { - factors.add(24); - } - if (isHour) { - factors.add(60); - } - factors.add(60); - for (int i = 0; i < thousandCount; i++) { - factors.add(1000); - } - for (int i = 0; i < factors.size(); i++) { - if (i != 0) { - writer.append(" * "); - } - writer.append(factors.get(i)); - } - return writer; - } - } - } - - return writer.append(EcmaScript.toString(value)); + return writer.append(formatted); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 38f55f4ad..5d8ba9a39 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2333,6 +2333,7 @@ public class ActionScript3Parser { GraphTargetItem num = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables); if (num instanceof IntegerValueAVM2Item) { ((IntegerValueAVM2Item) num).value = -((IntegerValueAVM2Item) num).value; + ((IntegerValueAVM2Item) num).detectFormat(); ret = num; } else if (num instanceof FloatValueAVM2Item) { Double d = ((FloatValueAVM2Item) num).value;