create domdocument.xml with xml writer 2

This commit is contained in:
honfika@gmail.com
2016-03-10 10:49:11 +01:00
parent 23e7790b39
commit 77f67709cb
7 changed files with 140 additions and 64 deletions

View File

@@ -509,9 +509,14 @@ public class DefineFont2Tag extends FontTag {
}
}
@Override
public int getCharacterCount() {
return codeTable.size();
}
@Override
public String getCharacters() {
StringBuilder ret = new StringBuilder();
StringBuilder ret = new StringBuilder(codeTable.size());
for (int i : codeTable) {
ret.append((char) i);
}

View File

@@ -502,9 +502,14 @@ public class DefineFont3Tag extends FontTag {
}
}
@Override
public int getCharacterCount() {
return codeTable.size();
}
@Override
public String getCharacters() {
StringBuilder ret = new StringBuilder();
StringBuilder ret = new StringBuilder(codeTable.size());
for (int i : codeTable) {
ret.append((char) i);
}

View File

@@ -311,15 +311,27 @@ public class DefineFontTag extends FontTag {
}
@Override
public String getCharacters() {
StringBuilder ret = new StringBuilder();
public int getCharacterCount() {
ensureFontInfo();
if (fontInfoTag != null) {
for (int i : fontInfoTag.getCodeTable()) {
List<Integer> codeTable = fontInfoTag.getCodeTable();
return codeTable.size();
}
return 0;
}
@Override
public String getCharacters() {
ensureFontInfo();
if (fontInfoTag != null) {
List<Integer> codeTable = fontInfoTag.getCodeTable();
StringBuilder ret = new StringBuilder(codeTable.size());
for (int i : codeTable) {
ret.append((char) i);
}
return ret.toString();
}
return ret.toString();
return "";
}
@Override

View File

@@ -153,6 +153,8 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
return fontStyle;
}
public abstract int getCharacterCount();
public abstract String getCharacters();
@Override

View File

@@ -314,6 +314,12 @@ public final class DefineCompactedFont extends FontTag {
return fonts.get(0).leading;
}
@Override
public int getCharacterCount() {
FontType ft = fonts.get(0);
return ft.glyphInfo.size();
}
@Override
public String getCharacters() {
FontType ft = fonts.get(0);

View File

@@ -1191,13 +1191,18 @@ public class XFLConverter {
//TODO: Imported assets
//linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf"
List<String> media = new ArrayList<>();
List<String> symbols = new ArrayList<>();
convertMedia(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, tags, characters, files, datfiles, flaVersion, writer);
convertSymbols(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, tags, characters, files, datfiles, flaVersion, writer);
}
private void convertSymbols(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, XFLXmlWriter writer) throws XMLStreamException {
boolean hasSymbol = false;
for (int ch : characters.keySet()) {
CharacterTag symbol = characters.get(ch);
if ((symbol instanceof ShapeTag) && nonLibraryShapes.contains(symbol.getCharacterId())) {
continue; //shapes with 1 ocurrence and single layer are not added to library
}
if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) {
StringBuilder symbolStr = new StringBuilder();
@@ -1331,7 +1336,9 @@ public class XFLConverter {
if (sprite.getTags().isEmpty()) { //probably AS2 class
continue;
}
symbolStr.append(convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files));
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());
} else if (symbol instanceof ShapeTag) {
itemIcon = "1";
ShapeTag shape = (ShapeTag) symbol;
@@ -1361,8 +1368,27 @@ public class XFLConverter {
//TODO: itemID=\"518de416-00000341\"
}
symbLinkStr += "/>";
symbols.add(symbLinkStr);
} else if (symbol instanceof ImageTag) {
if (!hasSymbol) {
writer.writeStartElement("symbols");
}
writer.writeCharactersRaw(symbLinkStr);
hasSymbol = true;
}
}
if (hasSymbol) {
writer.writeEndElement();
}
}
private void convertMedia(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, XFLXmlWriter writer) throws XMLStreamException {
int mediaCount = 0;
for (int ch : characters.keySet()) {
CharacterTag symbol = characters.get(ch);
String mediaLinkStr = null;
if (symbol instanceof ImageTag) {
ImageTag imageTag = (ImageTag) symbol;
boolean allowSmoothing = false;
@@ -1404,7 +1430,7 @@ public class XFLConverter {
ImageFormat format = imageTag.getImageFormat();
String symbolFile = "bitmap" + symbol.getCharacterId() + imageTag.getImageFormat().getExtension();
files.put(symbolFile, imageBytes);
String mediaLinkStr = "<DOMBitmapItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp(swf) + "\" externalFileSize=\"" + imageBytes.length + "\"";
mediaLinkStr = "<DOMBitmapItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp(swf) + "\" externalFileSize=\"" + imageBytes.length + "\"";
if (allowSmoothing) {
mediaLinkStr += " allowSmoothing=\"true\"";
}
@@ -1420,8 +1446,7 @@ public class XFLConverter {
if (characterClasses.containsKey(symbol.getCharacterId())) {
mediaLinkStr += " linkageExportForAS=\"true\" linkageClassName=\"" + characterClasses.get(symbol.getCharacterId()) + "\"";
}
mediaLinkStr += " quality=\"50\" href=\"" + symbolFile + "\" bitmapDataHRef=\"M " + (media.size() + 1) + " " + getTimestamp(swf) + ".dat\" frameRight=\"" + image.getWidth() + "\" frameBottom=\"" + image.getHeight() + "\"/>\n";
media.add(mediaLinkStr);
mediaLinkStr += " quality=\"50\" href=\"" + symbolFile + "\" bitmapDataHRef=\"M " + (mediaCount + 1) + " " + getTimestamp(swf) + ".dat\" frameRight=\"" + image.getWidth() + "\" frameBottom=\"" + image.getHeight() + "\"/>\n";
} else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) {
int soundFormat = 0;
@@ -1563,7 +1588,7 @@ public class XFLConverter {
String symbolFile = "sound" + symbol.getCharacterId() + "." + exportFormat;
files.put(symbolFile, data);
String mediaLinkStr = "<DOMSoundItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp(swf) + "\" externalFileSize=\"" + data.length + "\"";
mediaLinkStr = "<DOMSoundItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp(swf) + "\" externalFileSize=\"" + data.length + "\"";
mediaLinkStr += " href=\"" + symbolFile + "\"";
mediaLinkStr += " format=\"";
mediaLinkStr += rateMap[soundRate] + "kHz";
@@ -1587,7 +1612,6 @@ public class XFLConverter {
}
mediaLinkStr += "/>\n";
media.add(mediaLinkStr);
} else if (symbol instanceof DefineVideoStreamTag) {
DefineVideoStreamTag video = (DefineVideoStreamTag) symbol;
@@ -1614,7 +1638,6 @@ public class XFLConverter {
logger.log(Level.SEVERE, null, ex);
}
String symbolFile = "movie" + symbol.getCharacterId() + "." + "flv";
String mediaLinkStr = "";
if (data.length == 0) { //Video has zero length, this probably means it is "Video - Actionscript-controlled"
long ts = getTimestamp(swf);
String datFileName = "M " + (datfiles.size() + 1) + " " + ts + ".dat";
@@ -1659,24 +1682,20 @@ public class XFLConverter {
}
mediaLinkStr += "/>\n";
}
media.add(mediaLinkStr);
}
if (mediaLinkStr != null) {
if (mediaCount == 0) {
writer.writeStartElement("media");
}
writer.writeCharactersRaw(mediaLinkStr);
mediaCount++;
}
}
if (!media.isEmpty()) {
writer.writeStartElement("media");
for (String m : media) {
writer.writeCharactersRaw(m);
}
writer.writeEndElement();
}
if (!symbols.isEmpty()) {
writer.writeStartElement("symbols");
for (String s : symbols) {
writer.writeCharactersRaw(s);
}
if (mediaCount > 0) {
writer.writeEndElement();
}
}
@@ -1827,7 +1846,7 @@ public class XFLConverter {
return ret.toString();
}
private static void convertFrames(String prevStr, String afterStr, List<Integer> nonLibraryShapes, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, int depth, FLAVersion flaVersion, HashMap<String, byte[]> files, StringBuilder ret) {
private static void convertFrames(String prevStr, String afterStr, List<Integer> nonLibraryShapes, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, int depth, FLAVersion flaVersion, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
StringBuilder ret2 = new StringBuilder();
prevStr += "<frames>";
int frame = -1;
@@ -1997,12 +2016,29 @@ public class XFLConverter {
afterStr = "</frames>" + afterStr;
if (ret2.length() > 0) {
ret.append(prevStr).append(ret2).append(afterStr);
writer.writeCharactersRaw(prevStr);
writer.writeCharactersRaw(ret2.toString());
writer.writeCharactersRaw(afterStr);
}
}
private static void convertFonts(ReadOnlyTagList tags, XFLXmlWriter writer) throws XMLStreamException {
StringBuilder ret2 = new StringBuilder();
boolean hasFont = false;
for (Tag t : tags) {
if (t instanceof FontTag) {
FontTag font = (FontTag) t;
if (font.getCharacterCount() > 0) {
hasFont = true;
}
}
}
if (!hasFont) {
return;
}
writer.writeStartElement("fonts");
for (Tag t : tags) {
if (t instanceof FontTag) {
FontTag font = (FontTag) t;
@@ -2069,16 +2105,22 @@ public class XFLConverter {
if (hasAllRanges) {
embedRanges = "9999";
}
ret2.append("<DOMFontItem name=\"Font ").append(fontId).append("\" font=\"").append(Helper.escapeHTML(fontName)).append("\" size=\"0\" id=\"").append(fontId).append("\" embedRanges=\"").append(embedRanges).append("\"").append(!"".equals(embeddedCharacters) ? " embeddedCharacters=\"" + Helper.escapeHTML(embeddedCharacters) + "\"" : "").append(" />");
writer.writeStartElement("DOMFontItem", new String[]{
"name", "Font " + fontId,
"font", fontName,
"size", "0",
"id", Integer.toString(fontId),
"embedRanges", embedRanges});
if (!"".equals(embeddedCharacters)) {
writer.writeAttribute("embeddedCharacters", embeddedCharacters);
}
writer.writeEndElement();
}
}
if (ret2.length() > 0) {
writer.writeStartElement("fonts");
writer.writeCharactersRaw(ret2.toString());
writer.writeEndElement();
}
writer.writeEndElement();
}
private String convertActionScriptLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor) {
@@ -2199,7 +2241,7 @@ public class XFLConverter {
return retStr;
}
private void convertSoundLayer(int layerIndex, String backgroundColor, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, HashMap<String, byte[]> files, StringBuilder ret) {
private void convertSoundLayer(int layerIndex, String backgroundColor, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
StringBuilder ret2 = new StringBuilder();
StartSoundTag lastStartSound = null;
SoundStreamHeadTypeTag lastSoundStreamHead = null;
@@ -2255,9 +2297,9 @@ public class XFLConverter {
}
if (ret2.length() > 0) {
ret.append("<DOMLayer name=\"Layer ").append(layerIndex).append("\" color=\"").append(randomOutlineColor()).append("\">"
+ "<frames>").append(ret2).append("</frames>"
+ "</DOMLayer>");
writer.writeStartElement("DOMLayer", new String[]{"Layer " + layerIndex, "color", randomOutlineColor()});
writer.writeElementValue("frames", ret2.toString());
writer.writeEndElement();
}
}
@@ -2271,15 +2313,14 @@ public class XFLConverter {
return outlineColor.toHexRGB();
}
private String convertTimeline(int spriteId, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, String name, FLAVersion flaVersion, HashMap<String, byte[]> files) {
StringBuilder ret = new StringBuilder();
ret.append("<DOMTimeline name=\"").append(name).append("\">");
ret.append("<layers>");
private void convertTimeline(int spriteId, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, String name, FLAVersion flaVersion, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
writer.writeStartElement("DOMTimeline", new String[]{"name", name});
writer.writeStartElement("layers");
String labelsLayer = convertLabelsLayer(spriteId, tags, timelineTags, backgroundColor);
ret.append(labelsLayer);
writer.writeCharactersRaw(labelsLayer);
String scriptLayer = convertActionScriptLayer(spriteId, tags, timelineTags, backgroundColor);
ret.append(scriptLayer);
writer.writeCharactersRaw(scriptLayer);
int index = 0;
@@ -2303,11 +2344,13 @@ public class XFLConverter {
parentLayers.push(index);
}
ret.append("<DOMLayer name=\"Layer ").append(index + 1).append("\" color=\"").append(randomOutlineColor()).append("\" ");
ret.append(" layerType=\"mask\" locked=\"true\"");
ret.append(">");
convertFrames("", "", nonLibraryShapes, tags, timelineTags, characters, po.getDepth(), flaVersion, files, ret);
ret.append("</DOMLayer>");
writer.writeStartElement("DOMLayer", new String[]{
"name", "Layer " + (index + 1),
"color", randomOutlineColor(),
"layerType", "mask",
"locked", "true"});
convertFrames("", "", nonLibraryShapes, tags, timelineTags, characters, po.getDepth(), flaVersion, files, writer);
writer.writeEndElement();
index++;
break;
}
@@ -2347,19 +2390,18 @@ public class XFLConverter {
}
layerPrev += ">";
String layerAfter = "</DOMLayer>";
int prevLength = ret.length();
convertFrames(layerPrev, layerAfter, nonLibraryShapes, tags, timelineTags, characters, d, flaVersion, files, ret);
if (ret.length() == prevLength) {
int prevLength = writer.length();
convertFrames(layerPrev, layerAfter, nonLibraryShapes, tags, timelineTags, characters, d, flaVersion, files, writer);
if (writer.length() == prevLength) {
index--;
}
}
int soundLayerIndex = layerCount;
layerCount++;
convertSoundLayer(soundLayerIndex, backgroundColor, characters, tags, timelineTags, files, ret);
ret.append("</layers>");
ret.append("</DOMTimeline>");
return ret.toString();
convertSoundLayer(soundLayerIndex, backgroundColor, characters, tags, timelineTags, files, writer);
writer.writeEndElement();
writer.writeEndElement();
}
private static void writeFile(AbortRetryIgnoreHandler handler, final byte[] data, final String file) throws IOException, InterruptedException {
@@ -2806,7 +2848,7 @@ public class XFLConverter {
convertLibrary(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, swf.getTags(), characters, files, datfiles, flaVersion, domDocument);
domDocument.writeStartElement("timelines");
domDocument.writeCharactersRaw(convertTimeline(0, nonLibraryShapes, backgroundColor, swf.getTags(), swf.getTags(), characters, "Scene 1", flaVersion, files));
convertTimeline(0, nonLibraryShapes, backgroundColor, swf.getTags(), swf.getTags(), characters, "Scene 1", flaVersion, files, domDocument);
domDocument.writeEndElement();
domDocument.writeEndElement();

View File

@@ -346,4 +346,8 @@ public class XFLXmlWriter implements XMLStreamWriter {
}
return text;
}
public int length() {
return sb.length();
}
}