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 af3465899..dcd745edc 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 @@ -229,67 +229,74 @@ public class XFLConverter { return "normal"; } - private static void convertLineStyle(LINESTYLE ls, int shapeNum, XFLXmlWriter writer) { - writer.append("" - + ""); + private static void convertLineStyle(LINESTYLE ls, int shapeNum, XFLXmlWriter writer) throws XMLStreamException { + writer.writeStartElement("SolidStroke", new String[]{ + "scaleMode", getScaleMode(ls), + "weight", Double.toString(((float) ls.width) / SWF.unitDivisor),}); + + writer.writeStartElement("fill"); if (!(ls instanceof LINESTYLE2) || !((LINESTYLE2) ls).hasFillFlag) { - writer.append(""); + writer.writeStartElement("SolidColor", new String[]{"color", ls.color.toHexRGB()}); + if (shapeNum >= 3) { + writer.writeAttribute("alpha", ((RGBA) ls.color).getAlphaFloat()); + } + + writer.writeEndElement(); } else { // todo: line fill } - writer.append("" - + ""); + + writer.writeEndElement(); + writer.writeEndElement(); } private static void convertLineStyle(HashMap characters, LINESTYLE2 ls, int shapeNum, XFLXmlWriter writer) throws XMLStreamException { - StringBuilder params = new StringBuilder(); + writer.writeStartElement("SolidStroke", new String[]{"weight", Double.toString(((float) ls.width) / SWF.unitDivisor)}); if (ls.pixelHintingFlag) { - params.append(" pixelHinting=\"true\""); + writer.writeAttribute("pixelHinting", true); } if (ls.width == 1) { - params.append(" solidStyle=\"hairline\""); + writer.writeAttribute("solidStyle", "hairline"); } - params.append(" scaleMode=\"").append(getScaleMode(ls)).append("\""); + writer.writeAttribute("scaleMode", getScaleMode(ls)); switch (ls.endCapStyle) { //What about endCapStyle? case LINESTYLE2.NO_CAP: - params.append(" caps=\"none\""); + writer.writeAttribute("caps", "none"); break; case LINESTYLE2.SQUARE_CAP: - params.append(" caps=\"square\""); + writer.writeAttribute("caps", "square"); break; } switch (ls.joinStyle) { case LINESTYLE2.BEVEL_JOIN: - params.append(" joints=\"bevel\""); + writer.writeAttribute("joints", "bevel"); break; case LINESTYLE2.MITER_JOIN: - params.append(" joints=\"miter\""); + writer.writeAttribute("joints", "miter"); float miterLimitFactor = ls.miterLimitFactor; if (miterLimitFactor != 3.0f) { - params.append(" miterLimit=\"").append(miterLimitFactor).append("\""); + writer.writeAttribute("miterLimit", miterLimitFactor); } break; } - writer.append(""); - writer.append(""); + writer.writeStartElement("fill"); if (!ls.hasFillFlag) { RGBA color = (RGBA) ls.color; - writer.append(""); + writer.writeStartElement("SolidColor", new String[]{"color", color.toHexRGB()}); + if (color.getAlphaFloat() != 1) { + writer.writeAttribute("alpha", Float.toString(color.getAlphaFloat())); + } + + writer.writeEndElement(); } else { convertFillStyle(null/* FIXME */, characters, ls.fillType, shapeNum, writer); } - writer.append(""); - writer.append(""); + + writer.writeEndElement(); + writer.writeEndElement(); } private static void convertFillStyle(MATRIX mat, HashMap characters, FILLSTYLE fs, int shapeNum, XFLXmlWriter writer) throws XMLStreamException { @@ -300,58 +307,55 @@ public class XFLConverter { //ret.append(""); switch (fs.fillStyleType) { case FILLSTYLE.SOLID: - writer.append("= 3) { - writer.append(" alpha=\"").append(((RGBA) fs.color).getAlphaFloat()).append("\""); + writer.writeAttribute("alpha", ((RGBA) fs.color).getAlphaFloat()); } - writer.append(" />"); + + writer.writeEndElement(); break; case FILLSTYLE.REPEATING_BITMAP: case FILLSTYLE.CLIPPED_BITMAP: case FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP: case FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP: CharacterTag bitmapCh = characters.get(fs.bitmapId); - if (bitmapCh instanceof ImageTag) { - ImageTag it = (ImageTag) bitmapCh; - writer.append(""); + writer.writeEmptyElement("SolidColor", new String[]{"color", "#ffffff"}); return; } - writer.append("\""); + + ImageTag it = (ImageTag) bitmapCh; + writer.writeStartElement("BitmapFill"); + writer.writeAttribute("bitmapPath", "bitmap" + bitmapCh.getCharacterId() + it.getImageFormat().getExtension()); if ((fs.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) || (fs.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - writer.append(" bitmapIsClipped=\"true\""); + writer.writeAttribute("bitmapIsClipped", true); } - writer.append(">"); - writer.append(""); + writer.writeStartElement("matrix"); convertMatrix(fs.bitmapMatrix, writer); - writer.append(""); - writer.append(""); + writer.writeEndElement(); + writer.writeEndElement(); break; case FILLSTYLE.LINEAR_GRADIENT: case FILLSTYLE.RADIAL_GRADIENT: case FILLSTYLE.FOCAL_RADIAL_GRADIENT: if (fs.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) { - writer.append(""); - - writer.append(""); + writer.writeStartElement("matrix"); convertMatrix(fs.gradientMatrix, writer); - writer.append(""); + writer.writeEndElement(); GRADRECORD[] records; if (fs.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { records = fs.gradient.gradientRecords; @@ -393,18 +395,18 @@ public class XFLConverter { records = fs.gradient.gradientRecords; } for (GRADRECORD rec : records) { - writer.append("= 3) { - writer.append(" alpha=\"").append(((RGBA) rec.color).getAlphaFloat()).append("\""); + writer.writeAttribute("alpha", ((RGBA) rec.color).getAlphaFloat()); } - writer.append(" ratio=\"").append(rec.getRatioFloat()).append("\""); - writer.append(" />"); + writer.writeAttribute("ratio", rec.getRatioFloat()); + writer.writeEndElement(); } if (fs.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) { - writer.append(""); + writer.writeEndElement(); // LinearGradient } else { - writer.append(""); + writer.writeEndElement(); //RadialGradient } break; } @@ -436,20 +438,20 @@ public class XFLConverter { List layers = getShapeLayers(characters, mat, shapeNum, shapeRecords, fillStyles, lineStyles, morphshape); if (!useLayers) { for (int l = layers.size() - 1; l >= 0; l--) { - writer.append(layers.get(l)); + writer.writeCharactersRaw(layers.get(l)); } } else { int layer = 1; for (int l = layers.size() - 1; l >= 0; l--) { - writer.append(""); //color=\"#4FFF4F\" - writer.append(""); - writer.append(""); - writer.append(""); - writer.append(layers.get(l)); - writer.append(""); - writer.append(""); - writer.append(""); - writer.append(""); + writer.writeStartElement("DOMLayer", new String[]{"name", "Layer " + layer++}); //color="#4FFF4F" + writer.writeStartElement("frames"); + writer.writeStartElement("DOMFrame", new String[]{"index", "0", "motionTweenScale", "false", "keyMode", Integer.toString(KEY_MODE_SHAPE_LAYERS)}); + writer.writeStartElement("elements"); + writer.writeCharactersRaw(layers.get(l)); + writer.writeEndElement(); + writer.writeEndElement(); + writer.writeEndElement(); + writer.writeEndElement(); } } } @@ -526,49 +528,50 @@ public class XFLConverter { int strokeStyle = -1; XFLXmlWriter fillsStr = new XFLXmlWriter(); XFLXmlWriter strokesStr = new XFLXmlWriter(); - fillsStr.append(""); - strokesStr.append(""); + fillsStr.writeStartElement("fills"); + strokesStr.writeStartElement("strokes"); List layers = new ArrayList<>(); - StringBuilder currentLayer = new StringBuilder(); int fillStyleCount = 0; if (fillStyles != null) { for (FILLSTYLE fs : fillStyles.fillStyles) { - fillsStr.append(""); + fillsStr.writeStartElement("FillStyle", new String[]{"index", Integer.toString(fillStyleCount + 1)}); convertFillStyle(mat, characters, fs, shapeNum, fillsStr); - fillsStr.append(""); + fillsStr.writeEndElement(); fillStyleCount++; } } if (lineStyles != null) { if (shapeNum <= 3 && lineStyles.lineStyles != null) { for (int l = 0; l < lineStyles.lineStyles.length; l++) { - strokesStr.append(""); + strokesStr.writeStartElement("StrokeStyle", new String[]{"index", Integer.toString(lineStyleCount + 1)}); convertLineStyle(lineStyles.lineStyles[l], shapeNum, strokesStr); - strokesStr.append(""); + strokesStr.writeEndElement(); lineStyleCount++; } } else if (lineStyles.lineStyles != null) { for (int l = 0; l < lineStyles.lineStyles.length; l++) { - strokesStr.append(""); + strokesStr.writeStartElement("StrokeStyle", new String[]{"index", Integer.toString(lineStyleCount + 1)}); convertLineStyle(characters, (LINESTYLE2) lineStyles.lineStyles[l], shapeNum, strokesStr); - strokesStr.append(""); + strokesStr.writeEndElement(); lineStyleCount++; } } } - fillsStr.append(""); - strokesStr.append(""); + fillsStr.writeEndElement(); + strokesStr.writeEndElement(); int layer = 1; - if ((fillStyleCount > 0) || (lineStyleCount > 0)) { - currentLayer.append(""); - currentLayer.append(fillsStr); - currentLayer.append(strokesStr); - currentLayer.append(""); + XFLXmlWriter currentLayer = new XFLXmlWriter(); + if (fillStyleCount > 0 || lineStyleCount > 0) { + currentLayer.writeStartElement("DOMShape", new String[]{"isFloating", "true"}); + currentLayer.writeCharactersRaw(fillsStr.toString()); + currentLayer.writeCharactersRaw(strokesStr.toString()); + currentLayer.writeStartElement("edges"); } + int x = 0; int y = 0; int startEdgeX = 0; @@ -585,10 +588,10 @@ public class XFLConverter { int lastFillStyle0 = fillStyle0; int lastStrokeStyle = strokeStyle; if (scr.stateNewStyles) { - fillsStr.setLength(0); - strokesStr.setLength(0); - fillsStr.append(""); - strokesStr.append(""); + XFLXmlWriter fillsNewStr = new XFLXmlWriter(); + XFLXmlWriter strokesNewStr = new XFLXmlWriter(); + fillsNewStr.writeStartElement("fills"); + strokesNewStr.writeStartElement("strokes"); if (fillStyleCount > 0 || lineStyleCount > 0) { if ((fillStyle0 > 0) || (fillStyle1 > 0) || (strokeStyle > 0)) { @@ -607,62 +610,63 @@ public class XFLConverter { } } if (!empty) { - currentLayer.append(" -1) { - currentLayer.append(" fillStyle0=\"").append(fillStyle0).append("\""); + currentLayer.writeAttribute("fillStyle0", fillStyle0); } if (fillStyle1 > -1) { - currentLayer.append(" fillStyle1=\"").append(fillStyle1).append("\""); + currentLayer.writeAttribute("fillStyle1", fillStyle1); } if (strokeStyle > -1) { - currentLayer.append(" strokeStyle=\"").append(strokeStyle).append("\""); + currentLayer.writeAttribute("strokeStyle", strokeStyle); } - currentLayer.append(" edges=\""); - convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); - currentLayer.append("\" />"); + StringBuilder edgesSb = new StringBuilder(); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, edgesSb); + currentLayer.writeAttribute("edges", edgesSb.toString()); + currentLayer.writeEndElement(); } } } if (currentLayer.length() > 0) { - currentLayer.append(""); - currentLayer.append(""); + currentLayer.writeEndElement(); // edges + currentLayer.writeEndElement(); // DOMShape } String currentLayerString = currentLayer.toString(); if (!currentLayerString.contains("")) { //no empty layers, TODO:handle this better layers.add(currentLayerString); } currentLayer.setLength(0); - currentLayer.append(""); + currentLayer.writeStartElement("DOMShape", new String[]{"isFloating", "true"}); //ret += convertShape(characters, null, shape); for (int f = 0; f < scr.fillStyles.fillStyles.length; f++) { - fillsStr.append(""); - convertFillStyle(mat, characters, scr.fillStyles.fillStyles[f], shapeNum, fillsStr); - fillsStr.append(""); + fillsNewStr.writeStartElement("FillStyle", new String[]{"index", Integer.toString(f + 1)}); + convertFillStyle(mat, characters, scr.fillStyles.fillStyles[f], shapeNum, fillsNewStr); + fillsNewStr.writeEndElement(); fillStyleCount++; } lineStyleCount = 0; if (shapeNum <= 3) { for (int l = 0; l < scr.lineStyles.lineStyles.length; l++) { - strokesStr.append(""); - convertLineStyle(scr.lineStyles.lineStyles[l], shapeNum, strokesStr); - strokesStr.append(""); + strokesNewStr.writeStartElement("StrokeStyle", new String[]{"index", Integer.toString(lineStyleCount + 1)}); + convertLineStyle(scr.lineStyles.lineStyles[l], shapeNum, strokesNewStr); + strokesNewStr.writeEndElement(); lineStyleCount++; } } else { for (int l = 0; l < scr.lineStyles.lineStyles.length; l++) { - strokesStr.append(""); - convertLineStyle(characters, (LINESTYLE2) scr.lineStyles.lineStyles[l], shapeNum, strokesStr); - strokesStr.append(""); + strokesNewStr.writeStartElement("StrokeStyle", new String[]{"index", Integer.toString(lineStyleCount + 1)}); + convertLineStyle(characters, (LINESTYLE2) scr.lineStyles.lineStyles[l], shapeNum, strokesNewStr); + strokesNewStr.writeEndElement(); lineStyleCount++; } } - fillsStr.append(""); - strokesStr.append(""); - currentLayer.append(fillsStr); - currentLayer.append(strokesStr); - currentLayer.append(""); + fillsNewStr.writeEndElement(); // fills + strokesNewStr.writeEndElement(); // strokes + currentLayer.writeCharactersRaw(fillsNewStr.toString()); + currentLayer.writeCharactersRaw(strokesNewStr.toString()); + currentLayer.writeStartElement("edges"); actualLinestyles = scr.lineStyles; } if (scr.stateFillStyle0) { @@ -704,19 +708,20 @@ public class XFLConverter { } } if (!empty) { - currentLayer.append(" -1) { - currentLayer.append(" fillStyle0=\"").append(lastFillStyle0).append("\""); + currentLayer.writeAttribute("fillStyle0", lastFillStyle0); } if (fillStyle1 > -1) { - currentLayer.append(" fillStyle1=\"").append(lastFillStyle1).append("\""); + currentLayer.writeAttribute("fillStyle1", lastFillStyle1); } if (strokeStyle > -1) { - currentLayer.append(" strokeStyle=\"").append(lastStrokeStyle).append("\""); + currentLayer.writeAttribute("strokeStyle", lastStrokeStyle); } - currentLayer.append(" edges=\""); - convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); - currentLayer.append("\" />"); + StringBuilder edgesSb = new StringBuilder(); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, edgesSb); + currentLayer.writeAttribute("edges", edgesSb.toString()); + currentLayer.writeEndElement(); } startEdgeX = x; @@ -746,28 +751,27 @@ public class XFLConverter { } } if (!empty) { - currentLayer.append(" -1) { - currentLayer.append(" fillStyle0=\"").append(fillStyle0).append("\""); + currentLayer.writeAttribute("fillStyle0", fillStyle0); } if (fillStyle1 > -1) { - currentLayer.append(" fillStyle1=\"").append(fillStyle1).append("\""); + currentLayer.writeAttribute("fillStyle1", fillStyle1); } if (strokeStyle > -1) { - currentLayer.append(" strokeStyle=\"").append(strokeStyle).append("\""); + currentLayer.writeAttribute("strokeStyle", strokeStyle); } - currentLayer.append(" edges=\""); - convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); - currentLayer.append("\" />"); + StringBuilder edgesSb = new StringBuilder(); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, edgesSb); + currentLayer.writeAttribute("edges", edgesSb.toString()); + currentLayer.writeEndElement(); } } } edges.clear(); - fillsStr.append(""); - strokesStr.append(""); // todo: these fillsStr and strokeStr are not used, why? if (currentLayer.length() > 0) { - currentLayer.append(""); - currentLayer.append(""); + currentLayer.writeEndElement(); // edges + currentLayer.writeEndElement(); // DOMShape String currentLayerString = currentLayer.toString(); if (!currentLayerString.contains("")) { //no empty layers, TODO:handle this better @@ -915,137 +919,135 @@ public class XFLConverter { private static void convertFilter(FILTER filter, XFLXmlWriter writer) throws XMLStreamException { if (filter instanceof DROPSHADOWFILTER) { DROPSHADOWFILTER dsf = (DROPSHADOWFILTER) filter; - writer.append(""); + writer.writeAttribute("quality", dsf.passes); + writer.writeAttribute("strength", doubleToString(dsf.strength, 2)); + writer.writeEndElement(); } else if (filter instanceof BLURFILTER) { BLURFILTER bf = (BLURFILTER) filter; - writer.append(""); + writer.writeStartElement("BlurFilter"); + writer.writeAttribute("blurX", doubleToString(bf.blurX)); + writer.writeAttribute("blurY", doubleToString(bf.blurY)); + writer.writeAttribute("quality", bf.passes); + writer.writeEndElement(); } else if (filter instanceof GLOWFILTER) { GLOWFILTER gf = (GLOWFILTER) filter; - writer.append(""); + writer.writeAttribute("quality", gf.passes); + writer.writeAttribute("strength", doubleToString(gf.strength, 2)); + writer.writeEndElement(); } else if (filter instanceof BEVELFILTER) { BEVELFILTER bf = (BEVELFILTER) filter; - writer.append(""); + writer.writeEndElement(); } else if (filter instanceof GRADIENTGLOWFILTER) { GRADIENTGLOWFILTER ggf = (GRADIENTGLOWFILTER) filter; - writer.append(""); for (int g = 0; g < ggf.gradientColors.length; g++) { RGBA gc = ggf.gradientColors[g]; - writer.append(""); + writer.writeAttribute("ratio", doubleToString(((float) ggf.gradientRatio[g]) / 255.0)); + writer.writeEndElement(); } - writer.append(""); + writer.writeEndElement(); } else if (filter instanceof GRADIENTBEVELFILTER) { GRADIENTBEVELFILTER gbf = (GRADIENTBEVELFILTER) filter; - writer.append(""); for (int g = 0; g < gbf.gradientColors.length; g++) { RGBA gc = gbf.gradientColors[g]; - writer.append(""); + writer.writeAttribute("ratio", doubleToString(((float) gbf.gradientRatio[g]) / 255.0)); + writer.writeEndElement(); } - writer.append(""); + writer.writeEndElement(); } else if (filter instanceof COLORMATRIXFILTER) { COLORMATRIXFILTER cmf = (COLORMATRIXFILTER) filter; convertAdjustColorFilter(cmf, writer); @@ -1068,109 +1070,122 @@ public class XFLConverter { } } - writer.append("= FLAVersion.CS5_5.ordinal()) { - writer.append(" isVisible=\"false\""); + writer.writeAttribute("isVisible", false); } - writer.append(">"); - writer.append(""); + writer.writeStartElement("matrix"); convertMatrix(matrix, writer); - writer.append(""); - writer.append(""); + writer.writeEndElement(); + writer.writeStartElement("transformationPoint"); + writer.writeEmptyElement("Point"); + writer.writeEndElement(); if (backgroundColor != null) { - writer.append(""); + writer.writeEndElement(); } if (colorTransform != null) { - writer.append(""); + writer.writeEndElement(); + writer.writeEndElement(); // color } if (filters != null) { - writer.append(""); + writer.writeStartElement("filters"); for (FILTER f : filters) { convertFilter(f, writer); } - writer.append(""); + writer.writeEndElement(); } if (tag instanceof DefineButtonTag) { - writer.append(""); + writer.writeStartElement("Actionscript"); + writer.writeStartElement("script"); + writer.writeCData("on(press){\r\n" + convertActionScript(new ButtonAction((DefineButtonTag) tag)) + "}"); + writer.writeEndElement(); + writer.writeEndElement(); } if (tag instanceof DefineButton2Tag) { DefineButton2Tag db2 = (DefineButton2Tag) tag; if (!db2.actions.isEmpty()) { - writer.append(""); + writer.writeCData(sbActions.toString()); + writer.writeEndElement(); + writer.writeEndElement(); } } if (clipActions != null) { - writer.append(""); + writer.writeCData(sbActions.toString()); + writer.writeEndElement(); + writer.writeEndElement(); } - writer.append(""); + writer.writeEndElement(); } private static String convertActionScript(ASMSource as) { @@ -1205,36 +1220,39 @@ public class XFLConverter { } if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) { - StringBuilder symbolStr = new StringBuilder(); + XFLXmlWriter symbolStr = new XFLXmlWriter(); - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("timeline"); String itemIcon = null; if (symbol instanceof ButtonTag) { itemIcon = "0"; - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("DOMTimeline", new String[]{"name", "Symbol " + symbol.getCharacterId(), "currentFrame", "0"}); + symbolStr.writeStartElement(""); ButtonTag button = (ButtonTag) symbol; List records = button.getRecords(); @@ -1246,12 +1264,13 @@ public class XFLConverter { } } for (int i = maxDepth; i >= 1; i--) { - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("color", randomOutlineColor()); + symbolStr.writeStartElement(""); int lastFrame = 0; loopframes: for (int frame = 1; frame <= 4; frame++) { @@ -1307,77 +1326,67 @@ public class XFLConverter { lastFrame = frame; if (duration > 0) { if (duration > 1) { - symbolStr.append(""); - symbolStr.append(""); - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("DOMFrame", new String[]{ + "index", Integer.toString(frame - duration), + "duration", Integer.toString(duration - 1), + "keyMode", Integer.toString(KEY_MODE_NORMAL),}); + symbolStr.writeElementValue("elements", ""); + symbolStr.writeEndElement(); } - symbolStr.append(""); - symbolStr.append(""); - symbolStr.append(recCharWriter); - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("DOMFrame", new String[]{ + "index", Integer.toString(frame - 1), + "keyMode", Integer.toString(KEY_MODE_NORMAL),}); + symbolStr.writeElementValue("elements", recCharWriter.toString()); + symbolStr.writeEndElement(); } } } } - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeEndElement(); // frames + symbolStr.writeEndElement(); // DOMLayer } - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeEndElement(); // layers + symbolStr.writeEndElement(); // DOMTimeline } else if (symbol instanceof DefineSpriteTag) { DefineSpriteTag sprite = (DefineSpriteTag) symbol; if (sprite.getTags().isEmpty()) { //probably AS2 class continue; } - XFLXmlWriter writer2 = new XFLXmlWriter(); // todo: remove - convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files, writer2); - symbolStr.append(writer2.toString()); + convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files, symbolStr); } else if (symbol instanceof ShapeTag) { itemIcon = "1"; ShapeTag shape = (ShapeTag) symbol; - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeStartElement("DOMTimeline", new String[]{"name", "Symbol " + symbol.getCharacterId(), "currentFrame", "0"}); + symbolStr.writeStartElement("layers"); SHAPEWITHSTYLE shapeWithStyle = shape.getShapes(); if (shapeWithStyle != null) { - XFLXmlWriter writer2 = new XFLXmlWriter(); - convertShape(characters, null, shape.getShapeNum(), shapeWithStyle.shapeRecords, shapeWithStyle.fillStyles, shapeWithStyle.lineStyles, false, true, writer2); - symbolStr.append(writer2.toString()); + convertShape(characters, null, shape.getShapeNum(), shapeWithStyle.shapeRecords, shapeWithStyle.fillStyles, shapeWithStyle.lineStyles, false, true, symbolStr); } - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeEndElement(); // layers + symbolStr.writeEndElement(); // DOMTimeline } - symbolStr.append(""); - symbolStr.append(""); + symbolStr.writeEndElement(); // timeline + symbolStr.writeEndElement(); // DOMSymbolItem String symbolStr2 = prettyFormatXML(symbolStr.toString()); String symbolFile = "Symbol " + symbol.getCharacterId() + ".xml"; files.put(symbolFile, Utf8Helper.getBytes(symbolStr2)); - String symbLinkStr = ""; - symbLinkStr += "= FLAVersion.CS5_5.ordinal()) { - symbLinkStr += " lastModified=\"" + getTimestamp(swf) + "\""; - //TODO: itemID=\"518de416-00000341\" - } - symbLinkStr += "/>"; if (!hasSymbol) { writer.writeStartElement("symbols"); } - writer.writeCharactersRaw(symbLinkStr); + // write symbLink + writer.writeStartElement("Include", new String[]{"href", symbolFile}); + if (itemIcon != null) { + writer.writeAttribute("itemIcon", itemIcon); + } + writer.writeAttribute("loadImmediate", false); + if (flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) { + writer.writeAttribute("lastModified", getTimestamp(swf)); + //TODO: itemID="518de416-00000341" + } + writer.writeEndElement(); hasSymbol = true; } } @@ -1388,10 +1397,25 @@ public class XFLConverter { } private void convertMedia(SWF swf, Map characterVariables, Map characterClasses, List nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap characters, HashMap files, HashMap datfiles, FLAVersion flaVersion, XFLXmlWriter writer) throws XMLStreamException { - int mediaCount = 0; + boolean hasMedia = false; + for (int ch : characters.keySet()) { + CharacterTag symbol = characters.get(ch); + if (symbol instanceof ImageTag + || symbol instanceof SoundStreamHeadTypeTag || symbol instanceof DefineSoundTag + || symbol instanceof DefineVideoStreamTag) { + hasMedia = true; + } + } + + if (!hasMedia) { + return; + } + + int mediaCount = 0; + writer.writeStartElement("media"); + for (int ch : characters.keySet()) { CharacterTag symbol = characters.get(ch); - String mediaLinkStr = null; if (symbol instanceof ImageTag) { ImageTag imageTag = (ImageTag) symbol; boolean allowSmoothing = false; @@ -1434,24 +1458,35 @@ public class XFLConverter { ImageFormat format = imageTag.getImageFormat(); String symbolFile = "bitmap" + symbol.getCharacterId() + imageTag.getImageFormat().getExtension(); files.put(symbolFile, imageBytes); - mediaLinkStr = "\n"; - + writer.writeAttribute("quality", 50); + writer.writeAttribute("href", symbolFile); + writer.writeAttribute("bitmapDataHRef", "M " + (mediaCount + 1) + " " + getTimestamp(swf) + ".dat"); + writer.writeAttribute("frameRight", image.getWidth()); + writer.writeAttribute("frameBottom", image.getHeight()); + writer.writeEndElement(); + mediaCount++; } else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) { int soundFormat = 0; int soundRate = 0; @@ -1592,31 +1627,32 @@ public class XFLConverter { String symbolFile = "sound" + symbol.getCharacterId() + "." + exportFormat; files.put(symbolFile, data); - mediaLinkStr = ""; + writer.writeEmptyElement("DOMVideoItem", new String[]{ + "name", symbolFile, + "sourceExternalFilepath", "./LIBRARY/" + symbolFile, + "sourceLastImported", Long.toString(ts), + "videoDataHRef", datFileName, + "channels", "0", + "isSpecial", "true"}); //Use the dat file, otherwise it does not work datfiles.put(datFileName, new byte[]{ //Magic numbers, if anybody knows why, please tell me (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, @@ -1664,44 +1706,37 @@ public class XFLConverter { }); } else { files.put(symbolFile, data); - mediaLinkStr = " 0) { - writer.writeEndElement(); - } + writer.writeEndElement(); } private static String prettyFormatXML(String input) { @@ -1748,14 +1783,14 @@ public class XFLConverter { } else { writer.writeAttribute("keyMode", KEY_MODE_NORMAL); } - String soundEnvelopeStr = ""; + XFLXmlWriter soundEnvelopeStr = new XFLXmlWriter(); if (soundStreamHead != null && startSound == null) { String soundName = "sound" + soundStreamHead.getCharacterId() + "." + soundStreamHead.getExportFormat().toString().toLowerCase(); writer.writeAttribute("soundName", soundName); writer.writeAttribute("soundSync", "stream"); - soundEnvelopeStr += ""; - soundEnvelopeStr += ""; - soundEnvelopeStr += ""; + soundEnvelopeStr.writeStartElement("SoundEnvelope"); + soundEnvelopeStr.writeEmptyElement("SoundEnvelopePoint", new String[]{"level0", "32768", "level1", "32768"}); + soundEnvelopeStr.writeEndElement(); } if (startSound != null && sound != null) { String soundName = "sound" + sound.soundId + "." + sound.getExportFormat().toString().toLowerCase(); @@ -1778,11 +1813,11 @@ public class XFLConverter { } else if (startSound.soundInfo.syncNoMultiple) { writer.writeAttribute("soundSync", "start"); } - soundEnvelopeStr += ""; + soundEnvelopeStr.writeStartElement("SoundEnvelope"); if (startSound.soundInfo.hasEnvelope) { SOUNDENVELOPE[] envelopeRecords = startSound.soundInfo.envelopeRecords; for (SOUNDENVELOPE env : envelopeRecords) { - soundEnvelopeStr += ""; + soundEnvelopeStr.writeEmptyElement("SoundEnvelopePoint", new String[]{"mark44", Long.toString(env.pos44), "level0", Integer.toString(env.leftLevel), "level1", Integer.toString(env.rightLevel)}); } if (envelopeRecords.length == 1 @@ -1817,12 +1852,12 @@ public class XFLConverter { //TODO: fade in, fade out } else { - soundEnvelopeStr += ""; + soundEnvelopeStr.writeEmptyElement("SoundEnvelopePoint", new String[]{"level0", "32768", "level1", "32768"}); } - soundEnvelopeStr += ""; + soundEnvelopeStr.writeEndElement(); // SoundEnvelope } - writer.writeCharactersRaw(soundEnvelopeStr); + writer.writeCharactersRaw(soundEnvelopeStr.toString()); if (!actionScript.isEmpty()) { writer.writeStartElement("Actionscript"); writer.writeStartElement("script"); @@ -2036,6 +2071,7 @@ public class XFLConverter { FontTag font = (FontTag) t; if (font.getCharacterCount() > 0) { hasFont = true; + break; } } } @@ -2130,8 +2166,8 @@ public class XFLConverter { writer.writeEndElement(); } - private String convertActionScriptLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor) { - StringBuilder ret = new StringBuilder(); + private boolean convertActionScriptLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor, XFLXmlWriter writer) throws XMLStreamException { + boolean hasScript = false; String script = ""; int duration = 0; @@ -2157,43 +2193,51 @@ public class XFLConverter { if (script.isEmpty()) { duration++; } else { - if (duration > 0) { - ret.append(" 1) { - ret.append(" duration=\"").append(duration).append("\""); - } - ret.append(" keyMode=\"").append(KEY_MODE_NORMAL).append("\">"); - ret.append(""); - ret.append(""); - ret.append(""); + if (!hasScript) { + writer.writeStartElement("DOMLayer", new String[]{"name", "Script Layer", "color", randomOutlineColor()}); + writer.writeStartElement("frames"); + hasScript = true; } - ret.append(""); - ret.append(""); - ret.append(""); - ret.append(""); - ret.append(""); + + if (duration > 0) { + writer.writeStartElement("DOMFrame", new String[]{"index", Integer.toString(frame - duration)}); + if (duration > 1) { + writer.writeAttribute("duration", duration); + } + writer.writeAttribute("keyMode", KEY_MODE_NORMAL); + writer.writeElementValue("elements", ""); + writer.writeEndElement(); + } + + writer.writeStartElement("DOMFrame", new String[]{"index", Integer.toString(frame)}); + writer.writeAttribute("keyMode", KEY_MODE_NORMAL); + + writer.writeStartElement("Actionscript"); + writer.writeStartElement("script"); + writer.writeCData(script); + writer.writeEndElement(); + writer.writeEndElement(); + + writer.writeElementValue("elements", ""); + writer.writeEndElement(); script = ""; duration = 0; } frame++; } } - String retStr = ret.toString(); - if (!retStr.isEmpty()) { - retStr = "" - + "" - + retStr - + "" - + ""; + + if (hasScript) { + writer.writeEndElement(); // frames + writer.writeEndElement(); // DOMLayer } - return retStr; + + return hasScript; } - private String convertLabelsLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor) { - StringBuilder ret = new StringBuilder(); + private boolean convertLabelsLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor, XFLXmlWriter writer) throws XMLStreamException { + boolean hasLabel = false; + int duration = 0; int frame = 0; String frameLabel = ""; @@ -2203,49 +2247,50 @@ public class XFLConverter { FrameLabelTag fl = (FrameLabelTag) t; frameLabel = fl.getLabelName(); isAnchor = fl.isNamedAnchor(); - } - if (t instanceof ShowFrameTag) { - + } else if (t instanceof ShowFrameTag) { if (frameLabel.isEmpty()) { duration++; } else { + if (!hasLabel) { + writer.writeStartElement("DOMLayer", new String[]{"name", "Labels Layer", "color", randomOutlineColor()}); + writer.writeStartElement("frames"); + hasLabel = true; + } + if (duration > 0) { - ret.append(" 1) { - ret.append(" duration=\"").append(duration).append("\""); + writer.writeAttribute("duration", duration); } - ret.append(" keyMode=\"").append(KEY_MODE_NORMAL).append("\">"); - ret.append(""); - ret.append(""); - ret.append(""); + writer.writeAttribute("keyMode", KEY_MODE_NORMAL); + writer.writeElementValue("elements", ""); + writer.writeEndElement(); } - ret.append(""); - ret.append(""); - ret.append(""); - ret.append(""); + writer.writeElementValue("elements", ""); + writer.writeEndElement(); frameLabel = ""; duration = 0; } frame++; } } - String retStr = ret.toString(); - if (!retStr.isEmpty()) { - retStr = "" - + "" - + retStr - + "" - + ""; + + if (hasLabel) { + writer.writeEndElement(); // frames + writer.writeEndElement(); // DOMLayer } - return retStr; + + return hasLabel; } private void convertSoundLayer(int layerIndex, String backgroundColor, HashMap characters, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, HashMap files, XFLXmlWriter writer) throws XMLStreamException { @@ -2326,18 +2371,16 @@ public class XFLConverter { writer.writeStartElement("DOMTimeline", new String[]{"name", name}); writer.writeStartElement("layers"); - String labelsLayer = convertLabelsLayer(spriteId, tags, timelineTags, backgroundColor); - writer.writeCharactersRaw(labelsLayer); - String scriptLayer = convertActionScriptLayer(spriteId, tags, timelineTags, backgroundColor); - writer.writeCharactersRaw(scriptLayer); + boolean hasLabel = convertLabelsLayer(spriteId, tags, timelineTags, backgroundColor, writer); + boolean hasScript = convertActionScriptLayer(spriteId, tags, timelineTags, backgroundColor, writer); int index = 0; - if (!labelsLayer.isEmpty()) { + if (hasLabel) { index++; } - if (!scriptLayer.isEmpty()) { + if (hasScript) { index++; } @@ -2386,21 +2429,26 @@ public class XFLConverter { if (!parentLayers.isEmpty()) { parentLayer = parentLayers.pop(); } - String layerPrev = ""; - layerPrev += ""); + filterStr.writeStartElement("filters"); for (FILTER f : filters) { convertFilter(f, filterStr); } - filterStr.append(""); + filterStr.writeEndElement(); } SWF swf = tag.getSwf(); @@ -2475,25 +2523,23 @@ public class XFLConverter { } String fontRenderingMode = "standard"; - String antiAlias = ""; + String antiAliasSharpness = null; + String antiAliasThickness = null; if (csmts != null) { if (csmts.thickness == 0 & csmts.sharpness == 0) { fontRenderingMode = null; } else { fontRenderingMode = "customThicknessSharpness"; } - antiAlias = " antiAliasSharpness=\"" + doubleToString(csmts.sharpness) + "\" antiAliasThickness=\"" + doubleToString(csmts.thickness) + "\""; + antiAliasSharpness = doubleToString(csmts.sharpness); + antiAliasThickness = doubleToString(csmts.thickness); } - String left = ""; + String left = null; RECT bounds = tag.getBounds(); if ((tag instanceof DefineTextTag) || (tag instanceof DefineText2Tag)) { MATRIX textMatrix = tag.getTextMatrix(); - left = " left=\"" + doubleToString((textMatrix.translateX) / SWF.unitDivisor) + "\""; + left = doubleToString((textMatrix.translateX) / SWF.unitDivisor); } - XFLXmlWriter matStr = new XFLXmlWriter(); - matStr.append(""); - convertMatrix(matrix, matStr); - matStr.append(""); if ((tag instanceof DefineTextTag) || (tag instanceof DefineText2Tag)) { List textRecords = new ArrayList<>(); if (tag instanceof DefineTextTag) { @@ -2512,15 +2558,20 @@ public class XFLConverter { } } - writer.append(" attrs = TextTag.getTextRecordsAttributes(textRecords, swf); // todo: remove System.err.println("///////////============="); - writer.append(" width=\"").append(tag.getBounds().getWidth() / 2).append("\" height=\"").append(tag.getBounds().getHeight()).append("\" autoExpand=\"true\" isSelectable=\"false\">"); - writer.append(matStr.toString()); + writer.writeAttribute("width", tag.getBounds().getWidth() / 2); + writer.writeAttribute("height", tag.getBounds().getHeight()); + writer.writeAttribute("autoExpand", true); + writer.writeAttribute("isSelectable", false); + writer.writeStartElement("matrix"); + convertMatrix(matrix, writer); + writer.writeEndElement(); - writer.append(""); + writer.writeStartElement("textRuns"); int fontId = -1; FontTag font = null; String fontName = null; @@ -2589,32 +2645,40 @@ public class XFLConverter { } firstRun = false; if (font != null) { - writer.append(""); - writer.append("").append(Helper.escapeHTML((newline ? "\r" : "") + rec.getText(font))).append(""); - writer.append(""); + writer.writeStartElement("DOMTextRun"); + writer.writeStartElement("characters"); + writer.writeCharacters((newline ? "\r" : "") + rec.getText(font)); + writer.writeEndElement(); + writer.writeStartElement("textAttrs"); - writer.append(""); + writer.writeAttribute("face", psFontName); + writer.writeEndElement(); - writer.append(""); - writer.append(""); + writer.writeEndElement(); // textAttrs + writer.writeEndElement(); // DOMTextRun } } - writer.append(""); - writer.append(filterStr.toString()); - writer.append(""); + writer.writeEndElement(); // textRuns + writer.writeCharactersRaw(filterStr.toString()); + writer.writeEndElement(); // DOMStaticText } else if (tag instanceof DefineEditTextTag) { DefineEditTextTag det = (DefineEditTextTag) tag; String tagName; @@ -2632,14 +2696,17 @@ public class XFLConverter { } else { tagName = "DOMInputText"; } - writer.append("<").append(tagName); + writer.writeStartElement(tagName); if (fontRenderingMode != null) { - writer.append(" fontRenderingMode=\"").append(fontRenderingMode).append("\""); + writer.writeAttribute("fontRenderingMode", fontRenderingMode); } if (instanceName != null) { - writer.append(" name=\"").append(Helper.escapeHTML(instanceName)).append("\""); + writer.writeAttribute("name", instanceName); + } + if (antiAliasSharpness != null) { + writer.writeAttribute("antiAliasSharpness", antiAliasSharpness); + writer.writeAttribute("antiAliasThickness", antiAliasThickness); } - writer.append(antiAlias); double width = twipToPixel(bounds.getWidth()); double height = twipToPixel(bounds.getHeight()); //There is usually 4px difference between width/height and XML width/height @@ -2651,43 +2718,46 @@ public class XFLConverter { width -= twipToPixel(det.rightMargin); width -= twipToPixel(det.leftMargin); } - writer.append(" width=\"").append(width).append("\""); - writer.append(" height=\"").append(height).append("\""); + writer.writeAttribute("width", width); + writer.writeAttribute("height", height); if (det.border) { - writer.append(" border=\"true\""); + writer.writeAttribute("border", true); } if (det.html) { - writer.append(" renderAsHTML=\"true\""); + writer.writeAttribute("renderAsHTML", true); } if (det.noSelect) { - writer.append(" isSelectable=\"false\""); + writer.writeAttribute("isSelectable", false); } if (det.multiline && det.wordWrap) { - writer.append(" lineType=\"multiline\""); + writer.writeAttribute("lineType", "multiline"); } else if (det.multiline && (!det.wordWrap)) { - writer.append(" lineType=\"multiline no wrap\""); + writer.writeAttribute("lineType", "multiline no wrap"); } else if (det.password) { - writer.append(" lineType=\"password\""); + writer.writeAttribute("lineType", "password"); } if (det.hasMaxLength) { - writer.append(" maxCharacters=\"").append(det.maxLength).append("\""); + writer.writeAttribute("maxCharacters", det.maxLength); } if (!det.variableName.isEmpty()) { - writer.append(" variableName=\"").append(det.variableName).append("\""); + writer.writeAttribute("variableName", det.variableName); } - writer.append(">"); - writer.append(matStr.toString()); - writer.append(""); + writer.writeStartElement("matrix"); + convertMatrix(matrix, writer); + writer.writeEndElement(); + writer.writeStartElement("textRuns"); String txt = ""; if (det.hasText) { txt = det.initialText; } if (det.html) { - writer.append(convertHTMLText(swf.getTags(), det, txt)); + writer.writeCharactersRaw(convertHTMLText(swf.getTags(), det, txt)); } else { - writer.append(""); - writer.append("").append(Helper.escapeHTML(txt)).append(""); + writer.writeStartElement("DOMTextRun"); + writer.writeStartElement("characters"); + writer.writeCharacters(txt); + writer.writeEndElement(); int leftMargin = -1; int rightMargin = -1; int indent = -1; @@ -2744,41 +2814,42 @@ public class XFLConverter { alignment = "unknown"; } } - writer.append(""); - writer.append(" -1) { - writer.append(" indent=\"").append(twipToPixel(indent)).append("\""); + writer.writeAttribute("indent", twipToPixel(indent)); } if (leftMargin > -1) { - writer.append(" leftMargin=\"").append(twipToPixel(leftMargin)).append("\""); + writer.writeAttribute("leftMargin", twipToPixel(leftMargin)); } if (lineSpacing > -1) { - writer.append(" lineSpacing=\"").append(twipToPixel(lineSpacing)).append("\""); + writer.writeAttribute("lineSpacing", twipToPixel(lineSpacing)); } if (rightMargin > -1) { - writer.append(" rightMargin=\"").append(twipToPixel(rightMargin)).append("\""); + writer.writeAttribute("rightMargin", twipToPixel(rightMargin)); } if (size > -1) { - writer.append(" size=\"").append(twipToPixel(size)).append("\""); - writer.append(" bitmapSize=\"").append(size).append("\""); + writer.writeAttribute("size", twipToPixel(size)); + writer.writeAttribute("bitmapSize", size); } if (fontFace != null) { - writer.append(" face=\"").append(fontFace).append("\""); + writer.writeAttribute("face", fontFace); } if (textColor != null) { - writer.append(" fillColor=\"").append(textColor.toHexRGB()).append("\" alpha=\"").append(textColor.getAlphaFloat()).append("\""); + writer.writeAttribute("fillColor", textColor.toHexRGB()); + writer.writeAttribute("alpha", textColor.getAlphaFloat()); } - writer.append("/>"); - writer.append(""); - writer.append(""); + writer.writeEndElement(); + writer.writeEndElement(); // textAttrs + writer.writeEndElement(); // DOMTextRun } - writer.append(""); - writer.append(filterStr.toString()); - writer.append(""); + writer.writeEndElement(); // textRuns + writer.writeCharactersRaw(filterStr.toString()); + writer.writeEndElement(); // tagName } } @@ -2905,27 +2976,27 @@ public class XFLConverter { publishSettings.writeStartElement("flash_profile", new String[]{"version", "1.0", "name", "Default", "current", "true"}); publishSettings.writeStartElement("PublishFormatProperties", new String[]{"enabled", "true"}); - publishSettings.writeElementValue("defaultNames", "1"); - publishSettings.writeElementValue("flash", "1"); - publishSettings.writeElementValue("projectorWin", "0"); - publishSettings.writeElementValue("projectorMac", "0"); - publishSettings.writeElementValue("html", "1"); - publishSettings.writeElementValue("gif", "0"); - publishSettings.writeElementValue("jpeg", "0"); - publishSettings.writeElementValue("png", "0"); - publishSettings.writeElementValue(greaterThanCC ? "svg" : "qt", "0"); - publishSettings.writeElementValue("rnwk", "0"); - publishSettings.writeElementValue("swc", "0"); - publishSettings.writeElementValue("flashDefaultName", "1"); - publishSettings.writeElementValue("projectorWinDefaultName", "1"); - publishSettings.writeElementValue("projectorMacDefaultName", "1"); - publishSettings.writeElementValue("htmlDefaultName", "1"); - publishSettings.writeElementValue("gifDefaultName", "1"); - publishSettings.writeElementValue("jpegDefaultName", "1"); - publishSettings.writeElementValue("pngDefaultName", "1"); - publishSettings.writeElementValue(greaterThanCC ? "svgDefaultName" : "qtDefaultName", "1"); - publishSettings.writeElementValue("rnwkDefaultName", "1"); - publishSettings.writeElementValue("swcDefaultName", "1"); + publishSettings.writeElementValue("defaultNames", 1); + publishSettings.writeElementValue("flash", 1); + publishSettings.writeElementValue("projectorWin", 0); + publishSettings.writeElementValue("projectorMac", 0); + publishSettings.writeElementValue("html", 1); + publishSettings.writeElementValue("gif", 0); + publishSettings.writeElementValue("jpeg", 0); + publishSettings.writeElementValue("png", 0); + publishSettings.writeElementValue(greaterThanCC ? "svg" : "qt", 0); + publishSettings.writeElementValue("rnwk", 0); + publishSettings.writeElementValue("swc", 0); + publishSettings.writeElementValue("flashDefaultName", 1); + publishSettings.writeElementValue("projectorWinDefaultName", 1); + publishSettings.writeElementValue("projectorMacDefaultName", 1); + publishSettings.writeElementValue("htmlDefaultName", 1); + publishSettings.writeElementValue("gifDefaultName", 1); + publishSettings.writeElementValue("jpegDefaultName", 1); + publishSettings.writeElementValue("pngDefaultName", 1); + publishSettings.writeElementValue(greaterThanCC ? "svgDefaultName" : "qtDefaultName", 1); + publishSettings.writeElementValue("rnwkDefaultName", 1); + publishSettings.writeElementValue("swcDefaultName", 1); publishSettings.writeElementValue("flashFileName", baseName + ".swf"); publishSettings.writeElementValue("projectorWinFileName", baseName + ".exe"); publishSettings.writeElementValue("projectorMacFileName", baseName + ".app"); @@ -2933,79 +3004,79 @@ public class XFLConverter { publishSettings.writeElementValue("gifFileName", baseName + ".gif"); publishSettings.writeElementValue("jpegFileName", baseName + ".jpg"); publishSettings.writeElementValue("pngFileName", baseName + ".png"); - publishSettings.writeElementValue(greaterThanCC ? "svgFileName" : "qtFileName", "1"); + publishSettings.writeElementValue(greaterThanCC ? "svgFileName" : "qtFileName", 1); publishSettings.writeElementValue("rnwkFileName", baseName + ".smil"); publishSettings.writeElementValue("swcFileName", baseName + ".swc"); publishSettings.writeEndElement(); publishSettings.writeStartElement("PublishHtmlProperties", new String[]{"enabled", "true"}); - publishSettings.writeElementValue("VersionDetectionIfAvailable", "0"); + publishSettings.writeElementValue("VersionDetectionIfAvailable", 0); publishSettings.writeElementValue("VersionInfo", "12,0,0,0;11,2,0,0;11,1,0,0;10,3,0,0;10,2,153,0;10,1,52,0;9,0,124,0;8,0,24,0;7,0,14,0;6,0,79,0;5,0,58,0;4,0,32,0;3,0,8,0;2,0,1,12;1,0,0,1;"); - publishSettings.writeElementValue("UsingDefaultContentFilename", "1"); - publishSettings.writeElementValue("UsingDefaultAlternateFilename", "1"); + publishSettings.writeElementValue("UsingDefaultContentFilename", 1); + publishSettings.writeElementValue("UsingDefaultAlternateFilename", 1); publishSettings.writeElementValue("ContentFilename", baseName + "_content.html"); publishSettings.writeElementValue("AlternateFilename", baseName + "_alternate.html"); - publishSettings.writeElementValue("UsingOwnAlternateFile", "0"); + publishSettings.writeElementValue("UsingOwnAlternateFile", 0); publishSettings.writeElementValue("OwnAlternateFilename", ""); publishSettings.writeElementValue("Width", width); publishSettings.writeElementValue("Height", height); - publishSettings.writeElementValue("Align", "0"); - publishSettings.writeElementValue("Units", "0"); - publishSettings.writeElementValue("Loop", "1"); - publishSettings.writeElementValue("StartPaused", "0"); - publishSettings.writeElementValue("Scale", "0"); - publishSettings.writeElementValue("HorizontalAlignment", "1"); - publishSettings.writeElementValue("VerticalAlignment", "1"); - publishSettings.writeElementValue("Quality", "4"); - publishSettings.writeElementValue("DeblockingFilter", "0"); - publishSettings.writeElementValue("WindowMode", "0"); - publishSettings.writeElementValue("DisplayMenu", "1"); - publishSettings.writeElementValue("DeviceFont", "0"); + publishSettings.writeElementValue("Align", 0); + publishSettings.writeElementValue("Units", 0); + publishSettings.writeElementValue("Loop", 1); + publishSettings.writeElementValue("StartPaused", 0); + publishSettings.writeElementValue("Scale", 0); + publishSettings.writeElementValue("HorizontalAlignment", 1); + publishSettings.writeElementValue("VerticalAlignment", 1); + publishSettings.writeElementValue("Quality", 4); + publishSettings.writeElementValue("DeblockingFilter", 0); + publishSettings.writeElementValue("WindowMode", 0); + publishSettings.writeElementValue("DisplayMenu", 1); + publishSettings.writeElementValue("DeviceFont", 0); publishSettings.writeElementValue("TemplateFileName", ""); - publishSettings.writeElementValue("showTagWarnMsg", "1"); + publishSettings.writeElementValue("showTagWarnMsg", 1); publishSettings.writeEndElement(); publishSettings.writeStartElement("PublishFlashProperties", new String[]{"enabled", "true"}); publishSettings.writeElementValue("TopDown", ""); publishSettings.writeElementValue("FireFox", ""); - publishSettings.writeElementValue("Report", "0"); - publishSettings.writeElementValue("Protect", "0"); - publishSettings.writeElementValue("OmitTraceActions", "0"); + publishSettings.writeElementValue("Report", 0); + publishSettings.writeElementValue("Protect", 0); + publishSettings.writeElementValue("OmitTraceActions", 0); publishSettings.writeElementValue("Quality", "80"); - publishSettings.writeElementValue("DeblockingFilter", "0"); - publishSettings.writeElementValue("StreamFormat", "0"); - publishSettings.writeElementValue("StreamCompress", "7"); - publishSettings.writeElementValue("EventFormat", "0"); - publishSettings.writeElementValue("EventCompress", "7"); - publishSettings.writeElementValue("OverrideSounds", "0"); + publishSettings.writeElementValue("DeblockingFilter", 0); + publishSettings.writeElementValue("StreamFormat", 0); + publishSettings.writeElementValue("StreamCompress", 7); + publishSettings.writeElementValue("EventFormat", 0); + publishSettings.writeElementValue("EventCompress", 7); + publishSettings.writeElementValue("OverrideSounds", 0); publishSettings.writeElementValue("Version", flaSwfVersion); publishSettings.writeElementValue("ExternalPlayer", FLAVersion.swfVersionToPlayer(flaSwfVersion)); - publishSettings.writeElementValue("ActionScriptVersion", useAS3 ? "3" : "2"); - publishSettings.writeElementValue("PackageExportFrame", "1"); + publishSettings.writeElementValue("ActionScriptVersion", useAS3 ? 3 : 2); + publishSettings.writeElementValue("PackageExportFrame", 1); publishSettings.writeElementValue("PackagePaths", ""); publishSettings.writeElementValue("AS3PackagePaths", "."); publishSettings.writeElementValue("AS3ConfigConst", "CONFIG::FLASH_AUTHORING=\"true\";"); - publishSettings.writeElementValue("DebuggingPermitted", "0"); + publishSettings.writeElementValue("DebuggingPermitted", 0); publishSettings.writeElementValue("DebuggingPassword", ""); - publishSettings.writeElementValue("CompressMovie", swf.compression == SWFCompression.NONE ? "0" : "1"); - publishSettings.writeElementValue("CompressionType", swf.compression == SWFCompression.LZMA ? "1" : "0"); - publishSettings.writeElementValue("InvisibleLayer", "1"); - publishSettings.writeElementValue("DeviceSound", "0"); - publishSettings.writeElementValue("StreamUse8kSampleRate", "0"); - publishSettings.writeElementValue("EventUse8kSampleRate", "0"); + publishSettings.writeElementValue("CompressMovie", swf.compression == SWFCompression.NONE ? 0 : 1); + publishSettings.writeElementValue("CompressionType", swf.compression == SWFCompression.LZMA ? 1 : 0); + publishSettings.writeElementValue("InvisibleLayer", 1); + publishSettings.writeElementValue("DeviceSound", 0); + publishSettings.writeElementValue("StreamUse8kSampleRate", 0); + publishSettings.writeElementValue("EventUse8kSampleRate", 0); publishSettings.writeElementValue("UseNetwork", useNetwork ? 1 : 0); publishSettings.writeElementValue("DocumentClass", characterClasses.containsKey(0) ? characterClasses.get(0) : ""); - publishSettings.writeElementValue("AS3Strict", "2"); - publishSettings.writeElementValue("AS3Coach", "4"); - publishSettings.writeElementValue("AS3AutoDeclare", "4096"); + publishSettings.writeElementValue("AS3Strict", 2); + publishSettings.writeElementValue("AS3Coach", 4); + publishSettings.writeElementValue("AS3AutoDeclare", 4096); publishSettings.writeElementValue("AS3Dialect", "AS3"); - publishSettings.writeElementValue("AS3ExportFrame", "1"); - publishSettings.writeElementValue("AS3Optimize", "1"); - publishSettings.writeElementValue("ExportSwc", "0"); - publishSettings.writeElementValue("ScriptStuckDelay", "15"); - publishSettings.writeElementValue("IncludeXMP", "1"); - publishSettings.writeElementValue("HardwareAcceleration", "0"); - publishSettings.writeElementValue("AS3Flags", "4102"); + publishSettings.writeElementValue("AS3ExportFrame", 1); + publishSettings.writeElementValue("AS3Optimize", 1); + publishSettings.writeElementValue("ExportSwc", 0); + publishSettings.writeElementValue("ScriptStuckDelay", 15); + publishSettings.writeElementValue("IncludeXMP", 1); + publishSettings.writeElementValue("HardwareAcceleration", 0); + publishSettings.writeElementValue("AS3Flags", 4102); publishSettings.writeElementValue("DefaultLibraryLinkage", "rsl"); publishSettings.writeElementValue("RSLPreloaderMethod", "wrap"); publishSettings.writeElementValue("RSLPreloaderSWF", "$(AppConfig)/ActionScript 3.0/rsls/loader_animation.swf"); @@ -3058,66 +3129,66 @@ public class XFLConverter { publishSettings.writeStartElement("PublishJpegProperties", new String[]{"enabled", "true"}); publishSettings.writeElementValue("Width", width); publishSettings.writeElementValue("Height", height); - publishSettings.writeElementValue("Progressive", "0"); - publishSettings.writeElementValue("DPI", "4718592"); - publishSettings.writeElementValue("Size", "0"); - publishSettings.writeElementValue("Quality", "80"); - publishSettings.writeElementValue("MatchMovieDim", "1"); + publishSettings.writeElementValue("Progressive", 0); + publishSettings.writeElementValue("DPI", 4718592); + publishSettings.writeElementValue("Size", 0); + publishSettings.writeElementValue("Quality", 80); + publishSettings.writeElementValue("MatchMovieDim", 1); publishSettings.writeEndElement(); publishSettings.writeStartElement("PublishRNWKProperties", new String[]{"enabled", "true"}); - publishSettings.writeElementValue("exportFlash", "1"); - publishSettings.writeElementValue("flashBitRate", "0"); - publishSettings.writeElementValue("exportAudio", "1"); - publishSettings.writeElementValue("audioFormat", "0"); - publishSettings.writeElementValue("singleRateAudio", "0"); - publishSettings.writeElementValue("realVideoRate", "100000"); - publishSettings.writeElementValue("speed28K", "1"); - publishSettings.writeElementValue("speed56K", "1"); - publishSettings.writeElementValue("speedSingleISDN", "0"); - publishSettings.writeElementValue("speedDualISDN", "0"); - publishSettings.writeElementValue("speedCorporateLAN", "0"); - publishSettings.writeElementValue("speed256K", "0"); - publishSettings.writeElementValue("speed384K", "0"); - publishSettings.writeElementValue("speed512K", "0"); - publishSettings.writeElementValue("exportSMIL", "1"); + publishSettings.writeElementValue("exportFlash", 1); + publishSettings.writeElementValue("flashBitRate", 0); + publishSettings.writeElementValue("exportAudio", 1); + publishSettings.writeElementValue("audioFormat", 0); + publishSettings.writeElementValue("singleRateAudio", 0); + publishSettings.writeElementValue("realVideoRate", 100000); + publishSettings.writeElementValue("speed28K", 1); + publishSettings.writeElementValue("speed56K", 1); + publishSettings.writeElementValue("speedSingleISDN", 0); + publishSettings.writeElementValue("speedDualISDN", 0); + publishSettings.writeElementValue("speedCorporateLAN", 0); + publishSettings.writeElementValue("speed256K", 0); + publishSettings.writeElementValue("speed384K", 0); + publishSettings.writeElementValue("speed512K", 0); + publishSettings.writeElementValue("exportSMIL", 1); publishSettings.writeEndElement(); publishSettings.writeStartElement("PublishGifProperties", new String[]{"enabled", "true"}); publishSettings.writeElementValue("Width", width); publishSettings.writeElementValue("Height", height); - publishSettings.writeElementValue("Animated", "0"); - publishSettings.writeElementValue("MatchMovieDim", "1"); - publishSettings.writeElementValue("Loop", "1"); + publishSettings.writeElementValue("Animated", 0); + publishSettings.writeElementValue("MatchMovieDim", 1); + publishSettings.writeElementValue("Loop", 1); publishSettings.writeElementValue("LoopCount", ""); - publishSettings.writeElementValue("OptimizeColors", "1"); - publishSettings.writeElementValue("Interlace", "0"); - publishSettings.writeElementValue("Smooth", "1"); - publishSettings.writeElementValue("DitherSolids", "0"); - publishSettings.writeElementValue("RemoveGradients", "0"); + publishSettings.writeElementValue("OptimizeColors", 1); + publishSettings.writeElementValue("Interlace", 0); + publishSettings.writeElementValue("Smooth", 1); + publishSettings.writeElementValue("DitherSolids", 0); + publishSettings.writeElementValue("RemoveGradients", 0); publishSettings.writeElementValue("TransparentOption", ""); - publishSettings.writeElementValue("TransparentAlpha", "128"); + publishSettings.writeElementValue("TransparentAlpha", 128); publishSettings.writeElementValue("DitherOption", ""); publishSettings.writeElementValue("PaletteOption", ""); - publishSettings.writeElementValue("MaxColors", "255"); + publishSettings.writeElementValue("MaxColors", 255); publishSettings.writeElementValue("PaletteName", ""); publishSettings.writeEndElement(); publishSettings.writeStartElement("PublishPNGProperties", new String[]{"enabled", "true"}); publishSettings.writeElementValue("Width", width); publishSettings.writeElementValue("Height", height); - publishSettings.writeElementValue("OptimizeColors", "1"); - publishSettings.writeElementValue("Interlace", "0"); - publishSettings.writeElementValue("Transparent", "0"); - publishSettings.writeElementValue("Smooth", "1"); - publishSettings.writeElementValue("DitherSolids", "0"); - publishSettings.writeElementValue("RemoveGradients", "0"); - publishSettings.writeElementValue("MatchMovieDim", "1"); + publishSettings.writeElementValue("OptimizeColors", 1); + publishSettings.writeElementValue("Interlace", 0); + publishSettings.writeElementValue("Transparent", 0); + publishSettings.writeElementValue("Smooth", 1); + publishSettings.writeElementValue("DitherSolids", 0); + publishSettings.writeElementValue("RemoveGradients", 0); + publishSettings.writeElementValue("MatchMovieDim", 1); publishSettings.writeElementValue("DitherOption", ""); publishSettings.writeElementValue("FilterOption", ""); publishSettings.writeElementValue("PaletteOption", ""); publishSettings.writeElementValue("BitDepth", "24-bit with Alpha"); - publishSettings.writeElementValue("MaxColors", "255"); + publishSettings.writeElementValue("MaxColors", 255); publishSettings.writeElementValue("PaletteName", ""); publishSettings.writeEndElement(); @@ -3125,16 +3196,16 @@ public class XFLConverter { publishSettings.writeStartElement("PublishQTProperties", new String[]{"enabled", "true"}); publishSettings.writeElementValue("Width", width); publishSettings.writeElementValue("Height", height); - publishSettings.writeElementValue("MatchMovieDim", "1"); - publishSettings.writeElementValue("UseQTSoundCompression", "0"); + publishSettings.writeElementValue("MatchMovieDim", 1); + publishSettings.writeElementValue("UseQTSoundCompression", 0); publishSettings.writeElementValue("AlphaOption", ""); publishSettings.writeElementValue("LayerOption", ""); publishSettings.writeElementValue("QTSndSettings", "00000000"); - publishSettings.writeElementValue("ControllerOption", "0"); - publishSettings.writeElementValue("Looping", "0"); - publishSettings.writeElementValue("PausedAtStart", "0"); - publishSettings.writeElementValue("PlayEveryFrame", "0"); - publishSettings.writeElementValue("Flatten", "1"); + publishSettings.writeElementValue("ControllerOption", 0); + publishSettings.writeElementValue("Looping", 0); + publishSettings.writeElementValue("PausedAtStart", 0); + publishSettings.writeElementValue("PlayEveryFrame", 0); + publishSettings.writeElementValue("Flatten", 1); publishSettings.writeEndElement(); } @@ -3333,7 +3404,7 @@ public class XFLConverter { } catch (SAXException | IOException e) { logger.log(Level.SEVERE, "Error while converting HTML", e); } - return tparser.result; + return tparser.result.toString(); } private static double twipToPixel(double tw) { @@ -3342,7 +3413,7 @@ public class XFLConverter { private static class HTMLTextParser extends DefaultHandler { - public String result = ""; + public XFLXmlWriter result = new XFLXmlWriter(); private String fontFace = ""; @@ -3542,56 +3613,58 @@ public class XFLConverter { } private void putText(String txt) { - - result += ""; - result += "" + Helper.escapeHTML(txt) + ""; - result += ""; - result += "", txt); + result.writeStartElement("textAttrs"); + result.writeStartElement("DOMTextAttrs"); + if (alignment != null) { + result.writeAttribute("alignment", alignment); + } + result.writeAttribute("rotation", true); + if (indent > -1) { + result.writeAttribute("indent", twipToPixel(indent)); + } + if (leftMargin > -1) { + result.writeAttribute("leftMargin", twipToPixel(leftMargin)); + } + if (letterSpacing > -1) { + result.writeAttribute("letterSpacing", letterSpacing); + } + if (lineSpacing > -1) { + result.writeAttribute("lineSpacing", twipToPixel(lineSpacing)); + } + if (rightMargin > -1) { + result.writeAttribute("rightMargin", twipToPixel(rightMargin)); + } + if (size > -1) { + result.writeAttribute("size", size); + result.writeAttribute("bitmapSize", (int) (size * SWF.unitDivisor)); + } + if (fontFace != null) { + result.writeAttribute("face", fontFace); + } + if (color != null) { + result.writeAttribute("fillColor", color); + } + if (url != null) { + result.writeAttribute("url", url); + } + if (target != null) { + result.writeAttribute("target", target); + } + result.writeEndElement(); + result.writeEndElement(); + result.writeEndElement(); + } catch (XMLStreamException ex) { + Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, null, ex); } - result += " rotation=\"true\""; //? - if (indent > -1) { - result += " indent=\"" + twipToPixel(indent) + "\""; - } - if (leftMargin > -1) { - result += " leftMargin=\"" + twipToPixel(leftMargin) + "\""; - } - if (letterSpacing > -1) { - result += " letterSpacing=\"" + letterSpacing + "\""; - } - if (lineSpacing > -1) { - result += " lineSpacing=\"" + twipToPixel(lineSpacing) + "\""; - } - if (rightMargin > -1) { - result += " rightMargin=\"" + twipToPixel(rightMargin) + "\""; - } - if (size > -1) { - result += " size=\"" + size + "\""; - result += " bitmapSize=\"" + (size * 20) + "\""; - } - if (fontFace != null) { - result += " face=\"" + fontFace + "\""; - } - if (color != null) { - result += " fillColor=\"" + color + "\""; - } - if (url != null) { - result += " url=\"" + url + "\""; - } - if (target != null) { - result += " target=\"" + target + "\""; - } - result += "/>"; - result += ""; - result += ""; } @Override public void characters(char[] ch, int start, int length) throws SAXException { putText(new String(ch, start, length)); - } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLXmlWriter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLXmlWriter.java index e67b7ba97..11e6f55e8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLXmlWriter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLXmlWriter.java @@ -54,36 +54,7 @@ public class XFLXmlWriter implements XMLStreamWriter { return this; } - // todo: remove - public XFLXmlWriter append(StringBuilder stringBuilder) { - sb.append(stringBuilder); - newLine = false; - return this; - } - - // todo: remove - public XFLXmlWriter append(int value) { - sb.append(value); - newLine = false; - return this; - } - - // todo: remove - public XFLXmlWriter append(float value) { - sb.append(value); - newLine = false; - return this; - } - - // todo: remove - public XFLXmlWriter append(double value) { - sb.append(value); - newLine = false; - return this; - } - - // todo: make this private - public XFLXmlWriter append(String text) { + private XFLXmlWriter append(String text) { sb.append(text); newLine = false; return this; @@ -207,6 +178,10 @@ public class XFLXmlWriter implements XMLStreamWriter { writeEndElement(); } + public void writeElementValue(String localName, float value) throws XMLStreamException { + writeElementValue(localName, Float.toString(value)); + } + public void writeElementValue(String localName, double value) throws XMLStreamException { writeElementValue(localName, Double.toString(value)); } @@ -215,6 +190,10 @@ public class XFLXmlWriter implements XMLStreamWriter { writeElementValue(localName, Integer.toString(value)); } + public void writeElementValue(String localName, long value) throws XMLStreamException { + writeElementValue(localName, Long.toString(value)); + } + public void writeElementValueRaw(String localName, String value) throws XMLStreamException { writeStartElement(localName); writeCharactersRaw(value); @@ -245,6 +224,10 @@ public class XFLXmlWriter implements XMLStreamWriter { append(' ').append(localName).append("=\"").append(escapeAttribute(value)).append('"'); } + public void writeAttribute(String localName, float value) throws XMLStreamException { + writeAttribute(localName, Float.toString(value)); + } + public void writeAttribute(String localName, double value) throws XMLStreamException { writeAttribute(localName, Double.toString(value)); } @@ -253,6 +236,14 @@ public class XFLXmlWriter implements XMLStreamWriter { writeAttribute(localName, Integer.toString(value)); } + public void writeAttribute(String localName, long value) throws XMLStreamException { + writeAttribute(localName, Long.toString(value)); + } + + public void writeAttribute(String localName, boolean value) throws XMLStreamException { + writeAttribute(localName, value ? "true" : "false"); + } + @Override public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException { setPrefix(prefix, namespaceURI); @@ -389,7 +380,11 @@ public class XFLXmlWriter implements XMLStreamWriter { } // todo: remove - void setLength(int newLength) { + public void setLength(int newLength) { sb.setLength(newLength); } + + public boolean isEmpty() { + return sb.length() == 0; + } }