From 8c4457e1e8205b980d1e4c23f835c080bb7b0726 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sat, 19 Dec 2015 11:31:14 +0100 Subject: [PATCH 1/8] approximating elliptical arcs with Bezier curves --- .../flash/importers/ShapeImporter.java | 120 +++++++----------- 1 file changed, 45 insertions(+), 75 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java index 947e250ab..1d291cbae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java @@ -648,82 +648,58 @@ public class ShapeImporter { } double rcp = Math.sqrt(4 - 2 * Math.sqrt(2)); - double delta = Math.PI / 4 / 45; - if (deltaTheta > 0) { - int segmentCount = (int) Math.ceil(deltaTheta / delta); + double delta = Math.signum(deltaTheta) * Math.PI / 4; - double theta = theta1; + int segmentCount = (int) Math.ceil(deltaTheta / delta); + double theta = theta1; - PathCommand sera; - for (int i = 0; i < segmentCount - 1; i++) { - theta += delta; - sera = new PathCommand(); - sera.command = 'L'; - double x12 = Math.cos(theta) * rx; - double y12 = Math.sin(theta) * ry; - x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; - y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; - sera.params = new double[]{cx + x1Comma, cy + y1Comma}; - pathCommands.add(sera); - - /*sera = new PathCommand(); - sera.command = 'Q'; - double x12 = Math.cos(theta) * rx; - double y12 = Math.sin(theta) * ry; - x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; - y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; - - double theta2 = theta - Math.PI / 8; - x12 = Math.cos(theta2) * rx * rcp; - y12 = Math.sin(theta2) * ry * rcp; - double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12; - double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12; - sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma}; - pathCommands.add(sera);*/ - } + PathCommand sera; + for (int i = 0; i < segmentCount - 1; i++) { + theta += delta; + /*sera = new PathCommand(); + sera.command = 'L'; + double x12 = Math.cos(theta) * rx; + double y12 = Math.sin(theta) * ry; + x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; + y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; + sera.params = new double[]{cx + x1Comma, cy + y1Comma}; + pathCommands.add(sera);*/ sera = new PathCommand(); - sera.command = 'L'; - sera.params = new double[]{x, y}; - pathCommands.add(sera); - } else { - int segmentCount = (int) Math.ceil(-deltaTheta / delta); + sera.command = 'Q'; + double x12 = Math.cos(theta) * rx; + double y12 = Math.sin(theta) * ry; + x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; + y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; - double theta = theta1; - - PathCommand sera; - for (int i = 0; i < segmentCount - 1; i++) { - theta -= delta; - sera = new PathCommand(); - sera.command = 'L'; - double x12 = Math.cos(theta) * rx; - double y12 = Math.sin(theta) * ry; - x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; - y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; - sera.params = new double[]{cx + x1Comma, cy + y1Comma}; - pathCommands.add(sera); - - /*sera = new PathCommand(); - sera.command = 'Q'; - double x12 = Math.cos(theta) * rx; - double y12 = Math.sin(theta) * ry; - x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; - y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; - - double theta2 = theta + Math.PI / 8; - x12 = Math.cos(theta2) * rx * rcp; - y12 = Math.sin(theta2) * ry * rcp; - double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12; - double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12; - sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma}; - pathCommands.add(sera);*/ - } - - sera = new PathCommand(); - sera.command = 'L'; - sera.params = new double[]{x, y}; + double theta2 = theta - delta / 2; + x12 = Math.cos(theta2) * rx * rcp; + y12 = Math.sin(theta2) * ry * rcp; + double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12; + double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12; + sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma}; pathCommands.add(sera); } + + sera = new PathCommand(); + sera.command = 'Q'; + + theta += delta; + double diff = theta1 + deltaTheta - theta; + diff = -delta - diff; + theta = theta - delta - diff / 2; + + double rcpm = 1 + (rcp - 1) * (diff / delta) * (diff / delta); + double x12 = Math.cos(theta) * rx * rcpm; + double y12 = Math.sin(theta) * ry * rcpm; + x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12; + y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12; + sera.params = new double[]{cx + x1Comma, cy + y1Comma, x, y}; + pathCommands.add(sera); + /*sera = new PathCommand(); + sera.command = 'L'; + sera.params = new double[]{x, y}; + pathCommands.add(sera);*/ } break; default: @@ -746,12 +722,6 @@ public class ShapeImporter { processCommands(shapeNum, shapes, pathCommands, transform, style); } - private double[] getCoordinates() { - //rx, -sqrt2Minus1RY, - //sqrt2RXHalf, -sqrt2RYHalf, - return null; - } - private double calcAngle(double ux, double uy, double vx, double vy) { double lu = Math.sqrt(ux * ux + uy * uy); double lv = Math.sqrt(ux * ux + uy * uy); From da2d824e9cd68d086705cfca3b0bb387721ea0a0 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sat, 19 Dec 2015 13:11:02 +0100 Subject: [PATCH 2/8] svg transform parameter parsing fixed --- .../decompiler/flash/exporters/commonshape/Matrix.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/Matrix.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/Matrix.java index 30562d598..926fddb81 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/Matrix.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/Matrix.java @@ -247,6 +247,13 @@ public final class Matrix implements Cloneable { transformStr = transformStr.substring(funcName.length() + 1); String params = transformStr.split("\\)")[0]; transformStr = transformStr.substring(params.length() + 1); + while (params.contains(" ")) { + params = params.replaceAll(" ", " "); + } + + params = params.trim(); + params = params.replace(", ", ","); + params = params.replace(" ", ","); String[] args = params.split(","); funcName = funcName.trim(); switch (funcName) { From 300022acc7c5af701c636176d36d5eeb2571259e Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sun, 20 Dec 2015 11:12:32 +0100 Subject: [PATCH 3/8] #1075 Lenght of DefineText is more larger than original when DefineText is saved: detect letter spacing --- .../decompiler/flash/tags/base/FontTag.java | 31 ++++++--- .../flash/tags/base/StaticTextTag.java | 64 +++++++++++++++---- .../jpexs/decompiler/flash/gui/FontPanel.java | 24 +------ src/com/jpexs/decompiler/flash/gui/Main.java | 11 ++-- .../jpexs/decompiler/flash/gui/MainPanel.java | 2 +- 5 files changed, 81 insertions(+), 51 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index 41c1cbe90..8ce597858 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; @@ -181,16 +182,30 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } public String getSystemFontName() { - Map fontPairs = Configuration.getFontToNameMap(); - String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontNameIntag(); - if (fontPairs.containsKey(key)) { - return fontPairs.get(key); + int fontId = getFontId(); + String selectedFont = swf.sourceFontNamesMap.get(fontId); + if (selectedFont == null) { + SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortFileName()); + String key = fontId + "_" + getFontNameIntag(); + if (swfConf != null) { + selectedFont = swfConf.fontPairingMap.get(key); + } } - key = getFontNameIntag(); - if (fontPairs.containsKey(key)) { - return fontPairs.get(key); + + if (selectedFont == null) { + selectedFont = Configuration.getFontToNameMap().get(getFontNameIntag()); } - return defaultFontName; + + if (selectedFont != null && FontTag.installedFontsByName.containsKey(selectedFont)) { + return selectedFont; + } + + // findInstalledFontName always returns an available font name + return FontTag.findInstalledFontName(getFontName()); + } + + public Font getSystemFont() { + return FontTag.installedFontsByName.get(getSystemFontName()); } protected void shiftGlyphIndices(int fontId, int startIndex) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java index cdbded97d..0449be6f8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java @@ -261,6 +261,12 @@ public abstract class StaticTextTag extends TextTag { writer.append("font ").append(rec.fontId).newLine(); writer.append("height ").append(rec.textHeight).newLine(); } + if (fnt != null) { + int letterSpacing = detectLetterSpacing(rec, fnt, rec.textHeight); + if (letterSpacing != 0) { + writer.append("letterspacing ").append(letterSpacing).newLine(); + } + } if (rec.styleFlagsHasColor) { if (getTextNum() == 1) { writer.append("color ").append(rec.textColor.toHexRGB()).newLine(); @@ -296,8 +302,8 @@ public abstract class StaticTextTag extends TextTag { RGBA colorA = null; int fontId = -1; int textHeight = -1; + int letterSpacing = 0; FontTag font = null; - String fontName = null; Integer x = null; Integer y = null; int currentX = 0; @@ -342,7 +348,6 @@ public abstract class StaticTextTag extends TextTag { } font = (FontTag) ft; - fontName = font.getSystemFontName(); } catch (NumberFormatException nfe) { throw new TextParseException("Invalid font id - number expected. Found: " + paramValue, lexer.yyline()); } @@ -354,6 +359,13 @@ public abstract class StaticTextTag extends TextTag { throw new TextParseException("Invalid font height - number expected. Found: " + paramValue, lexer.yyline()); } break; + case "letterspacing": + try { + letterSpacing = Integer.parseInt(paramValue); + } catch (NumberFormatException nfe) { + throw new TextParseException("Invalid font letter spacing - number expected. Found: " + paramValue, lexer.yyline()); + } + break; case "x": try { x = Integer.parseInt(paramValue); @@ -527,17 +539,7 @@ public abstract class StaticTextTag extends TextTag { GLYPHENTRY ge = new GLYPHENTRY(); ge.glyphIndex = font.charToGlyph(c); - int advance; - if (font.hasLayout()) { - int kerningAdjustment = 0; - if (nextChar != null) { - kerningAdjustment = font.getCharKerningAdjustment(c, nextChar); - } - advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0)); - } else { - advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar)); - } - + int advance = getAdvance(font, ge.glyphIndex, textHeight, c, nextChar) + letterSpacing; ge.glyphAdvance = advance; tr.glyphEntries.add(ge); @@ -568,6 +570,42 @@ public abstract class StaticTextTag extends TextTag { return true; } + private int getAdvance(FontTag font, int glyphIndex, int textHeight, char c, Character nextChar) { + int advance; + if (font.hasLayout()) { + int kerningAdjustment = 0; + if (nextChar != null) { + kerningAdjustment = font.getCharKerningAdjustment(c, nextChar); + } + advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0)); + } else { + String fontName = font.getSystemFontName(); + advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar)); + } + + return advance; + } + + private int detectLetterSpacing(TEXTRECORD textRecord, FontTag font, int textHeight) { + int totalLetterSpacing = 0; + List glyphEntries = textRecord.glyphEntries; + for (int i = 0; i < glyphEntries.size(); i++) { + GLYPHENTRY glyph = glyphEntries.get(i); + GLYPHENTRY nextGlyph = null; + if (i + 1 < glyphEntries.size()) { + nextGlyph = glyphEntries.get(i + 1); + } + + char c = font.glyphToChar(glyph.glyphIndex); + Character nextChar = nextGlyph == null ? null : font.glyphToChar(nextGlyph.glyphIndex); + int advance = getAdvance(font, glyph.glyphIndex, textHeight, c, nextChar); + int letterSpacing = glyph.glyphAdvance - advance; + totalLetterSpacing += letterSpacing; + } + + return (int) Math.round(totalLetterSpacing / glyphEntries.size()); + } + @Override public void getNeededCharacters(Set needed) { for (TEXTRECORD tr : textRecords) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 80d248654..68c00ed4b 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration; import com.jpexs.decompiler.flash.gui.helpers.TableLayoutHelper; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.FontTag; @@ -214,28 +213,7 @@ public class FontPanel extends JPanel { fontCharactersScrollPane.getVerticalScrollBar().scrollRectToVisible(new Rectangle(0, 0, 1, 1)); setAllowSave(false); - String selectedFont; - - if (swf.sourceFontNamesMap.containsKey(ft.getFontId())) { - selectedFont = swf.sourceFontNamesMap.get(ft.getFontId()); - } else { - SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortFileName()); - String key = ft.getFontId() + "_" + ft.getFontNameIntag(); - if (swfConf != null && swfConf.fontPairingMap.containsKey(key)) { - selectedFont = swfConf.fontPairingMap.get(key); - } else if (Configuration.getFontToNameMap().containsKey(ft.getFontNameIntag())) { - selectedFont = Configuration.getFontToNameMap().get(ft.getFontNameIntag()); - } else { - selectedFont = FontTag.findInstalledFontName(ft.getFontName()); - } - } - - Font selFont = FontTag.installedFontsByName.get(selectedFont); - if (selFont == null) { - selectedFont = FontTag.findInstalledFontName(ft.getFontName()); - selFont = FontTag.installedFontsByName.get(selectedFont); - } - + Font selFont = ft.getSystemFont(); fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); fontFaceSelection.setSelectedItem(new FontFace(selFont)); diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index fcd4818fc..383764cb7 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -83,7 +83,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -1667,6 +1666,7 @@ public class Main { } private static void reloadLastSession() { + boolean openingFiles = false; if (Configuration.saveSessionOnExit.get()) { String lastSession = Configuration.lastSessionFiles.get(); if (lastSession != null && lastSession.length() > 0) { @@ -1694,17 +1694,16 @@ public class Main { sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle); } if (sourceInfos.length > 0) { + openingFiles = true; openFile(sourceInfos, () -> { mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get()); setSessionLoaded(true); }); - } else { - setSessionLoaded(true); } - } else { - setSessionLoaded(true); } - } else { + } + + if (!openingFiles) { setSessionLoaded(true); } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index f7f1b1eea..a27b8ea81 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -2486,7 +2486,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se final Font f = FontTag.installedFontsByName.get(fontName); if (f == null || !f.canDisplay(character)) { String msg = translate("error.font.nocharacter").replace("%char%", "" + character); - logger.log(Level.SEVERE, msg + " FontId: " + font.getCharacterId() + " TextId: " + textTag.getCharacterId()); + logger.log(Level.SEVERE, "{0} FontId: {1} TextId: {2}", new Object[]{msg, font.getCharacterId(), textTag.getCharacterId()}); ignoreMissingCharacters = View.showConfirmDialog(null, msg, translate("error"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE, showAgainIgnoreMissingCharacters, From 41507182689a0a81afc7236617e01dd6aeee5413 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sun, 20 Dec 2015 21:36:54 +0100 Subject: [PATCH 4/8] #1075 Lenght of DefineText is more larger than original when DefineText is saved: detect letter spacing --- .../jpexs/decompiler/flash/configuration/Configuration.java | 5 +++++ .../src/com/jpexs/decompiler/flash/tags/base/ImageTag.java | 3 ++- .../flash/gui/locales/AdvancedSettingsDialog.properties | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 5ac15b69c..32e74936e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -538,6 +538,11 @@ public class Configuration { @ConfigurationCategory("import") public static final ConfigurationItem warningSvgImport = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationName("shapeImport.useNonSmoothedFill") + @ConfigurationCategory("import") + public static final ConfigurationItem shapeImportUseNonSmoothedFill = null; + private enum OSId { WINDOWS, OSX, UNIX diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index a98825e22..85e3ad965 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -207,7 +207,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { shape.fillStyles = new FILLSTYLEARRAY(); shape.fillStyles.fillStyles = new FILLSTYLE[1]; FILLSTYLE fillStyle = new FILLSTYLE(); - fillStyle.fillStyleType = FILLSTYLE.REPEATING_BITMAP; + fillStyle.fillStyleType = Configuration.shapeImportUseNonSmoothedFill.get() + ? FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP : FILLSTYLE.REPEATING_BITMAP; fillStyle.bitmapId = getCharacterId(); MATRIX matrix = new MATRIX(); matrix.hasScale = true; diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index 8193b5990..186bff973 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -408,3 +408,6 @@ config.description.setMovieDelay = Not recommended to change this value below 10 config.name.warning.svgImport = Warn on SVG import config.description.warning.svgImport = + +config.name.shapeImport.useNonSmoothedFill = Use non-smoothed fill when a shape is replaced with an image +config.description.shapeImport.useNonSmoothedFill = From 760b5605ed85ff46296abd94f0840f30fce56e66 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Mon, 21 Dec 2015 16:20:42 +0100 Subject: [PATCH 5/8] remove config listeners on ffdec restart (solves a nullpointer exception problem) --- .../decompiler/flash/gui/ImagePanel.java | 10 ----- .../decompiler/flash/gui/MainFrameMenu.java | 37 +++++++++++++++---- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 3ac054ae4..dd38ac07e 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -54,7 +54,6 @@ import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseMotionListener; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -62,7 +61,6 @@ import java.util.Timer; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; -import javax.imageio.ImageIO; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.JLabel; @@ -518,14 +516,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay { return 1; } - public void setImage(byte[] data) { - try { - setImage(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data)))); - } catch (IOException ex) { - logger.log(Level.SEVERE, null, ex); - } - } - @Override public synchronized boolean zoomAvailable() { return zoomAvailable; diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java index 508f10dc7..7dd78ef04 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFBundle; import com.jpexs.decompiler.flash.SWFSourceInfo; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener; import com.jpexs.decompiler.flash.console.ContextMenuTools; import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools; import com.jpexs.decompiler.flash.gui.helpers.CheckResources; @@ -72,6 +73,20 @@ public abstract class MainFrameMenu implements MenuBuilder { private SWF swf; + private ConfigurationItemChangeListener configListenerAutoDeobfuscate; + + private ConfigurationItemChangeListener configListenerInternalFlashViewer; + + private ConfigurationItemChangeListener configListenerParallelSpeedUp; + + private ConfigurationItemChangeListener configListenerDecompile; + + private ConfigurationItemChangeListener configListenerCacheOnDisk; + + private ConfigurationItemChangeListener configListenerGotoMainClassOnStartup; + + private ConfigurationItemChangeListener configListenerAutoRenameIdentifiers; + protected final Map menuHotkeys = new HashMap<>(); @Override @@ -895,37 +910,37 @@ public abstract class MainFrameMenu implements MenuBuilder { finishMenu("/settings"); setMenuChecked("/settings/autoDeobfuscation", Configuration.autoDeobfuscate.get()); - Configuration.autoDeobfuscate.addListener((Boolean newValue) -> { + Configuration.autoDeobfuscate.addListener(configListenerAutoDeobfuscate = (Boolean newValue) -> { setMenuChecked("/settings/autoDeobfuscation", newValue); }); setMenuChecked("/settings/internalViewer", Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable); - Configuration.internalFlashViewer.addListener((Boolean newValue) -> { + Configuration.internalFlashViewer.addListener(configListenerInternalFlashViewer = (Boolean newValue) -> { setMenuChecked("/settings/internalViewer", newValue || externalFlashPlayerUnavailable); }); setMenuChecked("/settings/parallelSpeedUp", Configuration.parallelSpeedUp.get()); - Configuration.parallelSpeedUp.addListener((Boolean newValue) -> { + Configuration.parallelSpeedUp.addListener(configListenerParallelSpeedUp = (Boolean newValue) -> { setMenuChecked("/settings/parallelSpeedUp", newValue); }); setMenuChecked("/settings/disableDecompilation", !Configuration.decompile.get()); - Configuration.decompile.addListener((Boolean newValue) -> { + Configuration.decompile.addListener(configListenerDecompile = (Boolean newValue) -> { setMenuChecked("/settings/disableDecompilation", !newValue); }); setMenuChecked("/settings/cacheOnDisk", Configuration.cacheOnDisk.get()); - Configuration.cacheOnDisk.addListener((Boolean newValue) -> { + Configuration.cacheOnDisk.addListener(configListenerCacheOnDisk = (Boolean newValue) -> { setMenuChecked("/settings/cacheOnDisk", newValue); }); setMenuChecked("/settings/gotoMainClassOnStartup", Configuration.gotoMainClassOnStartup.get()); - Configuration.gotoMainClassOnStartup.addListener((Boolean newValue) -> { + Configuration.gotoMainClassOnStartup.addListener(configListenerGotoMainClassOnStartup = (Boolean newValue) -> { setMenuChecked("/settings/gotoMainClassOnStartup", newValue); }); setMenuChecked("/settings/autoRenameIdentifiers", Configuration.autoRenameIdentifiers.get()); - Configuration.autoRenameIdentifiers.addListener((Boolean newValue) -> { + Configuration.autoRenameIdentifiers.addListener(configListenerAutoRenameIdentifiers = (Boolean newValue) -> { setMenuChecked("/settings/autoRenameIdentifiers", newValue); }); @@ -1086,6 +1101,14 @@ public abstract class MainFrameMenu implements MenuBuilder { KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); manager.removeKeyEventDispatcher(keyEventDispatcher); + Configuration.autoDeobfuscate.removeListener(configListenerAutoDeobfuscate); + Configuration.internalFlashViewer.removeListener(configListenerInternalFlashViewer); + Configuration.parallelSpeedUp.removeListener(configListenerParallelSpeedUp); + Configuration.decompile.removeListener(configListenerDecompile); + Configuration.cacheOnDisk.removeListener(configListenerCacheOnDisk); + Configuration.gotoMainClassOnStartup.removeListener(configListenerGotoMainClassOnStartup); + Configuration.autoRenameIdentifiers.removeListener(configListenerAutoRenameIdentifiers); + Main.stopRun(); } From 112800f7eeb00a51b3747201f77d5cc663f48e13 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Tue, 22 Dec 2015 20:35:35 +0100 Subject: [PATCH 6/8] external player (multiple) setbackgourd tag problem fixed --- .../src/com/jpexs/decompiler/flash/SWF.java | 11 ++++++ .../flash/exporters/FrameExporter.java | 22 ++++------- .../decompiler/flash/xfl/XFLConverter.java | 10 ++--- .../decompiler/flash/gui/PreviewPanel.java | 37 ++++++++++++------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index f49d54729..340c6b803 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -91,6 +91,7 @@ import com.jpexs.decompiler.flash.tags.FileAttributesTag; import com.jpexs.decompiler.flash.tags.JPEGTablesTag; import com.jpexs.decompiler.flash.tags.MetadataTag; import com.jpexs.decompiler.flash.tags.ProtectTag; +import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.SymbolClassTag; import com.jpexs.decompiler.flash.tags.Tag; @@ -562,6 +563,16 @@ public final class SWF implements SWFContainerItem, Timelined { return null; } + public SetBackgroundColorTag getBackgroundColor() { + for (Tag t : tags) { + if (t instanceof SetBackgroundColorTag) { + return (SetBackgroundColorTag) t; + } + } + + return null; + } + public EnableTelemetryTag getEnableTelemetry() { for (Tag t : tags) { if (t instanceof EnableTelemetryTag) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java index de78e69e8..101938446 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java @@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.helpers.BMPFile; import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; -import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.decompiler.flash.timeline.DepthState; @@ -173,13 +172,9 @@ public class FrameExporter { final List fframes = frames; Color backgroundColor = null; - if (settings.mode == FrameExportMode.AVI) { - for (Tag t : swf.tags) { - if (t instanceof SetBackgroundColorTag) { - SetBackgroundColorTag sb = (SetBackgroundColorTag) t; - backgroundColor = sb.backgroundColor.toColor(); - } - } + SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor(); + if (setBgColorTag != null) { + backgroundColor = setBgColorTag.backgroundColor.toColor(); } if (settings.mode == FrameExportMode.SVG) { @@ -189,7 +184,7 @@ public class FrameExporter { } final int fi = i; - final Color fbackgroundColor = backgroundColor; + final Color fbackgroundColor = null; new RetryTask(() -> { int frame = fframes.get(fi); File f = new File(foutdir + File.separator + frame + ".svg"); @@ -223,7 +218,7 @@ public class FrameExporter { } final Timeline ftim = tim; - final Color fbackgroundColor = backgroundColor; + final Color fbackgroundColor = null; final SWF fswf = swf; new RetryTask(() -> { File fcanvas = new File(foutdir + File.separator + "canvas.js"); @@ -259,11 +254,8 @@ public class FrameExporter { } sb.append("\r\n"); RGB backgroundColor1 = new RGB(255, 255, 255); - for (Tag t : fswf.tags) { - if (t instanceof SetBackgroundColorTag) { - SetBackgroundColorTag sbgct = (SetBackgroundColorTag) t; - backgroundColor1 = sbgct.backgroundColor; - } + if (setBgColorTag != null) { + backgroundColor1 = setBgColorTag.backgroundColor; } sb.append("var backgroundColor = \"").append(backgroundColor1.toHexRGB()).append("\";\r\n"); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index 15b4350cb..9d5db8b79 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -103,7 +103,6 @@ import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.decompiler.flash.types.sound.MP3FRAME; import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA; import com.jpexs.decompiler.flash.types.sound.SoundFormat; -import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; import com.jpexs.helpers.SerializableImage; import com.jpexs.helpers.utf8.Utf8Helper; @@ -2688,12 +2687,11 @@ public class XFLConverter { Map characterVariables = getCharacterVariables(swf.tags); String backgroundColor = "#ffffff"; - for (Tag t : swf.tags) { - if (t instanceof SetBackgroundColorTag) { - SetBackgroundColorTag sbc = (SetBackgroundColorTag) t; - backgroundColor = sbc.backgroundColor.toHexRGB(); - } + SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor(); + if (setBgColorTag != null) { + backgroundColor = setBgColorTag.backgroundColor.toHexRGB(); } + domDocument.append(" doneCharacters = new ArrayList<>(); int frameCnt = 0; for (Tag t : subs) { + if (t instanceof FileAttributesTag || t instanceof SetBackgroundColorTag) { + continue; + } + if (t instanceof ShowFrameTag) { frameCnt++; continue; } + if (frameCnt > fn.frame) { break; } @@ -1059,11 +1070,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel public void showSwf(SWF swf) { Color backgroundColor = View.getDefaultBackgroundColor(); - for (Tag t : swf.tags) { - if (t instanceof SetBackgroundColorTag) { - backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); - break; - } + SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor(); + if (setBgColorTag != null) { + backgroundColor = setBgColorTag.backgroundColor.toColor(); } if (tempFile != null) { From 5255d9e80e9629336a6dc10eb950e873274908e2 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Wed, 23 Dec 2015 22:23:52 +0100 Subject: [PATCH 7/8] svg import: do not load dtd (from internet when xml is parsed) --- .../src/com/jpexs/decompiler/flash/importers/ShapeImporter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java index 757ed0399..3597da7b8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java @@ -173,6 +173,7 @@ public class ShapeImporter { try { DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.parse(new InputSource(new StringReader(svgXml))); Element rootElement = doc.getDocumentElement(); From f9254ef60b4abc98eff6bd4c65387258ca0b8794 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Thu, 24 Dec 2015 17:37:17 +0100 Subject: [PATCH 8/8] external player preview fixes --- .../flash/tags/PlaceObject2Tag.java | 26 ++- .../flash/tags/PlaceObject3Tag.java | 54 ++++++- .../flash/tags/PlaceObject4Tag.java | 55 ++++++- .../decompiler/flash/tags/PlaceObjectTag.java | 14 +- .../flash/tags/base/PlaceObjectTypeTag.java | 4 + .../decompiler/flash/timeline/DepthState.java | 37 ++++- .../decompiler/flash/timeline/Timeline.java | 1 + .../jpexs/decompiler/flash/types/CXFORM.java | 21 +++ .../flash/types/CXFORMWITHALPHA.java | 24 ++- .../decompiler/flash/gui/ImagePanel.java | 4 +- .../decompiler/flash/gui/PreviewPanel.java | 149 +++++++++--------- 11 files changed, 285 insertions(+), 104 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java index 1ccfa6af2..a0bf0c07f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java @@ -149,15 +149,15 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont super(swf, ID, NAME, null); } - public PlaceObject2Tag(SWF swf, boolean placeFlagHasClipActions, boolean placeFlagHasClipDepth, boolean placeFlagHasName, boolean placeFlagHasRatio, boolean placeFlagHasColorTransform, boolean placeFlagHasMatrix, boolean placeFlagHasCharacter, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) { + public PlaceObject2Tag(SWF swf, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) { super(swf, ID, NAME, null); - this.placeFlagHasClipActions = placeFlagHasClipActions; - this.placeFlagHasClipDepth = placeFlagHasClipDepth; - this.placeFlagHasName = placeFlagHasName; - this.placeFlagHasRatio = placeFlagHasRatio; - this.placeFlagHasColorTransform = placeFlagHasColorTransform; - this.placeFlagHasMatrix = placeFlagHasMatrix; - this.placeFlagHasCharacter = placeFlagHasCharacter; + this.placeFlagHasClipActions = clipActions != null; + this.placeFlagHasClipDepth = clipDepth >= 0; + this.placeFlagHasName = name != null; + this.placeFlagHasRatio = ratio >= 0; + this.placeFlagHasColorTransform = colorTransform != null; + this.placeFlagHasMatrix = matrix != null; + this.placeFlagHasCharacter = characterId >= 0; this.placeFlagMove = placeFlagMove; this.depth = depth; this.characterId = characterId; @@ -256,6 +256,11 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont } } + @Override + public int getPlaceObjectNum() { + return 2; + } + @Override public int getClipDepth() { if (placeFlagHasClipDepth) { @@ -329,6 +334,11 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont } } + @Override + public void setMatrix(MATRIX matrix) { + this.matrix = matrix; + } + @Override public String getInstanceName() { if (placeFlagHasName) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java index ea8de42b5..86365e845 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java @@ -239,6 +239,38 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont super(swf, ID, NAME, null); } + public PlaceObject3Tag(SWF swf, boolean placeFlagMove, int depth, String className, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, List surfaceFilterList, int blendMode, int bitmapCache, int visible, RGBA backgroundColor, CLIPACTIONS clipActions) { + super(swf, ID, NAME, null); + this.placeFlagHasClassName = className != null; + this.placeFlagHasFilterList = surfaceFilterList != null; + this.placeFlagHasBlendMode = blendMode >= 0; + this.placeFlagHasCacheAsBitmap = bitmapCache >= 0; + this.placeFlagHasVisible = visible >= 0; + this.placeFlagOpaqueBackground = backgroundColor != null; + this.placeFlagHasClipActions = clipActions != null; + this.placeFlagHasClipDepth = clipDepth >= 0; + this.placeFlagHasName = name != null; + this.placeFlagHasRatio = ratio >= 0; + this.placeFlagHasColorTransform = colorTransform != null; + this.placeFlagHasMatrix = matrix != null; + this.placeFlagHasCharacter = characterId >= 0; + this.placeFlagMove = placeFlagMove; + this.depth = depth; + this.className = className; + this.characterId = characterId; + this.matrix = matrix; + this.colorTransform = colorTransform; + this.ratio = ratio; + this.name = name; + this.clipDepth = clipDepth; + this.surfaceFilterList = surfaceFilterList; + this.blendMode = blendMode; + this.bitmapCache = bitmapCache; + this.visible = visible; + this.backgroundColor = backgroundColor; + this.clipActions = clipActions; + } + /** * Constructor * @@ -390,12 +422,8 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont } @Override - public List getFilters() { - if (placeFlagHasFilterList) { - return surfaceFilterList; - } else { - return null; - } + public int getPlaceObjectNum() { + return 3; } @Override @@ -406,6 +434,15 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont return -1; } + @Override + public List getFilters() { + if (placeFlagHasFilterList) { + return surfaceFilterList; + } else { + return null; + } + } + /** * Returns all sub-items * @@ -466,6 +503,11 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont } } + @Override + public void setMatrix(MATRIX matrix) { + this.matrix = matrix; + } + @Override public String getInstanceName() { if (placeFlagHasName) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java index 707921f77..235280161 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java @@ -241,6 +241,39 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont super(swf, ID, NAME, null); } + public PlaceObject4Tag(SWF swf, boolean placeFlagMove, int depth, String className, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, List surfaceFilterList, int blendMode, int bitmapCache, int visible, RGBA backgroundColor, CLIPACTIONS clipActions, byte[] amfData) { + super(swf, ID, NAME, null); + this.placeFlagHasClassName = className != null; + this.placeFlagHasFilterList = surfaceFilterList != null; + this.placeFlagHasBlendMode = blendMode >= 0; + this.placeFlagHasCacheAsBitmap = bitmapCache >= 0; + this.placeFlagHasVisible = visible >= 0; + this.placeFlagOpaqueBackground = backgroundColor != null; + this.placeFlagHasClipActions = clipActions != null; + this.placeFlagHasClipDepth = clipDepth >= 0; + this.placeFlagHasName = name != null; + this.placeFlagHasRatio = ratio >= 0; + this.placeFlagHasColorTransform = colorTransform != null; + this.placeFlagHasMatrix = matrix != null; + this.placeFlagHasCharacter = characterId >= 0; + this.placeFlagMove = placeFlagMove; + this.depth = depth; + this.className = className; + this.characterId = characterId; + this.matrix = matrix; + this.colorTransform = colorTransform; + this.ratio = ratio; + this.name = name; + this.clipDepth = clipDepth; + this.surfaceFilterList = surfaceFilterList; + this.blendMode = blendMode; + this.bitmapCache = bitmapCache; + this.visible = visible; + this.backgroundColor = backgroundColor; + this.clipActions = clipActions; + this.amfData = amfData; + } + /** * Constructor * @@ -394,12 +427,8 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont } @Override - public List getFilters() { - if (placeFlagHasFilterList) { - return surfaceFilterList; - } else { - return null; - } + public int getPlaceObjectNum() { + return 4; } @Override @@ -410,6 +439,15 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont return -1; } + @Override + public List getFilters() { + if (placeFlagHasFilterList) { + return surfaceFilterList; + } else { + return null; + } + } + /** * Returns all sub-items * @@ -470,6 +508,11 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont } } + @Override + public void setMatrix(MATRIX matrix) { + this.matrix = matrix; + } + @Override public String getInstanceName() { if (placeFlagHasName) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java index 21302a43c..60621cf95 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObjectTag.java @@ -127,8 +127,8 @@ public class PlaceObjectTag extends PlaceObjectTypeTag { public CXFORM colorTransform; @Override - public List getFilters() { - return null; + public int getPlaceObjectNum() { + return 1; } @Override @@ -136,6 +136,11 @@ public class PlaceObjectTag extends PlaceObjectTypeTag { return -1; } + @Override + public List getFilters() { + return null; + } + @Override public void getNeededCharacters(Set needed) { needed.add(characterId); @@ -172,6 +177,11 @@ public class PlaceObjectTag extends PlaceObjectTypeTag { return matrix; } + @Override + public void setMatrix(MATRIX matrix) { + this.matrix = matrix; + } + @Override public String getInstanceName() { return null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java index bff110857..ba3d8c2c8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java @@ -38,10 +38,14 @@ public abstract class PlaceObjectTypeTag extends Tag implements CharacterIdTag { super(swf, id, name, data); } + public abstract int getPlaceObjectNum(); + public abstract int getDepth(); public abstract MATRIX getMatrix(); + public abstract void setMatrix(MATRIX matrix); + public abstract String getInstanceName(); public abstract void setInstanceName(String name); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/DepthState.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/DepthState.java index 135ee97aa..6973e8e9a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/DepthState.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/DepthState.java @@ -17,8 +17,14 @@ package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject3Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject4Tag; +import com.jpexs.decompiler.flash.tags.PlaceObjectTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.types.CLIPACTIONS; +import com.jpexs.decompiler.flash.types.CXFORM; +import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RGBA; @@ -35,11 +41,11 @@ public class DepthState { public int characterId = -1; - public MATRIX matrix = null; + public MATRIX matrix; - public String instanceName = null; + public String instanceName; - public ColorTransform colorTransForm = null; + public ColorTransform colorTransForm; public boolean cacheAsBitmap = false; @@ -49,9 +55,11 @@ public class DepthState { public boolean isVisible = true; - public RGBA backGroundColor = null; + public RGBA backGroundColor; - public CLIPACTIONS clipActions = null; + public CLIPACTIONS clipActions; + + public byte[] amfData; public int ratio = -1; @@ -67,6 +75,8 @@ public class DepthState { public PlaceObjectTypeTag placeObjectTag; + public int minPlaceObjectNum; + public long instanceId; public boolean motionTween = false; @@ -100,6 +110,7 @@ public class DepthState { clipDepth = obj.clipDepth; time = obj.time; placeObjectTag = obj.placeObjectTag; + minPlaceObjectNum = obj.minPlaceObjectNum; if (sameInstance) { time++; instanceId = obj.instanceId; @@ -107,4 +118,20 @@ public class DepthState { instanceId = getNewInstanceId(); } } + + public PlaceObjectTypeTag toPlaceObjectTag(int depth) { + if (minPlaceObjectNum <= 1) { + CXFORM cxForm0 = colorTransForm == null ? null : new CXFORM(colorTransForm); + return new PlaceObjectTag(swf, characterId, depth, matrix, cxForm0); + } else if (minPlaceObjectNum == 2) { + CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm); + return new PlaceObject2Tag(swf, false, depth, characterId, matrix, cxForm, ratio, instanceName, clipDepth, clipActions); + } else if (minPlaceObjectNum == 3) { + CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm); + return new PlaceObject3Tag(swf, false, depth, null/*todo: className*/, characterId, matrix, cxForm, ratio, instanceName, clipDepth, filters, blendMode, cacheAsBitmap ? 1 : 0, isVisible ? 1 : 0, backGroundColor, clipActions); + } + + CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm); + return new PlaceObject4Tag(swf, false, depth, null/*todo: className*/, characterId, matrix, cxForm, ratio, instanceName, clipDepth, filters, blendMode, cacheAsBitmap ? 1 : 0, isVisible ? 1 : 0, backGroundColor, clipActions, null); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 38e63e4f4..12f03bc4d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -263,6 +263,7 @@ public class Timeline { } frame.layersChanged = true; fl.placeObjectTag = po; + fl.minPlaceObjectNum = Math.max(fl.minPlaceObjectNum, po.getPlaceObjectNum()); int characterId = po.getCharacterId(); if (characterId != -1) { fl.characterId = characterId; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORM.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORM.java index 5be519e72..683d6a742 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORM.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORM.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.types; import com.jpexs.decompiler.flash.types.annotations.Calculated; +import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.SWFType; /** @@ -44,36 +45,42 @@ public class CXFORM extends ColorTransform { /** * Red multiply value */ + @Conditional("hasMultTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int redMultTerm; /** * Green multiply value */ + @Conditional("hasMultTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int greenMultTerm; /** * Blue multiply value */ + @Conditional("hasMultTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int blueMultTerm; /** * Red addition value */ + @Conditional("hasAddTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int redAddTerm; /** * Green addition value */ + @Conditional("hasAddTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int greenAddTerm; /** * Blue addition value */ + @Conditional("hasAddTerms") @SWFType(value = BasicType.SB, countField = "nbits") public int blueAddTerm; @@ -107,6 +114,20 @@ public class CXFORM extends ColorTransform { return hasMultTerms ? blueMultTerm : super.getBlueMulti(); } + public CXFORM() { + } + + public CXFORM(ColorTransform colorTransform) { + redMultTerm = colorTransform.getRedMulti(); + greenMultTerm = colorTransform.getGreenMulti(); + blueMultTerm = colorTransform.getBlueMulti(); + redAddTerm = colorTransform.getRedAdd(); + greenAddTerm = colorTransform.getGreenAdd(); + blueAddTerm = colorTransform.getBlueAdd(); + hasAddTerms = redAddTerm != 0 || greenAddTerm != 0 || blueAddTerm != 0; + hasMultTerms = redMultTerm != 255 || greenMultTerm != 255 || blueMultTerm != 255; + } + @Override public CXFORM clone() { CXFORM ret = (CXFORM) super.clone(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java index 83a9c49f9..5f1972e2b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java @@ -38,6 +38,10 @@ public class CXFORMWITHALPHA extends ColorTransform { */ public boolean hasMultTerms; + @Calculated + @SWFType(value = BasicType.UB, count = 4) + public int nbits; + /** * Red multiply value */ @@ -94,10 +98,6 @@ public class CXFORMWITHALPHA extends ColorTransform { @SWFType(value = BasicType.SB, countField = "nbits") public int alphaAddTerm; - @Calculated - @SWFType(value = BasicType.UB, count = 4) - public int nbits; - @Override public int getRedAdd() { return hasAddTerms ? redAddTerm : super.getRedAdd(); @@ -138,6 +138,22 @@ public class CXFORMWITHALPHA extends ColorTransform { return hasMultTerms ? alphaMultTerm : super.getAlphaMulti(); } + public CXFORMWITHALPHA() { + } + + public CXFORMWITHALPHA(ColorTransform colorTransform) { + redMultTerm = colorTransform.getRedMulti(); + greenMultTerm = colorTransform.getGreenMulti(); + blueMultTerm = colorTransform.getBlueMulti(); + alphaMultTerm = colorTransform.getAlphaMulti(); + redAddTerm = colorTransform.getRedAdd(); + greenAddTerm = colorTransform.getGreenAdd(); + blueAddTerm = colorTransform.getBlueAdd(); + alphaAddTerm = colorTransform.getAlphaAdd(); + hasAddTerms = redAddTerm != 0 || greenAddTerm != 0 || blueAddTerm != 0 || alphaAddTerm != 0; + hasMultTerms = redMultTerm != 255 || greenMultTerm != 255 || blueMultTerm != 255 || alphaMultTerm != 255; + } + @Override public CXFORMWITHALPHA clone() { CXFORMWITHALPHA ret = (CXFORMWITHALPHA) super.clone(); diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index dd38ac07e..bdeb98cea 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -951,7 +951,9 @@ public final class ImagePanel extends JPanel implements MediaDisplay { float frameRate = timeline.frameRate; int msPerFrame = frameRate == 0 ? 1000 : (int) (1000.0 / frameRate); - final boolean singleFrame = !playing || (timeline.getRealFrameCount() <= 1 && timeline.isSingleFrame()); + final boolean singleFrame = !playing + || (stillFrame && timeline.isSingleFrame(frame)) + || (!stillFrame && timeline.getRealFrameCount() <= 1 && timeline.isSingleFrame()); timer = new Timer(); TimerTask task = new TimerTask() { diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 2087f7762..d3fc51d46 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -55,9 +55,11 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.decompiler.flash.tags.base.RemoveTag; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.TagScript; import com.jpexs.decompiler.flash.timeline.Timelined; @@ -69,7 +71,6 @@ import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; -import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; import java.awt.BorderLayout; import java.awt.CardLayout; @@ -93,6 +94,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -588,7 +590,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel return t; } - public void createAndShowTempSwf(TreeItem tagObj) { + public void createAndShowTempSwf(TreeItem treeItem) { SWF swf = null; try { if (tempFile != null) { @@ -600,14 +602,14 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel Color backgroundColor = View.getSwfBackgroundColor(); - if (tagObj instanceof Tag) { - Tag tag = (Tag) tagObj; + if (treeItem instanceof Tag) { + Tag tag = (Tag) treeItem; swf = tag.getSwf(); if (tag instanceof FontTag) { //Fonts are always black on white backgroundColor = View.getDefaultBackgroundColor(); } - } else if (tagObj instanceof Frame) { - Frame fn = (Frame) tagObj; + } else if (treeItem instanceof Frame) { + Frame fn = (Frame) treeItem; swf = fn.getSwf(); if (fn.timeline.timelined == swf) { SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor(); @@ -620,29 +622,29 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel int frameCount = 1; float frameRate = swf.frameRate; HashMap videoFrames = new HashMap<>(); - if (tagObj instanceof DefineVideoStreamTag) { - DefineVideoStreamTag vs = (DefineVideoStreamTag) tagObj; + if (treeItem instanceof DefineVideoStreamTag) { + DefineVideoStreamTag vs = (DefineVideoStreamTag) treeItem; SWF.populateVideoFrames(vs.getCharacterId(), swf.tags, videoFrames); frameCount = videoFrames.size(); } List soundFrames = new ArrayList<>(); - if (tagObj instanceof SoundStreamHeadTypeTag) { - soundFrames = ((SoundStreamHeadTypeTag) tagObj).getBlocks(); + if (treeItem instanceof SoundStreamHeadTypeTag) { + soundFrames = ((SoundStreamHeadTypeTag) treeItem).getBlocks(); frameCount = soundFrames.size(); } - if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { + if ((treeItem instanceof DefineMorphShapeTag) || (treeItem instanceof DefineMorphShape2Tag)) { frameRate = MainPanel.MORPH_SHAPE_ANIMATION_FRAME_RATE; frameCount = (int) (MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate); } - if (tagObj instanceof DefineSoundTag) { + if (treeItem instanceof DefineSoundTag) { frameCount = 1; } - if (tagObj instanceof DefineSpriteTag) { - frameCount = ((DefineSpriteTag) tagObj).frameCount; + if (treeItem instanceof DefineSpriteTag) { + frameCount = ((DefineSpriteTag) treeItem).frameCount; } byte[] data; @@ -650,12 +652,28 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel SWFOutputStream sos2 = new SWFOutputStream(baos, SWF.DEFAULT_VERSION); RECT outrect = new RECT(swf.displayRect); - if (tagObj instanceof FontTag) { + RECT treeItemBounds = null; + if (treeItem instanceof FontTag) { outrect.Xmin = 0; outrect.Ymin = 0; outrect.Xmax = FontTag.PREVIEWSIZE * 20; outrect.Ymax = FontTag.PREVIEWSIZE * 20; + } else if (treeItem instanceof BoundedTag) { + treeItemBounds = ((BoundedTag) treeItem).getRect(); + } else if (treeItem instanceof Frame) { + treeItemBounds = ((Frame) treeItem).timeline.timelined.getRect(); } + + if (treeItemBounds != null) { + if (outrect.getWidth() < treeItemBounds.getWidth()) { + outrect.Xmax += treeItemBounds.getWidth() - outrect.getWidth(); + } + + if (outrect.getHeight() < treeItemBounds.getHeight()) { + outrect.Ymax += treeItemBounds.getHeight() - outrect.getHeight(); + } + } + int width = outrect.getWidth(); int height = outrect.getHeight(); @@ -675,26 +693,15 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel setBgColorTag.writeTag(sos2); - if (tagObj instanceof Frame) { - Frame fn = (Frame) tagObj; + if (treeItem instanceof Frame) { + Frame fn = (Frame) treeItem; Timelined parent = fn.timeline.timelined; - List subs = fn.timeline.tags; List doneCharacters = new ArrayList<>(); - int frameCnt = 0; - for (Tag t : subs) { + for (Tag t : fn.timeline.tags) { if (t instanceof FileAttributesTag || t instanceof SetBackgroundColorTag) { continue; } - if (t instanceof ShowFrameTag) { - frameCnt++; - continue; - } - - if (frameCnt > fn.frame) { - break; - } - if (t instanceof DoActionTag || t instanceof DoInitActionTag) { // todo: Maybe DoABC tags should be removed, too continue; @@ -708,53 +715,52 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel doneCharacters.add(n); } } + + if (t instanceof ShowFrameTag || t instanceof PlaceObjectTypeTag || t instanceof RemoveTag) { + continue; + } + if (t instanceof CharacterTag) { int characterId = ((CharacterTag) t).getCharacterId(); if (!doneCharacters.contains(characterId)) { doneCharacters.add(((CharacterTag) t).getCharacterId()); } } + classicTag(t).writeTag(sos2); - - if (parent != null) { - if (t instanceof PlaceObjectTypeTag) { - PlaceObjectTypeTag pot = (PlaceObjectTypeTag) t; - int chid = pot.getCharacterId(); - int depth = pot.getDepth(); - MATRIX mat = pot.getMatrix(); - if (mat == null) { - mat = new MATRIX(); - } - mat = Helper.deepCopy(mat); - RECT r = parent.getRect(); - mat.translateX += width / 2 - r.getWidth() / 2; - mat.translateY += height / 2 - r.getHeight() / 2; - new PlaceObject2Tag(swf, false, false, false, false, false, true, false, true, depth, chid, mat, null, 0, null, 0, null).writeTag(sos2); - - } - } } + + RECT r = parent.getRect(); + for (Map.Entry value : fn.layers.entrySet()) { + PlaceObjectTypeTag pot = value.getValue().toPlaceObjectTag(value.getKey()); + MATRIX mat = new MATRIX(pot.getMatrix()); + mat.translateX += width / 2 - r.getWidth() / 2; + mat.translateY += height / 2 - r.getHeight() / 2; + pot.setMatrix(mat); + pot.writeTag(sos2); + } + new ShowFrameTag(swf).writeTag(sos2); } else { boolean isSprite = false; - if (tagObj instanceof DefineSpriteTag) { + if (treeItem instanceof DefineSpriteTag) { isSprite = true; } int chtId = 0; - if (tagObj instanceof CharacterTag) { - chtId = ((CharacterTag) tagObj).getCharacterId(); + if (treeItem instanceof CharacterTag) { + chtId = ((CharacterTag) treeItem).getCharacterId(); } - if (tagObj instanceof DefineBitsTag) { + if (treeItem instanceof DefineBitsTag) { JPEGTablesTag jtt = swf.getJtt(); if (jtt != null) { jtt.writeTag(sos2); } - } else if (tagObj instanceof AloneTag) { + } else if (treeItem instanceof AloneTag) { } else { Set needed = new HashSet<>(); - ((Tag) tagObj).getNeededCharactersDeep(needed); + ((Tag) treeItem).getNeededCharactersDeep(needed); for (int n : needed) { if (isSprite && chtId == n) { continue; @@ -772,15 +778,15 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel } } - classicTag((Tag) tagObj).writeTag(sos2); + classicTag((Tag) treeItem).writeTag(sos2); MATRIX mat = new MATRIX(); mat.hasRotate = false; mat.hasScale = false; mat.translateX = 0; mat.translateY = 0; - if (tagObj instanceof BoundedTag) { - RECT r = ((BoundedTag) tagObj).getRect(); + if (treeItem instanceof BoundedTag) { + RECT r = ((BoundedTag) treeItem).getRect(); mat.translateX = -r.Xmin; mat.translateY = -r.Ymin; mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; @@ -789,9 +795,8 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel mat.translateX = width / 4; mat.translateY = height / 4; } - if (tagObj instanceof FontTag) { - - FontTag ft = (FontTag) classicTag((Tag) tagObj); + if (treeItem instanceof FontTag) { + FontTag ft = (FontTag) classicTag((Tag) treeItem); int countGlyphsTotal = ft.getGlyphShapeTable().size(); int countGlyphs = Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW, countGlyphsTotal); @@ -875,25 +880,25 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel tmat.translateX = x * width / cols + width / cols / 2 - w / 2; tmat.translateY = y * height / rows + height / rows / 2; new DefineTextTag(swf, 999 + f, new RECT(0, cw, ymin, ymin + h), new MATRIX(), rec).writeTag(sos2); - new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1 + f, 999 + f, tmat, null, 0, null, 0, null).writeTag(sos2); + new PlaceObject2Tag(swf, false, 1 + f, 999 + f, tmat, null, 0, null, -1, null).writeTag(sos2); x++; } new ShowFrameTag(swf).writeTag(sos2); - } else if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { - new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2); + } else if ((treeItem instanceof DefineMorphShapeTag) || (treeItem instanceof DefineMorphShape2Tag)) { + new PlaceObject2Tag(swf, false, 1, chtId, mat, null, 0, null, -1, null).writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); for (int ratio = 0; ratio < 65536; ratio += 65536 / frameCount) { - new PlaceObject2Tag(swf, false, false, false, true, false, true, false, true, 1, chtId, mat, null, ratio, null, 0, null).writeTag(sos2); + new PlaceObject2Tag(swf, true, 1, chtId, mat, null, ratio, null, -1, null).writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); } - } else if (tagObj instanceof SoundStreamHeadTypeTag) { + } else if (treeItem instanceof SoundStreamHeadTypeTag) { for (SoundStreamBlockTag blk : soundFrames) { blk.writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); } - } else if (tagObj instanceof DefineSoundTag) { + } else if (treeItem instanceof DefineSoundTag) { ExportAssetsTag ea = new ExportAssetsTag(swf); - DefineSoundTag ds = (DefineSoundTag) tagObj; + DefineSoundTag ds = (DefineSoundTag) treeItem; ea.tags.add(ds.soundId); ea.names.add("my_define_sound"); ea.writeTag(sos2); @@ -999,9 +1004,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel new ShowFrameTag(swf).writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); - } else if (tagObj instanceof DefineVideoStreamTag) { + } else if (treeItem instanceof DefineVideoStreamTag) { - new PlaceObject2Tag(swf, false, false, false, false, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2); + new PlaceObject2Tag(swf, false, 1, chtId, mat, null, -1, null, -1, null).writeTag(sos2); List frs = new ArrayList<>(videoFrames.values()); Collections.sort(frs, new Comparator() { @Override @@ -1014,14 +1019,14 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel for (VideoFrameTag f : frs) { if (!first) { ratio++; - new PlaceObject2Tag(swf, false, false, false, true, false, false, false, true, 1, 0, null, null, ratio, null, 0, null).writeTag(sos2); + new PlaceObject2Tag(swf, true, 1, 0, null, null, ratio, null, -1, null).writeTag(sos2); } f.writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); first = false; } - } else if (tagObj instanceof DefineSpriteTag) { - DefineSpriteTag s = (DefineSpriteTag) tagObj; + } else if (treeItem instanceof DefineSpriteTag) { + DefineSpriteTag s = (DefineSpriteTag) treeItem; Tag lastTag = null; for (Tag t : s.subTags) { if (t instanceof EndTag) { @@ -1041,7 +1046,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel new ShowFrameTag(swf).writeTag(sos2); } } else { - new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2); + new PlaceObject2Tag(swf, false, 1, chtId, mat, null, 0, null, -1, null).writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); }