Add support for font loading and rendering

This commit is contained in:
Philosoph228 2025-03-24 05:50:10 +05:00
parent d9c68cd32d
commit 5a1d13f0a4
No known key found for this signature in database
GPG Key ID: 02FA07138D16BF76
3 changed files with 94 additions and 4 deletions

View File

@ -7,3 +7,9 @@ add_executable(win32_gdi WIN32 main.c)
target_compile_options(win32_gdi PUBLIC)
target_include_directories(win32_gdi PUBLIC .)
add_custom_command(
TARGET win32_gdi POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/resources
${CMAKE_CURRENT_BINARY_DIR}/resources)

View File

@ -25,6 +25,7 @@ void CenterWindow(HWND hWnd);
long lastMsgTime = 0;
bool ui_debug_mode;
HFONT fonts[1];
#define RECTWIDTH(rc) ((rc).right - (rc).left)
#define RECTHEIGHT(rc) ((rc).bottom - (rc).top)
@ -116,7 +117,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_PAINT:
{
Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(&demo_data);
Clay_Win32_Render(hwnd, renderCommands);
Clay_Win32_Render(hwnd, renderCommands, fonts);
break;
}
@ -154,7 +155,10 @@ int APIENTRY WinMain(
uint64_t clayRequiredMemory = Clay_MinMemorySize();
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(clayRequiredMemory, malloc(clayRequiredMemory));
Clay_Initialize(clayMemory, (Clay_Dimensions){.width = 800, .height = 600}, (Clay_ErrorHandler){HandleClayErrors}); // This final argument is new since the video was published
Clay_SetMeasureTextFunction(Clay_Win32_MeasureText, NULL);
// Initialize clay fonts and text drawing
fonts[FONT_ID_BODY_16] = Clay_Win32_SimpleCreateFont("resources/Roboto-Regular.ttf", "Roboto", -11, FW_NORMAL);
Clay_SetMeasureTextFunction(Clay_Win32_MeasureText, fonts);
ZeroMemory(&wc, sizeof wc);
wc.hInstance = hInstance;

View File

@ -5,7 +5,7 @@ HDC renderer_hdcMem = {0};
HBITMAP renderer_hbmMem = {0};
HANDLE renderer_hOld = {0};
void Clay_Win32_Render(HWND hwnd, Clay_RenderCommandArray renderCommands)
void Clay_Win32_Render(HWND hwnd, Clay_RenderCommandArray renderCommands, HFONT* fonts)
{
bool is_clipping = false;
HRGN clipping_region = {0};
@ -48,10 +48,17 @@ void Clay_Win32_Render(HWND hwnd, Clay_RenderCommandArray renderCommands)
r.right = boundingBox.x + boundingBox.width + r.right;
r.bottom = boundingBox.y + boundingBox.height + r.bottom;
uint16_t font_id = renderCommand->renderData.text.fontId;
HFONT hFont = fonts[font_id];
HFONT hPrevFont = SelectObject(renderer_hdcMem, hFont);
// Actually draw text
DrawTextA(renderer_hdcMem, renderCommand->renderData.text.stringContents.chars,
renderCommand->renderData.text.stringContents.length,
&r, DT_TOP | DT_LEFT);
SelectObject(renderer_hdcMem, hPrevFont);
break;
}
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE:
@ -216,6 +223,37 @@ static inline Clay_Dimensions Clay_Win32_MeasureText(Clay_StringSlice text, Clay
{
Clay_Dimensions textSize = {0};
if (userData != NULL)
{
HFONT* fonts = (HFONT*)userData;
HFONT hFont = fonts[config->fontId];
if (hFont != NULL)
{
HDC hScreenDC = GetDC(HWND_DESKTOP);
HDC hTempDC = CreateCompatibleDC(hScreenDC);
if (hTempDC != NULL)
{
HFONT hPrevFont = SelectObject(hTempDC, hFont);
SIZE size;
GetTextExtentPoint32(hTempDC, text.chars, text.length, &size);
textSize.width = size.cx;
textSize.height = size.cy;
SelectObject(hScreenDC, hPrevFont);
DeleteDC(hTempDC);
return textSize;
}
ReleaseDC(HWND_DESKTOP, hScreenDC);
}
}
// Fallback for system bitmap font
float maxTextWidth = 0.0f;
float lineTextWidth = 0;
float textHeight = WIN32_FONT_HEIGHT;
@ -238,4 +276,46 @@ static inline Clay_Dimensions Clay_Win32_MeasureText(Clay_StringSlice text, Clay
textSize.height = textHeight;
return textSize;
}
}
HFONT Clay_Win32_SimpleCreateFont(const char* filePath, const char* family, int height, int weight)
{
// Add the font resource to the application instance
int fontAdded = AddFontResourceEx(filePath, FR_PRIVATE, NULL);
if (fontAdded == 0) {
return NULL;
}
int fontHeight = height;
// If negative, treat height as Pt rather than pixels
if (height < 0) {
// Get the screen DPI
HDC hScreenDC = GetDC(HWND_DESKTOP);
int iScreenDPI = GetDeviceCaps(hScreenDC, LOGPIXELSY);
ReleaseDC(HWND_DESKTOP, hScreenDC);
// Convert font height from points to pixels
fontHeight = MulDiv(height, iScreenDPI, 72);
}
// Create the font using the calculated height and the font name
HFONT hFont = CreateFont(
fontHeight, // Height
0, // Width (0 means default width)
0, // Escapement angle
0, // Orientation angle
weight, // Font weight
FALSE, // Italic
FALSE, // Underline
FALSE, // Strikeout
ANSI_CHARSET, // Character set
OUT_DEFAULT_PRECIS, // Output precision
CLIP_DEFAULT_PRECIS, // Clipping precision
DEFAULT_QUALITY, // Font quality
DEFAULT_PITCH, // Pitch and family
family // Font name
);
return hFont;
}