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> /// Add something to the display list. TODO: Rename this method? /// </summary> /// <param name="dlistItem">The item to add.</param> public void AddTag(IDisplayListItem dlistItem) { this.displayList.Add(dlistItem); PlaceObject po = dlistItem as PlaceObject; if (po != null && po.Name != null) { this.placeObjectMap.Add(po.Name, po); } }
internal void RemoveDisplayListItem(IDisplayListItem dli) { this.displayList.Remove(dli); PlaceObject po = dli as PlaceObject; if (po != null && po.Name != null) { this.placeObjectMap.Remove(po.Name); } }
private Tag TagForPlaceObject(PlaceObject po) { if (po.HasClassName) { /* ISSUE 47: * Also indicated by presence of * - Surface filter list * - Blend mode * - Bitmap cache */ return(Tag.PlaceObject3); } if (po.HasName || po.IsMove || po.HasClipDepth || po.HasRatio || po.HasClipActions || po.HasColorTransformWithAlpha) { return(Tag.PlaceObject2); } return(Tag.PlaceObject); }
private void WritePlaceObjectTag(PlaceObject po) { Tag placeTag = this.TagForPlaceObject(po); WriteBuffer tagWriter = this.OpenTag(placeTag); int cid; switch (placeTag) { case Tag.PlaceObject: if (!po.HasCharacter) { throw new SWFModellerException( SWFModellerError.Internal, "A PlaceObject display list item must have a character unless it is a move instruction."); } #if DEBUG if (!this.characterMarshal.HasMarshalled(po.Character)) { throw new SWFModellerException( SWFModellerError.Internal, "Can't place object that hasn't been written to stream yet."); } #endif cid = this.characterMarshal.GetIDFor(po.Character); tagWriter.WriteUI16((uint)cid); #if DEBUG this.LogMessage("po cid =" + cid); #endif tagWriter.WriteUI16((uint)po.LayerIndex); if (!po.HasMatrix) { throw new SWFModellerException( SWFModellerError.Internal, "A PlaceObject display list item must have a Matrix, unless it's a PlaceObject2 tag. See spec for info, I can't work it out."); } tagWriter.WriteMatrix(po.Matrix); if (po.HasColorTransform) { tagWriter.WriteColorTransform(po.CXForm, false); } break; case Tag.PlaceObject2: tagWriter.WriteBit(po.HasClipActions); tagWriter.WriteBit(po.HasClipDepth); tagWriter.WriteBit(po.HasName); tagWriter.WriteBit(po.HasRatio); tagWriter.WriteBit(po.HasColorTransform); tagWriter.WriteBit(po.HasMatrix); tagWriter.WriteBit(po.HasCharacter); tagWriter.WriteBit(po.IsMove); tagWriter.WriteUI16((uint)po.LayerIndex); if (po.HasCharacter) { #if DEBUG if (!this.characterMarshal.HasMarshalled(po.Character)) { throw new SWFModellerException( SWFModellerError.Internal, "Can't place object that hasn't been written to stream yet."); } #endif cid = this.characterMarshal.GetIDFor(po.Character); tagWriter.WriteUI16((uint)cid); #if DEBUG this.LogMessage("po cid =" + cid); #endif } if (po.HasMatrix) { tagWriter.WriteMatrix(po.Matrix); } if (po.HasColorTransform) { tagWriter.WriteColorTransform(po.CXForm, true); } if (po.HasRatio) { tagWriter.WriteUI16((uint)po.Ratio); } if (po.HasName) { #if DEBUG this.LogMessage("name=" + po.Name); #endif tagWriter.WriteString(po.Name); } if (po.HasClipDepth) { tagWriter.WriteUI16((uint)po.ClipDepth); } if (po.HasClipActions) { throw new SWFModellerException( SWFModellerError.Internal, "Clips cannot have actions in the target SWF version."); } break; default: /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Unsupported PlaceObject tag: " + placeTag.ToString()); } #if DEBUG this.LogMessage("po char =" + po.Character); #endif this.CloseTag(); }
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> /// Finds a placed character on the stage by its instance name. /// </summary> /// <param name="qname">The qualified name, which is a dotted path through /// nested instances to the instance you want, starting from the root /// timeline.</param> /// <returns>The placeobject displaylist item, or null if not found.</returns> public PlaceObject LookupInstance(string qname) { /* ISSUE 31: In Swiffotron, we should be making a quick * check on qname to make sure it's not a store path since * if it is, and we've specified a wrong instance type, it * just crashes instead of supplying an informative error * message. */ string[] path = qname.Split('.'); if (path.Length == 0) { return(null); } PlaceObject po = null; ICharacter c = null; foreach (Frame f in this.FrameList) { po = f.FindInstance(path[0]); if (po != null) { c = po.Character; if (c == null) { throw new SWFModellerException( SWFModellerError.CharacterNotFound, "Instance has missing character: " + path[0]); } break; } } for (int i = 1; i < path.Length; i++) { if (!(c is Sprite)) { continue; } po = ((Sprite)c).FindInstance(path[i]); if (po == null) { return(null); } c = po.Character; if (c == null) { throw new SWFModellerException( SWFModellerError.CharacterNotFound, "Instance has missing character: " + path[i]); } } return(po); }
private void WritePlaceObjectTag(PlaceObject po) { Tag placeTag = this.TagForPlaceObject(po); WriteBuffer tagWriter = this.OpenTag(placeTag); int cid; switch (placeTag) { case Tag.PlaceObject: if (!po.HasCharacter) { throw new SWFModellerException( SWFModellerError.Internal, "A PlaceObject display list item must have a character unless it is a move instruction."); } #if DEBUG if (!this.characterMarshal.HasMarshalled(po.Character)) { throw new SWFModellerException( SWFModellerError.Internal, "Can't place object that hasn't been written to stream yet."); } #endif cid = this.characterMarshal.GetIDFor(po.Character); tagWriter.WriteUI16((uint)cid); #if DEBUG this.LogMessage("po cid =" + cid); #endif tagWriter.WriteUI16((uint)po.LayerIndex); if (!po.HasMatrix) { throw new SWFModellerException( SWFModellerError.Internal, "A PlaceObject display list item must have a Matrix, unless it's a PlaceObject2 tag. See spec for info, I can't work it out."); } tagWriter.WriteMatrix(po.Matrix); if (po.HasColorTransform) { tagWriter.WriteColorTransform(po.CXForm, false); } break; case Tag.PlaceObject2: tagWriter.WriteBit(po.HasClipActions); tagWriter.WriteBit(po.HasClipDepth); tagWriter.WriteBit(po.HasName); tagWriter.WriteBit(po.HasRatio); tagWriter.WriteBit(po.HasColorTransform); tagWriter.WriteBit(po.HasMatrix); tagWriter.WriteBit(po.HasCharacter); tagWriter.WriteBit(po.IsMove); tagWriter.WriteUI16((uint)po.LayerIndex); if (po.HasCharacter) { #if DEBUG if (!this.characterMarshal.HasMarshalled(po.Character)) { throw new SWFModellerException( SWFModellerError.Internal, "Can't place object that hasn't been written to stream yet."); } #endif cid = this.characterMarshal.GetIDFor(po.Character); tagWriter.WriteUI16((uint)cid); #if DEBUG this.LogMessage("po cid =" + cid); #endif } if (po.HasMatrix) { tagWriter.WriteMatrix(po.Matrix); } if (po.HasColorTransform) { tagWriter.WriteColorTransform(po.CXForm, true); } if (po.HasRatio) { tagWriter.WriteUI16((uint)po.Ratio); } if (po.HasName) { #if DEBUG this.LogMessage("name=" + po.Name); #endif tagWriter.WriteString(po.Name); } if (po.HasClipDepth) { tagWriter.WriteUI16((uint)po.ClipDepth); } if (po.HasClipActions) { throw new SWFModellerException( SWFModellerError.Internal, "Clips cannot have actions in the target SWF version."); } break; default: /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Unsupported PlaceObject tag: " + placeTag.ToString()); } #if DEBUG this.LogMessage("po char =" + po.Character); #endif this.CloseTag(); }
private Tag TagForPlaceObject(PlaceObject po) { if (po.HasClassName) { /* ISSUE 47: * Also indicated by presence of * - Surface filter list * - Blend mode * - Bitmap cache */ return Tag.PlaceObject3; } if (po.HasName || po.IsMove || po.HasClipDepth || po.HasRatio || po.HasClipActions || po.HasColorTransformWithAlpha) { return Tag.PlaceObject2; } return Tag.PlaceObject; }