public void GetGlyphKerningInfo( GlyphInfo glyph ) { if( !FontContainsChar( glyph.Character ) ) { glyph.ABCKernLeading = 0; glyph.ABCKernWidth = glyph.Size.Width; glyph.ABCKernTrailing = 0; return; } ABCFloat abc; GetCharABCWidthsFloatW( dc, (uint)glyph.Character, (uint)glyph.Character, out abc ); glyph.ABCKernLeading = abc.A; glyph.ABCKernWidth = abc.B; glyph.ABCKernTrailing = abc.C; }
public void WriteData(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } int[] kernMap = new int[glyphs.Count]; List <KeyValuePair <char, int> > allKernings = new List <KeyValuePair <char, int> >(); for (int i = 0; i < glyphs.Count; i++) { if (glyphs[i].Kernings.Count == 0) { kernMap[i] = -1; continue; } kernMap[i] = allKernings.Count; allKernings.AddRange(glyphs[i].Kernings); } BinaryWriter writer = new BinaryWriter(stream); writer.Write(FontIdent); writer.Write(FontVersion); writer.Write(fontName.Length); for (int i = 0; i < fontName.Length; i++) { writer.Write((int)fontName[i]); } writer.Write((int)style); writer.Write(size); writer.Write(lineHeight); writer.Write((int)glyphs.Count); writer.Write((int)sheets.Count); writer.Write((int)allKernings.Count); for (int i = 0; i < glyphs.Count; i++) { GlyphInfo g = glyphs[i]; writer.Write((int)g.Character); } for (int i = 0; i < glyphs.Count; i++) { GlyphInfo g = glyphs[i]; writer.Write(sheets.IndexOf(g.Sheet)); writer.Write(g.Size.Width); writer.Write(g.Size.Height); writer.Write(g.GlyphOffset.X); writer.Write(g.GlyphOffset.Y); writer.Write(g.SheetRectangle.X); writer.Write(g.SheetRectangle.Y); writer.Write(g.SheetRectangle.Width); writer.Write(g.SheetRectangle.Height); writer.Write(g.ABCKernLeading); writer.Write(g.ABCKernWidth); writer.Write(g.ABCKernTrailing); writer.Write(kernMap[i]); writer.Write(g.Kernings.Count); writer.Write(glyphs.IndexOf(g.SmallCap)); } for (int i = 0; i < allKernings.Count; i++) { writer.Write((int)allKernings[i].Key); writer.Write(allKernings[i].Value); } for (int i = 0; i < sheets.Count; i++) { writer.Write(sheets[i].SheetDataSize.Width); writer.Write(sheets[i].SheetDataSize.Height); for (int y = 0; y < sheets[i].SheetDataSize.Height; y++) { writer.Write(sheets[i].SheetData[y], 0, sheets[i].SheetDataSize.Width); } } writer.Flush(); }
private List <GlyphSheet> LayoutSheets(Queue <GlyphInfo> glyphs) { List <GlyphSheet> ret = new List <GlyphSheet>(); //ToDo: sort? while (glyphs.Count != 0) { GlyphSheet currSheet = new GlyphSheet(imageSize); int y; for (y = 0; glyphs.Count != 0 && y < imageSize.Height;) { int availY = imageSize.Height - y; int maxY = 0; for (int x = 0; glyphs.Count != 0 && x < imageSize.Width;) { GlyphInfo glyph = glyphs.Peek(); //see if we have room to add anything height-wise if (glyph.GlyphDataSize.Height > availY) { //no, break out break; } //find out where we'll be int newX = x + glyph.GlyphDataSize.Width; if (newX > imageSize.Width) { //no room, break on to the next room break; } //don't let the next row stomp on this if (glyph.GlyphDataSize.Height > maxY) { maxY = glyph.GlyphDataSize.Height; } glyph.Sheet = currSheet; glyph.SheetRectangle = new Rectangle(x, y, glyph.GlyphDataSize.Width, glyph.GlyphDataSize.Height); currSheet.Glyphs.Add(glyph); //advance to the next character glyphs.Dequeue(); x = newX + padding; } y += maxY + padding; } if (y == 0) { continue; } //see if we can cut off the bottom of the image if (y < currSheet.SheetDataSize.Height / 2) { int targetH = currSheet.SheetDataSize.Height / 2; while (y < targetH / 2) { targetH /= 2; } GlyphSheet newSheet = new GlyphSheet(new Size(currSheet.SheetDataSize.Width, targetH)); newSheet.Glyphs.AddRange(currSheet.Glyphs); foreach (GlyphInfo glyph in newSheet.Glyphs) { glyph.Sheet = newSheet; } currSheet = newSheet; } ret.Add(currSheet); } return(ret); }