215 lines
6.5 KiB
C
215 lines
6.5 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#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 );
|
|
}
|