/// <summary> /// Initializes a new instance of the PlaceObject class as a display /// list instruction to put an item onto the stage. /// </summary> public PlaceObject( ICharacter character, Layer layer, int? clipDepth, Matrix matrix, string name, bool isMove, ColorTransform cxform, string className, int? ratio) { this.Character = character; this.ClipDepth = clipDepth; this.Matrix = matrix; this.Name = name; this.IsMove = isMove; this.CXForm = cxform; this.Layer = layer; this.ClassName = className; this.Ratio = ratio; }
public void Instantiate(int frameNum, Sprite sprite, Layer.Position layering, Matrix position, string instanceName, string qClassName) { AS3Class instanceClass = sprite.Class; if (this.Class == null) { throw new SWFModellerException( SWFModellerError.Internal, "Can't instantiate " + instanceName + " on timeline with no code"); } DoABC scriptTag = this.Root.FirstScript; if (scriptTag == null) { /* ISSUE 70: Y'know, we can generate scripts. We should probably do that. */ throw new SWFModellerException( SWFModellerError.Internal, "Can't instantiate clips in a SWF with no code."); } if (instanceClass == null) { DoABC.GenerateDefaultScript(qClassName, sprite); instanceClass = sprite.Class; } /* Create instance variable of type referenced by instanceClass */ Namespace propNS = scriptTag.Code.CreateNamespace(Namespace.NamespaceKind.Package, string.Empty); Multiname propName = scriptTag.Code.CreateMultiname(Multiname.MultinameKind.QName, instanceName, propNS, NamespaceSet.EmptySet); if (this.Class is AS3ClassDef) { ((AS3ClassDef)this.Class).AddInstanceTrait(new SlotTrait() { Kind = TraitKind.Slot, TypeName = instanceClass.Name, Name = propName, ValKind = ConstantKind.ConUndefined }); } this.GetFrame(frameNum).AddTag(new PlaceObject(sprite, this.GetFreeLayer(layering), null, position, instanceName, false, null, null, null)); }
public int GetLayerIndex(Layer layer) { int idx = -1; if (this.LayerList != null) { idx = this.LayerList.FindIndex(l => l == layer); } if (idx == -1) { throw new SWFModellerException( SWFModellerError.Timeline, "Layer does not belong on this timeline"); } return idx + 1; }
public Layer GetFreeLayer(Layer.Position position) { switch (position) { case Layer.Position.Front: Layer l = new Layer(this); this.LayerList.Add(l); return l; case Layer.Position.Back: default: throw new SWFModellerException( SWFModellerError.Internal, "SWF::GetFreeLayer; " + position.ToString()); } }
public IDisplayListItem Clone(Layer l, bool rename) { /* ISSUE 19: Can't decide if we want to clone the characters, or clone them if we * pass in a flag and leave it to the swiffotron's logic to decide. */ string name = this.Name; if (rename && name != null) { name += "_copy"; } PlaceObject po = new PlaceObject( this.Character, l, this.ClipDepth, this.Matrix == null ? null : this.Matrix.Copy(), name, this.IsMove, this.CXForm == null ? null : this.CXForm.Clone(), this.ClassName, this.Ratio); /* ISSUE 19: Check that the name doesn't exist on the target layer's timeline. Remember the target * timeline might be different to the source timeline, so name collisions may or may not happen. * you might think passing in 'rename == true' all the time would be a good thing, but actually * this just breaks all the bytecode. I'm not entirely sure it's possible to fix that. * Best advice.. be careful with your names. */ return po; }
/// <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; } } }