#include #include #include #include "icon.h" #include "util.h" #include "view.h" #define BITS_TO_BYTES( x, y ) ( ( ( x ) * ( y ) + 7 ) / 8 ) #define BITMAP_SIZE( bm ) ( sizeof(BITMAPINFO) + \ sizeof(RGBQUAD) * ((1<<(bm)->biBitCount)-1)) /* * IconOpen - takes a handle to an icon resource file and returns an icon_file * structure which can be passed to other routines in this module to load a * given icon resource or extract a bitmap (XOR or AND) from an icon. Any file * opened in this manner must be closed with IconClose (see below). */ an_icon_file *IconOpen( FILE *fp ) { an_icon_file *icon_file; unsigned size; icon_file = UtilMalloc( sizeof( an_icon_file ) ); /* read the header once to find out how many icons are in the file */ fseek( fp, 0L, SEEK_SET ); fread( icon_file, sizeof( an_icon_file ), 1, fp ); if( icon_file->count > 1 ) { size = sizeof( an_icon_file ) + sizeof( an_icon_resource ) * ( icon_file->count - 1 ); icon_file = realloc( icon_file, size ); fseek( fp, 0L, SEEK_SET ); fread( icon_file, (long) size, 1, fp ); } return( icon_file ); } /* IconOpen */ /* * IconCount - returns the number of differ icons in an icon file. */ WORD IconCount( an_icon_file *icon_file ) { return( icon_file->count ); } /* IconCount */ /* * IconResInfo - puts the info for a particular icon into the resource * structure supplied. */ void IconResInfo( an_icon_file *icon_file, an_icon_resource *res, unsigned i ) { *res = icon_file->resources[ i ]; } /* IconResInfo */ /* * ReadIconBitmap - read in the bitmap information for an individual icon. * NOTE: assume fp is positioned at the start of the bitmap information. * we first read in the BITMAPINFOHEADER to get information about the * number of quads needed, then we reposition ourselves and read in * the entire BITMAPINFOHEADER structure. */ static BITMAPINFO *ReadIconBitmap( FILE *fp ) { BITMAPINFO *bm; BITMAPINFOHEADER *header; long DIB_offset, bitmap_size; header = UtilMalloc( sizeof( BITMAPINFOHEADER ) ); DIB_offset = ftell( fp ); fread( header, sizeof( BITMAPINFOHEADER ), 1, fp ); fseek( fp, DIB_offset, SEEK_SET ); bitmap_size = BITMAP_SIZE( header ); bm = realloc( header, bitmap_size ); if( !bm ) return( NULL ); fread( bm, bitmap_size, 1, fp ); return( bm ); } /* ReadIconBitmap */ /* * IconResourceToIcon - takes an icon file and creates an icon structure * from the i'th icon in the file. The structure must later be freed with * a call to the IconFini function. */ an_icon *IconResourceToIcon( FILE *fp, an_icon_file *icon_file, unsigned i ) { an_icon_resource *res; BITMAPINFO *bm; BITMAPINFOHEADER *h; an_icon *icon; if( i >= icon_file->count ) return( NULL ); res = &icon_file->resources[ i ]; fseek( fp, res->DIB_offset, SEEK_SET ); bm = ReadIconBitmap( fp ); if( bm ) { icon = UtilMalloc( sizeof( an_icon ) ); icon->bm = bm; h = &bm->bmiHeader; // h->biHeight /= 2; /* code gen bug */ h->biHeight = res->height; /* they have height * 2 in this field */ h->biSizeImage = BITS_TO_BYTES( h->biWidth * h->biBitCount, h->biHeight ); icon->xor_size = h->biSizeImage; icon->and_size = BITS_TO_BYTES( h->biWidth, h->biHeight ); icon->xor_mask = UtilMalloc( icon->xor_size + icon->and_size ); icon->and_mask = (char *)icon->xor_mask + icon->xor_size; fseek( fp, res->DIB_offset + BITMAP_SIZE( h ), SEEK_SET ); fread( icon->xor_mask, icon->xor_size + icon->and_size, 1, fp ); return( icon ); } return( NULL ); } /* IconResourceToIcon */ /* * IconFini - frees up memory allocated for an icon structure. */ void IconFini( an_icon *icon ) { UtilFree( icon->bm ); UtilFree( icon->xor_mask ); UtilFree( icon ); } /* IconFini */ /* * CreateIconPalette - creates a palette for the colours present in an * icon's bitmap. */ static HPALETTE CreateIconPalette( BITMAPINFO *info ) { unsigned num_colours, i; LOGPALETTE *palette; HPALETTE palette_handle; RGBQUAD *quads; num_colours = info->bmiHeader.biClrUsed; if( num_colours == 0 ) { num_colours = 1 << info->bmiHeader.biBitCount; } palette = UtilMalloc( sizeof( LOGPALETTE ) + num_colours * sizeof( PALETTEENTRY ) ); palette->palNumEntries = num_colours; palette->palVersion = 0x300; quads = &info->bmiColors[0]; for( i = 0; i < num_colours; i++ ) { palette->palPalEntry[i].peRed = quads[i].rgbRed; palette->palPalEntry[i].peGreen = quads[i].rgbGreen; palette->palPalEntry[i].peBlue = quads[i].rgbBlue; palette->palPalEntry[i].peFlags = 0; } palette_handle = CreatePalette( palette ); UtilFree( palette ); return( palette_handle ); } /* CreateIconPalette */ /* * IconToXorBitmap - creates a bitmap which contains the part of an icon * which is to be XOR'd against the background. */ HBITMAP IconToXorBitmap( HDC hdc, an_icon *icon ) { HBITMAP bitmap_handle = (HBITMAP)0; HPALETTE new_palette, old_palette; new_palette = CreateIconPalette( icon->bm ); old_palette = SelectPalette( hdc, new_palette, FALSE ); RealizePalette( hdc ); bitmap_handle = CreateDIBitmap( hdc, &icon->bm->bmiHeader, CBM_INIT, icon->xor_mask, icon->bm, DIB_RGB_COLORS ); SelectPalette( hdc, old_palette, FALSE ); DeleteObject( new_palette ); return( bitmap_handle ); } /* IconToXorBitmap */ /* * IconToAndBitmap - creates the bitmap which allows an icon to have a * tranparent border around the central image. */ HBITMAP IconToAndBitmap( HDC hdc, an_icon *icon ) { BITMAP bitmap; HBITMAP bitmap_handle; BITMAPINFOHEADER *h; hdc = hdc; h = &icon->bm->bmiHeader; bitmap.bmType = 0; bitmap.bmWidth = h->biWidth; bitmap.bmHeight = h->biWidth; bitmap.bmWidthBytes = ( bitmap.bmWidth + 7 ) / 8; bitmap.bmPlanes = 1; bitmap.bmBitsPixel = 1; bitmap.bmBits = icon->and_mask; bitmap_handle = CreateBitmapIndirect( &bitmap ); return( bitmap_handle ); } /* IconToAndBitmap */ /* * IconClose - closes an icon file which was opened with IconOpen. */ void IconClose( an_icon_file *icon_file ) { UtilFree( icon_file ); }