Exemple #1
0
        private void WriteFileAttributesTag()
        {
            WriteBuffer tagWriter = this.OpenTag(Tag.FileAttributes);

            /* ISSUE 27: Some of these flags are for SWF v10 - check the flash 9 spec for defaults instead. */

            /* No data written yet, so data will be aligned. */
            tagWriter.WriteBit(false);   /* Reserved, must be 0 */
            tagWriter.WriteBit(true);    /* UseDirectBlit, TODO: We set this to '1' but I dunno what the IDE does. */
            tagWriter.WriteBit(true);    /* UseGPU, TODO: We set this to '1' but I dunno what the IDE does. */
            tagWriter.WriteBit(this.options.RDFMetadata != null);
            tagWriter.WriteBit(true);    /* AS3, because we don't like AS2. Boo. */
            tagWriter.WriteUBits(0, 2);  /* Reserved, must be 0 */
            tagWriter.WriteBit(false);   /* UseNetwork. TODO: Check what the IDE sets for this. */
            tagWriter.WriteUBits(0, 24); /* Reserved, must be 0 */
            this.CloseTag();

            if (this.options.RDFMetadata != null)
            {
                this.OpenTag(Tag.Metadata)
                .WriteString(this.options.RDFMetadata);
                this.CloseTag();
            }
        }
Exemple #2
0
        private void WriteFont(SWFFont font, int fid)
        {
            WriteBuffer fontTag = this.OpenTag(Tag.DefineFont3, font.Name + "; id=" + fid);

            char[] codes = font.CodePoints;

            /* Tag.DefineFont3 */
            {
                fontTag.WriteUI16((uint)fid);

                fontTag.WriteBit(font.HasLayout);

                fontTag.WriteBit(false); /* ISSUE 50: ShiftJIS support */
                fontTag.WriteBit(font.IsSmall);
                fontTag.WriteBit(false); /* ISSUE 51: ANSI support, though I think this might never be false. */

                fontTag.WriteBit(true);  /* ISSUE 52: We always write wide offsets. This is because we're too lazy to measure our table. */
                fontTag.WriteBit(true);  /* Spec says must be true. */

                fontTag.WriteBit(font.IsItalic);
                fontTag.WriteBit(font.IsBold);

                fontTag.WriteUI8((uint)font.LanguageCode);

                fontTag.WriteString(font.Name, true);

                fontTag.WriteUI16((uint)font.GlyphCount);

                byte[][] shapeData       = new byte[font.GlyphCount][];
                int      totalShapeBytes = 0;
                for (int i = 0; i < font.GlyphCount; i++)
                {
                    Tag format;
                    shapeData[i] = ShapeWriter.ShapeToBytes(font.GetGlyphShape(codes[i]), out format);

                    if (format != Tag.DefineFont3)
                    {
                        throw new SWFModellerException(SWFModellerError.Internal, "Can't write non-font shapes as glyphs");
                    }

                    totalShapeBytes += shapeData[i].Length;
                }

                int startOffset = font.GlyphCount * 4 + 4; /* 4 bytes per offset (wide offsets) + 4 for the code table offset */
                int nextOffset  = startOffset;
                foreach (byte[] shapeBytes in shapeData)
                {
                    fontTag.WriteUI32((uint)nextOffset);
                    nextOffset += shapeBytes.Length;
                }

                fontTag.WriteUI32((uint)(startOffset + totalShapeBytes));

                foreach (byte[] shapeBytes in shapeData)
                {
                    fontTag.WriteBytes(shapeBytes);
                }

                foreach (char code in codes)
                {
                    fontTag.WriteUI16((uint)code);
                }

                if (font.HasLayout)
                {
                    fontTag.WriteSI16(font.Ascent.Value);
                    fontTag.WriteSI16(font.Descent.Value);
                    fontTag.WriteSI16(font.Leading.Value);

                    Rect[] bounds    = new Rect[font.GlyphCount];
                    int    boundsPos = 0;
                    foreach (char c in codes)
                    {
                        GlyphLayout gl = font.GetLayout(c);
                        fontTag.WriteSI16(gl.Advance);
                        bounds[boundsPos++] = gl.Bounds;
                    }

                    foreach (Rect bound in bounds)
                    {
                        fontTag.WriteRect(bound);
                        fontTag.Align8();
                    }

                    fontTag.WriteUI16((uint)font.KerningTable.Length);
                    foreach (KerningPair kern in font.KerningTable)
                    {
                        fontTag.WriteUI16(kern.LeftChar);
                        fontTag.WriteUI16(kern.RightChar);
                        fontTag.WriteSI16(kern.Adjustment);
                    }
                }
            }

            this.CloseTag();

            if (font.HasPixelAlignment)
            {
                WriteBuffer zonesTag = this.OpenTag(Tag.DefineFontAlignZones, font.Name + "; id=" + fid);

                zonesTag.WriteUI16((uint)fid);

                if (font.ThicknessHint == null)
                {
                    throw new SWFModellerException(SWFModellerError.Internal, "Can't have pixel aligmnent without a font thickness hint.");
                }

                zonesTag.WriteUBits((uint)font.ThicknessHint, 2);
                zonesTag.WriteUBits(0, 6); /* Reserved */

                foreach (char c in codes)
                {
                    PixelAlignment pa = font.GetPixelAligment(c);

                    if (pa.ZoneInfo.Length != 2)
                    {
                        throw new SWFModellerException(SWFModellerError.Internal, "Pixel aligment should always have 2 zones.");
                    }

                    zonesTag.WriteUI8((uint)pa.ZoneInfo.Length);

                    foreach (PixelAlignment.ZoneData zi in pa.ZoneInfo)
                    {
                        /* These int values are just unparsed 16-bit floats. */
                        zonesTag.WriteUI16((uint)zi.AlignmentCoord);
                        zonesTag.WriteUI16((uint)zi.Range);
                    }

                    zonesTag.WriteUBits(0, 6); /* Reserved */
                    zonesTag.WriteBit(pa.HasY);
                    zonesTag.WriteBit(pa.HasX);
                }

                this.CloseTag();
            }

            if (font.HasExtraNameInfo)
            {
                WriteBuffer nameTag = this.OpenTag(Tag.DefineFontName, font.FullName + "; id=" + fid);

                nameTag.WriteUI16((uint)fid);
                nameTag.WriteString(font.FullName);
                nameTag.WriteString(font.Copyright);

                this.CloseTag();
            }
        }
Exemple #3
0
        /// <param name="fontID">Pass -1 if this has no font.</param>
        private void WriteEditText(EditText text, int fontID)
        {
            int cid = characterMarshal.GetIDFor(text);

            WriteBuffer textTag = this.OpenTag(Tag.DefineEditText, "; id=" + cid);

            /* Tag.DefineEditText */
            {
                textTag.WriteUI16((uint)cid);

                textTag.WriteRect(text.Bounds);
                textTag.Align8();

                textTag.WriteBit(text.HasText);
                textTag.WriteBit(text.WordWrapEnabled);
                textTag.WriteBit(text.IsMultiline);
                textTag.WriteBit(text.IsPassword);
                textTag.WriteBit(text.IsReadOnly);
                textTag.WriteBit(text.HasTextColor);
                textTag.WriteBit(text.HasMaxLength);
                textTag.WriteBit(text.HasFont);
                textTag.WriteBit(text.HasFontClass);
                textTag.WriteBit(text.IsAutoSized);
                textTag.WriteBit(text.HasLayout);
                textTag.WriteBit(text.IsNonSelectable);
                textTag.WriteBit(text.HasBorder);
                textTag.WriteBit(text.IsStatic);
                textTag.WriteBit(text.IsHTML);
                textTag.WriteBit(text.UseOutlines);

                if (text.HasFont)
                {
                    textTag.WriteUI16((uint)fontID);
                }

                if (text.HasFontClass)
                {
                    /* ISSUE 14 */
                    throw new SWFModellerException(SWFModellerError.UnimplementedFeature, "Font classes can't be written.");
                }

                if (text.HasFont)
                {
                    textTag.WriteUI16((uint)text.FontHeight);
                }

                if (text.HasTextColor)
                {
                    textTag.WriteRGBA(text.Color.ToArgb());
                }

                if (text.HasMaxLength)
                {
                    textTag.WriteUI16((uint)text.MaxLength.Value);
                }

                if (text.HasLayout)
                {
                    EditText.Layout layout = text.LayoutInfo;

                    textTag.WriteUI8((uint)layout.Align);
                    textTag.WriteUI16((uint)layout.LeftMargin);
                    textTag.WriteUI16((uint)layout.RightMargin);
                    textTag.WriteUI16((uint)layout.Indent);
                    textTag.WriteSI16(layout.Leading);
                }

                textTag.WriteString(text.VarName);

                if (text.HasText)
                {
                    textTag.WriteString(text.Text);
                }
            }

            CloseTag();
        }
Exemple #4
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();
        }