#include <windows.h>
#include <stdio.h>
// Some default parameters:
int FontWidth=256, FontHeight=256;
int NumCellWidth=16, NumCellHeight=16;
// TGA output function and struct
typedef struct
{
int Width, Height;
unsigned long Depth;
unsigned char *Data;
} Image_t;
void TGA_PutData(char *file, Image_t *Image)
{
FILE *stream;
unsigned char IDLength=0;
unsigned char ColorMapType=0, ColorMapStart=0, ColorMapLength=0, ColorMapDepth=0;
unsigned short XOffset=0, YOffset=0;
unsigned char ImageDescriptor=0, ImageType=0;
switch(Image->Depth)
{
case 8:
ImageType=3;
break;
case 16:
case 24:
case 32:
ImageType=2;
break;
default:
return;
}
if((stream=fopen(file, "wb"))==NULL)
return;
fwrite(&IDLength, sizeof(unsigned char), 1, stream);
fwrite(&ColorMapType, sizeof(unsigned char), 1, stream);
fwrite(&ImageType, sizeof(unsigned char), 1, stream);
fwrite(&ColorMapStart, sizeof(unsigned short), 1, stream);
fwrite(&ColorMapLength, sizeof(unsigned short), 1, stream);
fwrite(&ColorMapDepth, sizeof(unsigned char), 1, stream);
fwrite(&XOffset, sizeof(unsigned short), 1, stream);
fwrite(&XOffset, sizeof(unsigned short), 1, stream);
fwrite(&Image->Width, sizeof(unsigned short), 1, stream);
fwrite(&Image->Height, sizeof(unsigned short), 1, stream);
fwrite(&Image->Depth, sizeof(unsigned char), 1, stream);
fwrite(&ImageDescriptor, sizeof(unsigned char), 1, stream);
fwrite(Image->Data, Image->Width*Image->Height*(Image->Depth/8), 1, stream);
fclose(stream);
}
// Pulled this from some old ID Software source code, nothing special
int CheckParm(char *parm, int argc, char **argv)
{
int i;
for(i=1;i<argc;i++)
{
if(stricmp(parm, argv[i])==0)
return i;
}
return 0;
}
int main(int argc, char **argv)
{
// General counters
int x, y, i;
// Bitmap info for CreateDIBSection
BITMAPINFO BitmapInfo;
// Bitmap handle
HBITMAP hBitmap=NULL;
// Font handle
HFONT hFont=NULL;
// Memory device context
HDC hDC=NULL;
// Font "cell" rect
RECT Rect;
// Cell width and height
int CellWidth, CellHeight;
// Bitmap pointer for the DC
unsigned char *Bitmap;
// Some more parameter stuff (Font name and output file name)
char *FontName=NULL;
char *OutputName=NULL;
// Output image struct
Image_t Image;
// Check the parameters
if((i=CheckParm("-w", argc, argv))!=0)
FontWidth=atoi(argv[i+1]);
if((i=CheckParm("-h", argc, argv))!=0)
FontHeight=atoi(argv[i+1]);
if((i=CheckParm("-cx", argc, argv))!=0)
NumCellWidth=atoi(argv[i+1]);
if((i=CheckParm("-cy", argc, argv))!=0)
NumCellHeight=atoi(argv[i+1]);
if((i=CheckParm("-f", argc, argv))!=0)
FontName=argv[i+1];
if((i=CheckParm("-o", argc, argv))!=0)
OutputName=argv[i+1];
if((i=CheckParm("-?", argc, argv))!=0)
{
fprintf(stderr, "Help:\n"
"-w [width] : Sets font width (defaults to 256)\n"
"-h [height] : Sets font height (defaults to 256)\n"
"-cx [numcellx] : Sets number of x cells (defaults to 16)\n"
"-cy [numcelly] : Sets numbers of y cells (defaults to 16)\n"
"-f \"Font Name\" : Sets font name (defaults to \"NULL\")\n"
"-o \"output.tga\" : Sets the output file name (defaults to \"font.tga\")\n\n"
"Standard Usage:\n"
"%s -w 256 -h 256 -f \"Courier New\"\n\n"
"Unicode Usage (warning! this generates a LARGE file):\n"
"%s -w 8192 -h 8192 -cx 256 -cy 256 -f \"MS PGothic\"\n", argv[0], argv[0]);
return -1;
}
// Calculate the cell width and height
CellWidth=FontWidth/NumCellWidth;
CellHeight=FontHeight/NumCellHeight;
// Set the bitmap info
memset(&BitmapInfo, 0, sizeof(BITMAPINFO));
BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biWidth=FontWidth;
BitmapInfo.bmiHeader.biHeight=FontHeight;
BitmapInfo.bmiHeader.biBitCount=24;
BitmapInfo.bmiHeader.biPlanes=1;
// Create the memory DC
hDC=CreateCompatibleDC(NULL);
if(hDC==NULL)
{
fprintf(stderr, "CreateCompatibleDC failed.");
return -2;
}
// Create the DIB section (to map the DC to a memory pointer)
hBitmap=CreateDIBSection(hDC, &BitmapInfo, DIB_RGB_COLORS, &Bitmap, NULL, 0);
if(hBitmap==NULL)
{
fprintf(stderr, "CreateDIBSection failed.");
return -2;
}
// Create a font based on the various parameters (mainly the character height and font name)
hFont=CreateFont(CellHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, FontName);
if(hFont==NULL)
{
fprintf(stderr, "CreateFont failed.");
return -2;
}
// Select the objects
SelectObject(hDC, hBitmap);
SelectObject(hDC, hFont);
// Set the colors
SetBkColor(hDC, RGB(0, 0, 0));
SetTextColor(hDC, RGB(255, 255, 255));
// Draw the characters to the DC
for(i=0, y=0;y<NumCellHeight;y++)
{
for(x=0;x<NumCellWidth;x++)
{
unsigned short text[1]={ i++ };
Rect.left=CellWidth*x;
Rect.right=Rect.left+CellWidth;
Rect.top=CellHeight*y;
Rect.bottom=Rect.top+CellHeight;
DrawTextW(hDC, text, 1, &Rect, DT_CENTER);
}
}
// Set the image struct with the bitmap info
Image.Depth=BitmapInfo.bmiHeader.biBitCount;
Image.Width=BitmapInfo.bmiHeader.biWidth;
Image.Height=BitmapInfo.bmiHeader.biHeight;
Image.Data=Bitmap;
// Write the TGA image
TGA_PutData((OutputName==NULL)?"font.tga":OutputName, &Image);
// Delete the objects and DC
DeleteObject(hFont);
DeleteObject(hBitmap);
DeleteDC(hDC);
// Lets get the hell out of here!
return 0;
} |