public static CharacterLayout[] LayoutCharacters( RuntimeFont font, string str, int startX, int startY ) { CharacterLayout[] layout = new CharacterLayout[ str.Length ]; int curX = startX; int curY = startY; for ( int i=0; i < str.Length; i++ ) { int whichCharacter = font.FindCharacter( str[i] ); if ( whichCharacter == -1 ) continue; layout[i].SudoFontIndex = whichCharacter; layout[i].XOffset = (int)( curX + font.Characters[whichCharacter].XOffset * font.RuntimeScale ); layout[i].YOffset = (int)( curY + font.Characters[whichCharacter].YOffset * font.RuntimeScale ); float totalXAdvance = font.Characters[whichCharacter].XAdvance * font.RuntimeScale; if ( i+1 < str.Length ) totalXAdvance += font.Characters[whichCharacter].GetKerning( str[i+1] ) * font.RuntimeScale; curX += (int)Math.Ceiling( totalXAdvance ); } return layout; }
public static Bitmap CreateBitmapFromString( RuntimeFont font, Bitmap pngBitmap, string testString, int startX, int startY, IFont comparisonFont=null ) { // Get the character positions. FontLayout.CharacterLayout[] layouts = FontLayout.LayoutCharacters( font, testString, 0, 0 ); // Draw the character. int extraLineSpacing = 5; int width = 1; int height = 1; if ( layouts.Length > 0 ) { width = layouts[ layouts.Length - 1 ].XOffset + font.LineHeight * 2; height = layouts[ layouts.Length - 1 ].YOffset + font.LineHeight; } if ( comparisonFont != null ) { height += font.LineHeight + extraLineSpacing; } Color textColor = Color.White; Bitmap bitmap = new Bitmap( width, height, PixelFormat.Format32bppArgb ); using ( Graphics g = Graphics.FromImage( bitmap ) ) { g.Clear( Color.Transparent ); foreach ( FontLayout.CharacterLayout layout in layouts ) { int sfi = layout.SudoFontIndex; Rectangle srcRect = new Rectangle( font.Characters[sfi].PackedX, font.Characters[sfi].PackedY, font.Characters[sfi].PackedWidth, font.Characters[sfi].PackedHeight ); Rectangle destRect = new Rectangle( layout.XOffset, layout.YOffset, srcRect.Width, srcRect.Height ); g.DrawImage( pngBitmap, destRect, srcRect, GraphicsUnit.Pixel ); } int curY = startY + font.LineHeight + extraLineSpacing; if ( comparisonFont != null ) { comparisonFont.DrawString( g, testString, new SolidBrush( textColor ), new Point( 0, curY ) ); curY += font.LineHeight + extraLineSpacing; } } return bitmap; }
public static int MeasureStringWidth( RuntimeFont font, string str ) { int width = 0; for ( int i=0; i < str.Length; i++ ) { Char ch = str[i]; int ic = font.FindCharacter( ch ); if ( ic != -1 ) { float totalXAdvance = font.Characters[ic].XAdvance * font.RuntimeScale; if ( i < str.Length-1 ) totalXAdvance += font.Characters[ic].GetKerning( str[i+1] ) * font.RuntimeScale; width += (int)Math.Ceiling( totalXAdvance ); } } return width; }
// This is a test that creates a bitmap using a SudoFont. // This can be used as reference for code that uses SudoFonts to rasterize text. // If you set comparisonFont, it'll render the same string into the bitmap under the SudoFont output. // This is useful for verifying/checking how close SudoFonts compare to .NET Graphics text output. public static Bitmap CreateBitmapFromString( string fontFilename, string testString, int startX, int startY, IFont comparisonFont=null ) { try { // Open the font file. using ( BinaryReader reader = new BinaryReader( File.OpenRead( fontFilename ) ) ) { // Load the font. RuntimeFont font = new RuntimeFont(); if ( !font.Load( reader ) ) return null; // Load the associated PNG file. Bitmap pngBitmap = new Bitmap( Path.ChangeExtension( fontFilename, null ) + "-texture.png" ); return CreateBitmapFromString( font, pngBitmap, testString, startX, startY, comparisonFont ); } } catch ( Exception ) { return null; } }
private void openMenuItem_Click( object sender, EventArgs e ) { OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = Environment.CurrentDirectory; dlg.Filter = "Font Files (*.sfn)|*.sfn|All files (*.*)|*.*" ; dlg.FilterIndex = 0; dlg.InitialDirectory = _dialogsInitialDirectory; if ( dlg.ShowDialog() == DialogResult.OK ) { _dialogsInitialDirectory = Path.GetDirectoryName( dlg.FileName ); try { // First, load the SudoFont. RuntimeFont loadedFont = new RuntimeFont(); using ( Stream stream = File.OpenRead( dlg.FileName ) ) { if ( !loadedFont.Load( new BinaryReader( stream ), keepConfigBlock: true ) ) MessageBox.Show( "Invalid font" ); // Then read the configuration out of it. MemoryStream configBlock = loadedFont.ConfigurationBlockStream; if ( ReadConfigurationFromStream( configBlock ) ) _prevFontFilename = dlg.FileName; else MessageBox.Show( "Unable to read configuration block" ); UpdateColorDisplays(); Recalculate(); } ClearDirtyFlag(); } catch ( Exception ) { MessageBox.Show( "Error loading font" ); } } }
// Update _fontPreviewBitmap void BuildFontPreviewBitmap() { // Save the font. Stream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter( stream ); WriteFontFileDataToStream( writer, _packedImage.Width, _packedImage.Height ); stream.Position = 0; // Load in the RuntimeFont. BinaryReader reader = new BinaryReader( stream ); RuntimeFont runtimeFont = new RuntimeFont(); runtimeFont.Load( reader ); // Draw the lines.. _fontPreviewBitmap = SudoFontTest.CreateBitmapFromString( runtimeFont, _packedImage, _currentPreviewText, 0, 0 ); UpdateAlphaPreviewWindow(); }