Top-level object for a SWF movie.
Inheritance: SWFProcessing.SWFModeller.Modelling.Timeline
示例#1
0
 public JQueryCanvasApp(string ID, SWF swf, SWF2HTMLOptions options)
 {
     this.html = new HTMLAssist(ID);
     this.Swf = swf;
     this.Width = (int)Swf.FrameWidth;
     this.Height = (int)Swf.FrameHeight;
     this.OutputComments = options.OutputComments;
     this.ConsoleLogging = options.ConsoleLogging;
 }
示例#2
0
        public SWF2HTML(SWF swf, string ID, SWF2HTMLOptions options = null)
        {
            this.Swf = swf;
            this.ID = ID;

            if (options == null)
            {
                options = new SWF2HTMLOptions(); /* Defaults */
            }

            this.Options = options;
        }
示例#3
0
        public void ConvertSWF(string name)
        {
            SWF swf = new SWF(new SWFContext(name), false);

            SWF2Raster converter = new SWF2Raster(swf);

            using (FileStream output = new FileStream(TestDir + name + ".png", FileMode.Create))
            using (Stream svgOut = converter.GetPNG())
            {
                byte[] buffer = new byte[32768];
                while (true)
                {
                    int read = svgOut.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return;
                    output.Write(buffer, 0, read);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Initializes a new instance of a SWF writer with the given options.
        /// </summary>
        /// <param name="swf">The SWF to write.</param>
        /// <param name="options">The options that control the output, or
        /// null for the defaults.</param>
        public SWFWriter(SWF swf, SWFWriterOptions options, StringBuilder writeLog, StringBuilder abcWriteLog)
        {
            if (options == null)
            {
                /* Create a default object */
                this.options = new SWFWriterOptions()
                {
                    Compressed     = true,
                    EnableDebugger = false
                };
            }
            else
            {
                this.options = options;
            }

            this.swf              = swf;
            this.writeLog         = writeLog;
            this.abcWriteLog      = abcWriteLog;
            this.characterMarshal = new IDMarshaller <ICharacter>(1);
        }
示例#5
0
        /// <summary>
        /// Initializes a new instance of a SWF writer with the given options.
        /// </summary>
        /// <param name="swf">The SWF to write.</param>
        /// <param name="options">The options that control the output, or
        /// null for the defaults.</param>
        public SWFWriter(SWF swf, SWFWriterOptions options, StringBuilder writeLog, StringBuilder abcWriteLog)
        {
            if (options == null)
            {
                /* Create a default object */
                this.options = new SWFWriterOptions()
                {
                    Compressed = true,
                    EnableDebugger = false
                };
            }
            else
            {
                this.options = options;
            }

            this.swf = swf;
            this.writeLog = writeLog;
            this.abcWriteLog = abcWriteLog;
            this.characterMarshal = new IDMarshaller<ICharacter>(1);
        }
示例#6
0
        /// <summary>
        /// Creates an instance from a referenced SWF.
        /// </summary>
        /// <param name="insTag">The instance tag.</param>
        /// <param name="swf">The SWF to place the instance into.</param>
        /// <param name="className">Name of the class for the new clip.</param>
        /// <param name="importSwf">The SWF to import as a clip.</param>
        private void CreateInstanceFromSWF(XPathNavigator insTag, SWF swf, string className, SWF importSwf)
        {
            if (!swf.HasClass)
            {
                /* Can't create instances if the parent timeline has no code now can we? */
                swf.GenerateTimelineScripts();
            }

            bool isAdobeClassname = className.StartsWith("flash.")
                || className.StartsWith("fl.")
                || className.StartsWith("adobe.")
                || className.StartsWith("air.")
                || className.StartsWith("flashx.");

            if (isAdobeClassname && importSwf.HasClass)
            {
                /* Can't rename a class to an Adobe class name. That's bonkers. */
                throw new SwiffotronException(
                        SwiffotronError.BadInputXML,
                        this.Context.Sentinel("InstanceClassNameInappropriate"),
                        "You can't rename a timeline class to a reserved adobe classname (" + className + "), SWF: " + importSwf.Context);
            }

            if (className == string.Empty)
            {
                if (importSwf.Class == null)
                {
                    /* No class name is fine if the imported SWF has no class to rename. We need
                     * a class to bind it to though, so let's make it MovieClip, just like
                     * real flash. */
                    className = "flash.display.MovieClip";
                }
                else
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadInputXML,
                            this.Context.Sentinel("MainTimelineInstanceNotRenamed"),
                            "An external instance with timeline code must be explicitely renamed with the instance tag's class attribute.");
                }
            }

            if (className == "flash.display.MovieClip")
            {
                Sprite spr = new Sprite(importSwf, swf);

                this.CreateInstanceIn(
                        insTag.GetAttribute(XMLHelper.AttrID, string.Empty),
                        swf,
                        insTag,
                        spr,
                        className);
            }
            else
            {
                Sprite spr = new Sprite(importSwf, swf, className);

                this.CreateInstanceIn(
                        insTag.GetAttribute(XMLHelper.AttrID, string.Empty),
                        swf,
                        insTag,
                        spr,
                        className);

                spr.SpriteProc(delegate(Sprite s)
                {
                    if (s.Class != null && !(s.Class is AdobeClass))
                    {
                        /* ISSUE 29: Only do this if the class hasn't already been bound. */
                        swf.FirstScript.Code.GenerateClipClassBindingScript(s);
                    }
                });

                if (spr.Class != null)
                {
                    swf.FirstScript.Code.GenerateClipClassBindingScript(spr);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Process an instantiation tag in the job XML
        /// </summary>
        /// <param name="insTag">A pointer to the instantiation node</param>
        /// <param name="currentSwfTag">A pointer to the current SWF node that contains
        /// the instance node.</param>
        /// <param name="swf">The SWF within which to instantiate something.</param>
        private void CreateInstance(XPathNavigator insTag, XPathNavigator currentSwfTag, SWF swf)
        {
            string type = insTag.GetAttribute(XMLHelper.AttrType, string.Empty);
            string src = insTag.GetAttribute(XMLHelper.AttrSrc, string.Empty);
            string className = insTag.GetAttribute(XMLHelper.AttrClass, string.Empty);

            /* ISSUE 58: If the instance name (id) is the same as the class name, it can
             * cause problems in files generated and decompiled again in sothink. We should
             * probably detect this and warn against it. */

            switch (type)
            {
                case XMLHelper.ValSwf:
                    if (className == string.Empty)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context,
                                "An instance created from a SWF needs a class name to be defined.");
                    }

                    if (src.StartsWith("store://"))
                    {
                        throw new SwiffotronException(SwiffotronError.BadPathOrID, this.Context, "Unexpected store path. Did you mean for the type to be extern, perhaps?");
                    }

                    if (!this.processedSWFs.ContainsKey(src))
                    {
                        throw new SwiffotronException(
                                SwiffotronError.Internal,
                                this.Context,
                                "Internal error. SWF tags were processed out of order (" + currentSwfTag.GetAttribute(XMLHelper.AttrID, string.Empty) + " requres " + src + ").");
                    }

                    SWF processedSWF = this.processedSWFs[src];

                    this.CreateInstanceFromSWF(insTag, swf, className, processedSWF);
                    break;

                case XMLHelper.ValMovieClip:
                    Sprite clip = swf.GetCharacter(src) as Sprite;
                    if (clip == null)
                    {
                        throw new SwiffotronException(SwiffotronError.BadInputXML, this.Context, "MovieClip not defined: " + src);
                    }

                    this.CreateInstanceIn(
                            insTag.GetAttribute(XMLHelper.AttrID, string.Empty),
                            swf,
                            insTag,
                            clip,
                            className);

                    clip.SpriteProc(delegate(Sprite s)
                    {
                        if (s.Class != null && !(s.Class is AdobeClass))
                        {
                            /* ISSUE 29: Only do this if the class hasn't already been bound.
                             * Note that this will be a problem if one movieclip is used to create
                             * several instances. At the time of writing, there is no unit test for
                             * this case. */
                            swf.FirstScript.Code.GenerateClipClassBindingScript(s);
                        }
                    });

                    break;

                case XMLHelper.ValInstance:
                    if (className != string.Empty)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context.Sentinel("ClassNameInClonedInstance"),
                                "An instance cannot be given a new classname if it is a clone of an existing instance (" + className + ")");
                    }

                    Sprite srcSprite = swfProc.SpritesFromQname(src, swf, false)[0];
                    if (!srcSprite.HasClass)
                    {
                        srcSprite.Class = AdobeClass.CreateFlashDisplayMovieClip(srcSprite.Root.FirstScript.Code);
                        className = srcSprite.Class.QualifiedName;
                    }

                    this.CreateInstanceIn(
                            insTag.GetAttribute(XMLHelper.AttrID, string.Empty),
                            swf,
                            insTag,
                            srcSprite,
                            className);
                    break;

                case XMLHelper.ValExtern:
                    SWF importSwf = this.SwfFromStore(src);

                    this.CreateInstanceFromSWF(insTag, swf, className, importSwf);

                    break;

                default:
                    /* ISSUE 73 */
                    throw new SwiffotronException(
                            SwiffotronError.UnimplementedFeature,
                            this.Context,
                            "Bad instance type: " + type);
            }
        }
示例#8
0
        /// <summary>
        /// Processes a remove instance tag
        /// </summary>
        /// <param name="nav">The remove node</param>
        /// <param name="swf">The SWF to remove from</param>
        private void RemoveInstance(XPathNavigator nav, SWF swf)
        {
            string qname = nav.GetAttribute(XMLHelper.AttrQName, string.Empty);

            string uname;
            Timeline parent = this.QNameToTimeline(qname, swf, out uname);

            if (!parent.RemoveInstance(uname))
            {
                /* ISSUE 57: Unit test for this please. Also for non-existant parent names in the qname. */
                throw new SwiffotronException(SwiffotronError.BadPathOrID, this.Context, "Cannot remove '" + qname + "'; it does not exist.");
            }
        }
示例#9
0
        /// <summary>
        /// Reads a SWF from the stream.
        /// </summary>
        /// <returns>A parsed SWF object</returns>
        public SWF ReadSWF(SWFContext ctx)
        {
#if DEBUG
            this.MarkDumpOffset("Start of file");
#endif

            this.jpegTable = null;

            this.sceneNotes      = new List <FrameNote>();
            this.frameLabelNotes = new List <FrameNote>();

            this.ReadHeader(ctx);

            this.fontDict = new Dictionary <int, SWFFont>();

            this.frameCursor = 1;

            bool as3 = false;
            if (this.version >= 8)
            {
#if DEBUG
                this.MarkDumpOffset("Start of file attributes tag");
#endif
                this.ReadFileAttributesTag(out as3);
            }

            if (!as3)
            {
                throw new SWFModellerException(
                          SWFModellerError.SWFParsing,
                          @"AS2 and under is not supported.", ctx);
            }

            this.swf             = new SWF(ctx, false);
            this.swf.FrameWidth  = this.frameSize.Width;
            this.swf.FrameHeight = this.frameSize.Height;
            this.swf.Fps         = this.fps;
            this.swf.FrameCount  = this.frameCount;

            this.currentTimeline = this.swf;

            bool hasMore = true;
            do
            {
                hasMore = this.ReadTag();
            }while (hasMore);

            foreach (FrameNote note in this.sceneNotes)
            {
                this.swf.GetFrame((int)note.frame).SceneName = note.note;
            }

            foreach (FrameNote note in this.frameLabelNotes)
            {
                this.swf.GetFrame((int)note.frame).Label = note.note;
            }

            foreach (string className in this.LateClassResolutions.Keys)
            {
                swf.MapClassnameToClip(className, this.LateClassResolutions[className]);
            }

            return(this.swf);
        }
示例#10
0
        /// <summary>
        /// Finds a timeline from a qualified instance name.
        /// </summary>
        /// <param name="qname">The dotted qname path to the instance.</param>
        /// <param name="swf">The SWF to search.</param>
        /// <param name="uname">The unqualified name of the found instance is returned here.</param>
        /// <returns>The found timeline</returns>
        private Timeline QNameToTimeline(string qname, SWF swf, out string uname)
        {
            int lpos = qname == null ? -1 : qname.LastIndexOf('.');
            uname = qname;
            if (lpos == -1)
            {
                /* If this is just a simple instance name, return the stage. */
                return swf;
            }
            else
            {
                uname = qname.Substring(lpos + 1);
                string parentQname = qname.Substring(0, lpos);
                PlaceObject parentIns = swf.LookupInstance(parentQname);
                if (parentIns == null)
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadPathOrID,
                            this.Context,
                            "Ancestor of '" + uname + "', i.e. '" + parentQname + "' does not exist.");
                }

                ICharacter parentChar = parentIns.Character;

                if (!(parentChar is Timeline))
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadPathOrID,
                            this.Context,
                            "QName '" + parentQname + "' does not refer to a timeline.");
                }

                return (Timeline)parentChar;
            }
        }
示例#11
0
 /// <summary>
 /// Initializes a new instance of a SWF writer with the default options.
 /// </summary>
 /// <param name="swf">The SWF to write.</param>
 public SWFWriter(SWF swf, StringBuilder writeLog, StringBuilder abcWriteLog)
     : this(swf, null, writeLog, abcWriteLog)
 {
     /* Convenience constructor. */
 }
示例#12
0
        private void ConvertSWF(string name, SWF swf)
        {
            SWF2HTML converter = new SWF2HTML(swf, name, new SWF2HTMLOptions() { 
                OutputComments = true,
                ConsoleLogging = true
            });

            using (FileStream output = new FileStream(TestDir + name + ".html", FileMode.Create))
            using (Stream htmlOut = converter.GetHTML(true))
            {
                byte[] buffer = new byte[32768];
                while (true)
                {
                    int read = htmlOut.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return;
                    output.Write(buffer, 0, read);
                }
            }
        }
示例#13
0
 public void ConvertSimplestSWF()
 {
     string name = "SWF2HTMLTest.ConvertSimplestSWF";
     SWF swf = new SWF(new SWFContext(name), false);
     ConvertSWF(name, swf);
 }
示例#14
0
 public SWF2Raster(SWF swf)
 {
     this.Swf = swf;
 }
示例#15
0
        /// <summary>
        /// Create a MovieClip that can later be referenced by SWFs and instantiated.
        /// </summary>
        /// <param name="movieClipTag">A pointer to the movie clip node in the job XML</param>
        /// <param name="currentSwfTag">A pointer to the currently processing SWF node</param>
        /// <param name="swf">The SWF to add the movie clip to</param>
        private void CreateMovieClip(XPathNavigator movieClipTag, XPathNavigator currentSwfTag, SWF swf)
        {
            string type = movieClipTag.GetAttribute(XMLHelper.AttrType, string.Empty);
            string src = movieClipTag.GetAttribute(XMLHelper.AttrSrc, string.Empty);
            string className = movieClipTag.GetAttribute(XMLHelper.AttrClass, string.Empty);
            string swfTag = movieClipTag.GetAttribute(XMLHelper.AttrSwf, string.Empty);

            /*
             * ISSUE 59: The examples in unit tests all put instances in the same package, e.g.
             *  <instance blahblah class="com.swiffotron.Class1" />
             *  <instance blahblah class="com.swiffotron.Class2" />
             * both put them into com.swiffotron. These are moved from the IDE generated packages
             * myswf1_fla and myswf2_fla so if you think about it, moving them both to com.swiffotron
             * makes sense because they would both have been put into the same generated package
             * if you'd done it via the IDE. The problem comes if we move them into different packages.
             * I don't know what will happen, I just haven't tried it. I have a sneaking suspicion that
             * we'll run into problems in namespace sets and the bugs will be very hard
             * to track down. Some solutions:
             * - Insist on using the same package in classes
             * - make class just be a class name, and dictate the package automatically
             * - Resolve the namespace sets to include all relevant, foreign packages (hard)
             */

            bool fromOtherSwf = swfTag != null && swfTag != string.Empty;
            if (fromOtherSwf)
            {
                /* ISSUE 60: If swf attribute is present, find the swf. It should be loaded/generated. It should not be the current swf. */
                throw new SwiffotronException(
                        SwiffotronError.UnimplementedFeature,
                        this.Context,
                        "swf attribute is not supported in movieclip tags yet.");
            }

            switch (type)
            {
                case XMLHelper.ValSwf:
                    if (fromOtherSwf)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context,
                                "The movieclip 'swf' attribute does not make sense when the type is set to 'swf'.");
                    }

                    if (!this.processedSWFs.ContainsKey(src))
                    {
                        throw new SwiffotronException(
                                SwiffotronError.Internal,
                                this.Context,
                                "Internal error. SWF tags were processed out of order (" + currentSwfTag.GetAttribute(XMLHelper.AttrID, string.Empty) + " requres " + src + ").");
                    }

                    if (className == string.Empty)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context,
                                "An clip created from a SWF needs a class name to be defined.");
                    }

                    SWF importSwf = this.processedSWFs[src];

                    /* ISSUE 55: There's an issue comment up there next to the declaration of processedSWFs which is intended
                     * to cache the new Sprite() bit below. */
                    swf.AddCharacter(movieClipTag.GetAttribute(XMLHelper.AttrID, string.Empty), new Sprite(importSwf, swf, className));

                    /* ISSUE 61: The above new Sprite will merge the sprite's code into the SWF regardless of whether
                     * it's instantiated. This should be done based on the exportforscript flag, or if the sprite
                     * is instantiated. Mind you, there is an argument that says if you declare a movieclip and
                     * never use it, and don't mark if for export, then you should probably remove it. Perhaps
                     * a more elegant solution would be to verify this in the XML and give a warning that you're
                     * doing redundant things. */

                    break;

                case XMLHelper.ValExtern:
                    if (fromOtherSwf)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context,
                                "The movieclip 'swf' attribute does not make sense when the type is set to 'extern'. Try declaring the external SWF in its own tag instead, and reference it by ID.");
                    }

                    if (className == string.Empty)
                    {
                        throw new SwiffotronException(
                                SwiffotronError.BadInputXML,
                                this.Context,
                                "An clip created from a SWF needs a class name to be defined.");
                    }

                    SWF forImport = this.SwfFromStore(src);
                    try
                    {
                        swf.AddCharacter(movieClipTag.GetAttribute(XMLHelper.AttrID, string.Empty), new Sprite(forImport, swf, className));
                    }
                    catch (SWFModellerException sme)
                    {
                        if (sme.Error == SWFModellerError.CodeMerge)
                        {
                            throw new SwiffotronException(SwiffotronError.BadInputXML, this.Context.Sentinel("ClassNameCollision"), "Possible class name collision.", sme);
                        }
                        else
                        {
                            throw;
                        }
                    }

                    break;

                default:
                    /* ISSUE 73 */
                    throw new SwiffotronException(
                            SwiffotronError.UnimplementedFeature,
                            this.Context,
                            "Bad instance type: " + type);
            }
        }
示例#16
0
        /// <summary>
        /// Creates an instance within another instance's clip, e.g. creating "mc1.mc2.mc3"
        /// will create mc3 within mc2, where mc1.mc2 is mc2's qname.
        /// </summary>
        /// <param name="qname">The qualified name of the instance to create.</param>
        /// <param name="swf">The SWF to create it in.</param>
        /// <param name="transform">This is an XML node which extends transformRelativeToType in the XSD, and
        /// can be queried for transform information.</param>
        /// <param name="charToInstantiate">The character to create an instance of.</param>
        private void CreateInstanceIn(string qname, SWF swf, XPathNavigator transform, Sprite charToInstantiate, string qClassName)
        {
            string newInsName;
            Timeline parent = this.QNameToTimeline(qname, swf, out newInsName);

            string relativeToQname = transform.GetAttribute(XMLHelper.AttrRelativeTo, string.Empty);
            Matrix m = null;
            if (relativeToQname == null || relativeToQname == string.Empty)
            {
                m = Xml.TransformTagToMatrix(transform);
                if (m.IsSimpleTranslate)
                {
                    m.TransX = m.TransX;
                    m.TransY = m.TransY;
                }
            }
            else
            {
                m = swfProc.PositionFromQname(relativeToQname, swf);
                Matrix rel = Xml.TransformTagToMatrix(transform);
                if (rel.IsSimpleTranslate)
                {
                    m.Translate(rel.TransX, rel.TransY);
                }
                else
                {
                    m.Apply(rel);
                }
            }

            try
            {
                parent.Instantiate(1, charToInstantiate, Layer.Position.Front, m, newInsName, qClassName);
            }
            catch (SWFModellerException sme)
            {
                throw new SwiffotronException(
                        SwiffotronError.BadInputXML,
                        this.Context.Sentinel("CreateInstanceIn"),
                        "Failed to instantiate an instance in a timeline. instance name:" + qname + ", instance class:" + qClassName,
                        sme);
            }
        }
示例#17
0
        /// <summary>
        /// Serialize a SWF to a store path
        /// </summary>
        /// <param name="swfNav">The node of the SWF being stored</param>
        /// <param name="swf">The processed SWF object</param>
        /// <param name="writeLog">Only used in debug builds. Accumulates a log of write operations
        /// to the SWF file.</param>
        /// <param name="abcWriteLog">Only used in debug builds. Accumulates a log of write operations
        /// to the ABC data within the SWF file.</param>
        private void ProcessSWFOutput(XPathNavigator swfNav, SWF swf, StringBuilder writeLog, StringBuilder abcWriteLog)
        {
            byte[] swfData = null;
            byte[] pngData = null;
            byte[] svgData = null;
            byte[] htmlData = null;

            int swfOuts = Xml.SelectChildren(swfNav, @"swfout").Count;
            int pngOuts = Xml.SelectChildren(swfNav, @"pngout").Count;
            int vidOuts = Xml.SelectChildren(swfNav, @"vidout").Count;
            int svgOuts = Xml.SelectChildren(swfNav, @"svgout").Count;
            int htmlOuts = Xml.SelectChildren(swfNav, @"htmlout").Count;

            if (swfOuts > 0)
            {
                swfData = new SWFWriter(swf, conf.swfWriterOptions, writeLog, abcWriteLog).ToByteArray();
            }

            foreach (XPathNavigator swfout in Xml.SelectChildren(swfNav, @"swfout"))
            {
                string swfoutStore = swfout.GetAttribute(@"store", string.Empty);

                if (swfoutStore == string.Empty)
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadInputXML,
                            this.Context,
                            @"The swfout tag needs either a cachekey or a storeput attribute");
                }

                this.SaveToStore(swfoutStore, swfData);
            }

            if (pngOuts > 0)
            {
                SWF2Raster pngConv = new SWF2Raster(swf);
                pngData = pngConv.GetPNGAsBytes();
            }

            foreach (XPathNavigator pngout in Xml.SelectChildren(swfNav, @"pngout"))
            {
                string pngoutStore = pngout.GetAttribute(@"store", string.Empty);

                if (pngoutStore == string.Empty)
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadInputXML,
                            this.Context,
                            @"The pngout tag needs either a cachekey or a storeput attribute");
                }

                this.SaveToStore(pngoutStore, pngData);
            }

            if (htmlOuts > 0)
            {
                SWF2HTML htmlConv = new SWF2HTML(
                        swf,
                        swfNav.GetAttribute(XMLHelper.AttrID, string.Empty),
                        new SWFProcessing.SWF2HTML.SWF2HTMLOptions() {
                            Framework = conf.HTMLType
                        });
                htmlData = htmlConv.GetHTMLAsBytes(false);
            }

            foreach (XPathNavigator htmlout in Xml.SelectChildren(swfNav, @"htmlout"))
            {
                string htmloutStore = htmlout.GetAttribute(@"store", string.Empty);

                if (htmloutStore == string.Empty)
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadInputXML,
                            this.Context,
                            @"The htmlout tag needs either a cachekey or a storeput attribute");
                }

                this.SaveToStore(htmloutStore, htmlData);
            }

            if (svgOuts > 0)
            {
                SWF2SVG svgConv = new SWF2SVG(swf);
                svgData = svgConv.GetSVGAsBytes();
            }

            foreach (XPathNavigator svgout in Xml.SelectChildren(swfNav, @"svgout"))
            {
                string svgoutStore = svgout.GetAttribute(@"store", string.Empty);

                if (svgoutStore == string.Empty)
                {
                    throw new SwiffotronException(
                            SwiffotronError.BadInputXML,
                            this.Context,
                            @"The svgout tag needs either a cachekey or a storeput attribute");
                }

                this.SaveToStore(svgoutStore, svgData);
            }

            if (vidOuts > 0)
            {
                /* ISSUE 66 */
                throw new SwiffotronException(
                        SwiffotronError.UnimplementedFeature,
                        this.Context,
                        "We can't do video output yet.");
            }
        }
示例#18
0
        /// <summary>
        /// Executes a modify tag on a SWF
        /// </summary>
        /// <param name="modify">A navigator pointing to the modify element in the XML</param>
        /// <param name="swf">The SWF to modify</param>
        private void ModifyInstance(XPathNavigator modify, SWF swf)
        {
            string qname = modify.GetAttribute(XMLHelper.AttrQName, string.Empty);

            PlaceObject po = swf.LookupInstance(qname);

            /* ISSUE 63: There is a question of whether to error if the instance is not found. Some are
             * found with a pattern rather than a path, and you may not expect it to always find something. 
             * At the moment, we shall throw an exception, because it suits our development, unit testing
             * fail-fast strictness. */
            if (po == null)
            {
                throw new SwiffotronException(
                        SwiffotronError.BadPathOrID,
                        this.Context.Sentinel("ModifyInstance"),
                        @"Instance not found: " + qname);
            }

            Xml.MoveToFirstChildElement(modify);

            do
            {
                if (modify.NodeType == XPathNodeType.Element)
                {
                    switch (modify.LocalName)
                    {
                        case XMLHelper.TagMoveRel:
                            Matrix rel = Xml.TransformTagToMatrix(modify);
                            po.Matrix.Apply(rel);
                            break;

                        case XMLHelper.TagMoveAbs:
                            Matrix abs = Xml.TransformTagToMatrix(modify);
                            po.Matrix = abs;
                            break;

                        default:
                            /* ISSUE 73 */
                            throw new SwiffotronException(
                                    SwiffotronError.UnimplementedFeature,
                                    this.Context,
                                    @"Unsupported modification tag: " + modify.LocalName);
                    }
                }
            }
            while (modify.MoveToNext(XPathNodeType.Element));

            modify.MoveToParent();
        }
示例#19
0
        /// <summary>
        /// Process a SWF tag in the job XML
        /// </summary>
        /// <param name="swfTag">A pointer to the SWF node</param>
        /// <param name="baseSwf">A path to the SWF file upon which to base this new SWF</param>
        /// <param name="width">The stage width</param>
        /// <param name="height">The stage height</param>
        /// <param name="bgcolor">The stage colour</param>
        /// <param name="cachekey">A key to cache the results in (Or to get it from, which would
        /// be ever so nice)</param>
        /// <param name="writeLog">Only used in debug builds. This will accumulate a log of
        /// writes to an output from this SWF.</param>
        /// <param name="abcWriteLog">Only used in debug builds. This will accumulate a log of
        /// writes to ABC bytecode data within the output SWF.</param>
        private void ProcessSWF(
                XPathNavigator swfTag,
                string baseSwf,
                int? width,
                int? height,
                Color? bgcolor,
                string cachekey,
                StringBuilder writeLog,
                StringBuilder abcWriteLog)
        {
            SWF swf;
            if (baseSwf == string.Empty)
            {
                /* It's a new SWF */
                swf = new SWF(new SWFContext(swfTag.GetAttribute(XMLHelper.AttrID, string.Empty)), true);

                /* ISSUE 56: If this SWF has no output, then perhaps we can create it as a movieclip
                 * since it'll certainly be converted into one later on. */
            }
            else
            {
                /* It's a SWF loaded from a store */
                swf = this.SwfFromStore(baseSwf);
            }

            if (bgcolor != null)
            {
                swf.BackgroundColor = (Color)bgcolor;
            }

            if (width != null)
            {
                swf.FrameWidth = (int)width;
            }

            if (height != null)
            {
                swf.FrameHeight = (int)height;
            }

            if (swfTag.HasChildren)
            {
                /* Move down to the swf tag child nodes which we will process in order. */
                XPathNavigator nav = swfTag.Clone();
                Xml.MoveToFirstChildElement(nav);

                do
                {
                    switch (nav.LocalName)
                    {
                        case XMLHelper.TagModify:
                            this.ModifyInstance(nav, swf);
                            break;

                        case XMLHelper.TagTextReplace:
                            this.TextReplace(nav, swf);
                            break;

                        case XMLHelper.TagInstance:
                            this.CreateInstance(nav, swfTag, swf);
                            break;

                        case XMLHelper.TagRemove:
                            this.RemoveInstance(nav, swf);
                            break;

                        case XMLHelper.TagMovieClip:
                            this.CreateMovieClip(nav, swfTag, swf);
                            break;

                        case XMLHelper.TagSwfOut:
                        case XMLHelper.TagPngOut:
                        case XMLHelper.TagVidOut:
                        case XMLHelper.TagSvgOut:
                        case XMLHelper.TagHTMLOut:
                            /* These are not processing steps. Skip 'em. */
                            break;

                        default:
                            /* ISSUE 73 */
                            throw new SwiffotronException(
                                    SwiffotronError.UnimplementedFeature,
                                    this.Context,
                                    @"Unsupported tag: " + nav.LocalName);
                    }
                }
                while (nav.MoveToNext(XPathNodeType.Element));
            }

            this.processedSWFs.Add(swfTag.GetAttribute(XMLHelper.AttrID, string.Empty), swf);

            this.ProcessSWFOutput(swfTag, swf, writeLog, abcWriteLog);
        }
示例#20
0
 public SWF2SVG(SWF swf)
 {
     this.Swf = swf;
 }
示例#21
0
        /// <summary>
        /// Processes a text replacement tag
        /// </summary>
        /// <param name="nav">The text replacement node.</param>
        /// <param name="swf">The SWF being processed.</param>
        private void TextReplace(XPathNavigator nav, SWF swf)
        {
            XPathNavigator findNode = Xml.SelectNode(nav, @"swf:find/text()");
            if (findNode == null)
            {
                throw new SwiffotronException(SwiffotronError.BadInputXML, this.Context, "The find element in textreplace operations cannot be empty.");
            }

            string find = findNode.Value;

            XPathNavigator replaceNode = Xml.SelectNode(nav, @"swf:replace/text()");
            string replace = replaceNode == null ? string.Empty : replaceNode.Value;

            foreach (XPathNavigator loc in Xml.SelectChildren(nav, @"location"))
            {
                string type = loc.GetAttribute(XMLHelper.AttrType, string.Empty);
                switch (type)
                {
                    case XMLHelper.ValActionscript:
                        swf.TextReplaceInCode(find, replace);
                        break;

                    case XMLHelper.ValMovieClip:
                        string path = loc.GetAttribute(XMLHelper.AttrPath, string.Empty);
                        Timeline[] clips = new Timeline[] { swf };
                        if (path != "*")
                        {
                            clips = swfProc.SpritesFromQname(path, swf, true);
                        }

                        foreach (Timeline clip in clips)
                        {
                            clip.CharacterProc(delegate(ICharacter ch)
                            {
                                if (ch is IText)
                                {
                                    IText t = (IText)ch;
                                    string text = t.Text;
                                    if (text.Contains(find))
                                    {
                                        /* The Contains test may seem redundant here, but the cost of the
                                         * assignment, even if there was nothing replaced is potentially
                                         * quite high. */
                                        t.Text = text.Replace(find, replace);
                                    }
                                }
                            });
                        }

                        break;

                    default:
                        throw new SwiffotronException(SwiffotronError.BadInputXML, this.Context, "Bad text replace location type: " + type);
                }
            }
        }
示例#22
0
 /// <summary>
 /// Initializes a new instance of a SWF writer with the default options.
 /// </summary>
 /// <param name="swf">The SWF to write.</param>
 public SWFWriter(SWF swf, StringBuilder writeLog, StringBuilder abcWriteLog)
     : this(swf, null, writeLog, abcWriteLog)
 {
     /* Convenience constructor. */
 }
示例#23
0
        /// <summary>
        /// Reads a SWF from the stream.
        /// </summary>
        /// <returns>A parsed SWF object</returns>
        public SWF ReadSWF(SWFContext ctx)
        {
            #if DEBUG
            this.MarkDumpOffset("Start of file");
            #endif

            this.jpegTable = null;

            this.sceneNotes = new List<FrameNote>();
            this.frameLabelNotes = new List<FrameNote>();

            this.ReadHeader(ctx);

            this.fontDict = new Dictionary<int, SWFFont>();

            this.frameCursor = 1;

            bool as3 = false;
            if (this.version >= 8)
            {
            #if DEBUG
                this.MarkDumpOffset("Start of file attributes tag");
            #endif
                this.ReadFileAttributesTag(out as3);
            }

            if (!as3)
            {
                throw new SWFModellerException(
                        SWFModellerError.SWFParsing,
                        @"AS2 and under is not supported.", ctx);
            }

            this.swf = new SWF(ctx, false);
            this.swf.FrameWidth = this.frameSize.Width;
            this.swf.FrameHeight = this.frameSize.Height;
            this.swf.Fps = this.fps;
            this.swf.FrameCount = this.frameCount;

            this.currentTimeline = this.swf;

            bool hasMore = true;
            do
            {
                hasMore = this.ReadTag();
            }
            while (hasMore);

            foreach (FrameNote note in this.sceneNotes)
            {
                this.swf.GetFrame((int)note.frame).SceneName = note.note;
            }

            foreach (FrameNote note in this.frameLabelNotes)
            {
                this.swf.GetFrame((int)note.frame).Label = note.note;
            }

            foreach (string className in this.LateClassResolutions.Keys)
            {
                swf.MapClassnameToClip(className, this.LateClassResolutions[className]);
            }

            return this.swf;
        }