home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 9.ddi / TTFONT.ZIP / TTFONT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  9.8 KB  |  330 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2. //
  3. // ttfont.cpp
  4.  
  5. #include <owl.h>
  6. #include <string.h>
  7. #include "ttfont.h"
  8. #include <math.h>
  9. #include <commdlg.h>
  10.  
  11. class TFontWindow: public TWindow
  12. {
  13. private:
  14.   LOGFONT  MainFontRec,
  15.            CornerFontRec,
  16.            BorlandFontRec;
  17.   COLORREF FanColor[10];
  18.   BOOL ShadowAll,
  19.        ShowAlignmentMarks,
  20.        Rendering;
  21. public:
  22.   TFontWindow( PTWindowsObject AParent, LPSTR ATitle );
  23.   virtual void cmAbout( TMessage& ) = [CM_FIRST + CM_ABOUT];
  24.   virtual void cmAlignmentMarks( TMessage& ) = [CM_FIRST + CM_ALIGNMENTMARKS];
  25.   virtual void cmFonts( TMessage& ) = [CM_FIRST + CM_FONTS];
  26.   virtual void cmShadows( TMessage& ) = [ CM_FIRST + CM_SHADOWS ];
  27.   virtual LPSTR GetClassName();
  28.   virtual void GetWindowClass(WNDCLASS _FAR & AWndClass);
  29.   virtual void Paint( HDC, PAINTSTRUCT& );
  30.   virtual void WMGetMinMaxInfo( TMessage& ) = [WM_FIRST + WM_GETMINMAXINFO];
  31.   virtual void WMSize( TMessage& ) = [WM_FIRST + WM_SIZE];
  32. };
  33.  
  34.  
  35. #define ROUND(x)  (floor(x + .5))
  36. #define SQR(x)    (pow(x,2))
  37.  
  38. TFontWindow::TFontWindow( PTWindowsObject AParent, LPSTR ATitle ) :
  39.                 TWindow( AParent, ATitle)
  40. {
  41.   AssignMenu(100);
  42.  
  43.   MainFontRec.lfHeight = 26;
  44.   MainFontRec.lfWidth = 10;
  45.   MainFontRec.lfEscapement = 0;
  46.   MainFontRec.lfOrientation = 0;
  47.   MainFontRec.lfWeight = FW_BOLD;
  48.   MainFontRec.lfItalic = 0;
  49.   MainFontRec.lfUnderline = 0;
  50.   MainFontRec.lfStrikeOut = 0;
  51.   MainFontRec.lfCharSet = ANSI_CHARSET;
  52.   MainFontRec.lfOutPrecision = OUT_DEFAULT_PRECIS;
  53.   MainFontRec.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  54.   MainFontRec.lfQuality = PROOF_QUALITY;
  55.   MainFontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
  56.   strcpy(MainFontRec.lfFaceName,"Times New Roman");
  57.  
  58.   CornerFontRec = MainFontRec;
  59.  
  60.   BorlandFontRec  = MainFontRec;
  61.   BorlandFontRec.lfHeight = 60;
  62.   BorlandFontRec.lfWidth = 0;   // choose best width for this height
  63.   BorlandFontRec.lfWeight = 900;
  64.   strcpy(BorlandFontRec.lfFaceName, "Arial");
  65.  
  66.   // Array of colors used to color the fan text
  67.   FanColor[0] = RGB(255,0,0);
  68.   FanColor[1] = RGB(128,0,0);
  69.   FanColor[2] = RGB(255,128,0);
  70.   FanColor[3] = RGB(80,80,0);
  71.   FanColor[4] = RGB(80,255,0);
  72.   FanColor[5] = RGB(0,128,0);
  73.   FanColor[6] = RGB(0,128,255);
  74.   FanColor[7] = RGB(0,0,255);
  75.   FanColor[8] = RGB(128,128,128);
  76.   FanColor[9] = RGB(255,0,0);
  77.  
  78.   ShadowAll = 0;
  79.   ShowAlignmentMarks = 0;
  80.   Rendering = 0;
  81. };
  82.  
  83.  
  84. LPCSTR ArcText = "TrueType";
  85. const char* WaitText = "Windows is rendering fonts...";
  86. const char* FanText = "Borland C++ for Windows";
  87. const char* BorlandText = "Borland";
  88. const int   Radius = 100;
  89. const float Deg2Rad = M_PI / 18;
  90.  
  91. void TFontWindow::Paint( HDC DC, PAINTSTRUCT& )
  92. {
  93.  
  94.           LOGFONT FontRec;
  95. OUTLINETEXTMETRIC FontMetric;
  96.               int FontHeight, x, y, j, k;
  97.              WORD BaseWidth, DesiredExtent, FanTextLen;
  98.             float Theta;
  99.            LPCSTR P;
  100.              RECT R;
  101.              long TE;
  102.  
  103.   P = ArcText;
  104.   FanTextLen = strlen(FanText);
  105.  
  106.   SaveDC(DC);
  107.  
  108.   if (Rendering)
  109.   {
  110.     // display a message that Windows is rendering fonts, please wait...
  111.     SetWindowText(HWindow, WaitText);
  112.   };
  113.  
  114.   FontRec = CornerFontRec;
  115.   SetBkMode(DC, TRANSPARENT);
  116.   SetTextColor(DC, RGB(128,128,128));
  117.   FontRec.lfHeight = FontRec.lfHeight * 2;
  118.   FontRec.lfWidth = floor(FontRec.lfWidth * 2.1);
  119.   SelectObject(DC, CreateFontIndirect(&FontRec));
  120.   TextOut(DC, 18, 5, "T", 1);
  121.   SetTextColor(DC, RGB(0,0,0));
  122.   TextOut(DC, 32, 13,"T", 1);
  123.  
  124.   GetClientRect(HWindow, &R);
  125.  
  126.   FontRec = MainFontRec;
  127.   DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
  128.   GetOutlineTextMetrics(DC, sizeof(FontMetric), &FontMetric);
  129.   FontHeight = FontMetric.otmTextMetrics.tmHeight;
  130.   SetViewportOrg(DC, FontHeight+2, 0);
  131.   R.right -= FontHeight+2;
  132.   BaseWidth = LOWORD(GetTextExtent(DC, FanText, FanTextLen));
  133.  
  134.   SelectObject(DC, GetStockObject(NULL_BRUSH));
  135.   if (ShowAlignmentMarks)
  136.   { Ellipse(DC, -R.right, -R.bottom, R.right, R.bottom);};
  137.   Ellipse(DC, -(Radius-5), -(Radius-5), (Radius-5), Radius-5);
  138.   Ellipse(DC, -(Radius-10), -(Radius-10), (Radius-10), Radius-10);
  139.  
  140.   SetTextColor(DC, FanColor[0]);
  141.   for (int d = 27; d <= 36; d++)
  142.   {
  143.     x = ROUND(Radius * cos(d * Deg2Rad));
  144.     y = ROUND(Radius * sin(-d * Deg2Rad)); // -d because y axis is inverted
  145.  
  146.     Theta = -d * Deg2Rad;
  147.     if (x)
  148.       { Theta = atan((R.right / (R.bottom * 1.0)) * (y / (x * 1.0))); };
  149.     j = ROUND(R.right * cos(Theta));
  150.     k = ROUND(R.bottom * sin(Theta));
  151.  
  152.     if (ShowAlignmentMarks)
  153.     {
  154.       MoveTo(DC, x,y);
  155.       LineTo(DC, j,k);
  156.     };
  157.  
  158.     DesiredExtent = ROUND(sqrt(SQR(x*1.0 - j) + SQR(y*1.0 - k))) - 5;
  159.     FontRec = MainFontRec;
  160.     FontRec.lfEscapement = d * 100;
  161.     FontRec.lfWidth = floor((FontMetric.otmTextMetrics.tmAveCharWidth) * (DesiredExtent / (BaseWidth * 1.0)));
  162.     DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
  163.     TE = GetTextExtent(DC, FanText, FanTextLen);
  164.  
  165.     for ( ;(LOWORD(TE) > DesiredExtent) && (FontRec.lfWidth); FontRec.lfWidth-- )
  166.     { // Shave off some character width until the string fits
  167.       DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
  168.       TE = GetTextExtent(DC, FanText, FanTextLen);
  169.     };
  170.  
  171.     // Expand the string if necessary to make it fit the desired extent
  172.     if (LOWORD(TE) < DesiredExtent)
  173.       { SetTextJustification(DC,DesiredExtent - LOWORD(TE), 3); };
  174.     if (ShadowAll)
  175.     {
  176.       SetTextColor(DC, RGB(0,0,0));
  177.       TextOut(DC, x+2, y+1, FanText, FanTextLen);
  178.     };
  179.     SetTextColor(DC, FanColor[d - 27]);
  180.     TextOut(DC, x, y, FanText, FanTextLen);
  181.     SetTextJustification(DC,0,0);  // clear justifier's internal error accumulator
  182.  
  183.     if (P[0])
  184.     {
  185.       FontRec = CornerFontRec;
  186.       FontRec.lfEscapement = (d+10) * 100;
  187.       FontRec.lfWidth = 0;
  188.       DeleteObject(SelectObject(DC, CreateFontIndirect(&FontRec)));
  189.       SetTextColor(DC, 0);
  190.       x = floor((Radius - FontHeight - 5) * cos(d * Deg2Rad));
  191.       y = floor((Radius - FontHeight - 5) * sin(-d * Deg2Rad));
  192.       TextOut(DC, x, y, P, 1);
  193.       P++;
  194.     };
  195.   };
  196.  
  197.   DeleteObject(SelectObject(DC, CreateFontIndirect(&BorlandFontRec)));
  198.   TE = GetTextExtent(DC, BorlandText, strlen(BorlandText));
  199.   SetTextColor(DC, RGB(0,0,0));
  200.   TextOut(DC, R.right - LOWORD(TE), R.bottom - HIWORD(TE), BorlandText, strlen(BorlandText));
  201.   SetTextColor(DC, RGB(255,0,0));
  202.   TextOut(DC, R.right - LOWORD(TE) - 5, R.bottom - HIWORD(TE), BorlandText, strlen(BorlandText));
  203.  
  204.   if (Rendering)
  205.   {
  206.     // restore the window caption to the proper title string
  207.     SetWindowText(HWindow, Title);
  208.     // clear the rendering flag.  It will be set again when the window is resized (WMSIZE)
  209.     Rendering = 0;
  210.   };
  211.  
  212.   DeleteObject(SelectObject(DC, GetStockObject(SYSTEM_FONT)));
  213.   RestoreDC(DC, -1);
  214. };
  215.  
  216.  
  217. void TFontWindow::cmShadows( TMessage& )
  218. {
  219.   ShadowAll = !ShadowAll;
  220.   if (ShadowAll)
  221.   { CheckMenuItem(GetMenu(HWindow), CM_SHADOWS, MF_BYCOMMAND | MF_CHECKED); }
  222.   else
  223.   { CheckMenuItem(GetMenu(HWindow), CM_SHADOWS, MF_BYCOMMAND | MF_UNCHECKED); };
  224.  
  225.   // Erase if going Shadow -> no Shadow
  226.   InvalidateRect(HWindow, NULL, !ShadowAll);
  227. };
  228.  
  229. void TFontWindow::cmAlignmentMarks( TMessage& )
  230. {
  231.   ShowAlignmentMarks = !ShowAlignmentMarks;
  232.   if (ShowAlignmentMarks)
  233.   { CheckMenuItem(GetMenu(HWindow), CM_ALIGNMENTMARKS, MF_BYCOMMAND | MF_CHECKED); }
  234.   else
  235.   { CheckMenuItem(GetMenu(HWindow), CM_ALIGNMENTMARKS, MF_BYCOMMAND | MF_UNCHECKED); };
  236.  
  237.   // Erase if going Marks -> no Marks
  238.   InvalidateRect(HWindow, NULL, !ShowAlignmentMarks);
  239. };
  240.  
  241. void TFontWindow::WMGetMinMaxInfo( TMessage& Msg )
  242. {
  243.   // Limit the minimum size of the window to 300x300, so the fonts don't
  244.   //  get too small }
  245.   ((POINT far *)Msg.LParam)[3].x = 300;
  246.   ((POINT far *)Msg.LParam)[3].y = 300;
  247. };
  248.  
  249.  
  250. void TFontWindow::cmAbout( TMessage& )
  251. {
  252.   GetApplication()->ExecDialog(new TDialog(this, "About"));
  253. };
  254.  
  255. void TFontWindow::cmFonts( TMessage& )
  256. {
  257.   CHOOSEFONT CF;
  258.   LOGFONT FontRec = MainFontRec;
  259.  
  260.   CF.lStructSize = sizeof(CF);
  261.   CF.hwndOwner = HWindow;
  262.   CF.Flags = CF_ANSIONLY | CF_TTONLY | CF_SCREENFONTS
  263.          | CF_INITTOLOGFONTSTRUCT | CF_ENABLETEMPLATE;
  264.   CF.nFontType = SCREEN_FONTTYPE;
  265.   CF.lpLogFont = &FontRec;
  266.   CF.nSizeMin = 20;
  267.   CF.nSizeMax = 20;
  268.   CF.lpTemplateName = "FontDlg";
  269.   CF.hInstance = GetApplication()->hInstance;
  270.  
  271.   if (ChooseFont(&CF))
  272.   {
  273.     // Only get the font name, weight, and italics - we don't care about size }
  274.     strcpy(MainFontRec.lfFaceName, FontRec.lfFaceName);
  275.     MainFontRec.lfWeight = FontRec.lfWeight;
  276.     MainFontRec.lfItalic = FontRec.lfItalic;
  277.     Rendering = 1;
  278.     InvalidateRect(HWindow, NULL, TRUE);
  279.   };
  280. };
  281.  
  282.  
  283. LPSTR TFontWindow::GetClassName()
  284. {
  285.   return "OWLTrueTypeFontDemoWindow";
  286. };
  287.  
  288.  
  289. void TFontWindow::GetWindowClass(WNDCLASS _FAR & AWndClass)
  290. {
  291.  TWindow::GetWindowClass(AWndClass);
  292.  AWndClass.hIcon = LoadIcon(GetApplication()->hInstance, MAKEINTRESOURCE(1));
  293. };
  294.  
  295. void TFontWindow::WMSize( TMessage& Msg )
  296. {
  297.  TWindow::WMSize(Msg);
  298.  if ((Msg.WParam == SIZENORMAL) || (Msg.WParam == SIZEFULLSCREEN))
  299.  {  Rendering = 1; };
  300. };
  301.  
  302.  
  303.  
  304.  
  305.  
  306. // Define a class derived from TApplication
  307. class THelloApp :public TApplication
  308. {
  309. public:
  310.   THelloApp(LPSTR AName, HINSTANCE hInstance, HINSTANCE hPrevInstance,
  311.     LPSTR lpCmdLine, int nCmdShow)
  312.     : TApplication(AName, hInstance, hPrevInstance, lpCmdLine, nCmdShow) {};
  313.   virtual void InitMainWindow();
  314. };
  315.  
  316. // Construct the THelloApp's MainWindow data member
  317. void THelloApp::InitMainWindow()
  318. {
  319.   MainWindow = new TFontWindow(NULL, "TrueType Font Lab");
  320. }
  321.  
  322. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  323.   LPSTR lpCmdLine, int nCmdShow)
  324. {
  325.   THelloApp HelloApp ("HelloApp", hInstance, hPrevInstance,
  326.     lpCmdLine, nCmdShow);
  327.   HelloApp.Run();
  328.   return HelloApp.Status;
  329. }
  330.