// Imports the source font associated to the given command line options. public void Import(CommandLineOptions options) { if (options == null) { throw new NullReferenceException("The given command line options may not be equal to null."); } // Load the source bitmap. Bitmap bitmap; try { bitmap = new Bitmap(options.SourceFont); } catch { throw new Exception(string.Format("Unable to load '{0}'.", options.SourceFont)); } // Convert to our desired pixel format. bitmap = BitmapUtils.ConvertToPixelFormat(bitmap, PixelFormat.Format32bppArgb); // What characters are included in this font? var characters = CharacterRegion.Flatten(options.CharacterRegions).ToArray(); int characterIndex = 0; char currentCharacter = '\0'; // Split the source image into a list of individual glyphs. var glyphList = new List <Glyph>(); Glyphs = glyphList; LineSpacing = 0; foreach (Rectangle region in BitmapUtils.GetGlyphRegions(bitmap, IsMarkerColor)) { if (characterIndex < characters.Length) { currentCharacter = characters[characterIndex]; } ++currentCharacter; glyphList.Add(new Glyph(currentCharacter, bitmap, region)); LineSpacing = Math.Max(LineSpacing, region.Height); } // If the bitmap doesn't already have an alpha channel, create one now. if (BitmapUtils.MatchesAlpha(255, bitmap)) { BitmapUtils.ConvertGreyToAlpha(bitmap); } }
// Rasterizes a single character glyph. static Glyph ImportGlyph(char character, Font font, Brush brush, StringFormat stringFormat, Bitmap bitmap, Graphics graphics) { string characterString = character.ToString(); // Measure the size of this character. SizeF size = graphics.MeasureString(characterString, font, Point.Empty, stringFormat); int characterWidth = (int)Math.Ceiling(size.Width); int characterHeight = (int)Math.Ceiling(size.Height); // Pad to make sure we capture any overhangs (negative ABC spacing, etc.) int padWidth = characterWidth; int padHeight = characterHeight / 2; int bitmapWidth = characterWidth + padWidth * 2; int bitmapHeight = characterHeight + padHeight * 2; if (bitmapWidth > MaxGlyphSize || bitmapHeight > MaxGlyphSize) { throw new Exception("Excessively large glyph won't fit in my lazily implemented fixed size temp surface."); } // Render the character. graphics.Clear(Color.Black); graphics.DrawString(characterString, font, brush, padWidth, padHeight, stringFormat); graphics.Flush(); // Clone the newly rendered image. Bitmap glyphBitmap = bitmap.Clone(new Rectangle(0, 0, bitmapWidth, bitmapHeight), PixelFormat.Format32bppArgb); BitmapUtils.ConvertGreyToAlpha(glyphBitmap); // Query its ABC spacing. float?abc = GetCharacterWidth(character, font, graphics); // Construct the output Glyph object. return(new Glyph(character, glyphBitmap) { OffsetX = -padWidth, AdvanceX = abc.HasValue ? padWidth - bitmapWidth + abc.Value : -padWidth, OffsetY = -padHeight, }); }