public static void Crop(Glyph glyph) { // Crop the top. while ((glyph.Subrect.Height > 1) && BitmapUtils.IsAlphaEntirely(0, glyph.Bitmap, new System.Drawing.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 System.Drawing.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 System.Drawing.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 System.Drawing.Rectangle(glyph.Subrect.Right - 1, glyph.Subrect.Y, 1, glyph.Subrect.Height))) { glyph.Subrect.Width--; glyph.XAdvance++; } }
public static BitmapContent ArrangeGlyphs(Glyph[] sourceGlyphs, bool requirePOT, bool requireSquare) { // Build up a list of all the glyphs needing to be arranged. var glyphs = new List<ArrangedGlyph>(); for (int i = 0; i < sourceGlyphs.Length; i++) { var 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++) { PositionGlyph(glyphs, i, outputWidth); outputHeight = Math.Max(outputHeight, glyphs[i].Y + glyphs[i].Height); } // Create the merged output bitmap. outputHeight = MakeValidTextureSize(outputHeight, requirePOT); if (requireSquare) { outputHeight = Math.Max (outputWidth, outputHeight); outputWidth = outputHeight; } return CopyGlyphsToOutput(glyphs, outputWidth, outputHeight); }
// 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.Bitmap.Width); totalSize += glyph.Bitmap.Width * glyph.Bitmap.Height; } int width = Math.Max((int)Math.Sqrt(totalSize), maxWidth); return MakeValidTextureSize(width, true); }