Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2babfb4
Initial plan
Copilot Dec 17, 2025
29d4aaf
Add ege_setfont implementation with GDI+ Font support
Copilot Dec 17, 2025
ee4b9e0
Address code review feedback: improve font fallback and fix sprintf
Copilot Dec 17, 2025
08f0374
Fix demo to use proper GDI+ constants and improve font fallback
Copilot Dec 17, 2025
88bb75c
Fix FontFamily handling to use proper lifetime management
Copilot Dec 17, 2025
dbefef3
Use safer swprintf_s and optimize GenericSansSerif usage
Copilot Dec 17, 2025
7d2bf54
Code quality improvements: simplify array size and null checks
Copilot Dec 17, 2025
558aacd
Add input validation for typeface and size parameters
Copilot Dec 17, 2025
3f7585b
Fix const parameter modification and add final fallback validation
Copilot Dec 17, 2025
ddfd070
修复了编译错误
FeJS8888 Dec 20, 2025
3024259
Fix documentation and use UnitPixel for size consistency with GDI
Copilot Dec 21, 2025
adabb6d
Fix GDI+ font size to match GDI by using Font(HDC, HFONT) conversion
Copilot Dec 21, 2025
b4a768d
Fix measuretext to match ege_drawtext_p StringFormat flags
Copilot Dec 21, 2025
fa9fd88
Use MeasureString instead of MeasureCharacterRanges for accurate bounds
Copilot Dec 21, 2025
c0569ac
Fix floating-point font size precision by scaling from rounded LOGFONT
Copilot Dec 21, 2025
d84cb5e
Simplify ege_setfont to use direct Font creation with UnitPixel
Copilot Dec 21, 2025
cbabbe7
修复了 GDI+ 绘制文字和 GDI 绘制大小不匹配的问题
FeJS8888 Dec 21, 2025
11bc687
移除了无用代码
FeJS8888 Dec 21, 2025
7802c19
Add NULL checks to ANSI ege_setfont functions for security
Copilot Dec 22, 2025
4b34902
Update documentation to clarify size adjustment for GDI compatibility
Copilot Dec 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions demo/test_ege_setfont.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Test demo for ege_setfont function
* This demo demonstrates the use of floating-point font sizes with GDI+
* Font sizes are in pixels to match the existing setfont() behavior
*/

#include <graphics.h>
#include <stdio.h>

int main()
{
// Initialize graphics window
initgraph(800, 600);
setbkcolor(WHITE);
cleardevice();

// Test 1: Basic ege_setfont with floating-point size
settextcolor(BLACK);
ege_setfont(24.5f, L"Arial");
ege_drawtext(L"24.5px Arial font (floating-point size)", 50.0f, 50.0f);

// Test 2: Different sizes to show precision
ege_setfont(12.0f, L"Times New Roman");
ege_drawtext(L"12.0px Times New Roman", 50.0f, 100.0f);

ege_setfont(12.5f, L"Times New Roman");
ege_drawtext(L"12.5px Times New Roman", 50.0f, 120.0f);

ege_setfont(13.0f, L"Times New Roman");
ege_drawtext(L"13.0px Times New Roman", 50.0f, 140.0f);

// Test 3: With font styles
ege_setfont(20.0f, L"Arial", Gdiplus::FontStyleBold);
ege_drawtext(L"20px Arial Bold", 50.0f, 200.0f);

ege_setfont(18.0f, L"Arial", Gdiplus::FontStyleItalic);
ege_drawtext(L"18px Arial Italic", 50.0f, 240.0f);

ege_setfont(16.0f, L"Arial", Gdiplus::FontStyleBold | Gdiplus::FontStyleItalic);
ege_drawtext(L"16px Arial Bold Italic", 50.0f, 280.0f);

ege_setfont(14.0f, L"Arial", Gdiplus::FontStyleUnderline);
ege_drawtext(L"14px Arial Underline", 50.0f, 320.0f);

// Test 4: Very precise sizes
ege_setfont(15.25f, L"Courier New");
ege_drawtext(L"15.25px Courier New (very precise)", 50.0f, 380.0f);

// Test 5: Chinese characters with floating-point size
ege_setfont(22.5f, L"SimSun");
ege_drawtext(L"22.5像素宋体 - 中文测试", 50.0f, 430.0f);

// Test 6: Compare with measuretext
float width, height;
const wchar_t* testText = L"Test measuretext with GDI+ Font";
ege_setfont(18.0f, L"Arial");
measuretext(testText, &width, &height);

const size_t INFO_BUFFER_SIZE = 256;
wchar_t info[INFO_BUFFER_SIZE];
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
swprintf_s(info, INFO_BUFFER_SIZE, L"Width: %.2f, Height: %.2f", width, height);
#else
swprintf(info, INFO_BUFFER_SIZE, L"Width: %.2f, Height: %.2f", width, height);
#endif
ege_drawtext(testText, 50.0f, 480.0f);
ege_setfont(12.0f, L"Arial");
ege_drawtext(info, 50.0f, 510.0f);

// Instructions
ege_setfont(14.0f, L"Arial");
settextcolor(BLUE);
ege_drawtext(L"Press any key to exit...", 50.0f, 550.0f);

// Wait for key press
getch();
closegraph();
return 0;
}
50 changes: 50 additions & 0 deletions include/ege.h
Original file line number Diff line number Diff line change
Expand Up @@ -3996,6 +3996,56 @@ void EGEAPI setfont(const LOGFONTA *font, PIMAGE pimg = NULL);
EGE_DEPRECATE(getfont, "Please use the 'getfont' function with the LOGFONTW* parameter instead.")
void EGEAPI getfont(LOGFONTA *font, PCIMAGE pimg = NULL);

/**
* @brief Set font for GDI+ text rendering with floating-point size
* @param size Font size (floating-point), measured in cell height pixels to match GDI setfont() behavior
* @param typeface Font family name
* @param pimg Target image pointer, NULL means current ege window
* @note This function creates a GDI+ Font directly, allowing floating-point font sizes.
* When set, ege_drawtext will use this GDI+ font instead of converting from GDI HFONT.
* The size represents the cell height (like GDI's LOGFONT.lfHeight). The implementation
* adjusts this to GDI+'s em height internally to ensure the rendered size matches GDI fonts.
*/
void EGEAPI ege_setfont(float size, const char* typeface, PIMAGE pimg = NULL);

/**
* @brief Set font for GDI+ text rendering with floating-point size (Unicode)
* @param size Font size (floating-point), measured in cell height pixels to match GDI setfont() behavior
* @param typeface Font family name
* @param pimg Target image pointer, NULL means current ege window
* @note This function creates a GDI+ Font directly, allowing floating-point font sizes.
* When set, ege_drawtext will use this GDI+ font instead of converting from GDI HFONT.
* The size represents the cell height (like GDI's LOGFONT.lfHeight). The implementation
* adjusts this to GDI+'s em height internally to ensure the rendered size matches GDI fonts.
*/
void EGEAPI ege_setfont(float size, const wchar_t* typeface, PIMAGE pimg = NULL);

/**
* @brief Set font for GDI+ text rendering with floating-point size and style
* @param size Font size (floating-point), measured in cell height pixels to match GDI setfont() behavior
* @param typeface Font family name
* @param style Font style (combination of Gdiplus::FontStyle flags: FontStyleBold, FontStyleItalic, etc.)
* @param pimg Target image pointer, NULL means current ege window
* @note This function creates a GDI+ Font directly, allowing floating-point font sizes and GDI+ font styles.
* When set, ege_drawtext will use this GDI+ font instead of converting from GDI HFONT.
* The size represents the cell height (like GDI's LOGFONT.lfHeight). The implementation
* adjusts this to GDI+'s em height internally to ensure the rendered size matches GDI fonts.
*/
void EGEAPI ege_setfont(float size, const char* typeface, int style, PIMAGE pimg = NULL);

/**
* @brief Set font for GDI+ text rendering with floating-point size and style (Unicode)
* @param size Font size (floating-point), measured in cell height pixels to match GDI setfont() behavior
* @param typeface Font family name
* @param style Font style (combination of Gdiplus::FontStyle flags: FontStyleBold, FontStyleItalic, etc.)
* @param pimg Target image pointer, NULL means current ege window
* @note This function creates a GDI+ Font directly, allowing floating-point font sizes and GDI+ font styles.
* When set, ege_drawtext will use this GDI+ font instead of converting from GDI HFONT.
* The size represents the cell height (like GDI's LOGFONT.lfHeight). The implementation
* adjusts this to GDI+'s em height internally to ensure the rendered size matches GDI fonts.
*/
void EGEAPI ege_setfont(float size, const wchar_t* typeface, int style, PIMAGE pimg = NULL);

/// @}

#define getmaxx getwidth
Expand Down
50 changes: 50 additions & 0 deletions include/ege.zh_CN.h
Original file line number Diff line number Diff line change
Expand Up @@ -3991,6 +3991,56 @@ void EGEAPI setfont(const LOGFONTA *font, PIMAGE pimg = NULL);
EGE_DEPRECATE(getfont, "Please use the 'getfont' function with the LOGFONTW* parameter instead.")
void EGEAPI getfont(LOGFONTA *font, PCIMAGE pimg = NULL);

/**
* @brief 设置用于GDI+文字渲染的浮点数大小字体
* @param size 字体大小(浮点数),以单元格高度像素为单位,与GDI setfont()行为保持一致
* @param typeface 字体名称
* @param pimg 目标图像指针,NULL 表示当前ege窗口
* @note 此函数直接创建GDI+ Font,允许使用浮点数字体大小。
* 设置后,ege_drawtext将使用此GDI+字体,而不是从GDI HFONT转换。
* 大小表示单元格高度(类似GDI的LOGFONT.lfHeight)。实现内部会将其调整为
* GDI+的em高度,以确保渲染大小与GDI字体一致。
*/
void EGEAPI ege_setfont(float size, const char* typeface, PIMAGE pimg = NULL);

/**
* @brief 设置用于GDI+文字渲染的浮点数大小字体(Unicode版本)
* @param size 字体大小(浮点数),以单元格高度像素为单位,与GDI setfont()行为保持一致
* @param typeface 字体名称
* @param pimg 目标图像指针,NULL 表示当前ege窗口
* @note 此函数直接创建GDI+ Font,允许使用浮点数字体大小。
* 设置后,ege_drawtext将使用此GDI+字体,而不是从GDI HFONT转换。
* 大小表示单元格高度(类似GDI的LOGFONT.lfHeight)。实现内部会将其调整为
* GDI+的em高度,以确保渲染大小与GDI字体一致。
*/
void EGEAPI ege_setfont(float size, const wchar_t* typeface, PIMAGE pimg = NULL);

/**
* @brief 设置用于GDI+文字渲染的浮点数大小和样式字体
* @param size 字体大小(浮点数),以单元格高度像素为单位,与GDI setfont()行为保持一致
* @param typeface 字体名称
* @param style 字体样式(Gdiplus::FontStyle标志的组合:FontStyleBold、FontStyleItalic等)
* @param pimg 目标图像指针,NULL 表示当前ege窗口
* @note 此函数直接创建GDI+ Font,允许使用浮点数字体大小和GDI+字体样式。
* 设置后,ege_drawtext将使用此GDI+字体,而不是从GDI HFONT转换。
* 大小表示单元格高度(类似GDI的LOGFONT.lfHeight)。实现内部会将其调整为
* GDI+的em高度,以确保渲染大小与GDI字体一致。
*/
void EGEAPI ege_setfont(float size, const char* typeface, int style, PIMAGE pimg = NULL);

/**
* @brief 设置用于GDI+文字渲染的浮点数大小和样式字体(Unicode版本)
* @param size 字体大小(浮点数),以单元格高度像素为单位,与GDI setfont()行为保持一致
* @param typeface 字体名称
* @param style 字体样式(Gdiplus::FontStyle标志的组合:FontStyleBold、FontStyleItalic等)
* @param pimg 目标图像指针,NULL 表示当前ege窗口
* @note 此函数直接创建GDI+ Font,允许使用浮点数字体大小和GDI+字体样式。
* 设置后,ege_drawtext将使用此GDI+字体,而不是从GDI HFONT转换。
* 大小表示单元格高度(类似GDI的LOGFONT.lfHeight)。实现内部会将其调整为
* GDI+的em高度,以确保渲染大小与GDI字体一致。
*/
void EGEAPI ege_setfont(float size, const wchar_t* typeface, int style, PIMAGE pimg = NULL);

/// @}

#define getmaxx getwidth
Expand Down
Loading
Loading