📄 ttfont.cpp
字号:
// ObjectWindows - (C) Copyright 1992 by Borland International
//
// ttfont.cpp
#include <owl.h>
#include <string.h>
#include "ttfont.h"
#include <math.h>
#include <commdlg.h>
class TFontWindow: public TWindow
{
private:
LOGFONT MainFontRec,
CornerFontRec,
BorlandFontRec;
COLORREF FanColor[10];
BOOL ShadowAll,
ShowAlignmentMarks,
Rendering;
public:
TFontWindow( PTWindowsObject AParent, LPSTR ATitle );
virtual void cmAbout( TMessage& ) = [CM_FIRST + CM_ABOUT];
virtual void cmAlignmentMarks( TMessage& ) = [CM_FIRST + CM_ALIGNMENTMARKS];
virtual void cmFonts( TMessage& ) = [CM_FIRST + CM_FONTS];
virtual void cmShadows( TMessage& ) = [ CM_FIRST + CM_SHADOWS ];
virtual LPSTR GetClassName();
virtual void GetWindowClass(WNDCLASS _FAR & AWndClass);
virtual void Paint( HDC, PAINTSTRUCT& );
virtual void WMGetMinMaxInfo( TMessage& ) = [WM_FIRST + WM_GETMINMAXINFO];
virtual void WMSize( TMessage& ) = [WM_FIRST + WM_SIZE];
};
#define ROUND(x) (floor(x + .5))
#define SQR(x) (pow(x,2))
TFontWindow::TFontWindow( PTWindowsObject AParent, LPSTR ATitle ) :
TWindow( AParent, ATitle)
{
AssignMenu(100);
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");
CornerFontRec = MainFontRec;
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;
Rendering = 0;
};
LPCSTR ArcText = "TrueType";
const char* WaitText = "Windows is rendering fonts...";
const char* FanText = "Borland C++ for Windows";
const char* BorlandText = "Borland";
const int Radius = 100;
const float Deg2Rad = M_PI / 18;
void TFontWindow::Paint( HDC DC, PAINTSTRUCT& )
{
LOGFONT FontRec;
OUTLINETEXTMETRIC FontMetric;
int FontHeight, x, y, j, k;
WORD BaseWidth, DesiredExtent, FanTextLen;
float Theta;
LPCSTR P;
RECT R;
long TE;
P = ArcText;
FanTextLen = strlen(FanText);
SaveDC(DC);
if (Rendering)
{
// display a message that Windows is rendering fonts, please wait...
SetWindowText(HWindow, WaitText);
};
FontRec = CornerFontRec;
SetBkMode(DC, TRANSPARENT);
SetTextColor(DC, RGB(128,128,128));
FontRec.lfHeight = FontRec.lfHeight * 2;
FontRec.lfWidth = floor(FontRec.lfWidth * 2.1);
SelectObject(DC, CreateFontIndirect(&FontRec));
TextOut(DC, 18, 5, "T", 1);
SetTextColor(DC, RGB(0,0,0));
TextOut(DC, 32, 13,"T", 1);
GetClientRect(HWindow, &R);
FontRec = MainFontRec;
DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
GetOutlineTextMetrics(DC, sizeof(FontMetric), &FontMetric);
FontHeight = FontMetric.otmTextMetrics.tmHeight;
SetViewportOrg(DC, FontHeight+2, 0);
R.right -= FontHeight+2;
BaseWidth = LOWORD(GetTextExtent(DC, FanText, FanTextLen));
SelectObject(DC, GetStockObject(NULL_BRUSH));
if (ShowAlignmentMarks)
{ Ellipse(DC, -R.right, -R.bottom, R.right, R.bottom);};
Ellipse(DC, -(Radius-5), -(Radius-5), (Radius-5), Radius-5);
Ellipse(DC, -(Radius-10), -(Radius-10), (Radius-10), Radius-10);
SetTextColor(DC, FanColor[0]);
for (int 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(DC, x,y);
LineTo(DC, 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(DC, CreateFontIndirect(&FontRec)));
TE = GetTextExtent(DC, FanText, FanTextLen);
for ( ;(LOWORD(TE) > DesiredExtent) && (FontRec.lfWidth); FontRec.lfWidth-- )
{ // Shave off some character width until the string fits
DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
TE = GetTextExtent(DC, FanText, FanTextLen);
};
// Expand the string if necessary to make it fit the desired extent
if (LOWORD(TE) < DesiredExtent)
{ SetTextJustification(DC,DesiredExtent - LOWORD(TE), 3); };
if (ShadowAll)
{
SetTextColor(DC, RGB(0,0,0));
TextOut(DC, x+2, y+1, FanText, FanTextLen);
};
SetTextColor(DC, FanColor[d - 27]);
TextOut(DC, x, y, FanText, FanTextLen);
SetTextJustification(DC,0,0); // clear justifier's internal error accumulator
if (P[0])
{
FontRec = CornerFontRec;
FontRec.lfEscapement = (d+10) * 100;
FontRec.lfWidth = 0;
DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
SetTextColor(DC, 0);
x = floor((Radius - FontHeight - 5) * cos(d * Deg2Rad));
y = floor((Radius - FontHeight - 5) * sin(-d * Deg2Rad));
TextOut(DC, x, y, P, 1);
P++;
};
};
DeleteObject(SelectObject(DC, CreateFontIndirect(&BorlandFontRec)));
TE = GetTextExtent(DC, BorlandText, strlen(BorlandText));
SetTextColor(DC, RGB(0,0,0));
TextOut(DC, R.right - LOWORD(TE), R.bottom - HIWORD(TE), BorlandText, strlen(BorlandText));
SetTextColor(DC, RGB(255,0,0));
TextOut(DC, R.right - LOWORD(TE) - 5, R.bottom - HIWORD(TE), BorlandText, strlen(BorlandText));
if (Rendering)
{
// restore the window caption to the proper title string
SetWindowText(HWindow, Title);
// clear the rendering flag. It will be set again when the window is resized (WMSIZE)
Rendering = 0;
};
DeleteObject(SelectObject(DC, GetStockObject(SYSTEM_FONT)));
RestoreDC(DC, -1);
};
void TFontWindow::cmShadows( TMessage& )
{
ShadowAll = !ShadowAll;
if (ShadowAll)
{ CheckMenuItem(GetMenu(HWindow), CM_SHADOWS, MF_BYCOMMAND | MF_CHECKED); }
else
{ CheckMenuItem(GetMenu(HWindow), CM_SHADOWS, MF_BYCOMMAND | MF_UNCHECKED); };
// Erase if going Shadow -> no Shadow
InvalidateRect(HWindow, NULL, !ShadowAll);
};
void TFontWindow::cmAlignmentMarks( TMessage& )
{
ShowAlignmentMarks = !ShowAlignmentMarks;
if (ShowAlignmentMarks)
{ CheckMenuItem(GetMenu(HWindow), CM_ALIGNMENTMARKS, MF_BYCOMMAND | MF_CHECKED); }
else
{ CheckMenuItem(GetMenu(HWindow), CM_ALIGNMENTMARKS, MF_BYCOMMAND | MF_UNCHECKED); };
// Erase if going Marks -> no Marks
InvalidateRect(HWindow, NULL, !ShowAlignmentMarks);
};
void TFontWindow::WMGetMinMaxInfo( TMessage& Msg )
{
// Limit the minimum size of the window to 300x300, so the fonts don't
// get too small }
((POINT far *)Msg.LParam)[3].x = 300;
((POINT far *)Msg.LParam)[3].y = 300;
};
void TFontWindow::cmAbout( TMessage& )
{
GetApplication()->ExecDialog(new TDialog(this, "About"));
};
void TFontWindow::cmFonts( TMessage& )
{
CHOOSEFONT CF;
LOGFONT FontRec = MainFontRec;
CF.lStructSize = sizeof(CF);
CF.hwndOwner = HWindow;
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 = GetApplication()->hInstance;
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;
Rendering = 1;
InvalidateRect(HWindow, NULL, TRUE);
};
};
LPSTR TFontWindow::GetClassName()
{
return "OWLTrueTypeFontDemoWindow";
};
void TFontWindow::GetWindowClass(WNDCLASS _FAR & AWndClass)
{
TWindow::GetWindowClass(AWndClass);
AWndClass.hIcon = LoadIcon(GetApplication()->hInstance, MAKEINTRESOURCE(1));
};
void TFontWindow::WMSize( TMessage& Msg )
{
TWindow::WMSize(Msg);
if ((Msg.WParam == SIZENORMAL) || (Msg.WParam == SIZEFULLSCREEN))
{ Rendering = 1; };
};
// Define a class derived from TApplication
class THelloApp :public TApplication
{
public:
THelloApp(LPSTR AName, HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
: TApplication(AName, hInstance, hPrevInstance, lpCmdLine, nCmdShow) {};
virtual void InitMainWindow();
};
// Construct the THelloApp's MainWindow data member
void THelloApp::InitMainWindow()
{
MainWindow = new TFontWindow(NULL, "TrueType Font Lab");
}
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
THelloApp HelloApp ("HelloApp", hInstance, hPrevInstance,
lpCmdLine, nCmdShow);
HelloApp.Run();
return HelloApp.Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -