A display list instruction that places an item onto the stage.
Inheritance: IDisplayListItem, ICharacterReference
Example #1
0
        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);
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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();
        }
Example #6
0
        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;
        }
Example #7
0
        /// <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);
        }
Example #8
0
        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();
        }
Example #9
0
        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;
        }