public void FontProc(FontProcessor fd) { /* If you like delegate methods, you'll love this. */ foreach (Frame f in FrameList) { foreach (IDisplayListItem dl in f.DisplayList) { if (dl is ICharacterReference) { ICharacter ch = ((ICharacterReference)dl).Character; if (ch is IFontUserProcessor) { IFontUserProcessor fup = (IFontUserProcessor)ch; fup.FontUserProc(delegate(IFontUser fu) { if (fu.HasFont) { fd(fu.Font); } }); } if (ch is Timeline) { /* ISSUE 69: Is there any risk of infinite recursion here? Possible pass in a set * of visited objects, timelines and fonts. */ ((Timeline)ch).FontProc(fd); } } } } }
private void WriteCharacter(ICharacter ch, ListSet <Timeline> unboundClasses) { int cid; if (ch == null) { return; } if (this.characterMarshal.HasMarshalled(ch)) { return; } int fontID = -1; if (ch is IFontUserProcessor) { IFontUserProcessor fup = (IFontUserProcessor)ch; fup.FontUserProc(delegate(IFontUser fu) { if (fu.HasFont && !characterMarshal.HasMarshalled(fu.Font)) { fontID = characterMarshal.GetIDFor(fu.Font); this.WriteFont(fu.Font, fontID); } else { fontID = characterMarshal.GetExistingIDFor(fu.Font); } }); } if (ch is IShape) { IImage[] images = ((IShape)ch).GetImages(); if (images != null) { foreach (IImage image in images) { this.WriteImage(image); } } Tag format; byte[] shapeBytes = ShapeWriter.ShapeToBytes((IShape)ch, out format); WriteBuffer shapeTag = this.OpenTag(format); cid = this.characterMarshal.GetIDFor(ch); shapeTag.WriteUI16((uint)cid); shapeTag.WriteBytes(shapeBytes); #if DEBUG this.LogMessage("char id=" + cid); #endif this.CloseTag(); } else if (ch is Sprite) { this.WriteSprite((Sprite)ch, unboundClasses); } else if (ch is EditText) { this.WriteEditText((EditText)ch, fontID); } else if (ch is StaticText) { this.WriteStaticText((StaticText)ch); } else { /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Character of type " + ch.GetType().ToString() + " not currently supported in writer"); } if (ch is Timeline) { Timeline tl = (Timeline)ch; if (tl.HasClass && !(tl.Class is AdobeClass) && !unboundClasses.Contains(tl)) { unboundClasses.Add(tl); } } }
/// <summary> /// This will alter the incoming SWF's font references. Any new fonts will be /// left untouched. Any fonts that exist in root already will have their glyphs /// imported into the root SWF's fonts and references will re-point to the /// now possibly larger font. Any fonts that exist only in incoming will be left /// alone since importing the SWF as a movieclip will automatically make those /// fonts part of root. /// </summary> /// <param name="incoming">The SWF being absorbed into the root.</param> /// <param name="root">The root SWF that will absord new fonts or glyphs.</param> private void RemapFonts(SWF incoming, SWF root) { List <SWFFont> rootFonts = new List <SWFFont>(); root.FontProc(delegate(SWFFont font) { rootFonts.Add(font); }); Dictionary <SWFFont, SWFFont> remaps = new Dictionary <SWFFont, SWFFont>(); incoming.FontProc(delegate(SWFFont font) { foreach (SWFFont rootFont in rootFonts) { if (font.CanMergeWith(rootFont)) { remaps.Add(font, rootFont); char[] codes = font.CodePoints; foreach (char c in codes) { bool hasPixelAlignment = font.HasPixelAlignment; bool hasLayout = font.HasLayout; if (!rootFont.HasGlyph(c)) { rootFont.AddGlyph(c, font.GetGlyphShape(c)); if (hasPixelAlignment) { rootFont.AddPixelAlignment(c, font.GetPixelAligment(c)); } if (hasLayout) { rootFont.AddLayout(c, font.GetLayout(c)); } } } } } }); /* Now we've merged glyphs into our target fonts, we need to go over all * uses of the old fonts and remap them... */ incoming.CharacterProc(delegate(ICharacter ch) { if (ch is IFontUserProcessor) { IFontUserProcessor fup = (IFontUserProcessor)ch; fup.FontUserProc(delegate(IFontUser fu) { if (fu.HasFont && remaps.ContainsKey(fu.Font)) { fu.Font = remaps[fu.Font]; } }); } }); }