diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aab83559..a0dbbed90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ All notable changes to this project will be documented in this file. - Outputstreams position calculation (ABCOutputStream, ...) - [#2260] Reading end of file on old GFX format (1.x) - [#2260] DefineExternalImage on old GFX format (1.x) +- fontFace html attribute in DefineEditText can be also an exportName +- BUTTONRECORD preview not showing in situations like GFX or importAssets ### Changed - [#2185] MochiCrypt no longer offered for auto decrypt, user needs to choose variant from "Use unpacker" menu @@ -72,7 +74,8 @@ All notable changes to this project will be documented in this file. - Information in the tag node title now has abbreviated prefix of type for each bit of info. Example: `DefineSprite (chid: 27, cls: pkg.MySprite)` instead of `DefineSprite (27, pkg.MySprite)` - Information in the tag node title - separated exportName from assigned class - +- ImportAssets tag reorganized - now imported items are not in the tag tree, but when referenced it works + ## [20.1.0] - 2023-12-30 ### Added - Configurable tab size (formatting must be set to use tabs) - default matches indent size of 3 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 a1b87e7f1..751ed0edd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -207,6 +207,7 @@ import java.util.Date; import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -323,7 +324,14 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { @Internal private volatile Map characters; + + @Internal + private volatile Map charactersWithImported; + + @Internal + private volatile Map characterToId; + @Internal private volatile Map externalImages2; @@ -417,6 +425,9 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { @Internal private Map exportNameToCharacter = new HashMap<>(); + @Internal + private Map importedNameToCharacter = new HashMap<>(); + @Internal private AbcIndexing abcIndex; @@ -430,7 +441,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { @Internal public String debuggerPackage = null; - + + private Map importedCharacterSourceSwfs = new HashMap<>(); + private Map importedCharacterIds = new HashMap<>(); + + private static AbcIndexing playerGlobalAbcIndex; private static AbcIndexing airGlobalAbcIndex; @@ -572,6 +587,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { public void updateCharacters() { characters = null; + charactersWithImported = null; + characterToId = null; characterIdTags = null; externalImages2 = null; } @@ -628,6 +645,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { clearAbcListCache(); characters = null; + charactersWithImported = null; + characterToId = null; characterIdTags = null; externalImages2 = null; @@ -647,31 +666,59 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { di.getChildInfos().clear(); } - - public Map getCharacters() { - if (characters == null) { + + public Map getCharacters(boolean withImported) { + if (characters == null) { synchronized (this) { if (characters == null) { if (destroyed) { return new HashMap<>(); } Map chars = new HashMap<>(); + Map charsWithImported = new HashMap<>(); Map> charIdtags = new HashMap<>(); Map eimages = new HashMap<>(); parseCharacters(getTags(), eimages, chars, charIdtags); + charsWithImported.putAll(chars); + for (int importedCharacterId : importedCharacterIds.keySet()) { + int exportedCharacterId = importedCharacterIds.get(importedCharacterId); + SWF importedSwf = importedCharacterSourceSwfs.get(importedCharacterId); + charsWithImported.put(importedCharacterId, importedSwf.getCharacter(exportedCharacterId)); + charIdtags.put(importedCharacterId, importedSwf.getCharacterIdTags(exportedCharacterId)); + //FIXME? eimages + + charsWithImported.get(importedCharacterId).setImported(true, true); + for (CharacterIdTag chi : charIdtags.get(importedCharacterId)) { + if (chi instanceof Tag) { + ((Tag) chi).setImported(true, true); + } + } + } + Map charToId = new IdentityHashMap<>(); + for (int id : charsWithImported.keySet()) { + charToId.put(charsWithImported.get(id), id); + } + for (int id : charIdtags.keySet()) { + for (CharacterIdTag ch : charIdtags.get(id)) { + charToId.put(ch, id); + } + } + characters = Collections.unmodifiableMap(chars); + charactersWithImported = Collections.unmodifiableMap(charsWithImported); + characterToId = Collections.unmodifiableMap(charToId); characterIdTags = Collections.unmodifiableMap(charIdtags); externalImages2 = Collections.unmodifiableMap(eimages); } } } - return characters; + return withImported ? charactersWithImported : characters; } public Map getExternalImages2() { if (externalImages2 == null) { - getCharacters(); + getCharacters(true); } return externalImages2; } @@ -683,12 +730,12 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { public List getCharacterIdTags(int characterId) { if (characterIdTags == null) { - getCharacters(); + getCharacters(true); } return characterIdTags.get(characterId); } - + public CharacterIdTag getCharacterIdTag(int characterId, int tagId) { List characterIdTags = getCharacterIdTags(characterId); if (characterIdTags != null) { @@ -760,7 +807,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { for (int chId : dependents2) { if (!visited.contains(chId)) { visited.add(chId); - if (getCharacters().containsKey(chId)) { + if (getCharacters(true).containsKey(chId)) { deps = getDependentCharacters().get(chId); if (deps != null) { dependents2.addAll(deps); @@ -774,7 +821,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { Set dependents = new LinkedHashSet<>(); for (Integer chId : dependents2) { - if (getCharacters().containsKey(chId)) { + if (getCharacters(true).containsKey(chId)) { dependents.add(chId); } } @@ -816,7 +863,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public CharacterTag getCharacter(int characterId) { - return getCharacters().get(characterId); + return getCharacters(true).get(characterId); } public CharacterTag getCharacterByClass(String className) { @@ -828,15 +875,19 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public CharacterTag getCharacterByExportName(String exportName) { - if (!exportNameToCharacter.containsKey(exportName)) { - return null; + int charId; + if (importedNameToCharacter.containsKey(exportName)) { + charId = importedNameToCharacter.get(exportName); + } else if (exportNameToCharacter.containsKey(exportName)){ + charId = exportNameToCharacter.get(exportName); + } else { + return null; } - int charId = exportNameToCharacter.get(exportName); return getCharacter(charId); } public String getExportName(int characterId) { - CharacterTag characterTag = getCharacters().get(characterId); + CharacterTag characterTag = getCharacters(true).get(characterId); String exportName = characterTag != null ? characterTag.getExportName() : null; return exportName; } @@ -884,8 +935,24 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { return null; } + /** + * This gets real character id of a character tag on this SWF. + * Normal .getCharacterId method od the CharacterTag does not work for imported characters + * @param tag + * @return Character id or -1 if not found + */ + public int getCharacterId(CharacterIdTag tag) { + if (characterToId == null) { + getCharacters(true); + } + if (!characterToId.containsKey(tag)) { + return -1; + } + return characterToId.get(tag); + } + public FontTag getFont(int fontId) { - CharacterTag characterTag = getCharacters().get(fontId); + CharacterTag characterTag = getCharacters(true).get(fontId); if (characterTag instanceof FontTag) { return (FontTag) characterTag; } @@ -898,7 +965,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public ImageTag getImage(int imageId) { - CharacterTag characterTag = getCharacters().get(imageId); + CharacterTag characterTag = getCharacters(true).get(imageId); if (characterTag instanceof ImageTag) { return (ImageTag) characterTag; } @@ -911,7 +978,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public DefineSoundTag getSound(int soundId) { - CharacterTag characterTag = getCharacters().get(soundId); + CharacterTag characterTag = getCharacters(true).get(soundId); if (characterTag instanceof DefineSoundTag) { return (DefineSoundTag) characterTag; } @@ -924,7 +991,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public TextTag getText(int textId) { - CharacterTag characterTag = getCharacters().get(textId); + CharacterTag characterTag = getCharacters(true).get(textId); if (characterTag instanceof TextTag) { return (TextTag) characterTag; } @@ -996,7 +1063,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { public int getNextCharacterId() { int max = 0; - Set ids = new HashSet<>(getCharacters().keySet()); + Set ids = new HashSet<>(getCharacters(false).keySet()); for (Tag t : tags) { if (t instanceof ImportTag) { ids.addAll(((ImportTag) t).getAssets().keySet()); @@ -1505,7 +1572,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } } - private void resolveImported(UrlResolver resolver) { + private synchronized void resolveImported(UrlResolver resolver) { for (int p = 0; p < tags.size(); p++) { Tag t = tags.get(p); if (t instanceof ImportTag) { @@ -1513,186 +1580,33 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { SWF iSwf = resolver.resolveUrl(importTag.getUrl()); if (iSwf != null) { - Map exportedMap1 = new HashMap<>(); - Map classesMap1 = new HashMap<>(); - + + Map importedIdToNameMap = importTag.getAssets(); + + Map exportedNameToIdsMap = new HashMap<>(); + for (Tag t2 : iSwf.tags) { if (t2 instanceof ExportAssetsTag) { ExportAssetsTag sc = (ExportAssetsTag) t2; - Map m2 = sc.getTagToNameMap(); - for (int key : m2.keySet()) { - if (!exportedMap1.containsKey(key)) { - exportedMap1.put(key, m2.get(key)); - } - } - } - if (t2 instanceof SymbolClassTag) { - SymbolClassTag sc = (SymbolClassTag) t2; - Map m2 = sc.getTagToNameMap(); - for (int key : m2.keySet()) { - if (!classesMap1.containsKey(key)) { - classesMap1.put(key, m2.get(key)); - } - } - } + for (int i = 0; i < sc.names.size(); i++) { + exportedNameToIdsMap.put(sc.names.get(i), sc.tags.get(i)); + } + } } - Map exportedMap2 = new HashMap<>(); - for (int k : exportedMap1.keySet()) { - exportedMap2.put(exportedMap1.get(k), k); - } - - Map classesMap2 = new HashMap<>(); - for (int k : classesMap1.keySet()) { - classesMap2.put(classesMap1.get(k), k); - } - - Map importedMap1 = importTag.getAssets(); - Map importedMap2 = new HashMap<>(); - for (int k : importedMap1.keySet()) { - importedMap2.put(importedMap1.get(k), k); - } - - int pos = 0; - Set importedCharIds = new HashSet<>(); - Set importedTagPos = new HashSet<>(); - List importedCharacters = new ArrayList<>(); - for (String key : importedMap2.keySet()) { - if (!exportedMap2.containsKey(key)) { - continue; //? - } - int exportedId = exportedMap2.get(key); - int importedId = importedMap2.get(key); - int ip = 0; - for (Tag cht : iSwf.tags) { - if ((cht instanceof CharacterIdTag) && (((CharacterIdTag) cht).getCharacterId() == exportedId) && !(cht instanceof PlaceObjectTypeTag) && !(cht instanceof RemoveTag)) { - - importedCharIds.add(exportedId); - Tag chtCopy = null; - try { - chtCopy = cht.cloneTag(); - CharacterIdTag ch = (CharacterIdTag) chtCopy; - ch.setCharacterId(importedId); - setImportedDeep(chtCopy, false); - - tags.add(p + 1 + pos, chtCopy); - } catch (InterruptedException | IOException ex) { - Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex); - } - - importedTagPos.add(ip); - if (cht instanceof CharacterTag) { - importedCharacters.add((CharacterTag) chtCopy); - String exportName = ((CharacterTag) cht).getExportName(); - LinkedHashSet classNames = ((CharacterTag) cht).getClassNames(); - if (exportName != null) { - importedTagToExportNameMapping.put(importedId, exportName); - } - if (!classNames.isEmpty()) { - importedTagToClassesMapping.put(importedId, classNames); - } - } else { - chtCopy.setTimelined(this); - chtCopy.setSwf(this); - } - pos++; - } - ip++; - } - } - - int newId = getNextCharacterId(); - pos = 0; - for (String key : classesMap2.keySet()) { - int exportedId = classesMap2.get(key); - int importedId = newId++; - int ip = 0; - for (Tag cht : iSwf.tags) { - if (!importedTagPos.contains(ip) && (cht instanceof CharacterIdTag) && (((CharacterIdTag) cht).getCharacterId() == exportedId) && !(cht instanceof PlaceObjectTypeTag) && !(cht instanceof RemoveTag)) { - - importedCharIds.add(exportedId); - Tag chtCopy = null; - try { - chtCopy = cht.cloneTag(); - CharacterIdTag ch = (CharacterIdTag) chtCopy; - ch.setCharacterId(importedId); - setImportedDeep(chtCopy, false); - - tags.add(p + 1 + pos, chtCopy); - } catch (InterruptedException | IOException ex) { - Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex); - } - if (cht instanceof CharacterTag) { - importedCharacters.add((CharacterTag) chtCopy); - String exportName = ((CharacterTag) cht).getExportName(); - LinkedHashSet classNames = ((CharacterTag) cht).getClassNames(); - if (exportName != null) { - importedTagToExportNameMapping.put(importedId, exportName); - } - if (!classNames.isEmpty()) { - importedTagToClassesMapping.put(importedId, classNames); - } - } else { - chtCopy.setSwf(this); - chtCopy.setTimelined(this); - } - pos++; - } - ip++; - } - } - - pos = 0; - for (CharacterTag ich : importedCharacters) { - Set needed = new LinkedHashSet<>(); - ich.getNeededCharactersDeep(needed); - Map replaceCharactersMap = new HashMap<>(); - for (int n : needed) { - if (importedCharIds.contains(n)) { - continue; - } - CharacterTag cht = iSwf.getCharacter(n); - int importedId = newId++; - CharacterTag chtCopy = null; - try { - chtCopy = (CharacterTag) cht.cloneTag(); - } catch (InterruptedException | IOException ex) { - Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex); - } - chtCopy.setSwf(this); - replaceCharactersMap.put(n, importedId); - chtCopy.setCharacterId(importedId); - setImportedDeep(chtCopy, true); - tags.add(p + 1 + pos, chtCopy); - pos++; - } - - Map replaceCharactersMap2 = new HashMap<>(); - - //first map to non existing ids - int iNewId = iSwf.getNextCharacterId(); - for (int from : replaceCharactersMap.keySet()) { - int to = iNewId++; - replaceCharactersMap2.put(to, replaceCharactersMap.get(from)); - ich.replaceCharacter(from, to); - } - - for (int from : replaceCharactersMap2.keySet()) { - int to = replaceCharactersMap2.get(from); - ich.replaceCharacter(from, to); - } - //ich.setModified(false); - setSwfDeep(ich); - ich.setTimelined(this); - } - updateCharacters(); - for (CharacterTag ich : importedCharacters) { - if (ich instanceof DefineSpriteTag) { - ((DefineSpriteTag) ich).resetTimeline(); + + for (int importedId : importedIdToNameMap.keySet()) { + String importedName = importedIdToNameMap.get(importedId); + if (exportedNameToIdsMap.containsKey(importedName)) { + int exportedId = exportedNameToIdsMap.get(importedName); + importedCharacterSourceSwfs.put(importedId, iSwf); + importedCharacterIds.put(importedId, exportedId); + importedNameToCharacter.put(importedName, importedId); } } } } } + updateCharacters(); } private void setSwfDeep(Tag t) { @@ -2663,7 +2577,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { if (ch instanceof FontTag) { StringBuilder sb = new StringBuilder(); sb.append("function ").append(getTypePrefix(ch)).append(c).append("(ctx,ch,textColor){\r\n"); - ((FontTag) ch).toHtmlCanvas(sb, 1); + ((FontTag) ch).toHtmlCanvas(fswf, sb, 1); sb.append("}\r\n\r\n"); fos.write(Utf8Helper.getBytes(sb.toString())); } else { @@ -2677,7 +2591,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,ctrans,frame,ratio,time){\r\n")); if (ch instanceof DrawableTag) { StringBuilder sb = new StringBuilder(); - ((DrawableTag) ch).toHtmlCanvas(sb, 1); + ((DrawableTag) ch).toHtmlCanvas(fswf, sb, 1); fos.write(Utf8Helper.getBytes(sb.toString())); } fos.write(Utf8Helper.getBytes("}\r\n\r\n")); @@ -3351,6 +3265,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { public void clearAllCache() { characters = null; + charactersWithImported = null; + characterToId = null; characterIdTags = null; externalImages2 = null; timeline = null; @@ -3857,13 +3773,13 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public ReadOnlyTagList getLocalTags() { - List localTags = new ArrayList<>(); + /*List localTags = new ArrayList<>(); for (Tag t : tags) { if (!t.isImported()) { localTags.add(t); } - } - return new ReadOnlyTagList(localTags); + }*/ + return new ReadOnlyTagList(tags); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java index 8a80733ef..de901c134 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java @@ -124,7 +124,7 @@ public class InstanceInfo { FontTag ft = (FontTag) ct; boolean hasFontAlignZones = false; - List sameIdTags = ft.getSwf().getCharacterIdTags(ft.getFontId()); + List sameIdTags = ft.getSwf().getCharacterIdTags(abc.getSwf().getCharacterId(ft)); for (CharacterIdTag sit : sameIdTags) { if (sit instanceof DefineFontAlignZonesTag) { hasFontAlignZones = true; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/DualPdfGraphics2D.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/DualPdfGraphics2D.java index c17f5a842..bde6956bf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/DualPdfGraphics2D.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/DualPdfGraphics2D.java @@ -610,7 +610,7 @@ public class DualPdfGraphics2D extends Graphics2D implements BlendModeSetable, G char ch = font.glyphToChar(entry.glyphIndex); if (spacing != 0) { text.append(currentChar); - drawText(x, y, trans, textColor, existingFonts, font, text.toString(), textHeight, pdfGraphics); + drawText(swf, x, y, trans, textColor, existingFonts, font, text.toString(), textHeight, pdfGraphics); text = new StringBuilder(); x = x + deltaX + entry.glyphAdvance; deltaX = 0; @@ -626,14 +626,14 @@ public class DualPdfGraphics2D extends Graphics2D implements BlendModeSetable, G } } if (text.length() > 0) { - drawText(x, y, trans, textColor, existingFonts, font, text.toString(), textHeight, pdfGraphics); + drawText(swf, x, y, trans, textColor, existingFonts, font, text.toString(), textHeight, pdfGraphics); } x = x + deltaX; } } - private static void drawText(float x, float y, Matrix trans, int textColor, Map existingFonts, FontTag font, String text, int textHeight, PDFGraphics g) { - int fontId = font.getFontId(); + private static void drawText(SWF swf, float x, float y, Matrix trans, int textColor, Map existingFonts, FontTag font, String text, int textHeight, PDFGraphics g) { + int fontId = swf.getCharacterId(font); if (existingFonts.containsKey(fontId)) { g.setExistingTtfFont(existingFonts.get(fontId).deriveFont((float) textHeight)); } else { 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 ea1efabce..efff2ed66 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 @@ -641,8 +641,8 @@ public class FrameExporter { return ret; } - private static void drawText(float x, float y, Matrix trans, int textColor, Map existingFonts, FontTag font, String text, int textHeight, Graphics g) { - int fontId = font.getFontId(); + private static void drawText(SWF swf, float x, float y, Matrix trans, int textColor, Map existingFonts, FontTag font, String text, int textHeight, Graphics g) { + int fontId = swf.getCharacterId(font); PDFGraphics g2 = (PDFGraphics) g; if (existingFonts.containsKey(fontId)) { g2.setExistingTtfFont(existingFonts.get(fontId).deriveFont((float) textHeight)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java index 8649ed525..750bb7ac1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java @@ -120,7 +120,7 @@ public class MorphShapeExporter { rect.xMin *= settings.zoom; rect.yMin *= settings.zoom; SVGExporter exporter = new SVGExporter(rect, settings.zoom, "shape"); - mst.getStartShapeTag().toSVG(exporter, -2, new CXFORMWITHALPHA(), 0); + mst.getStartShapeTag().toSVG(mst.getSwf(), exporter, -2, new CXFORMWITHALPHA(), 0); fos.write(Utf8Helper.getBytes(exporter.getSVG())); } try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fileEnd))) { @@ -130,7 +130,7 @@ public class MorphShapeExporter { rect.xMin *= settings.zoom; rect.yMin *= settings.zoom; SVGExporter exporter = new SVGExporter(rect, settings.zoom, "shape"); - mst.getEndShapeTag().toSVG(exporter, -2, new CXFORMWITHALPHA(), 0); + mst.getEndShapeTag().toSVG(mst.getSwf(), exporter, -2, new CXFORMWITHALPHA(), 0); fos.write(Utf8Helper.getBytes(exporter.getSVG())); } break; @@ -142,7 +142,7 @@ public class MorphShapeExporter { rect.xMin *= settings.zoom; rect.yMin *= settings.zoom; SVGExporter exporter = new SVGExporter(rect, settings.zoom, "morphshape"); - mst.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0); + mst.toSVG(mst.getSwf(), exporter, -2, new CXFORMWITHALPHA(), 0); fos.write(Utf8Helper.getBytes(exporter.getSVG())); } break; @@ -165,7 +165,7 @@ public class MorphShapeExporter { } Matrix m = Matrix.getScaleInstance(settings.zoom); m.translate(-rect.Xmin, -rect.Ymin); - st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); + st.toImage(st.getSwf(), 0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); if (settings.mode == MorphShapeExportMode.PNG_START_END) { ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileStart); } else { @@ -188,7 +188,7 @@ public class MorphShapeExporter { } m = Matrix.getScaleInstance(settings.zoom); m.translate(-rect.Xmin, -rect.Ymin); - st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); + st.toImage(st.getSwf(), 0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); if (settings.mode == MorphShapeExportMode.PNG_START_END) { ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileEnd); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java index 55faf3431..756fdf6da 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java @@ -456,7 +456,7 @@ public class PreviewExporter { int countGlyphsTotal = ft.getGlyphShapeTable().size(); int countGlyphs = Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW, countGlyphsTotal); - int fontId = ft.getFontId(); + int fontId = swf.getCharacterId(ft); int cols = (int) Math.ceil(Math.sqrt(countGlyphs)); int rows = (int) Math.ceil(((float) countGlyphs) / ((float) cols)); if (rows == 0) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java index 0aff26592..f3a69c18d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java @@ -109,7 +109,7 @@ public class ShapeExporter { rect.xMin *= settings.zoom; rect.yMin *= settings.zoom; SVGExporter exporter = new SVGExporter(rect, settings.zoom, "shape"); - st.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0); + st.toSVG(st.getSwf(), exporter, -2, new CXFORMWITHALPHA(), 0); fos.write(Utf8Helper.getBytes(exporter.getSVG())); } break; @@ -130,7 +130,7 @@ public class ShapeExporter { } Matrix m = Matrix.getScaleInstance(settings.zoom); m.translate(-rect.Xmin, -rect.Ymin); - st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); + st.toImage(st.getSwf(), 0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true); if (settings.mode == ShapeExportMode.PNG) { ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/TextExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/TextExporter.java index 1b089ab90..466462a3b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/TextExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/TextExporter.java @@ -87,7 +87,7 @@ public class TextExporter { try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) { ExportRectangle rect = new ExportRectangle(textTag.getRect()); SVGExporter exporter = new SVGExporter(rect, settings.zoom, "text"); - textTag.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0); + textTag.toSVG(textTag.getSwf(), exporter, -2, new CXFORMWITHALPHA(), 0); fos.write(Utf8Helper.getBytes(exporter.getSVG())); } }, handler).run(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/gfx/GfxConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/gfx/GfxConvertor.java index cef35b07c..498cb48f6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/gfx/GfxConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/gfx/GfxConvertor.java @@ -56,7 +56,7 @@ public class GfxConvertor { public DefineFont2Tag convertDefineCompactedFont(DefineCompactedFont compactedFont) { DefineFont2Tag ret = new DefineFont2Tag(compactedFont.getSwf()); - ret.fontID = compactedFont.getFontId(); + ret.fontID = compactedFont.getCharacterId(); ret.fontFlagsBold = compactedFont.isBold(); ret.fontFlagsItalic = compactedFont.isItalic(); ret.fontFlagsWideOffsets = true; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java index 8a9c9ee35..971bf4ec9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java @@ -194,7 +194,7 @@ public class ImageImporter extends TagImporter { public int bulkImport(File imagesDir, SWF swf, boolean printOut) { int count = 0; - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); List extensions = Arrays.asList("png", "jpg", "jpeg", "gif", "bmp"); List alphaExtensions = Arrays.asList("png"); File[] allFiles = imagesDir.listFiles(new FilenameFilter() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java index 123c09482..e2d29f917 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java @@ -57,7 +57,7 @@ import java.util.logging.Logger; public class MovieImporter { public int bulkImport(File moviesDir, SWF swf, boolean printOut) { - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); int movieCount = 0; List extensions = Arrays.asList("flv"); File[] allFiles = moviesDir.listFiles(new FilenameFilter() { 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 0fbf29749..dbcf3c2eb 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 @@ -195,7 +195,7 @@ public class ShapeImporter { public int bulkImport(File shapesDir, SWF swf, boolean noFill, boolean printOut) { SvgImporter svgImporter = new SvgImporter(); - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); int shapeCount = 0; List extensions = Arrays.asList("svg", "png", "jpg", "jpeg", "gif", "bmp"); File[] allFiles = shapesDir.listFiles(new FilenameFilter() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java index 98a6c8f3e..c5a798c58 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java @@ -483,7 +483,7 @@ public class SoundImporter { public int bulkImport(File soundDir, SWF swf, boolean printOut) { - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); int soundCount = 0; List extensions = Arrays.asList("mp3", "wav"); File[] allFiles = soundDir.listFiles(new FilenameFilter() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SpriteImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SpriteImporter.java index 79d77b56e..8ec8571eb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SpriteImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SpriteImporter.java @@ -154,7 +154,7 @@ public class SpriteImporter { } public int bulkImport(File spritesDir, SWF swf, boolean printOut) { - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); int spriteCount = 0; List extensions = Arrays.asList("gif"); File[] allFiles = spritesDir.listFiles(new FilenameFilter() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index 2ee59d350..2a97501f2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.helpers.HighlightedText; import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; 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.MissingCharacterHandler; import com.jpexs.decompiler.flash.tags.base.RenderContext; @@ -516,7 +517,12 @@ public class DefineEditTextTag extends TextTag { String txt = unescape(new String(ch, start, length)); TextStyle style = styles.peek(); if (style.fontFace != null && useOutlines) { - style.font = swf.getFontByNameInTag(style.fontFace, style.bold, style.italic); + CharacterTag ct = swf.getCharacterByExportName(style.fontFace); + if (ct != null && (ct instanceof FontTag)) { + style.font = (FontTag) ct; + } else { + style.font = swf.getFontByNameInTag(style.fontFace, style.bold, style.italic); + } if (style.font == null) { style.fontFace = null; } @@ -974,7 +980,7 @@ public class DefineEditTextTag extends TextTag { List chs = getTextWithStyle(); for (CharacterWithStyle ch : chs) { if (ch.style.font != null) { - needed.add(ch.style.font.getFontId()); + needed.add(swf.getCharacterId(ch.style.font)); } } } @@ -1007,21 +1013,21 @@ public class DefineEditTextTag extends TextTag { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { - render(TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1); + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + render(swf, TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1); } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { - render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1); + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { + render(swf, TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1); } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { - render(TextRenderMode.HTML5_CANVAS, null, null, result, new Matrix(), null, unitDivisor); + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { + render(swf, TextRenderMode.HTML5_CANVAS, null, null, result, new Matrix(), null, unitDivisor); } - private void render(TextRenderMode renderMode, SerializableImage image, SVGExporter svgExporter, StringBuilder htmlCanvasBuilder, Matrix transformation, ColorTransform colorTransform, double zoom) { + private void render(SWF swf, TextRenderMode renderMode, SerializableImage image, SVGExporter svgExporter, StringBuilder htmlCanvasBuilder, Matrix transformation, ColorTransform colorTransform, double zoom) { if (border) { // border is always black, fill color is always white? RGB borderColor = new RGBA(Color.black); @@ -1039,7 +1045,7 @@ public class DefineEditTextTag extends TextTag { } } if (hasText) { - List allTextRecords = getTextRecords(); + List allTextRecords = getTextRecords(swf); switch (renderMode) { case BITMAP: staticTextToImage(swf, allTextRecords, 2, image, getTextMatrix(), transformation, colorTransform); @@ -1054,7 +1060,7 @@ public class DefineEditTextTag extends TextTag { } } - public List getTextRecords() { + public List getTextRecords(SWF swf) { DynamicTextModel textModel = new DynamicTextModel(); List txt = getTextWithStyle(); TextStyle lastStyle = null; @@ -1279,11 +1285,11 @@ public class DefineEditTextTag extends TextTag { if (fontClass != null) { FontTag ft = swf.getFontByClass(fontClass); if (ft != null) { - fid = ft.getFontId(); + fid = swf.getCharacterId(ft); } } if (tr.style.font != null) { - fid = tr.style.font.getFontId(); + fid = swf.getCharacterId(tr.style.font); } tr2.styleFlagsHasFont = fid != 0; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index 9bf020a74..86a6f637b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -415,17 +415,17 @@ public class DefineSpriteTag extends DrawableTag implements Timelined { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing); } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1); } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { getTimeline().toHtmlCanvas(result, unitDivisor, null); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java index 5e249740a..7e75c6bd6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java @@ -334,7 +334,7 @@ public class DefineVideoStreamTag extends DrawableTag implements BoundedTag, Tim } @Override - public synchronized void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public synchronized void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { if (renderingPaused || !SimpleMediaPlayer.isAvailable()) { Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics(); @@ -419,11 +419,11 @@ public class DefineVideoStreamTag extends DrawableTag implements BoundedTag, Tim } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java index 7575844c3..59be9c2c5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.Exportable; +import com.jpexs.decompiler.flash.tags.base.ImportTag; import com.jpexs.decompiler.flash.tags.base.NeedsCharacters; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; import com.jpexs.decompiler.flash.tags.gfx.DefineExternalGradient; @@ -639,6 +640,13 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable { } ReadOnlyTagList tags = tim.getTags(); for (int i = tags.indexOf(this) - 1; i >= 0; i--) { + if (tags.get(i) instanceof ImportTag) { + ImportTag it = (ImportTag) tags.get(i); + needed2.removeAll(it.getAssets().keySet()); + if (needed2.isEmpty()) { + return needed2; + } + } if (tags.get(i) instanceof CharacterTag) { int charId = ((CharacterTag) tags.get(i)).getCharacterId(); needed2.remove(charId); @@ -670,9 +678,12 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable { if (swf == null) { return; } - if (swf.getCharacters().containsKey(characterId) && !swf.getCyclicCharacters().contains(characterId)) { + if (swf.getCharacters(true).containsKey(characterId) && !swf.getCyclicCharacters().contains(characterId)) { Set needed4 = new LinkedHashSet<>(); CharacterTag character = swf.getCharacter(characterId); + if (character.isImported()) { + continue; + } character.getNeededCharacters(needed4, swf); List newItems = new ArrayList<>(); for (int n : needed4) { @@ -695,7 +706,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable { if (swf == null) { return; } - if (swf.getCharacters().containsKey(characterId)) { + if (swf.getCharacters(true).containsKey(characterId)) { needed.add(characterId); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java index ddb7f53b5..2189f9cf4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java @@ -93,12 +93,12 @@ public abstract class ButtonTag extends DrawableTag implements Timelined { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing); } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1); } @@ -110,7 +110,7 @@ public abstract class ButtonTag extends DrawableTag implements Timelined { } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { getTimeline().toHtmlCanvas(result, unitDivisor, Arrays.asList(0)); //TODO: handle states? } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java index eda8f2176..4e2f89aef 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java @@ -61,11 +61,11 @@ public abstract class DrawableTag extends CharacterTag implements BoundedTag { */ public abstract Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom); - public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing); + public abstract void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing); - public abstract void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException; + public abstract void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException; - public abstract void toHtmlCanvas(StringBuilder result, double unitDivisor); + public abstract void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor); public abstract int getNumFrames(); 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 9ee249a6a..4fce4d427 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 @@ -175,11 +175,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag { reload(); } firstLoaded = true; - } - - public int getFontId() { - return getCharacterId(); - } + } public boolean hasLayout() { return false; @@ -226,7 +222,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag { } public String getSystemFontName() { - int fontId = getFontId(); + int fontId = getCharacterId(); String selectedFont = swf.sourceFontNamesMap.get(fontId); if (selectedFont == null) { SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortPathTitle()); @@ -429,16 +425,16 @@ public abstract class FontTag extends DrawableTag implements AloneTag { } @Override - public synchronized void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public synchronized void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { SHAPERECORD.shapeListToImage(ShapeTag.WIND_EVEN_ODD, 1, swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform); } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { List shapes = getGlyphShapeTable(); result.append("\tdefaultFill = textColor;\r\n"); result.append("\tswitch(ch){\r\n"); @@ -496,7 +492,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag { for (Tag t : swf.getTags()) { if (t instanceof DefineFontNameTag) { DefineFontNameTag dfn = (DefineFontNameTag) t; - if (dfn.fontId == getFontId()) { + if (dfn.fontId == getCharacterId()) { return dfn; } } 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 0e0d58e5c..5e9029751 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 @@ -262,18 +262,18 @@ public abstract class ImageTag extends DrawableTag { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, getShape(1), null, image, unzoom, transformation, strokeTransformation, colorTransform, true, canUseSmoothing); } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { SVGShapeExporter shapeExporter = new SVGShapeExporter(ShapeTag.WIND_EVEN_ODD, 1, swf, getShape(1), getCharacterId(), exporter, null, colorTransform, 1); shapeExporter.export(); } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { CanvasShapeExporter cse = new CanvasShapeExporter(ShapeTag.WIND_EVEN_ODD, 1, null, unitDivisor, swf, getShape(1), null, 0, 0); cse.export(); result.append(cse.getShapeData()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MorphShapeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MorphShapeTag.java index 70b6ac589..398289b19 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MorphShapeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MorphShapeTag.java @@ -331,7 +331,7 @@ public abstract class MorphShapeTag extends DrawableTag { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { SHAPEWITHSTYLE shape = getShapeAtRatio(ratio); // morphShape using shapeNum=3, morphShape2 using shapeNum=4 // todo: Currently the generated image is not cached, because the cache @@ -341,7 +341,7 @@ public abstract class MorphShapeTag extends DrawableTag { } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { if (ratio == -2) { SHAPEWITHSTYLE beginShapes = getShapeAtRatio(0); SHAPEWITHSTYLE endShapes = getShapeAtRatio(65535); @@ -371,7 +371,7 @@ public abstract class MorphShapeTag extends DrawableTag { } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { CanvasMorphShapeExporter cmse = new CanvasMorphShapeExporter(getShapeNum(), swf, getShapeAtRatio(0), getShapeAtRatio(MAX_RATIO), null, unitDivisor, 0, 0); cmse.export(); result.append(cmse.getShapeData()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java index 6cb811a9c..236490249 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java @@ -194,7 +194,7 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { BitmapExporter.export(getWindingRule(), getShapeNum(), swf, getShapes(), null, image, unzoom, transformation, strokeTransformation, colorTransform, scaleStrokes, canUseSmoothing); if (Configuration._debugMode.get()) { // show control points List paths = PathExporter.export(getWindingRule(), getShapeNum(), swf, getShapes()); @@ -238,13 +238,13 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject { } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException { SVGShapeExporter shapeExporter = new SVGShapeExporter(getWindingRule(), getShapeNum(), swf, getShapes(), getCharacterId(), exporter, null, colorTransform, 1); shapeExporter.export(); } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { CanvasShapeExporter cse = new CanvasShapeExporter(getWindingRule(), getShapeNum(), null, unitDivisor, swf, getShapes(), null, 0, 0); cse.export(); result.append(cse.getShapeData()); 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 f9f2de252..e5cde77cd 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 @@ -743,7 +743,7 @@ public abstract class StaticTextTag extends TextTag { } @Override - public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { + public void toImage(SWF swf, int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) { staticTextToImage(swf, textRecords, getTextNum(), image, textMatrix, transformation, colorTransform); /*try { TextTag originalTag = (TextTag) getOriginalTag(); @@ -757,12 +757,12 @@ public abstract class StaticTextTag extends TextTag { } @Override - public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { + public void toSVG(SWF swf, SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) { staticTextToSVG(swf, textRecords, getTextNum(), exporter, getRect(), textMatrix, colorTransform, 1); } @Override - public void toHtmlCanvas(StringBuilder result, double unitDivisor) { + public void toHtmlCanvas(SWF swf, StringBuilder result, double unitDivisor) { staticTextToHtmlCanvas(unitDivisor, swf, textRecords, getTextNum(), result, textBounds, textMatrix, 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 bd3c4d822..75834c15b 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 @@ -768,7 +768,7 @@ public class Timeline { toImage(frame, time, renderContext, image, isClip, transforms[i], absoluteTransformation, colorTransform, targetRect[i]); } }*/ - private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, int parentBlendMode, List clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, DrawableTag drawable, List filters, double unzoom, ColorTransform clrTrans, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode, boolean canUseSmoothing) { + private void drawDrawable(SWF swf, Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, int parentBlendMode, List clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, DrawableTag drawable, List filters, double unzoom, ColorTransform clrTrans, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode, boolean canUseSmoothing) { Matrix drawMatrix = new Matrix(); int drawableFrameCount = drawable.getNumFrames(); if (drawableFrameCount == 0) { @@ -967,7 +967,7 @@ public class Timeline { } if (!(drawable instanceof ImageTag) || (swf.isAS3() && layer.hasImage)) { - drawable.toImage(dframe, dtime, ratio, renderContext, img, fullImage, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, clrTrans2, unzoom, sameImage, viewRect2, scaleStrokes, drawMode, layer.blendMode, canUseSmoothing); + drawable.toImage(swf, dframe, dtime, ratio, renderContext, img, fullImage, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, clrTrans2, unzoom, sameImage, viewRect2, scaleStrokes, drawMode, layer.blendMode, canUseSmoothing); } else { // todo: show one time warning } @@ -1236,7 +1236,7 @@ public class Timeline { Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight()); g.setClip(r); - drawDrawable(strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, false, DRAW_MODE_SHAPES, canUseSmoothing); + drawDrawable(swf, strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, false, DRAW_MODE_SHAPES, canUseSmoothing); s++; } } @@ -1245,13 +1245,13 @@ public class Timeline { g.setTransform(origTransform); //draw all nonshapes (normally scaled) next - drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES, canUseSmoothing); + drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES, canUseSmoothing); } else { boolean subScaleStrokes = scaleStrokes; if (character instanceof DefineSpriteTag) { subScaleStrokes = true; } - drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, subScaleStrokes, DRAW_MODE_ALL, canUseSmoothing); + drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, subScaleStrokes, DRAW_MODE_ALL, canUseSmoothing); } } else if (character instanceof BoundedTag) { showPlaceholder = true; @@ -1357,12 +1357,12 @@ public class Timeline { exporter.createClipPath(mat, clipName); SvgClip clip = new SvgClip(clipName, layer.clipDepth); clips.add(clip); - drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1); + drawable.toSVG(swf, exporter, layer.ratio, clrTrans, level + 1); exporter.endGroup(); } else { if (createNew) { exporter.createDefGroup(new ExportRectangle(boundRect), assetName); - drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1); + drawable.toSVG(swf, exporter, layer.ratio, clrTrans, level + 1); exporter.endGroup(); } Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java index c0fb72a03..a538c3017 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java @@ -150,7 +150,7 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh @Override public String toString() { - return "BUTTONRECORD (" + characterId + ") Depth:" + placeDepth + " State:" + ((buttonStateDown ? "down " : "") + (buttonStateHitTest ? "hit " : "") + (buttonStateOver ? "over " : "") + (buttonStateUp ? "up " : "")); + return "BUTTONRECORD (chid: " + characterId + ", dpt: " + placeDepth + ", state: " + ((buttonStateDown ? "down " : "") + (buttonStateHitTest ? "hit " : "") + (buttonStateOver ? "over " : "") + (buttonStateUp ? "up " : "")).trim() + ")"; } @Override 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 e54d31cf1..854bee3e4 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 @@ -2906,7 +2906,7 @@ public class XFLConverter { statusStack.pushStatus(t.toString()); SWF swf = t.getSwf(); FontTag font = (FontTag) t; - int fontId = font.getFontId(); + int fontId = font.getCharacterId(); DefineFontNameTag fontNameTag = (DefineFontNameTag) swf.getCharacterIdTag(fontId, DefineFontNameTag.ID); String fontName = fontNameTag == null ? null : fontNameTag.fontName; if (fontName == null) { @@ -5576,7 +5576,7 @@ public class XFLConverter { } } if (u instanceof FontTag) { - if (((FontTag) u).getFontId() == det.fontId) { + if (((FontTag) u).getCharacterId()== det.fontId) { ft = (FontTag) u; } } @@ -5694,7 +5694,7 @@ public class XFLConverter { if (f.equals(ft.getFontNameIntag())) { for (Tag u : tags) { if (u instanceof DefineFontNameTag) { - if (((DefineFontNameTag) u).fontId == ft.getFontId()) { + if (((DefineFontNameTag) u).fontId == ft.getCharacterId()) { fontName = ((DefineFontNameTag) u).fontName; } } diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 449afd26a..a6534d682 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -2932,7 +2932,7 @@ public class CommandLineArgumentParser { CharacterTag characterTag = null; if (characterId == -1) { //replacing soundstreamhead on main timeline - } else if (swf.getCharacters().containsKey(characterId)) { + } else if (swf.getCharacters(false).containsKey(characterId)) { characterTag = swf.getCharacter(characterId); } else { System.err.println("CharacterId does not exist"); @@ -3163,7 +3163,7 @@ public class CommandLineArgumentParser { System.err.println("ImageId should be integer"); badArguments("replacealpha"); } - if (!swf.getCharacters().containsKey(imageId)) { + if (!swf.getCharacters(false).containsKey(imageId)) { System.err.println("ImageId does not exist"); System.exit(1); } @@ -3219,7 +3219,7 @@ public class CommandLineArgumentParser { System.err.println("CharacterId should be integer"); badArguments("replacecharacter"); } - if (!swf.getCharacters().containsKey(characterId)) { + if (!swf.getCharacters(false).containsKey(characterId)) { System.err.println("CharacterId does not exist"); System.exit(1); } @@ -3234,7 +3234,7 @@ public class CommandLineArgumentParser { System.err.println("NewCharacterId should be integer"); badArguments("replacecharacter"); } - if (!swf.getCharacters().containsKey(newCharacterId)) { + if (!swf.getCharacters(false).containsKey(newCharacterId)) { System.err.println("NewCharacterId does not exist"); System.exit(1); } @@ -3337,7 +3337,7 @@ public class CommandLineArgumentParser { System.err.println("CharacterId should be integer"); badArguments("convert"); } - if (!swf.getCharacters().containsKey(characterId)) { + if (!swf.getCharacters(false).containsKey(characterId)) { System.err.println("CharacterId does not exist"); System.exit(1); } @@ -3535,7 +3535,7 @@ public class CommandLineArgumentParser { System.err.println("CharacterId should be integer"); badArguments("removecharacter"); } - if (!swf.getCharacters().containsKey(characterId)) { + if (!swf.getCharacters(false).containsKey(characterId)) { System.err.println("CharacterId does not exist"); System.exit(1); } @@ -3808,7 +3808,7 @@ public class CommandLineArgumentParser { @Override public boolean handle(TextTag textTag, final FontTag font, final char character) { - String fontName = font.getSwf().sourceFontNamesMap.get(font.getFontId()); + String fontName = font.getSwf().sourceFontNamesMap.get(font.getCharacterId()); if (fontName == null) { fontName = font.getFontName(); } @@ -4222,7 +4222,7 @@ public class CommandLineArgumentParser { pw.println("[tags]"); pw.println("tagCount=" + swf.getTags().size()); pw.println("hasEndTag=" + swf.hasEndTag); - pw.println("characterCount=" + (swf.getCharacters().size())); + pw.println("characterCount=" + (swf.getCharacters(true).size())); pw.println("maxCharacterId=" + (swf.getNextCharacterId() - 1)); pw.println(); diff --git a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java index 4da8bfa27..dabb87c2d 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java @@ -383,7 +383,7 @@ public class FolderPreviewPanel extends JPanel { if (imgSrc == null) { DrawableTag drawable = (DrawableTag) treeItem; ExportRectangle viewRectangle = new ExportRectangle(0, 0, ow, oh); - drawable.toImage(0, 0, 0, new RenderContext(), image, image, false, m, new Matrix(), m, m, null, scale, false, viewRectangle, true, Timeline.DRAW_MODE_ALL, 0, !Configuration.disableBitmapSmoothing.get()); + drawable.toImage(swf, 0, 0, 0, new RenderContext(), image, image, false, m, new Matrix(), m, m, null, scale, false, viewRectangle, true, Timeline.DRAW_MODE_ALL, 0, !Configuration.disableBitmapSmoothing.get()); } else { Graphics2D g = (Graphics2D) image.getGraphics(); g.setTransform(m.toTransform()); diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 835ccc757..416305b13 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -230,7 +230,7 @@ public class FontPanel extends JPanel implements TagEditorPanel { if (replaced) { if (ViewMessages.showConfirmDialog(FontPanel.this, translate("message.font.replace.updateTexts"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.YES_OPTION) { - int fontId = ft.getFontId(); + int fontId = ft.getCharacterId(); SWF swf = ft.getSwf(); for (Tag tag : swf.getTags()) { if (tag instanceof TextTag) { @@ -678,8 +678,8 @@ public class FontPanel extends JPanel implements TagEditorPanel { FontTag f = (FontTag) item; SWF swf = f.getSwf(); String selectedName = ((FontFace) fontFaceSelection.getSelectedItem()).font.getFontName(Locale.ENGLISH); - swf.sourceFontNamesMap.put(f.getFontId(), selectedName); - Configuration.addFontPair(swf.getShortPathTitle(), f.getFontId(), f.getFontNameIntag(), selectedName); + swf.sourceFontNamesMap.put(f.getCharacterId(), selectedName); + Configuration.addFontPair(swf.getShortPathTitle(), f.getCharacterId(), f.getFontNameIntag(), selectedName); } } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 6aed03c12..6ce53da5c 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -2823,10 +2823,10 @@ public final class ImagePanel extends JPanel implements MediaDisplay { image.fillTransparent(); Matrix m = Matrix.getTranslateInstance(-rect.Xmin * zoomDouble, -rect.Ymin * zoomDouble); m.scale(zoomDouble); - textTag.toImage(0, 0, 0, new RenderContext(), image, image, false, m, m, m, m, new ConstantColorColorTransform(0xFFC0C0C0), zoomDouble, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, false); + textTag.toImage(textTag.getSwf(), 0, 0, 0, new RenderContext(), image, image, false, m, m, m, m, new ConstantColorColorTransform(0xFFC0C0C0), zoomDouble, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, false); if (newTextTag != null) { - newTextTag.toImage(0, 0, 0, new RenderContext(), image, image, false, m, m, m, m, new ConstantColorColorTransform(0xFF000000), zoomDouble, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, false); + newTextTag.toImage(textTag.getSwf(), 0, 0, 0, new RenderContext(), image, image, false, m, m, m, m, new ConstantColorColorTransform(0xFF000000), zoomDouble, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, false); } iconPanel.setImg(image); @@ -3376,7 +3376,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { List soundClasses = new ArrayList<>(); List soundInfos = new ArrayList<>(); timeline.getSounds(frame, time, renderContext.mouseOverButton, mouseButton, sounds, soundClasses, soundInfos); - for (int cid : swf.getCharacters().keySet()) { + for (int cid : swf.getCharacters(true).keySet()) { CharacterTag c = swf.getCharacter(cid); for (int k = 0; k < soundClasses.size(); k++) { String cls = soundClasses.get(k); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 19ec5b8cf..296e0998d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -2340,7 +2340,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (export.isOptionEnabled(SpriteExportMode.class)) { SpriteExportSettings ses = new SpriteExportSettings(export.getValue(SpriteExportMode.class), export.getZoom()); - for (CharacterTag c : swf.getCharacters().values()) { + for (CharacterTag c : swf.getCharacters(false).values()) { if (c instanceof DefineSpriteTag) { frameExporter.exportSpriteFrames(handler, Path.combine(selFile, SpriteExportSettings.EXPORT_FOLDER_NAME), swf, c.getCharacterId(), null, ses, evl); } @@ -2349,7 +2349,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (export.isOptionEnabled(ButtonExportMode.class)) { ButtonExportSettings bes = new ButtonExportSettings(export.getValue(ButtonExportMode.class), export.getZoom()); - for (CharacterTag c : swf.getCharacters().values()) { + for (CharacterTag c : swf.getCharacters(false).values()) { if (c instanceof ButtonTag) { frameExporter.exportButtonFrames(handler, Path.combine(selFile, ButtonExportSettings.EXPORT_FOLDER_NAME), swf, c.getCharacterId(), null, bes, evl); } @@ -2453,7 +2453,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (export.isOptionEnabled(SpriteExportMode.class)) { for (SpriteExportMode exportMode : SpriteExportMode.values()) { SpriteExportSettings ses = new SpriteExportSettings(exportMode, export.getZoom()); - for (CharacterTag c : swf.getCharacters().values()) { + for (CharacterTag c : swf.getCharacters(false).values()) { if (c instanceof DefineSpriteTag) { frameExporter.exportSpriteFrames(handler, Path.combine(selFile, SpriteExportSettings.EXPORT_FOLDER_NAME, exportMode.name()), swf, c.getCharacterId(), null, ses, evl); } @@ -2464,7 +2464,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (export.isOptionEnabled(ButtonExportMode.class)) { for (ButtonExportMode exportMode : ButtonExportMode.values()) { ButtonExportSettings bes = new ButtonExportSettings(exportMode, export.getZoom()); - for (CharacterTag c : swf.getCharacters().values()) { + for (CharacterTag c : swf.getCharacters(false).values()) { if (c instanceof ButtonTag) { frameExporter.exportButtonFrames(handler, Path.combine(selFile, ButtonExportSettings.EXPORT_FOLDER_NAME, exportMode.name()), swf, c.getCharacterId(), null, bes, evl); } @@ -4462,7 +4462,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se @Override public boolean handle(TextTag textTag, final FontTag font, final char character) { - String fontName = font.getSwf().sourceFontNamesMap.get(font.getFontId()); + String fontName = font.getSwf().sourceFontNamesMap.get(font.getCharacterId()); if (fontName == null) { fontName = font.getFontName(); } @@ -5601,17 +5601,20 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else if ((treeItem instanceof BUTTONRECORD) && (!((BUTTONRECORD) treeItem).getSwf().getCyclicCharacters().contains(((BUTTONRECORD) treeItem).characterId))) { BUTTONRECORD buttonRecord = (BUTTONRECORD) treeItem; previewPanel.setParametersPanelVisible(false); - SWF swf = new SWF(buttonRecord.getSwf().getCharset()); + SWF origSwf = ((SWF)treeItem.getOpenable()); + /*SWF swf = new SWF(buttonRecord.getSwf().getCharset()); swf.frameCount = 1; swf.frameRate = buttonRecord.getSwf().frameRate; swf.displayRect = buttonRecord.getTag().getRect(); + swf.gfx = origSwf.gfx; + swf.setFile(origSwf.getFile()); // For GFX to properly load if (swf.getBackgroundColor() != null) { SetBackgroundColorTag setBackgroundColorTag = new SetBackgroundColorTag(swf, swf.getBackgroundColor().backgroundColor); swf.addTag(setBackgroundColorTag); setBackgroundColorTag.setTimelined(swf); - } + }*/ CharacterTag character = buttonRecord.getSwf().getCharacter(buttonRecord.characterId); - Set needed = new LinkedHashSet<>(); + /*Set needed = new LinkedHashSet<>(); character.getNeededCharactersDeep(needed); needed.remove(buttonRecord.characterId); needed.add(buttonRecord.characterId); @@ -5628,16 +5631,110 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se neededCharacter.setTimelined(swf); swf.addTag(neededCharacter); } +*/ + Timelined tim = new Timelined() { + + ReadOnlyTagList cachedTags = null; + + @Override + public SWF getSwf() { + return origSwf; + } - PlaceObject3Tag placeTag = buttonRecord.toPlaceObject(); - placeTag.setSwf(swf); + @Override + public Timeline getTimeline() { + return new Timeline(origSwf, this, Integer.MAX_VALUE,buttonRecord.getTag().getRect()); + } - swf.addTag(placeTag); - placeTag.setTimelined(swf); - ShowFrameTag showFrameTag = new ShowFrameTag(swf); - swf.addTag(showFrameTag); - showFrameTag.setTimelined(swf); - previewPanel.showImagePanel(swf, swf, 0, true, true, !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true, false, true); + @Override + public void resetTimeline() { + + } + + @Override + public void setModified(boolean value) { + + } + + @Override + public ReadOnlyTagList getTags() { + if (cachedTags == null) { + List tags = new ArrayList<>(); + PlaceObject3Tag placeTag = buttonRecord.toPlaceObject(); + placeTag.setSwf(origSwf); + placeTag.setTimelined(this); + tags.add(placeTag); + + ShowFrameTag showFrameTag = new ShowFrameTag(origSwf); + showFrameTag.setTimelined(this); + tags.add(showFrameTag); + cachedTags = new ReadOnlyTagList(tags); + } + return cachedTags; + } + + @Override + public void removeTag(int index) { + } + + @Override + public void removeTag(Tag tag) { + } + + @Override + public void addTag(Tag tag) { + } + + @Override + public void addTag(int index, Tag tag) { + } + + @Override + public void replaceTag(int index, Tag newTag) { + } + + @Override + public void replaceTag(Tag oldTag, Tag newTag) { + } + + @Override + public int indexOfTag(Tag tag) { + return getTags().indexOf(tag); + } + + @Override + public void setFrameCount(int frameCount) { + } + + @Override + public int getFrameCount() { + return 1; + } + + @Override + public RECT getRect() { + return buttonRecord.getTag().getRect(); + } + + @Override + public RECT getRect(Set added) { + return getRect(); + } + + @Override + public RECT getRectWithStrokes() { + return getRect(); + } + }; + + + + //swf.addTag(placeTag); + //placeTag.setTimelined(origSwf); + //ShowFrameTag showFrameTag = new ShowFrameTag(swf); + //swf.addTag(showFrameTag); + //showFrameTag.setTimelined(swf); + previewPanel.showImagePanel(tim, origSwf, 0, true, true, !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true, false, true); } else if (treeItem instanceof DefineFont4Tag) { previewPanel.showGenericTagPanel((Tag) treeItem); } else { diff --git a/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java b/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java index f23164feb..865f2a420 100644 --- a/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java @@ -184,11 +184,14 @@ public class ReplaceCharacterDialog extends AppDialog { } public int showDialog(SWF swf, int selectedCharacterId) { - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(false); fullModel = new DefaultListModel<>(); fullModel.clear(); for (Integer key : characters.keySet()) { CharacterTag character = characters.get(key); + if (character.isImported()) { + continue; + } int characterId = character.getCharacterId(); if (characterId != selectedCharacterId) { fullModel.addElement(new ComboBoxItem<>(character.getName(), character)); diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 71c520a37..0cdf06b6a 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -2274,7 +2274,7 @@ public class TagTreeContextMenu extends JPopupMenu { } targetSwf.updateCharacters(); - targetSwf.getCharacters(); // force rebuild character id cache + targetSwf.getCharacters(true); // force rebuild character id cache copyTag.setModified(true); newTags.add(copyTag); if (itemsSet.contains(tag)) { @@ -5132,7 +5132,7 @@ public class TagTreeContextMenu extends JPopupMenu { realTargetTimelined.addTag(positionInt, copyTag); targetSwf.updateCharacters(); - targetSwf.getCharacters(); // force rebuild character id cache + targetSwf.getCharacters(true); // force rebuild character id cache copyTag.setModified(true); newTags.add(copyTag); if (move) {