mirror of
https://github.com/reactos/reactos.git
synced 2024-08-21 02:43:48 +00:00
195 lines
5.3 KiB
C
195 lines
5.3 KiB
C
/*
|
|
* PROJECT: ReactOS BootVid Font Generator Utility
|
|
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
|
* PURPOSE: Generates the FontData array for the bootdata.c file of bootvid.dll
|
|
* COPYRIGHT: Copyright 2016 Colin Finck <colin@reactos.org>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <conio.h>
|
|
#include <windows.h>
|
|
|
|
/*
|
|
* Enable this #define if you want to dump the generated character on screen
|
|
*/
|
|
// #define DUMP_CHAR_ON_SCREEN
|
|
|
|
// Windows original Blue Screen font is "Lucida Console" at FONT_SIZE 10 with no offsets.
|
|
#define FONT_NAME_DEF "Lucida Console" // "DejaVu Sans Mono" // "Anonymous Pro"
|
|
#define FONT_SIZE_DEF 10
|
|
#define X_OFFSET_DEF 0 // 0 // 1
|
|
#define Y_OFFSET_DEF 0
|
|
|
|
#define HEIGHT 13 // Must be == BOOTCHAR_HEIGHT (see reactos/drivers/base/bootvid/precomp.h)
|
|
#define WIDTH 8 // 8 bits == 1 byte
|
|
|
|
#ifdef DUMP_CHAR_ON_SCREEN
|
|
/**
|
|
* Sketch the character on the console screen using ASCII characters.
|
|
* Allows you to easily check if the font fits properly into the 8x13 box.
|
|
*/
|
|
static void DumpCharacterOnScreen(DWORD BmpBits[])
|
|
{
|
|
int i, j;
|
|
|
|
for (i = 0; i < HEIGHT; i++)
|
|
{
|
|
for (j = WIDTH; --j >= 0;)
|
|
{
|
|
if (BmpBits[i] >> j & 0x1)
|
|
putchar(' ');
|
|
else
|
|
putchar('#');
|
|
}
|
|
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
/**
|
|
* Dump the FontData for the bootvid/i386/bootdata.c array.
|
|
*/
|
|
static void DumpCharacterFontData(DWORD BmpBits[])
|
|
{
|
|
static int iBegin = 0;
|
|
int i;
|
|
|
|
fprintf(stdout, " ");
|
|
|
|
for (i = 0; i < HEIGHT; i++)
|
|
fprintf(stdout, "0x%02lX, ", BmpBits[i]);
|
|
|
|
fprintf(stdout, " // %d\n", iBegin);
|
|
iBegin += HEIGHT;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Use GDI APIs to load a monospace font and plot a single character into a bitmap.
|
|
*/
|
|
static BOOL PlotCharacter(HDC hDC, HFONT hFont, INT XOffset, INT YOffset, CHAR Character, DWORD BmpBits[])
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
HBITMAP hOldBmp;
|
|
HFONT hOldFont;
|
|
HBITMAP hBmp = NULL;
|
|
BYTE BmpInfo[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
|
|
PBITMAPINFO pBmpInfo = (PBITMAPINFO)&BmpInfo;
|
|
|
|
hBmp = CreateCompatibleBitmap(hDC, WIDTH, HEIGHT);
|
|
if (!hBmp)
|
|
{
|
|
fprintf(stderr, "CreateCompatibleBitmap failed with error %lu!\n", GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
hOldBmp = SelectObject(hDC, hBmp);
|
|
hOldFont = SelectObject(hDC, hFont);
|
|
SetBkColor(hDC, RGB(0, 0, 0));
|
|
SetTextColor(hDC, RGB(255, 255, 255));
|
|
TextOutA(hDC, XOffset, YOffset, &Character, 1);
|
|
|
|
/*
|
|
* Use enough memory for BITMAPINFO and one additional color in the color table.
|
|
* BITMAPINFO already contains a color table entry for a single color and
|
|
* GetDIBits needs space for two colors (black and white).
|
|
*/
|
|
ZeroMemory(&BmpInfo, sizeof(BmpInfo));
|
|
pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
pBmpInfo->bmiHeader.biHeight = -HEIGHT;
|
|
pBmpInfo->bmiHeader.biWidth = WIDTH;
|
|
pBmpInfo->bmiHeader.biBitCount = 1;
|
|
pBmpInfo->bmiHeader.biPlanes = 1;
|
|
|
|
bReturnValue = TRUE;
|
|
|
|
if (!GetDIBits(hDC, hBmp, 0, HEIGHT, BmpBits, pBmpInfo, 0))
|
|
{
|
|
fprintf(stderr, "GetDIBits failed with error %lu!\n", GetLastError());
|
|
bReturnValue = FALSE;
|
|
}
|
|
|
|
SelectObject(hDC, hOldBmp);
|
|
SelectObject(hDC, hOldFont);
|
|
|
|
Cleanup:
|
|
if (hBmp)
|
|
DeleteObject(hBmp);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
static void DumpFont(LPSTR FontName, INT FontSize, INT XOffset, INT YOffset)
|
|
{
|
|
int iHeight;
|
|
HDC hDC = NULL;
|
|
HFONT hFont = NULL;
|
|
|
|
DWORD BmpBits[HEIGHT];
|
|
USHORT c;
|
|
|
|
hDC = CreateCompatibleDC(NULL);
|
|
if (!hDC)
|
|
{
|
|
fprintf(stderr, "CreateCompatibleDC failed with error %lu!\n", GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
iHeight = -MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
|
hFont = CreateFontA(iHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
|
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
|
NONANTIALIASED_QUALITY, FIXED_PITCH, FontName);
|
|
if (!hFont)
|
|
{
|
|
fprintf(stderr, "CreateFont failed with error %lu!\n", GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
for (c = 0; c < 256; c++)
|
|
{
|
|
PlotCharacter(hDC, hFont, XOffset, YOffset, (CHAR)c, BmpBits);
|
|
|
|
#ifdef DUMP_CHAR_ON_SCREEN
|
|
DumpCharacterOnScreen(BmpBits);
|
|
fprintf(stdout, "\nPress any key to continue...\n");
|
|
_getch();
|
|
system("cls");
|
|
#else
|
|
DumpCharacterFontData(BmpBits);
|
|
#endif
|
|
}
|
|
|
|
Cleanup:
|
|
if (hFont)
|
|
DeleteObject(hFont);
|
|
|
|
if (hDC)
|
|
DeleteDC(hDC);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
/* Validate the arguments */
|
|
if (argc > 5 || (argc >= 2 && strncmp(argv[1], "/?", 2) == 0))
|
|
{
|
|
fprintf(stdout,
|
|
"Usage: %s \"font name\" [font size] [X-offset] [Y-offset]\n"
|
|
"Default font name is: \"%s\"\n"
|
|
"Default font size is: %i\n"
|
|
"Default X-offset is: %i\n"
|
|
"Default Y-offset is: %i\n",
|
|
argv[0],
|
|
FONT_NAME_DEF, FONT_SIZE_DEF, X_OFFSET_DEF, Y_OFFSET_DEF);
|
|
|
|
return -1;
|
|
}
|
|
|
|
DumpFont((argc <= 1) ? FONT_NAME_DEF : argv[1],
|
|
(argc <= 2) ? FONT_SIZE_DEF : atoi(argv[2]),
|
|
(argc <= 3) ? X_OFFSET_DEF : atoi(argv[3]),
|
|
(argc <= 4) ? Y_OFFSET_DEF : atoi(argv[4]));
|
|
return 0;
|
|
}
|