public static void Crop(Glyph glyph) { // Crop the top. while ((glyph.Subrect.Height > 1) && BitmapUtils.IsAlphaEntirely(0, glyph.Bitmap, new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, 1))) { glyph.Subrect.Y++; glyph.Subrect.Height--; glyph.YOffset++; } // Crop the bottom. while ((glyph.Subrect.Height > 1) && BitmapUtils.IsAlphaEntirely(0, glyph.Bitmap, new Rectangle(glyph.Subrect.X, glyph.Subrect.Bottom - 1, glyph.Subrect.Width, 1))) { glyph.Subrect.Height--; } // Crop the left. while ((glyph.Subrect.Width > 1) && BitmapUtils.IsAlphaEntirely(0, glyph.Bitmap, new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, 1, glyph.Subrect.Height))) { glyph.Subrect.X++; glyph.Subrect.Width--; glyph.XOffset++; } // Crop the right. while ((glyph.Subrect.Width > 1) && BitmapUtils.IsAlphaEntirely(0, glyph.Bitmap, new Rectangle(glyph.Subrect.Right - 1, glyph.Subrect.Y, 1, glyph.Subrect.Height))) { glyph.Subrect.Width--; glyph.XAdvance++; } }
public static Bitmap ArrangeGlyphsFast(Glyph[] sourceGlyphs) { // Build up a list of all the glyphs needing to be arranged. List<ArrangedGlyph> glyphs = new List<ArrangedGlyph>(); int largestWidth = 1; int largestHeight = 1; for (int i = 0; i < sourceGlyphs.Length; i++) { ArrangedGlyph glyph = new ArrangedGlyph(); glyph.Source = sourceGlyphs[i]; // Leave a one pixel border around every glyph in the output bitmap. glyph.Width = sourceGlyphs[i].Subrect.Width + 2; glyph.Height = sourceGlyphs[i].Subrect.Height + 2; if (glyph.Width > largestWidth) largestWidth = glyph.Width; if (glyph.Height > largestHeight) largestHeight = glyph.Height; glyphs.Add(glyph); } // Work out how big the output bitmap should be. int outputWidth = GuessOutputWidth(sourceGlyphs); // Place each glyph in a grid based on the largest glyph size int curx = 0; int cury = 0; for (int i = 0; i < glyphs.Count; i++) { glyphs[i].X = curx; glyphs[i].Y = cury; curx += largestWidth; if (curx + largestWidth > outputWidth) { curx = 0; cury += largestHeight; } } // Create the merged output bitmap. int outputHeight = MakeValidTextureSize(cury + largestHeight, false); return CopyGlyphsToOutput(glyphs, outputWidth, outputHeight); }
public static void WriteSpriteFont(CommandLineOptions options, Glyph[] glyphs, float lineSpacing, Bitmap bitmap) { using (FileStream file = File.OpenWrite(options.OutputFile)) using (BinaryWriter writer = new BinaryWriter(file)) { WriteMagic(writer); WriteGlyphs(writer, glyphs); writer.Write(lineSpacing); writer.Write(options.DefaultCharacter); WriteBitmap(writer, options, bitmap); } }
public static Bitmap ArrangeGlyphs(Glyph[] sourceGlyphs) { // Build up a list of all the glyphs needing to be arranged. List<ArrangedGlyph> glyphs = new List<ArrangedGlyph>(); for (int i = 0; i < sourceGlyphs.Length; i++) { ArrangedGlyph glyph = new ArrangedGlyph(); glyph.Source = sourceGlyphs[i]; // Leave a one pixel border around every glyph in the output bitmap. glyph.Width = sourceGlyphs[i].Subrect.Width + 2; glyph.Height = sourceGlyphs[i].Subrect.Height + 2; glyphs.Add(glyph); } // Sort so the largest glyphs get arranged first. glyphs.Sort(CompareGlyphSizes); // Work out how big the output bitmap should be. int outputWidth = GuessOutputWidth(sourceGlyphs); int outputHeight = 0; // Choose positions for each glyph, one at a time. for (int i = 0; i < glyphs.Count; i++) { if (i > 0 && (i % 500) == 0) { Console.Write("."); } PositionGlyph(glyphs, i, outputWidth); outputHeight = Math.Max(outputHeight, glyphs[i].Y + glyphs[i].Height); } if (glyphs.Count >= 500) { Console.WriteLine(); } // Create the merged output bitmap. outputHeight = MakeValidTextureSize(outputHeight, false); return CopyGlyphsToOutput(glyphs, outputWidth, outputHeight); }
static void WriteGlyphs(BinaryWriter writer, Glyph[] glyphs) { writer.Write(glyphs.Length); foreach (Glyph glyph in glyphs) { writer.Write((int)glyph.Character); writer.Write(glyph.Subrect.Left); writer.Write(glyph.Subrect.Top); writer.Write(glyph.Subrect.Right); writer.Write(glyph.Subrect.Bottom); writer.Write(glyph.XOffset); writer.Write(glyph.YOffset); writer.Write(glyph.XAdvance); } }
// Heuristic guesses what might be a good output width for a list of glyphs. static int GuessOutputWidth(Glyph[] sourceGlyphs) { int maxWidth = 0; int totalSize = 0; foreach (Glyph glyph in sourceGlyphs) { maxWidth = Math.Max(maxWidth, glyph.Subrect.Width); totalSize += glyph.Subrect.Width * glyph.Subrect.Height; } int width = Math.Max((int)Math.Sqrt(totalSize), maxWidth); return MakeValidTextureSize(width, true); }