透過 GDI 路徑與字體屬性設定,可實作多種視覺衝擊力強的特殊字體效果。本文提供四種經典效果的完整實作代碼。
CClientDC dc(this);
LOGFONT lf;
dc.GetCurrentFont()->GetLogFont(lf);
CFont font, *pOldFont;
lf.lfCharSet = 134; // GB2312
lf.lfHeight = -150;
lf.lfWidth = 0;
strcpy(lf.lfFaceName, "隸書");
font.CreateFontIndirect(&lf);
pOldFont = dc.SelectObject(&font);
dc.SetBkMode(TRANSPARENT);
原理:建立文字路徑 → 設定裁切區域 → 繪製同心橢圓漸變填充
// 空畫筆、空畫刷
CPen pen(PS_NULL, 1, RGB(255,0,0)), *pOldPen = dc.SelectObject(&pen);
CBrush br, *pOldBrush = dc.SelectObject(&br);
dc.BeginPath();
dc.TextOut(10, 10, "漸變字");
dc.EndPath();
dc.SelectClipPath(RGN_COPY); // 文字路徑作為裁切區
for (int i=255; i>0; i--) {
int radius = (600*i)/255;
dc.SelectObject(pOldBrush); br.DeleteObject();
br.CreateSolidBrush(RGB(255, i, 0)); // 紅→黃漸變
dc.SelectObject(&br);
dc.Ellipse(-radius, -radius/3, radius, radius/3);
}
// 恢復 DC 狀態
dc.SelectObject(pOldFont);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
原理:建立文字路徑 → StrokePath 僅繪製輪廓
CPen pen(PS_SOLID, 1, RGB(255,0,0)), *pOldPen = dc.SelectObject(&pen);
dc.BeginPath();
dc.TextOut(10, 130, "空心字");
dc.EndPath();
dc.StrokePath(); // 僅繪製路徑輪廓
dc.SelectObject(pOldFont);
dc.SelectObject(pOldPen);
原理:陰影色偏移繪製 + 高光色原位繪製,字體建議粗體、非預設字型
LOGFONT lf;
lf.lfHeight = 50; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0;
lf.lfWeight = FW_HEAVY; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; lf.lfStrikeOut = FALSE;
lf.lfCharSet = GB2312_CHARSET; strcpy(lf.lfFaceName, "幼圓");
CFont font; font.CreateFontIndirect(&lf);
CFont* pOldFont = dc.SelectObject(&font);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(::GetSysColor(COLOR_3DDKSHADOW)); // 陰影色
dc.TextOut(10, 10, "立體字");
dc.SetTextColor(::GetSysColor(COLOR_3DHILIGHT)); // 高光色
dc.TextOut(13, 7, "立體字"); // 向左上偏移 3 像素
dc.SelectObject(pOldFont);
原理:lf.lfEscapement 設定字體基線與 X 軸夾角(單位:0.1 度)
LOGFONT lf;
lf.lfHeight = 50; lf.lfWidth = 0; lf.lfEscapement = 300; // 30 度
lf.lfOrientation = 0; lf.lfWeight = FW_HEAVY;
lf.lfItalic = FALSE; lf.lfUnderline = FALSE; lf.lfStrikeOut = FALSE;
lf.lfCharSet = GB2312_CHARSET; strcpy(lf.lfFaceName, "幼圓");
CFont font; font.CreateFontIndirect(&lf);
CFont* pOldFont = dc.SelectObject(&font);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(255,0,0));
dc.TextOut(10, 300, "旋轉的字體");
dc.SelectObject(pOldFont);
| 效果 | 核心技術 | 關鍵函式/屬性 |
|---|---|---|
| 漸變字 | 路徑裁切 + 同心圓填充 | BeginPath/EndPath, SelectClipPath, Ellipse |
| 空心字 | 路徑描邊 | BeginPath/EndPath, StrokePath |
| 立體字 | 雙層偏移繪製 | TextOut 兩次, 系統色彩常數 |
| 旋轉字 | 字體傾斜角度 | lfEscapement (0.1度單位) |