//////////////////////////////////////////////////////////////////////////////// // // ADOBE SYSTEMS INCORPORATED // Copyright 2003-2007 Adobe Systems Incorporated // All Rights Reserved. // // NOTICE: Adobe permits you to use, modify, and distribute this file // in accordance with the terms of the license agreement accompanying it. // //////////////////////////////////////////////////////////////////////////////// package flash.swf.tools; import flash.util.Base64; import flash.util.SwfImageUtils; import flash.swf.Dictionary; import flash.swf.Header; import flash.swf.TagEncoder; import flash.swf.TagHandler; import flash.swf.TagValues; import flash.swf.tags.DebugID; import flash.swf.tags.DefineBits; import flash.swf.tags.DefineShape; import flash.swf.tags.DefineSprite; import flash.swf.tags.DefineTag; import flash.swf.tags.DoAction; import flash.swf.tags.DoInitAction; import flash.swf.tags.EnableDebugger; import flash.swf.tags.ExportAssets; import flash.swf.tags.FrameLabel; import flash.swf.tags.GenericTag; import flash.swf.tags.ImportAssets; import flash.swf.tags.PlaceObject; import flash.swf.tags.ProductInfo; import flash.swf.tags.ScriptLimits; import flash.swf.tags.SetBackgroundColor; import flash.swf.tags.ShowFrame; import flash.swf.tags.FileAttributes; import flash.swf.types.CXForm; import flash.swf.types.CurvedEdgeRecord; import flash.swf.types.FillStyle; import flash.swf.types.FlashUUID; import flash.swf.types.GradRecord; import flash.swf.types.ImportRecord; import flash.swf.types.LineStyle; import flash.swf.types.Matrix; import flash.swf.types.Rect; import flash.swf.types.ShapeWithStyle; import flash.swf.types.StraightEdgeRecord; import flash.swf.types.StyleChangeRecord; import flash.swf.types.Gradient; import flash.util.FileUtils; import flash.util.StringUtils; import flash.util.Trace; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Stack; /** * read SWFX format and turn it back into a SWF. SWFX format can be created by * hand or it also can be generated by the swfdump utility. * * @author Edwin Smith * @see SwfxPrinter#main */ public class SwfxParser extends DefaultHandler implements TagValues { private TagHandler tagHandler; private DefineSprite sprite; private Locator locator; private StringBuilder text; private Header header; private Stack stack; private ArrayList fillstyles; private ArrayList linestyles; private String docPath; private Dictionary dict; private String[] aspath; private String topLevel; private GenericTag jpegTables; private int startLineNumber; private TagHandler currentHandler() { return sprite != null ? sprite.tagList : tagHandler; } public SwfxParser(TagHandler handler, String[] aspath) { this.tagHandler = handler; this.aspath = aspath; try { this.topLevel = FileUtils.readFile(aspath[0] + File.separator + "toplevel.as", null); } catch (IOException ex) { this.topLevel = null; } stack = new Stack(); dict = new Dictionary(); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { try { Method method = getClass().getMethod(qName, new Class[]{Attributes.class}); method.invoke(this, new Object[]{attributes}); } catch (NoSuchMethodException e) { warning(new SAXParseException("no start handler for " + qName, locator)); } catch (IllegalAccessException e) { fatalError(new SAXParseException(e.getMessage(), locator, e)); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof SAXException) { throw (SAXException)t; } else { fatalError(new SAXParseException(e.getMessage(), locator, e)); } } } public void characters(char ch[], int start, int length) throws SAXException { if (text != null) text.append(ch, start, length); } public void curve(Attributes attributes) throws SAXParseException { CurvedEdgeRecord curvedEdge = new CurvedEdgeRecord(); curvedEdge.controlDeltaX = parseInt(getAttribute(attributes, "cdx")); curvedEdge.controlDeltaY = parseInt(getAttribute(attributes, "cdy")); curvedEdge.anchorDeltaX = parseInt(getAttribute(attributes, "dx")); curvedEdge.anchorDeltaY = parseInt(getAttribute(attributes, "dy")); DefineShape defineShape = (DefineShape)stack.peek(); defineShape.shapeWithStyle.shapeRecords.add(curvedEdge); } public void curve() {} public void DebugID(Attributes attributes) throws SAXParseException { DebugID debugId = new DebugID(parseUUID(getAttribute(attributes, "uuid"))); tagHandler.debugID(debugId); } public void DebugID() { } private FlashUUID parseUUID(String s) { byte[] b = new byte[s.length() / 2]; for (int i = 0; i < b.length; i++) { b[i] = (byte)((Character.digit(s.charAt(2 * i), 16) << 4) | (Character.digit(s.charAt(2 * i + 1), 16) << 0)); } return new FlashUUID(b); } /** * Add an id to the dictionary of characters, tracking what the player * would do anyway. The player will ignore the new definition if another * one with the same ID already exists. * * @param id * @param tag * @throws SAXParseException */ private void createCharacter(int id, DefineTag tag) throws SAXParseException { try { dict.add(id, tag); } catch (IllegalArgumentException e) { // player will ignore dups, so print a warning error(new SAXParseException(e.getMessage(), locator, e)); } } private SwfImageUtils.JPEG loadJPEG(Attributes attributes) throws SAXException { if (hasAttribute(attributes, "encoding")) { if (!getAttribute(attributes, "encoding").equals("base64")) fatalError(new SAXParseException("unknown encoding " + getAttribute(attributes, "encoding"), locator)); if (hasAttribute(attributes, "src")) fatalError(new SAXParseException("can only specify one of src or encoding attributes", locator)); text = new StringBuilder(); } else { text = null; if (!hasAttribute(attributes, "src")) fatalError(new SAXParseException("must provide either src or encoding attribute", locator)); try { File src = new File(getAttribute(attributes, "src")); FileInputStream input = new FileInputStream(getAttribute(attributes, "src")); byte[] image = new byte[(int)src.length()]; input.read(image); input.close(); SwfImageUtils.JPEG jpeg = new SwfImageUtils.JPEG(image, true); if (!jpeg.validate()) fatalError(new SAXParseException("Invalid JPEG data in " + src.getName(), locator)); return jpeg; } catch (IOException e) { throw new SAXParseException(e.getMessage(), locator); } } return null; } public void DefineBits(Attributes attributes) throws SAXException { if (jpegTables == null) fatalError(new SAXParseException("DefineBits must follow JPEGTables", locator)); DefineBits db = new DefineBits(stagDefineBits); int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, db); SwfImageUtils.JPEG jpeg = loadJPEG(attributes); if (jpeg != null) { if (!Arrays.equals(jpeg.table, jpegTables.data)) { fatalError(new SAXParseException("JPEGTables data does not match, use DefineBitsJPEG2", locator)); } db.data = jpeg.data; } stack.push(db); } public void DefineBits() { DefineBits db = (DefineBits)stack.pop(); if (text != null) { // text is allocated for the base64 encoding Base64.Decoder dec = new Base64.Decoder(); dec.decode(text.toString()); db.data = dec.flush(); db.jpegTables = jpegTables; } currentHandler().defineBits(db); } public void DefineBitsJPEG2(Attributes attributes) throws SAXException { DefineBits db = new DefineBits(stagDefineBitsJPEG2); int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, db); if (hasAttribute(attributes, "encoding")) { if (!getAttribute(attributes, "encoding").equals("base64")) fatalError(new SAXParseException("unknown encoding " + getAttribute(attributes, "encoding"), locator)); if (hasAttribute(attributes, "src")) fatalError(new SAXParseException("can only specify one of src or encoding attributes", locator)); text = new StringBuilder(); } else { if (!hasAttribute(attributes, "src")) fatalError(new SAXParseException("must provide either src or encoding attribute", locator)); File src = new File(getAttribute(attributes, "src")); try { FileInputStream input = new FileInputStream(getAttribute(attributes, "src")); db.data = new byte[(int)src.length()]; input.read(db.data); } catch (IOException e) { fatalError(new SAXParseException("Unable to load DefineBitsJPEG2 src " + src.getName() + ":" + e.getMessage(), locator)); } } stack.push(db); } public void DefineBitsJPEG2() { DefineBits db = (DefineBits)stack.pop(); if (text != null) { // text is allocated for the base64 encoding Base64.Decoder dec = new Base64.Decoder(); dec.decode(text.toString()); db.data = dec.flush(); db.jpegTables = null; } currentHandler().defineBits(db); } public void DefineShape(Attributes attributes) throws SAXException { DefineShape tag = new DefineShape(stagDefineShape); int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, tag); tag.bounds = parseRect(getAttribute(attributes, "bounds")); tag.shapeWithStyle = new ShapeWithStyle(); tag.shapeWithStyle.fillstyles = new ArrayList(); tag.shapeWithStyle.linestyles = new ArrayList(); tag.shapeWithStyle.shapeRecords = new ArrayList(); stack.push(tag); fillstyles = tag.shapeWithStyle.fillstyles; linestyles = tag.shapeWithStyle.linestyles; } public void DefineShape() { DefineShape tag = (DefineShape)stack.pop(); fillstyles = null; linestyles = null; tagHandler.defineShape(tag); } public void DefineShape3(Attributes attributes) throws SAXException { DefineShape tag = new DefineShape(TagValues.stagDefineShape3); int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, tag); tag.bounds = parseRect(getAttribute(attributes, "bounds")); tag.shapeWithStyle = new ShapeWithStyle(); tag.shapeWithStyle.fillstyles = new ArrayList(); tag.shapeWithStyle.linestyles = new ArrayList(); tag.shapeWithStyle.shapeRecords = new ArrayList(); stack.push(tag); fillstyles = tag.shapeWithStyle.fillstyles; linestyles = tag.shapeWithStyle.linestyles; } public void DefineShape3() { DefineShape tag = (DefineShape)stack.pop(); fillstyles = null; linestyles = null; tagHandler.defineShape3(tag); } public void DefineSprite(Attributes attributes) throws SAXParseException { DefineSprite sprite = new DefineSprite(); int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, sprite); stack.push(sprite); this.sprite = sprite; } public void DefineSprite() { DefineSprite sprite = (DefineSprite)stack.pop(); this.sprite = null; tagHandler.defineSprite(sprite); } public void DoAction(Attributes attributes) { text = new StringBuilder(); startLineNumber = locator.getLineNumber(); } public void DoAction() throws SAXException { //try //{ //String code = text.toString(); text = null; /* AsActionsContainerInfo info = new AsActionsContainerInfo(); ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kFrameActions, CompileFlags.kCompileString, startLineNumber); compiler.setFileName(docPath); compiler.compile(code, true); if (compiler.errorsExist()) { throw new SAXParseException("compile failed", locator); } byte[] bytecode = compiler.getAsBytes(); */ DoAction doAction = new DoAction(); //SwfDecoder r = new SwfDecoder(bytecode, header.version); //doAction.actionList = new ActionDecoder(r).decode(bytecode.length); currentHandler().doAction(doAction); //} //catch (IOException e) //{ // fatalError(new SAXParseException(e.getMessage(), locator, e)); //} } public void ProductInfo(Attributes attributes) throws SAXException { int product = parseInt(getAttribute(attributes, "product")); int edition = parseInt(getAttribute(attributes, "edition")); byte majorVersion = Byte.parseByte(getAttribute(attributes, "majorVersion")); byte minorVersion = Byte.parseByte(getAttribute(attributes, "majorVersion")); long build = Long.parseLong(getAttribute(attributes, "build")); long compileDate = Long.parseLong(getAttribute(attributes, "compileDate")); stack.push(new ProductInfo(product, edition, majorVersion, minorVersion, build, compileDate)); } public void FileAttributes() { tagHandler.fileAttributes((FileAttributes)stack.pop()); } public void FileAttributes(Attributes attributes) throws SAXException { FileAttributes tag = new FileAttributes(); tag.hasMetadata = parseBoolean(getAttribute(attributes, "hasMetadata")); tag.actionScript3 = parseBoolean(getAttribute(attributes, "actionScript3")); tag.suppressCrossDomainCaching = parseBoolean(getAttribute(attributes, "suppressCrossDomainCaching")); tag.swfRelativeUrls = parseBoolean(getAttribute(attributes, "swfRelativeUrls")); tag.useNetwork = parseBoolean(getAttribute(attributes, "useNetwork")); stack.push(tag); } public void ProductInfo() { tagHandler.productInfo((ProductInfo)stack.pop()); } private DefineTag findCharacter(int idref) throws SAXParseException { try { return dict.getTag(idref); } catch (IllegalArgumentException e) { //return null; throw new SAXParseException(e.getMessage(), locator, e); } } public void Package(Attributes attributes) throws SAXParseException { text = new StringBuilder(); DefineSprite pkg = new DefineSprite(); DoInitAction initAction = new DoInitAction(pkg); // get id for this package int id = parseInt(getAttribute(attributes, "id")); createCharacter(id, pkg); currentHandler().defineSprite(pkg); startLineNumber = locator.getLineNumber(); stack.push(initAction); } public void Package() throws SAXException { //try //{ // String code = text.toString(); text = null; DoInitAction initAction = (DoInitAction)stack.pop(); /* AsActionsContainerInfo info = new AsActionsContainerInfo(); info.setModuleName(docPath); ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kPackageActions, CompileFlags.kCompileString, startLineNumber); // don't set the filename here because it makes AS2 compilain about the filename //compiler.setFileName(docPath); compiler.compile(code, true); if (compiler.errorsExist()) { throw new SAXParseException("compile failed", locator); } byte[] bytecode = compiler.getAsBytes(); */ //ActionDecoder actionDecoder = new ActionDecoder(new SwfDecoder(bytecode, header.version)); //initAction.actionList = actionDecoder.decode(bytecode.length); currentHandler().doInitAction(initAction); //} //catch (IOException e) //{ // fatalError(new SAXParseException(e.getMessage(), locator, e)); //} } public void DoInitAction(Attributes attributes) throws SAXParseException { text = new StringBuilder(); DoInitAction initAction = new DoInitAction(); // get id of previous DefineSprite int idref = parseInt(getAttribute(attributes, "idref")); initAction.sprite = (DefineSprite)findCharacter(idref); startLineNumber = locator.getLineNumber(); stack.push(initAction); } public void DoInitAction() throws SAXException { //try //{ //String code = text.toString(); text = null; DoInitAction initAction = (DoInitAction)stack.pop(); /* AsActionsContainerInfo info = new AsActionsContainerInfo(); ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kUndefinedActions, CompileFlags.kCompileString, startLineNumber); compiler.setFileName(docPath); compiler.compile(code, true); if (compiler.errorsExist()) { throw new SAXParseException("compile failed", locator); } byte[] bytecode = compiler.getAsBytes(); ActionDecoder actionDecoder = new ActionDecoder(new SwfDecoder(bytecode, header.version)); initAction.actionList = actionDecoder.decode(bytecode.length); */ currentHandler().doInitAction(initAction); //} //catch (IOException e) //{ // fatalError(new SAXParseException(e.getMessage(), locator, e)); //} } public void EnableDebugger2(Attributes attributes) throws SAXParseException { EnableDebugger enableDebugger2 = new EnableDebugger(stagEnableDebugger2); enableDebugger2.password = getAttribute(attributes, "password"); tagHandler.enableDebugger2(enableDebugger2); } public void EnableDebugger2() {} public void ExportAssets(Attributes attributes) { ExportAssets tag = new ExportAssets(); stack.push(tag); } public void ExportAssets() { ExportAssets tag = (ExportAssets)stack.pop(); tagHandler.exportAssets(tag); } public void Export(Attributes attributes) throws SAXParseException { ExportAssets tag = (ExportAssets)stack.peek(); int idref = parseInt(getAttribute(attributes, "idref")); String name = getAttribute(attributes, "name"); DefineTag ref = findCharacter(idref); ref.name = name; tag.exports.add(ref); } public void Export() { } public void fillstyle(Attributes attributes) throws SAXParseException { DefineShape defineShape = (DefineShape)stack.peek(); boolean hasAlpha = (defineShape.code == stagDefineShape3); FillStyle fillstyle = new FillStyle(); if (hasAttribute(attributes, "color")) { fillstyle.setType(FillStyle.FILL_SOLID); fillstyle.color = hasAlpha ? parseRGBA(getAttribute(attributes, "color")) : parseRGB(getAttribute(attributes, "color")); } if (hasAttribute(attributes, "gradient")) { // todo support radial gradients fillstyle.setType(FillStyle.FILL_LINEAR_GRADIENT); fillstyle.gradient = parseGradient(getAttribute(attributes, "gradient"), hasAlpha); fillstyle.matrix = parseMatrix(getAttribute(attributes, "matrix")); } if (hasAttribute(attributes, "idref")) { // todo support clipped bitmaps fillstyle.setType(FillStyle.FILL_BITS); // tiled int idref = parseInt(getAttribute(attributes, "idref")); // todo check to make sure bitmapId points to a bitmap fillstyle.bitmap = findCharacter(idref); fillstyle.matrix = parseMatrix(getAttribute(attributes, "matrix")); } defineShape.shapeWithStyle.fillstyles.add(fillstyle); } public void fillstyle() {} public void FrameLabel(Attributes attributes) throws SAXParseException { FrameLabel frameLabel = new FrameLabel(); frameLabel.label = getAttribute(attributes, "label"); frameLabel.anchor = parseBoolean(getAttribute(attributes, "anchor")); tagHandler.frameLabel(frameLabel); } public void FrameLabel() {} public void Import(Attributes attributes) throws SAXParseException { ImportRecord record = new ImportRecord(); int id = parseInt(getAttribute(attributes, "id")); record.name = getAttribute(attributes, "name"); ImportAssets importAssets = (ImportAssets)stack.peek(); importAssets.importRecords.add(record); // todo find the actual tag imported createCharacter(id, record); } public void Import() {} public void ImportAssets(Attributes attributes) throws SAXParseException { ImportAssets importAssets = new ImportAssets(stagImportAssets); importAssets.url = getAttribute(attributes, "url"); importAssets.importRecords = new ArrayList(); stack.push(importAssets); } public void ImportAssets() { ImportAssets importAssets = (ImportAssets)stack.pop(); tagHandler.importAssets(importAssets); } public void line(Attributes attributes) throws SAXParseException { StraightEdgeRecord straightEdge = new StraightEdgeRecord(); if (hasAttribute(attributes, "dx")) { straightEdge.deltaX = parseInt(getAttribute(attributes, "dx")); } if (hasAttribute(attributes, "dy")) { straightEdge.deltaY = parseInt(getAttribute(attributes, "dy")); } DefineShape defineShape = (DefineShape)stack.peek(); defineShape.shapeWithStyle.shapeRecords.add(straightEdge); } public void line() {} public void linestyle(Attributes attributes) throws SAXParseException { DefineShape defineShape = (DefineShape)stack.peek(); LineStyle linestyle = new LineStyle(); if (defineShape.code == stagDefineShape3) { linestyle.color = parseRGBA(getAttribute(attributes, "color")); } else { linestyle.color = parseRGB(getAttribute(attributes, "color")); } linestyle.width = parseInt(getAttribute(attributes, "width")); linestyles.add(linestyle); } public void linestyle() {} public void swf(Attributes attributes) throws SAXException { Header h = new Header(); h.version = parseInt(getAttribute(attributes, "version")); h.compressed = parseBoolean(getAttribute(attributes, "compressed")); h.rate = parseInt(getAttribute(attributes, "framerate")); h.size = parseRect(getAttribute(attributes, "size")); this.header = h; tagHandler.header(h); /* this.packageManager = new CompilerPackageManager(h.version, topLevel, 0); // register an asclassloader for the given aspath ASClassLoader asLoader = new ASClassLoader(aspath, false, null); asLoader.pm = packageManager; asLoader.debug = false; packageManager.addLoader(asLoader); packageManager.findType("String"); MessageHandler.setThreadLocalMessageHandler(outputHandler); */ } public void swf() { } public void JPEGTables(Attributes attributes) throws SAXParseException { text = new StringBuilder(); if (hasAttribute(attributes, "encoding")) { if (!getAttribute(attributes, "encoding").equals("base64")) fatalError(new SAXParseException("unknown encoding " + getAttribute(attributes, "encoding"), locator)); } } public void JPEGTables() { if (text != null) { String encoded = text.toString(); text = null; Base64.Decoder dec = new Base64.Decoder(); dec.decode(encoded); jpegTables = new GenericTag(stagJPEGTables); jpegTables.data = dec.flush(); currentHandler().jpegTables(jpegTables); } } public void ShowFrame(Attributes attributes) { currentHandler().showFrame(new ShowFrame()); if (sprite != null) { sprite.framecount++; } else { header.framecount++; } } public void ShowFrame() { } public void styleChange(Attributes attributes) throws SAXParseException { StyleChangeRecord styleChange = new StyleChangeRecord(); if (hasAttribute(attributes, "dx") || hasAttribute(attributes, "dy")) { styleChange.stateMoveTo = true; styleChange.moveDeltaX = parseInt(getAttribute(attributes, "dx")); styleChange.moveDeltaY = parseInt(getAttribute(attributes, "dy")); } if (hasAttribute(attributes, "fillStyle0")) { styleChange.stateFillStyle0 = true; styleChange.fillstyle0 = parseInt(getAttribute(attributes, "fillStyle0")); } if (hasAttribute(attributes, "fillStyle1")) { styleChange.stateFillStyle1 = true; styleChange.fillstyle1 = parseInt(getAttribute(attributes, "fillStyle1")); } if (hasAttribute(attributes, "lineStyle")) { styleChange.stateLineStyle = true; styleChange.linestyle = parseInt(getAttribute(attributes, "lineStyle")); } styleChange.fillstyles = new ArrayList(); styleChange.linestyles = new ArrayList(); fillstyles = styleChange.fillstyles; linestyles = styleChange.linestyles; stack.push(styleChange); } public void styleChange() { StyleChangeRecord styleChange = (StyleChangeRecord)stack.pop(); if (fillstyles.size() != 0) { styleChange.stateNewStyles = true; } DefineShape defineShape = (DefineShape)stack.peek(); defineShape.shapeWithStyle.shapeRecords.add(styleChange); fillstyles = defineShape.shapeWithStyle.fillstyles; linestyles = defineShape.shapeWithStyle.linestyles; } public void PlaceObject2(Attributes attributes) throws SAXParseException { PlaceObject tag = new PlaceObject(stagPlaceObject2); tag.depth = parseInt(getAttribute(attributes, "depth")); if (hasAttribute(attributes, "className")) { tag.setClassName(getAttribute(attributes, "className")); } if (hasAttribute(attributes, "hasImage")) { tag.setHasImage(getAttribute(attributes, "hasImage").equals("true")); } if (hasAttribute(attributes, "idref")) { int idref = parseInt(getAttribute(attributes, "idref")); tag.setRef(findCharacter(idref)); } if (hasAttribute(attributes, "name")) { tag.setName(getAttribute(attributes, "name")); } if (hasAttribute(attributes, "clipDepth")) { tag.setClipDepth(parseInt(getAttribute(attributes, "clipDepth"))); } if (hasAttribute(attributes, "ratio")) { tag.setRatio(parseInt(getAttribute(attributes, "ratio"))); } if (hasAttribute(attributes, "cxform")) { tag.setCxform(parseCXForm(getAttribute(attributes, "cxform"))); } if (hasAttribute(attributes, "matrix")) { tag.setMatrix(parseMatrix(getAttribute(attributes, "matrix"))); } stack.push(tag); text = new StringBuilder(); } public void PlaceObject2() throws SAXException { PlaceObject tag = (PlaceObject)stack.pop(); //try //{ //String code = text.toString(); text = null; /* if (code.length() > 0) { AsActionsContainerInfo info = new AsActionsContainerInfo(); ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kSpriteActions, CompileFlags.kCompileString, locator.getLineNumber()); compiler.setFileName(docPath); compiler.compile(code, true); if (compiler.errorsExist()) { throw new SAXParseException("compile failed", locator); } byte[] bytecode = compiler.getAsBytes(); ActionDecoder decoder = new ActionDecoder(new SwfDecoder(bytecode, header.version)); tag.setClipActions(decoder.decodeClipActions(bytecode.length)); } */ currentHandler().placeObject2(tag); //} //catch (IOException e) //{ // fatalError(new SAXParseException(e.getMessage(), locator, e)); //} } public void SetBackgroundColor(Attributes attributes) throws SAXParseException { SetBackgroundColor tag = new SetBackgroundColor(parseRGB(getAttribute(attributes, "color"))); currentHandler().setBackgroundColor(tag); } public void SetBackgroundColor() { } public void ScriptLimits(Attributes attributes) throws SAXParseException { ScriptLimits tag = new ScriptLimits(parseInt(getAttribute(attributes, "maxRecursionLimit")), parseInt(getAttribute(attributes, "scriptTimeLimit"))); currentHandler().scriptLimits(tag); } public void ScriptLimits() { } private Matrix parseMatrix(String s) { Matrix matrix = new Matrix(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case 'r': i++; String[] parts = StringUtils.split(s.substring(i), "[, ]", 3); matrix.setRotate(Double.parseDouble(parts[0]), Double.parseDouble(parts[1])); break; case 's': i++; parts = StringUtils.split(s.substring(i), "[, ]", 3); matrix.setScale(Double.parseDouble(parts[0]), Double.parseDouble(parts[1])); break; case 't': i++; parts = StringUtils.split(s.substring(i), "[, ]", 3); matrix.translateX = Integer.parseInt(parts[0]); matrix.translateY = Integer.parseInt(parts[1]); break; } } return matrix; } private Gradient parseGradient(String s, boolean hasAlpha) { Gradient gradient = new Gradient(); // todo - support focal // todo add error checking // count must be 1..8 // number of parts must be even // ratio must be 0..255 String[] parts = StringUtils.split(s, " "); int count = parts.length / 2; gradient.records = new GradRecord[count]; for (int i = 0; i < count; i++) { GradRecord record = gradient.records[i] = new GradRecord(); record.ratio = Integer.parseInt(parts[2 * i]); record.color = hasAlpha ? parseRGBA(parts[2 * i + 1]) : parseRGB(parts[2 * i + 1]); } return gradient; } private CXForm parseCXForm(String s) { // todo add error checking // must be six parts // each term must be -32768..32767 String[] parts = StringUtils.split(s, "([rgb]\\+?| )"); CXForm cxform = new CXForm(); cxform.redAddTerm = Integer.parseInt(parts[0]); cxform.redMultTerm = Integer.parseInt(parts[1]); cxform.greenAddTerm = Integer.parseInt(parts[2]); cxform.greenMultTerm = Integer.parseInt(parts[3]); cxform.blueAddTerm = Integer.parseInt(parts[4]); cxform.blueMultTerm = Integer.parseInt(parts[5]); return cxform; } private boolean parseBoolean(String attribute) { return Boolean.valueOf(attribute).booleanValue(); } /** * @param s * @return 0x00RRGGBB */ private int parseRGB(String s) { int rgb = parseColor(s); int color = ((rgb >> 16) & 255) << 16; // red color |= ((rgb >> 8) & 255) << 8; // green color |= ((rgb >> 0) & 255); // blue return color; } /** * @param s * @return 0xAARRGGBB */ private int parseRGBA(String s) { int rgb = parseColor(s); int color = ((rgb >> 24) & 255) << 16; // red color |= ((rgb >> 16) & 255) << 8; // green color |= ((rgb >> 8) & 255); // blue color |= ((rgb >> 0) & 255) << 24; // alpha return color; } public static int parseColor(String string) { if (string.length() > 0) { if (string.charAt(0) == '#') { return (int)Long.parseLong(string.substring(1), 16); } else if (string.startsWith("0x") || string.startsWith("0X")) { return Integer.parseInt(string.substring(2), 16); } else { return Integer.parseInt(string); } } else { return 0; } } private boolean hasAttribute(Attributes attributes, String qName) { return attributes.getValue(qName) != null; } private String getAttribute(Attributes attributes, String qName) throws SAXParseException { String value = attributes.getValue(qName); if (value == null) { error(new SAXParseException("attribute not found: " + qName, locator)); } return value; } private Rect parseRect(String s) { String[] parts = StringUtils.split(s, "x"); return new Rect(Integer.parseInt(parts[0]), Integer.parseInt(parts[1])); } private int parseInt(String s) { return Integer.parseInt(s); } public void endElement(String uri, String localName, String qName) throws SAXException { try { Method method = getClass().getMethod(qName, new Class[]{}); method.invoke(this, new Object[]{}); } catch (NoSuchMethodException e) { warning(new SAXParseException("no end handler for " + qName, locator)); } catch (IllegalAccessException e) { fatalError(new SAXParseException(e.getMessage(), locator, e)); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof SAXException) { throw (SAXException)t; } else if (t instanceof Error) { throw (Error)t; } else { fatalError(new SAXParseException(t.getMessage(), locator)); } } } public void endDocument() throws SAXException { tagHandler.finish(); } public void warning(SAXParseException e) throws SAXParseException { //outputHandler.warning(0, e.getLineNumber(), docPath, e.getMessage()); } public void error(SAXParseException e) throws SAXParseException { //outputHandler.error(0, e.getLineNumber(), docPath, e.getMessage()); } public void fatalError(SAXParseException e) throws SAXParseException { //outputHandler.error(0, e.getLineNumber(), docPath, e.getMessage()); throw e; } public void setDocumentLocator(Locator locator) { this.locator = locator; } public boolean parse(String path) throws IOException//, OutputHandler handler) throws IOException { // parser property names final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; this.docPath = path; //this.outputHandler = handler; InputStream in = new BufferedInputStream(new FileInputStream(path)); SAXParser parser; try { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); factory.setNamespaceAware(true); try { parser = factory.newSAXParser(); parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); parser.setProperty(JAXP_SCHEMA_SOURCE, new InputSource(getClass().getResource("swfx.xsd").toExternalForm())); } catch (Exception e) { if (e instanceof SAXNotRecognizedException) { // schema validation not supported... ignore factory.setValidating(false); factory.setNamespaceAware(true); parser = factory.newSAXParser(); } else if (e instanceof IOException) { throw (IOException)e; } else if (e instanceof SAXException) { throw (SAXException)e; } else { e.printStackTrace(); parser = null; } } parser.parse(in, this); return true; } catch (SAXException e) { // errors will have been reported already //e.printStackTrace(); return false; } catch (Exception e) { if (e instanceof ParserConfigurationException) { if (Trace.error) e.printStackTrace(); return false; } else if (e instanceof IOException) { throw (IOException)e; } else { e.printStackTrace(); return true; } } finally { in.close(); } } public static void main(String[] args) throws IOException { String aspath = null; for (int i = 0; i < args.length; i++) { if (args[i].equals("-aspath")) { aspath = args[++i]; continue; } TagEncoder encoder = new TagEncoder(); //ConsoleOutputHandler tagHandler = new ConsoleOutputHandler(null, null); SwfxParser swfxParser = new SwfxParser(encoder, StringUtils.splitPath(aspath)); boolean success = swfxParser.parse(args[i]);//, tagHandler); if (success) { String swfFileName = args[i].substring(0, args[i].lastIndexOf('.')) + ".swf"; OutputStream out = new BufferedOutputStream(new FileOutputStream(swfFileName)); try { encoder.writeTo(out); } finally { out.close(); } } else { System.exit(1); } } } }