private void WriteStaticText(StaticText text) { int cid = characterMarshal.GetIDFor(text); bool hasAlpha = text.HasAlpha; WriteBuffer textTag = this.OpenTag(hasAlpha ? Tag.DefineText2 : Tag.DefineText, "; id=" + cid); /* Tag.DefineText(2) */ { textTag.WriteUI16((uint)cid); textTag.WriteRect(text.Bounds); textTag.Align8(); textTag.WriteMatrix(text.Position); textTag.Align8(); /* ISSUE 49: We're lazy here. We max out the bits for text and advances coz we can't * yet calculate them. Fix this attrocity. */ int glyphBits = 16; int advanceBits = 16; textTag.WriteUI8((uint)glyphBits); textTag.WriteUI8((uint)advanceBits); foreach (TextRecord tr in text.Records) { Dictionary <char, int> glyphIDX = null; uint flags = 0x80; if (tr.HasFont) { flags |= 0x08; } if (tr.HasColour) { flags |= 0x04; } if (tr.HasYOffset) { flags |= 0x02; } if (tr.HasXOffset) { flags |= 0x01; } textTag.WriteUI8(flags); if (tr.HasFont) { textTag.WriteUI16((uint)this.characterMarshal.GetExistingIDFor(tr.Font)); } if (tr.HasColour) { if (hasAlpha) { textTag.WriteRGBA(tr.Colour.ToArgb()); } else { textTag.WriteRGB(tr.Colour.ToArgb()); } } if (tr.HasXOffset) { textTag.WriteSI16(tr.XOffset); } if (tr.HasYOffset) { textTag.WriteSI16(tr.YOffset); } if (tr.HasFont) { textTag.WriteUI16((uint)tr.FontHeight); glyphIDX = tr.Font.IndexMap; } char[] chars = tr.Text.ToCharArray(); if (chars.Length > 255) { throw new SWFModellerException(SWFModellerError.Internal, "String too long. This should be split across text records."); } textTag.WriteUI8((uint)chars.Length); for (int i = 0; i < tr.Advances.Length; i++) { textTag.WriteUBits((uint)glyphIDX[chars[i]], glyphBits); textTag.WriteSBits(tr.Advances[i], advanceBits); } textTag.Align8(); } textTag.WriteUI8(0); /* End record */ } /* End of tag code. */ this.CloseTag(); }
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(); }