mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 00:26:17 +00:00 
			
		
		
		
	Add support for font loading and rendering
This commit is contained in:
		
							parent
							
								
									d9c68cd32d
								
							
						
					
					
						commit
						5a1d13f0a4
					
				| 
						 | 
					@ -7,3 +7,9 @@ add_executable(win32_gdi WIN32 main.c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_compile_options(win32_gdi PUBLIC)
 | 
					target_compile_options(win32_gdi PUBLIC)
 | 
				
			||||||
target_include_directories(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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ void CenterWindow(HWND hWnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
long lastMsgTime = 0;
 | 
					long lastMsgTime = 0;
 | 
				
			||||||
bool ui_debug_mode;
 | 
					bool ui_debug_mode;
 | 
				
			||||||
 | 
					HFONT fonts[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RECTWIDTH(rc)   ((rc).right - (rc).left)
 | 
					#define RECTWIDTH(rc)   ((rc).right - (rc).left)
 | 
				
			||||||
#define RECTHEIGHT(rc)  ((rc).bottom - (rc).top)
 | 
					#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:
 | 
					    case WM_PAINT:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(&demo_data);
 | 
					        Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(&demo_data);
 | 
				
			||||||
        Clay_Win32_Render(hwnd, renderCommands);
 | 
					        Clay_Win32_Render(hwnd, renderCommands, fonts);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,7 +155,10 @@ int APIENTRY WinMain(
 | 
				
			||||||
    uint64_t clayRequiredMemory = Clay_MinMemorySize();
 | 
					    uint64_t clayRequiredMemory = Clay_MinMemorySize();
 | 
				
			||||||
    Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(clayRequiredMemory, malloc(clayRequiredMemory));
 | 
					    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_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);
 | 
					    ZeroMemory(&wc, sizeof wc);
 | 
				
			||||||
    wc.hInstance = hInstance;
 | 
					    wc.hInstance = hInstance;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ HDC renderer_hdcMem = {0};
 | 
				
			||||||
HBITMAP renderer_hbmMem = {0};
 | 
					HBITMAP renderer_hbmMem = {0};
 | 
				
			||||||
HANDLE renderer_hOld = {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;
 | 
					    bool is_clipping = false;
 | 
				
			||||||
    HRGN clipping_region = {0};
 | 
					    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.right = boundingBox.x + boundingBox.width + r.right;
 | 
				
			||||||
            r.bottom = boundingBox.y + boundingBox.height + r.bottom;
 | 
					            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,
 | 
					            DrawTextA(renderer_hdcMem, renderCommand->renderData.text.stringContents.chars,
 | 
				
			||||||
                      renderCommand->renderData.text.stringContents.length,
 | 
					                      renderCommand->renderData.text.stringContents.length,
 | 
				
			||||||
                      &r, DT_TOP | DT_LEFT);
 | 
					                      &r, DT_TOP | DT_LEFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SelectObject(renderer_hdcMem, hPrevFont);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case CLAY_RENDER_COMMAND_TYPE_RECTANGLE:
 | 
					        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};
 | 
					    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 maxTextWidth = 0.0f;
 | 
				
			||||||
    float lineTextWidth = 0;
 | 
					    float lineTextWidth = 0;
 | 
				
			||||||
    float textHeight = WIN32_FONT_HEIGHT;
 | 
					    float textHeight = WIN32_FONT_HEIGHT;
 | 
				
			||||||
| 
						 | 
					@ -239,3 +277,45 @@ static inline Clay_Dimensions Clay_Win32_MeasureText(Clay_StringSlice text, Clay
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return textSize;
 | 
					    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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue