void FontGen::Go() { // Starts genereting the font stuff PrepareFont(); PrepareBitmap(); PrepareHeader(); DrawFont(); if (!cppFormat) { SaveTarga(); SaveFontdef(); } else { SaveCpp(); } }
//----------------------------------------------------------------------------- // The font class constructor //----------------------------------------------------------------------------- Font::Font( char *name, short size, unsigned long bold, bool italic ) { HBITMAP bitmap = NULL; HGDIOBJ oldBitmap = NULL; HFONT oldFont = NULL; BYTE *dstRow = NULL; unsigned long x, y; HDC hDC = CreateCompatibleDC( NULL ); SetMapMode( hDC, MM_TEXT ); // Create the font. char height = -MulDiv( size, GetDeviceCaps( hDC, LOGPIXELSY ), 72 ); HFONT font = CreateFontA( height, 0, 0, 0, bold, italic, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, name ); if( font == NULL ) goto End; oldFont = (HFONT)SelectObject( hDC, font ); // Find the dimensions of the smallest texture to hold the characters. m_textureWidth = m_textureHeight = 128; while( !PrepareFont( hDC, true ) ) { m_textureWidth *= 2; m_textureHeight *= 2; } // Create a new texture for the font if( FAILED( g_engine->GetDevice()->CreateTexture( m_textureWidth, m_textureHeight, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &m_texture, NULL ) ) ) goto End; // Prepare the bitmap. unsigned long *bitmapBits; BITMAPINFO bmi; ZeroMemory( &bmi.bmiHeader, sizeof( BITMAPINFOHEADER ) ); bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); bmi.bmiHeader.biWidth = (int)m_textureWidth; bmi.bmiHeader.biHeight = -(int)m_textureHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a bitmap for the font. bitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (void**)&bitmapBits, NULL, 0 ); oldBitmap = SelectObject( hDC, bitmap ); // Set the text properties. SetTextColor( hDC, RGB( 255,255,255 ) ); SetBkColor( hDC, 0x00000000 ); SetTextAlign( hDC, TA_TOP ); // Prepare the font by drawing the characters onto the bitmap. if( !PrepareFont( hDC ) ) goto End; // Lock the surface and write the alpha values for the set pixels. D3DLOCKED_RECT d3dlr; m_texture->LockRect( 0, &d3dlr, 0, 0 ); dstRow = (BYTE*)d3dlr.pBits; WORD *dst16; BYTE alpha; for( y = 0; y < m_textureHeight; y++ ) { dst16 = (WORD*)dstRow; for( x = 0; x < m_textureWidth; x++ ) { alpha = (BYTE)( ( bitmapBits[m_textureWidth*y + x] & 0xff ) >> 4 ); if( alpha > 0 ) *dst16++ = (WORD)( ( alpha << 12 ) | 0x0fff ); else *dst16++ = 0x0000; } dstRow += d3dlr.Pitch; } // Create the vertex buffer for the characters. g_engine->GetDevice()->CreateVertexBuffer( 1020 * sizeof( TLVertex ), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_vb, NULL ); // Prepare the alpha testing for rendering the characters. g_engine->GetDevice()->SetRenderState( D3DRS_ALPHAREF, 0x08 ); g_engine->GetDevice()->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); // Create a state block for capturing the volatile render states. g_engine->GetDevice()->BeginStateBlock(); g_engine->GetDevice()->SetRenderState( D3DRS_LIGHTING, false ); g_engine->GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, false ); g_engine->GetDevice()->SetRenderState( D3DRS_FOGENABLE, false ); g_engine->GetDevice()->EndStateBlock( &m_states ); // Clean up and return. End: if( m_texture ) m_texture->UnlockRect( 0 ); SelectObject( hDC, oldBitmap ); SelectObject( hDC, oldFont ); DeleteObject( bitmap ); DeleteObject( font ); DeleteDC( hDC ); }