static byte[] PackCharacters(CharacterGlyph[] characters, int lineSpace, out int bitmapWidth, out int bitmapHeight) { var offsetX = 0u; var offsetY = 0u; bitmapWidth = 0; bitmapHeight = characters.Max(x => x.Bitmap.Height); int currentRowWidth = 0; for (int i = 0; i < characters.Length; i++) { currentRowWidth += characters[i].Bitmap.Width; if (currentRowWidth > kMaxFontWidth) { currentRowWidth = characters[i].Bitmap.Width; bitmapHeight += lineSpace; } if (currentRowWidth > bitmapWidth) { bitmapWidth = currentRowWidth; } } var bitmap = new byte[4 * bitmapHeight * bitmapWidth]; for (int i = 0; i < characters.Length; i++) { var sourceBitmap = characters[i].Bitmap; var sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); if (offsetX + (uint)characters[i].Bitmap.Width > kMaxFontWidth) { offsetX = 0; offsetY += (uint)lineSpace; } var offset = offsetY * bitmapWidth + offsetX; for (int u = 0; u < sourceBitmap.Height; u++) { unsafe { var sourceLine = (byte*)sourceBitmapData.Scan0.ToPointer() + sourceBitmapData.Stride * u; for (int v = 0; v < 4 * sourceBitmap.Width; v++) { bitmap[4 * u * bitmapWidth + v + 4 * offset] = *sourceLine; sourceLine++; } } } characters[i].Bitmap.UnlockBits(sourceBitmapData); characters[i].XOffset = offsetX; characters[i].YOffset = offsetY; offsetX += (uint)characters[i].Bitmap.Width; } GrayToAlpha(bitmap); //SaveAsBitmap(bitmapWidth, bitmapHeight, bitmap); return bitmap; }
// Binary format: // 4 bytes - bitmap width // 4 bytes - bitmap height // * - bitmap data // 4 bytes - number of characters // 1 byte - character // 4 bytes - xOffset // 4 bytes - yOffset // 4 bytes - characterWidth // 4 bytes - characterHeight // 4 bytes - font line spacing private static void SaveFont(CharacterGlyph[] characters, float lineSpace, int bitmapWidth, int bitmapHeight, byte[] bitmapData, string outputPath) { using (var fileStream = new FileStream(outputPath, FileMode.Create)) { using (var writer = new BinaryWriter(fileStream)) { writer.Write(bitmapWidth); writer.Write(bitmapHeight); writer.Write(bitmapData); writer.Write(characters.Length); foreach (var character in characters) { writer.Write((byte)character.Character); writer.Write(character.XOffset); writer.Write(character.YOffset); writer.Write(character.CharacterWidth); writer.Write(character.CharacterHeight); } writer.Write((uint)lineSpace); } } }
private static CharacterGlyph[] ImportFont(Font font, Bitmap stagingBitmap, Graphics stagingGraphics) { var characters = new CharacterGlyph[characterRangeTo - characterRangeFrom]; for (int i = characterRangeFrom; i < characterRangeTo; i++) { characters[i - characterRangeFrom] = ImportCharacter((char)i, font, stagingBitmap, stagingGraphics); } return characters; }