Timeline objects are simply objects that have frames in them.
Beispiel #1
0
 /// <summary>
 /// Maps the classname to a clip.
 /// </summary>
 /// <param name="className">Name of the class.</param>
 /// <param name="tl">The timeline to bind the class to.</param>
 internal void MapClassnameToClip(string className, Timeline tl)
 {
     AS3ClassDef clazz = this.ClassByName(className);
     tl.Class = clazz;
     this.clipClassMap[clazz] = tl;
 }
Beispiel #2
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);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Generates a main timeline script for a new SWF
        /// </summary>
        /// <param name="qClassName">Qualified class name for the MainTimeline class,
        /// e.g. mygeneratedswf_fla.MainTimeline</param>
        /// <returns>A DoABC tag that can be inserted into a new SWF, which may be the one
        /// from the timeline (And so may already be in the SWF).</returns>
        public static DoABC GenerateDefaultScript(string qClassName, Timeline timeline)
        {
            DoABC abc = timeline.Root.FirstScript;
            if (abc == null)
            {
                abc = new DoABC(true, string.Empty, null, null);
                abc.code = new AbcCode();
            }

            AS3ClassDef classDef = GenerateTimelineClass(abc.code, qClassName, timeline.Root.Context);
            timeline.Class = classDef;

            Script s = new Script() { Method = GenerateTimelineScript(abc.code, classDef) };

            abc.code.AddScript(s);

            s.AddTrait(new ClassTrait() { As3class = classDef, Kind = TraitKind.Class, Name = timeline.Class.Name });

            return abc;
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of a sprite by cloning another timeline.
        /// </summary>
        /// <param name="srcTimeline">The timeline to clone.</param>
        /// <param name="className">If the cloned timeline is a SWF, then
        /// you should pass in a class name here. The MainTimeline class
        /// will be renamed in here to this new name.</param>
        public Sprite(Timeline srcTimeline, SWF root, string className = null)
        {
            this._root = root;

            /* Layers are just objects that exist purely to be arranged in some
             * kind of order and be pointed at by more meaningful, other things.
             * To clone layers, we need to simply copy the list and map old
             * layer refs to our new ones. */
            Dictionary<Layer, Layer> newLayers = new Dictionary<Layer, Layer>(srcTimeline.LayerCount);
            foreach (Layer l in srcTimeline.Layers)
            {
                Layer newLayer = new Layer(this);
                LayerList.Add(newLayer);
                newLayers.Add(l, newLayer);
            }

            FrameList = new List<Frame>((int)srcTimeline.FrameCount);
            foreach (Frame f in srcTimeline.Frames)
            {
                Frame newFrame = new Frame();
                foreach (IDisplayListItem dli in f.DisplayList)
                {
                    newFrame.AddTag(dli.Clone(newLayers[dli.Layer], false));
                }
                FrameList.Add(newFrame);
            }

            if (srcTimeline is SWF)
            {
                SWF srcSWF = (SWF)srcTimeline;

                if (className != null)
                {
                    if (srcSWF.Class != null)
                    {
                        srcSWF.RenameMainTimelineClass(className);
                    }
                    /* Else the class will be generated later */
                }

                RemapFonts(srcSWF, root);

                if (className != null)
                {
                    foreach (DoABC abc in srcSWF.Scripts)
                    {
                        root.MergeScript(abc);
                    }
                }

                if (className == null)
                {
                    /* It's tempting to use ClassByName("flash.display.MovieClip") but
                     * remember that that class exists in the player, not the SWF. What
                     * we need in this case is just the name of the class, not a reference
                     * to the class itself. Because that's complicated, we assign a
                     * dummy class and watch for it when we write the class out. */
                    this.Class = AdobeClass.CreateFlashDisplayMovieClip(root.FirstScript.Code);
                }
                else
                {
                    this.Class = srcSWF.Class;
                }
            }
        }
Beispiel #5
0
        private string RegisterTimeline(Timeline t)
        {
            int num = TimelineIDs.Count;
            TimelineIDs.Add(t, num);

            string name = "s" + num;

            this.NameTimelineMap.Add(name, t);

            return name;
        }
Beispiel #6
0
        private void BuildDictionary(Timeline timeline, StringBuilder buff)
        {
            if (this.OutputComments)
            {
                buff.AppendLine("  /* timeline for "+timeline.ToString()+" */");
            }

            foreach (Frame f in Swf.Frames)
            {
                foreach (IDisplayListItem dli in f.DisplayList)
                {
                    if (!Dict.ContainsKey(dli) && dli.Type == DisplayListItemType.PlaceObjectX)
                    {
                        string name = "mc" + Dict.Count + 1;
                        Dict.Add(dli, name);

                        PlaceObject po = dli as PlaceObject;
                        ICharacter ch = po.Character;

                        if (ch is Shape)
                        {
                            buff.AppendLine("  dict['" + name + "'] = \"" + ShapeToJS(ch as Shape) + "\";");
                        }
                        else if (ch is Sprite)
                        {
                            string clipName = RegisterTimeline((Timeline)ch);

                            buff.AppendLine("  var " + clipName + " = swiffoid.createMovieClipClass([o,o,o,o,o]);");
                            buff.AppendLine("  swiffoid.addClip('" + clipName + "', " + clipName + ");");
                            buff.AppendLine("  var instance = swiffoid.instantiateClip('" + clipName + "');");

                            html.JQueryAppendNew(buff, "  ", "$root", "canvas", new string[][] {
                                new string[] {"width", this.Width + "px"},
                                new string[] {"height", this.Height + "px"},
                            });

                            BuildDictionary((Sprite)ch, buff);
                        }
                    }
                }
            }
        }
Beispiel #7
0
        private void ReadSprite()
        {
            int characterID = this.sdtr.ReadUI16();
            uint frameCount = this.sdtr.ReadUI16();

            #if DEBUG
            this.Log("char id=" + characterID + ", frames=" + frameCount);
            #endif

            Sprite sprite = this.swf.NewSprite(CID_PREFIX + characterID, frameCount, (this.frameCursor == 1));

            this.currentTimeline = sprite;
            this.characterUnmarshaller.Add(characterID, sprite);

            int currentFrame = 1;
            for (; ; )
            {
                int type;
                uint followingOffset;
                this.sdtr.ReadRECORDHEADER(out type, out followingOffset);

            #if DEBUG
                Tag _tag = (Tag)type;
                bool isDefine = _tag == Tag.DefineShape ||
                     _tag == Tag.DefineShape3 ||
                     _tag == Tag.DefineShape4 ||
                     _tag == Tag.DefineSprite;
                this.MarkDumpOffset(
                    "Body of " + _tag + " (" + type + ") len=" + (followingOffset - this.sdtr.Offset),
                    isDefine);
                this.binaryDumpNest++;
            #endif

                switch ((Tag)type)
                {
                    case Tag.ShowFrame:
            #if DEBUG
                        this.MarkDumpOffset("");
            #endif
                        currentFrame++;
                        break;

                    case Tag.End:
                        if ((currentFrame - 1) != frameCount)
                        {
                            throw new SWFModellerException(
                                    SWFModellerError.SWFParsing,
                                    @"Frame count mismatch in sprite " + characterID, swf.Context);
                        }
                        this.currentTimeline = this.swf;
            #if DEBUG
                        this.binaryDumpNest--;
            #endif
                        return;

                    case Tag.PlaceObject2:
                        sprite.GetFrame(currentFrame).AddTag(this.ReadPlaceObject2());
                        break;

                    case Tag.PlaceObject:
                        sprite.GetFrame(currentFrame).AddTag(this.ReadPlaceObject(followingOffset));
                        break;

                    case Tag.FrameLabel:
                        sprite.GetFrame(currentFrame).Label = this.sdtr.ReadString();
            #if DEBUG
                        this.Log("Frame label = " + sprite.GetFrame(currentFrame).Label);
            #endif
                        break;

                    case Tag.RemoveObject2:
                        sprite.GetFrame(currentFrame).AddTag(this.ReadRemoveObject2());
                        break;

                    case Tag.RemoveObject:
                    case Tag.StartSound:
                    case Tag.SoundStreamHead:
                    case Tag.SoundStreamHead2:
                    case Tag.SoundStreamBlock:
                    case Tag.DoAction:
                        /* ISSUE 73 */
                        throw new SWFModellerException(
                                SWFModellerError.UnimplementedFeature,
                                @"Unsupported tag within a sprite definition: " + ((Tag)type).ToString(), swf.Context);

                    default:
                        throw new SWFModellerException(
                                SWFModellerError.SWFParsing,
                                @"Bad SWF; A " + ((Tag)type).ToString() + @" tag is not permitted within a sprite definition", swf.Context);
                }
            #if DEBUG
                this.binaryDumpNest--;
            #endif
            }
        }
Beispiel #8
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;
        }