Re: Get Bitmap From a Font
"Ian Semmel" <anyone@rocketcomp.com.au> wrote in message
news:eWA9svZfIHA.2000@TK2MSFTNGP03.phx.gbl...
Given a font, how do I get the bits which make up each character.
It doesn't have to be anything fancy, I just need a string of 8x16 sets of
bytes to download to a device.
I don't know tif this is "fancy" but the essential steps are as below.
The central API for this job is GetGlyphOutline().
A word or two of caution. I am doing this with symbol fonts with fewer
than 256 characters and nChar in the range [0,255]. I am not using Unicode
code points, which is why I use GetGlyphOutlineA() rather than
GetGlyphOutline(). For years I did this to get a collection of musical
symbols from a TrueType font and then blitted them onto the page with
BitBlt. Some Hewlett Packard printer drivers choked on having lots of mono
bitmaps blitted onto a page. HP would fix the drivers (eventually), but
then they'd bring out a new printer with the same bug in its drivers. So I
gave it up and started drawing the characters with TextOut() and a string of
one character. No more problems. The result is that I haven't used this
code in anger for a few years now, so there are no guarantees :-)
Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
================================
1. Select the font into CDC *pDC,
2. Then to get the nChar'th character:
===========
GLYPHMETRICS GlyphMetrics;
MAT2 Mt2 = Mat2NoRotation();
// Find the required buffer size for the data bits:
DWORD dwBufferSize = ::GetGlyphOutlineA( pDC->m_hAttribDC,
(UINT)nChar, GGO_BITMAP,
&GlyphMetrics, 0, NULL, &Mt2 );
LPSTR lpBitmapBuffer = (LPSTR)GlobalAllocPtr( GMEM_MOVEABLE,
dwBufferSize );
// Get the data bits and the GLYPHMETRICS
::GetGlyphOutlineA( pDC->m_hAttribDC, (UINT)nChar, GGO_BITMAP,
&GlyphMetrics,
dwBufferSize, lpBitmapBuffer, &Mt2 );
// Make a bitmap:
HBITMAP hBitmap = MakeMonochromeBitmap( pDC, GlyphMetrics.gmBlackBoxX,
GlyphMetrics.gmBlackBoxY,
lpBitmapBuffer );
// Have copied the bitmap data into the hBitmap block of memory
// so now I can free the original:
GlobalFreePtr( lpBitmapBuffer );
===========
Where MakeMonochromeBitmap is
===========
HBITMAP MakeMonochromeBitmap( CDC *pDC, UINT uWidth, UINT uHeight, LPSTR
lpBitmapData )
{
// The first thing I need for an n-colour DIB is an area
// of memory for a BITMAPINFO which consists of a
// BITMAPINFOHEADER followed by n RGBQUAD structures
// containing the colour information.
HBITMAP hBitmap;
int nColours = 2;
RGBQUAD rgbqBlack = { 0, 0, 0, 0 };
RGBQUAD rgbqWhite = { 255, 255, 255, 0 };
// Define the number of bytes for the header information (including
// colour information) and the total number of bytes:
DWORD dwBytes = sizeof(BITMAPINFOHEADER) + (nColours*sizeof(RGBQUAD));
// Allocate the appropriate space and note where
// the copy of the data is to be put:
LPBITMAPINFO lpbmi = (LPBITMAPINFO) GlobalAllocPtr( GHND, dwBytes );
// Define the BITMAPINFOHEADER information:
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth = uWidth;
lpbmi->bmiHeader.biHeight = uHeight;
lpbmi->bmiHeader.biPlanes = 1; // 1 plane.
lpbmi->bmiHeader.biBitCount = 1; // 1 bit per pixel.
lpbmi->bmiHeader.biCompression = BI_RGB; // No fancy compression.
lpbmi->bmiHeader.biSizeImage = 0;
lpbmi->bmiHeader.biXPelsPerMeter = 0;
lpbmi->bmiHeader.biYPelsPerMeter = 0;
lpbmi->bmiHeader.biClrUsed = nColours;
lpbmi->bmiHeader.biClrImportant = 0; // Ignore.
// Now fill in the RGB information starting after the BITMAPINFOHEADER:
LPRGBQUAD lprgbq = (LPRGBQUAD)( (LPSTR)lpbmi+sizeof(BITMAPINFOHEADER) );
lprgbq[1] = rgbqBlack;
lprgbq[0] = rgbqWhite;
// Now create the bitmap using the copy of the data:
hBitmap = CreateDIBitmap( pDC->m_hDC, (LPBITMAPINFOHEADER)lpbmi,
CBM_INIT, lpBitmapData, lpbmi, DIB_RGB_COLORS );
// The original data in lpBitmapData may now be discarded
// by the calling function if it wants to, as the bitmap
// has its own copy. This routine frees the bitmap info.
GlobalFreePtr( lpbmi );
return hBitmap;
}
====
Et voila!