📄 truetype.c
字号:
//*******************************************************************
// DlgBoxProc - handle dialog messages
//
// parameters:
// hDlg - The window handle for this message
// message - The message number
// wParam - The WPARAM parameter for this message
// lParam - The LPARAM parameter for this message
//
//*******************************************************************
#pragma argsused
BOOL CALLBACK DlgBoxProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SYSCOMMAND:
// Pass WM_SYSCOMMAND messages on to main window so both
// main window and dialog box get iconized, minimized etc.
// in parallel.
SendMessage(hwnd, message, wParam, lParam);
break;
case WM_COMMAND:
// regardless of the command (only ID_OK should arrive)
// we want to exit the dialog
EndDialog(hDlg, TRUE);
break;
default:
return FALSE;
} // switch
return(TRUE);
} // end of DlgBoxProc()
//*************************************************************************
// DoPaint -- this is the WM_PAINT action routine for the main window.
// It places the TrueType logo in the upper left corner of the window, draws
// a "fan hub" around it, and draws "fan leaves" of text out from the hub.
// These leaves are scaled to reach the bottom and the right edge of the
// window, by defining an ellipse centered on the TrueType logo which just
// touches those two edges. The text strings span the distance from the
// hub to the ellipse along radial lines, and are both scaled and rotated.
// Depending on user-set state variables, the ellipse and baselines
// for the text fan may be shown (ShowAlignmentMarks), and/or the text may
// be shadowed (ShadowAll). Other attributes, such as bolding or
// italicization, may be selected from the font dialog box.
//*************************************************************************
void DoPaint()
{
PAINTSTRUCT PaintInfo;
HDC hDC;
LOGFONT FontRec;
OUTLINETEXTMETRIC FontMetric;
int FontHeight, x, y, j, k;
WORD BaseWidth, DesiredExtent, FanTextLen;
float Theta;
LPCSTR P;
RECT R;
long TE;
int d;
BeginPaint(hwnd, &PaintInfo);
hDC = PaintInfo.hdc;
P = ArcText;
FanTextLen = strlen(FanText);
// save device context; easiest way to preserve current state
SaveDC(hDC);
// set initial font data (for TrueType logo)
FontRec = CornerFontRec;
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB(128,128,128));
FontRec.lfHeight = FontRec.lfHeight * 2;
FontRec.lfWidth = floor(FontRec.lfWidth * 2.1);
// create the TrueType logo
SelectObject(hDC, CreateFontIndirect(&FontRec));
TextOut(hDC, 18, 5, "T", 1);
SetTextColor(hDC, RGB(0,0,0));
TextOut(hDC, 32, 13,"T", 1);
// determine window dimensions & set up fan text parameters
GetClientRect(hwnd, &R);
FontRec = MainFontRec;
DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
GetOutlineTextMetrics(hDC, sizeof(FontMetric), &FontMetric);
FontHeight = FontMetric.otmTextMetrics.tmHeight;
SetViewportOrg(hDC, FontHeight+2, 0);
R.right -= FontHeight+2;
BaseWidth = LOWORD(GetTextExtent(hDC, FanText, FanTextLen));
// get a "black brush" for drawing operations
SelectObject(hDC, GetStockObject(NULL_BRUSH));
// if we want to show the alignment marks, draw the bounding ellipse
if (ShowAlignmentMarks)
{
Ellipse(hDC, -R.right, -R.bottom, R.right, R.bottom);
}
// draw the "hub" of the fan
Ellipse(hDC, -(Radius-5), -(Radius-5), (Radius-5), Radius-5);
Ellipse(hDC, -(Radius-10), -(Radius-10), (Radius-10), Radius-10);
SetTextColor(hDC, FanColor[0]);
// loop over the "fan leaves"
for ( d = 27; d <= 36; d++)
{
x = ROUND(Radius * cos(d * Deg2Rad));
y = ROUND(Radius * sin(-d * Deg2Rad)); // -d because y axis is inverted
Theta = -d * Deg2Rad;
if (x)
{
Theta = atan((R.right / (R.bottom * 1.0)) * (y / (x * 1.0)));
}
j = ROUND(R.right * cos(Theta));
k = ROUND(R.bottom * sin(Theta));
if (ShowAlignmentMarks)
{
MoveTo(hDC, x,y);
LineTo(hDC, j,k);
}
DesiredExtent = ROUND(sqrt(SQR(x*1.0 - j) + SQR(y*1.0 - k))) - 5;
FontRec = MainFontRec;
FontRec.lfEscapement = d * 100;
FontRec.lfWidth = floor((FontMetric.otmTextMetrics.tmAveCharWidth) *
(DesiredExtent / (BaseWidth * 1.0)));
DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
TE = GetTextExtent(hDC, FanText, FanTextLen);
for ( ;(LOWORD(TE) > DesiredExtent) && (FontRec.lfWidth);
FontRec.lfWidth-- )
{
// Shave off some character width until the string fits
DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
TE = GetTextExtent(hDC, FanText, FanTextLen);
}
// Expand the string if necessary to make it fit the desired extent
if (LOWORD(TE) < DesiredExtent)
{ SetTextJustification(hDC,DesiredExtent - LOWORD(TE), 3); }
if (ShadowAll)
{
SetTextColor(hDC, RGB(0,0,0));
TextOut(hDC, x+2, y+1, FanText, FanTextLen);
}
SetTextColor(hDC, FanColor[d - 27]);
TextOut(hDC, x, y, FanText, FanTextLen);
// clear justifier's internal error accumulator
SetTextJustification(hDC,0,0);
if (P[0])
{
FontRec = CornerFontRec;
FontRec.lfEscapement = (d+10) * 100;
FontRec.lfWidth = 0;
DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
SetTextColor(hDC, 0);
x = floor((Radius - FontHeight - 5) * cos(d * Deg2Rad));
y = floor((Radius - FontHeight - 5) * sin(-d * Deg2Rad));
TextOut(hDC, x, y, P, 1);
P++;
} // if
} // for d
// lose the fan font, selecting in the Borland text font
DeleteObject(SelectObject(hDC, CreateFontIndirect(&BorlandFontRec)));
TE = GetTextExtent(hDC, BorlandText, strlen(BorlandText));
SetTextColor(hDC, RGB(0,0,0));
// write the Borland text in the lower right corner, with a shadow effect
TextOut(hDC, R.right - LOWORD(TE), R.bottom - HIWORD(TE), BorlandText,
strlen(BorlandText));
SetTextColor(hDC, RGB(255,0,0));
TextOut(hDC, R.right - LOWORD(TE) - 5, R.bottom - HIWORD(TE), BorlandText,
strlen(BorlandText));
DeleteObject(SelectObject(hDC, GetStockObject(SYSTEM_FONT)));
// restore the saved DC; easiest way to reset to entry state
RestoreDC(hDC, -1);
EndPaint(hwnd, &PaintInfo);
} // end of DoPaint()
//*************************************************************************
// wmCreate -- action routine for the WM_CREATE message. This routine
// sets up font record data and colors for use in the painting routines,
// and creates a thunk for the dialog process
//*************************************************************************
void wmCreate(void)
{
// create the font data for the main font
MainFontRec.lfHeight = 26;
MainFontRec.lfWidth = 10;
MainFontRec.lfEscapement = 0;
MainFontRec.lfOrientation = 0;
MainFontRec.lfWeight = FW_BOLD;
MainFontRec.lfItalic = 0;
MainFontRec.lfUnderline = 0;
MainFontRec.lfStrikeOut = 0;
MainFontRec.lfCharSet = ANSI_CHARSET;
MainFontRec.lfOutPrecision = OUT_DEFAULT_PRECIS;
MainFontRec.lfClipPrecision = CLIP_DEFAULT_PRECIS;
MainFontRec.lfQuality = PROOF_QUALITY;
MainFontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
strcpy(MainFontRec.lfFaceName,"Times New Roman");
// structure copy (!) into corner font
CornerFontRec = MainFontRec;
// copy again inot Borland font, but switch to Arial typeface, new size
BorlandFontRec = MainFontRec;
BorlandFontRec.lfHeight = 60;
BorlandFontRec.lfWidth = 0; // choose best width for this height
BorlandFontRec.lfWeight = 900;
strcpy(BorlandFontRec.lfFaceName, "Arial");
// Array of colors used to color the fan text
FanColor[0] = RGB(255,0,0);
FanColor[1] = RGB(128,0,0);
FanColor[2] = RGB(255,128,0);
FanColor[3] = RGB(80,80,0);
FanColor[4] = RGB(80,255,0);
FanColor[5] = RGB(0,128,0);
FanColor[6] = RGB(0,128,255);
FanColor[7] = RGB(0,0,255);
FanColor[8] = RGB(128,128,128);
FanColor[9] = RGB(255,0,0);
ShadowAll = 0;
ShowAlignmentMarks = 0;
} // end of wmCreate()
/*********************************************************************
cmXxxx routines -- these are action routines for menu commands
*********************************************************************/
//*************************************************************************
// cmShadows -- toggle the ShadowsAll flag, and set the menu checkmark
// as appropriate
//*************************************************************************
void cmShadows(void)
{
ShadowAll = !ShadowAll;
if (ShadowAll)
{
CheckMenuItem(GetMenu(hwnd), CM_SHADOWS, MF_BYCOMMAND | MF_CHECKED);
}
else
{
CheckMenuItem(GetMenu(hwnd), CM_SHADOWS,
MF_BYCOMMAND | MF_UNCHECKED);
}
// Erase if going Shadow -> no Shadow
InvalidateRect(hwnd, NULL, !ShadowAll);
} // end of cmShadows()
//*************************************************************************
// cmAlignmentMarks -- toggle the state of ShowAlignmentMarks, and toggle
// the checkmark in the menu to match
//*************************************************************************
void cmAlignmentMarks(void)
{
ShowAlignmentMarks = !ShowAlignmentMarks;
if (ShowAlignmentMarks)
{
CheckMenuItem(GetMenu(hwnd), CM_ALIGNMENTMARKS,
MF_BYCOMMAND | MF_CHECKED);
}
else
{
CheckMenuItem(GetMenu(hwnd), CM_ALIGNMENTMARKS,
MF_BYCOMMAND | MF_UNCHECKED);
}
// Erase if going Marks -> no Marks
InvalidateRect(hwnd, NULL, !ShowAlignmentMarks);
} // end of cmAlignmentMarks()
//*************************************************************************
// cmAbout -- invoke the "About" dialog. Its return code is ignored, since
// the About dialog doesn't return anything to the program.
//*************************************************************************
void cmAbout(void)
{
lpDlgProc = (DLGPROC) MakeProcInstance( (FARPROC) DlgBoxProc, hInst);
DialogBox(hInst, "About", hwnd, lpDlgProc);
FreeProcInstance ( (FARPROC) lpDlgProc );
} // end of cmAbout()
//*************************************************************************
// cmFonts -- use the Choose Fonts common dialog to get a new font spec
// from the user. To do this, we fill out a CHOOSEFONTS structure and
// pass it to the ChooseFonts routine. Windows 3.1 takes care of the rest!
//*************************************************************************
void cmFonts(HWND hWnd)
{
CHOOSEFONT CF;
LOGFONT FontRec = MainFontRec;
CF.lStructSize = sizeof(CF);
CF.hwndOwner = hWnd;
CF.Flags = CF_ANSIONLY | CF_TTONLY | CF_SCREENFONTS |
CF_INITTOLOGFONTSTRUCT | CF_ENABLETEMPLATE;
CF.nFontType = SCREEN_FONTTYPE;
CF.lpLogFont = &FontRec;
CF.nSizeMin = 20;
CF.nSizeMax = 20;
CF.lpTemplateName = "FontDlg";
CF.hInstance = hInst;
if (ChooseFont(&CF))
{
// Only get the font name, weight, and italics;
// we don't care about size
strcpy(MainFontRec.lfFaceName, FontRec.lfFaceName);
MainFontRec.lfWeight = FontRec.lfWeight;
MainFontRec.lfItalic = FontRec.lfItalic;
InvalidateRect(hwnd, NULL, TRUE);
}
} // end of cmFonts()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -