mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-23 22:58:06 +00:00
Merge 5a1d13f0a4
into ad49977f1b
This commit is contained in:
commit
d061380118
@ -9,6 +9,7 @@ option(CLAY_INCLUDE_CPP_EXAMPLE "Build C++ example" OFF)
|
|||||||
option(CLAY_INCLUDE_RAYLIB_EXAMPLES "Build raylib examples" OFF)
|
option(CLAY_INCLUDE_RAYLIB_EXAMPLES "Build raylib examples" OFF)
|
||||||
option(CLAY_INCLUDE_SDL2_EXAMPLES "Build SDL 2 examples" OFF)
|
option(CLAY_INCLUDE_SDL2_EXAMPLES "Build SDL 2 examples" OFF)
|
||||||
option(CLAY_INCLUDE_SDL3_EXAMPLES "Build SDL 3 examples" OFF)
|
option(CLAY_INCLUDE_SDL3_EXAMPLES "Build SDL 3 examples" OFF)
|
||||||
|
option(CLAY_INCLUDE_WIN32_GDI_EXAMPLES "Build Win32 GDI examples" OFF)
|
||||||
|
|
||||||
message(STATUS "CLAY_INCLUDE_DEMOS: ${CLAY_INCLUDE_DEMOS}")
|
message(STATUS "CLAY_INCLUDE_DEMOS: ${CLAY_INCLUDE_DEMOS}")
|
||||||
|
|
||||||
@ -37,4 +38,10 @@ if(NOT MSVC AND (CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SDL3_EXAMPLES))
|
|||||||
add_subdirectory("examples/SDL3-simple-demo")
|
add_subdirectory("examples/SDL3-simple-demo")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WIN32) # Build only for Win or Wine
|
||||||
|
if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_WIN32_GDI_EXAMPLES)
|
||||||
|
add_subdirectory("examples/win32_gdi")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now
|
# add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now
|
||||||
|
15
examples/win32_gdi/CMakeLists.txt
Normal file
15
examples/win32_gdi/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.27)
|
||||||
|
project(win32_gdi C)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
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)
|
@ -25,6 +25,10 @@ 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 RECTHEIGHT(rc) ((rc).bottom - (rc).top)
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@ -113,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,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;
|
||||||
@ -165,6 +172,10 @@ int APIENTRY WinMain(
|
|||||||
if (FALSE == RegisterClass(&wc))
|
if (FALSE == RegisterClass(&wc))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Calculate window rectangle by given client size
|
||||||
|
// TODO: AdjustWindowRectExForDpi for DPI support
|
||||||
|
RECT rcWindow = { .right = 800, .bottom = 600 };
|
||||||
|
AdjustWindowRect(&rcWindow, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
|
||||||
hwnd = CreateWindow(
|
hwnd = CreateWindow(
|
||||||
szAppName,
|
szAppName,
|
||||||
@ -172,8 +183,8 @@ int APIENTRY WinMain(
|
|||||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
CW_USEDEFAULT,
|
CW_USEDEFAULT,
|
||||||
CW_USEDEFAULT,
|
CW_USEDEFAULT,
|
||||||
800, // CW_USEDEFAULT,
|
RECTWIDTH(rcWindow), // CW_USEDEFAULT,
|
||||||
600, // CW_USEDEFAULT,
|
RECTHEIGHT(rcWindow), // CW_USEDEFAULT,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
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;
|
||||||
@ -238,4 +276,46 @@ static inline Clay_Dimensions Clay_Win32_MeasureText(Clay_StringSlice text, Clay
|
|||||||
textSize.height = textHeight;
|
textSize.height = textHeight;
|
||||||
|
|
||||||
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 New Issue
Block a user