internal void AddLayout(char codepoint, GlyphLayout glyphLayout) { this.layouts.Add(codepoint, glyphLayout); }
internal void ToStringModelView(int nest, StringBuilder sb) { string indent = new string(' ', nest * 4); sb.Append(indent + "Font: '" + this.Name + "'\n"); sb.Append(indent + "{\n"); string indentPlus = indent + " "; sb.Append(indentPlus + "Bold: " + this.IsBold + ", Italic: " + this.IsItalic + ", Small: " + this.IsSmall + "\n"); sb.Append(indentPlus + "Language: " + this.LanguageCode.ToString() + "\n"); sb.Append(indentPlus + "Ascent: " + (this.Ascent == null ? "none" : this.Ascent.Value.ToString()) + "\n"); sb.Append(indentPlus + "Descent: " + (this.Descent == null ? "none" : this.Descent.Value.ToString()) + "\n"); sb.Append(indentPlus + "Leading: " + (this.Leading == null ? "none" : this.Leading.Value.ToString()) + "\n"); char[] codes = this.CodePoints; sb.Append(indentPlus + codes.Length + " glyphs:\n"); for (int i = 0; i < codes.Length; i++) { char c = codes[i]; IShape shape = glyphs[c]; sb.Append(indentPlus + "Glyph #" + (i + 1) + " '" + c + "' (U+" + String.Format("{0:X4}", (int)c) + "): " + shape.ToString() + "\n"); } if (this.HasExtraNameInfo) { sb.Append('\n'); sb.Append(indentPlus + "Font has extra name info...\n"); sb.Append(indentPlus + "FullName: " + this.FullName + "\n"); sb.Append(indentPlus + "Copyright: " + this.Copyright + "\n");; } if (this.HasLayout) { sb.Append('\n'); sb.Append(indentPlus + "Font has layout info...\n"); for (int i = 0; i < codes.Length; i++) { char c = codes[i]; GlyphLayout layout = this.layouts[c]; sb.Append(indentPlus + "Layout #" + (i + 1) + " '" + c + "' (U+" + String.Format("{0:X4}", (int)c) + "): " + layout.ToString() + "\n"); } } if (this.HasPixelAlignment) { sb.Append('\n'); sb.Append(indentPlus + "Font has pixel alignment info...\n"); sb.Append(indentPlus + "Thickness hint: " + this.ThicknessHint.ToString() + "\n"); for (int i = 0; i < codes.Length; i++) { char c = codes[i]; PixelAlignment alignment = this.pixelAlignment[c]; sb.Append(indentPlus + "PixelAlignment #" + (i + 1) + " '" + c + "' (U+" + String.Format("{0:X4}", (int)c) + "): " + alignment.ToString() + "\n"); } } if (this.KerningTable.Length > 0) { sb.Append('\n'); sb.Append(indentPlus + "Font has kerning table...\n"); foreach (KerningPair kp in this.KerningTable) { sb.Append(indentPlus + "Kern '" + kp.LeftChar + "' (U+" + String.Format("{0:X4}", (int)kp.LeftChar) + ") + " + kp.RightChar + "' (U+" + String.Format("{0:X4}", (int)kp.RightChar) + ") => " + kp.Adjustment + "\n"); } } sb.Append(indent + "}\n"); }
private void ReadFont(Tag fontType) { int fontID = this.sdtr.ReadUI16(); /* Bunch of flags */ bool hasLayout = this.sdtr.ReadBit(); bool isShiftJIS = this.sdtr.ReadBit(); bool isSmallText = this.sdtr.ReadBit(); bool isANSI = this.sdtr.ReadBit(); bool isWideOffsets = this.sdtr.ReadBit(); bool isWideCodes = this.sdtr.ReadBit(); bool isItalic = this.sdtr.ReadBit(); bool isBold = this.sdtr.ReadBit(); if (!isWideCodes) { throw new SWFModellerException(SWFModellerError.SWFParsing, "Non-wide codes in font encodings are not valid.", swf.Context); } if (isShiftJIS) { /* ISSUE 50 */ throw new SWFModellerException(SWFModellerError.UnimplementedFeature, "ShiftJIS character encoding is not supported.", swf.Context); } int language = this.sdtr.ReadUI8(); string name = this.sdtr.ReadLengthedUTF8(this.sdtr.ReadUI8()); int numGlyphs = this.sdtr.ReadUI16(); #if DEBUG this.Log("id=" + fontID + ", name=" + name); #endif SWFFont font = new SWFFont( (SWFFont.Language)language, name, isBold, isItalic, isSmallText, numGlyphs); int startOffset = (int)this.sdtr.Offset; /* The offset table measures from this point. */ int[] shapeOffsets = new int[numGlyphs]; for (int i = 0; i < numGlyphs; i++) { shapeOffsets[i] = isWideOffsets ? (int)this.sdtr.ReadUI32() : this.sdtr.ReadUI16(); } int codeTableOffset = isWideOffsets ? (int)this.sdtr.ReadUI32() : this.sdtr.ReadUI16(); IShape[] shapes = new IShape[numGlyphs]; for (int i = 0; i < numGlyphs; i++) { int shapeOffset = (int)sdtr.Offset - startOffset; if (shapeOffsets[i] != shapeOffset) { throw new SWFModellerException(SWFModellerError.SWFParsing, "Bad font data.", swf.Context); } int end = codeTableOffset; if (i < numGlyphs - 1) { end = shapeOffsets[i + 1]; } int len = end - shapeOffset; byte[] shapeData = this.sdtr.ReadByteBlock(len); shapes[i] = new ShapeParser().Parse(fontType, shapeData, this); } char[] codes = new char[numGlyphs]; for (int i = 0; i < numGlyphs; i++) { codes[i] = (char)this.sdtr.ReadUI16(); font.AddGlyph(codes[i], shapes[i]); } if (hasLayout) { font.Ascent = this.sdtr.ReadSI16(); font.Descent = this.sdtr.ReadSI16(); font.Leading = this.sdtr.ReadSI16(); GlyphLayout[] layouts = new GlyphLayout[numGlyphs]; for (int i = 0; i < numGlyphs; i++) { layouts[i] = new GlyphLayout() { Advance = this.sdtr.ReadSI16() }; } for (int i = 0; i < numGlyphs; i++) { layouts[i].Bounds = this.sdtr.ReadRect(); font.AddLayout(codes[i], layouts[i]); } int kerningCount = this.sdtr.ReadUI16(); KerningPair[] kernTable = new KerningPair[kerningCount]; for (int i = 0; i < kerningCount; i++) { kernTable[i] = new KerningPair() { LeftChar = (char)(isWideCodes ? this.sdtr.ReadUI16() : this.sdtr.ReadUI8()), RightChar = (char)(isWideCodes ? this.sdtr.ReadUI16() : this.sdtr.ReadUI8()), Adjustment = this.sdtr.ReadSI16() }; } font.KerningTable = kernTable; } fontDict.Add(fontID, font); swf.AddFont(font); }