home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_14 / Font / Font.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  13.6 KB  |  583 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : font.cpp                                                             //
  10. //  Description: Font demo program, Chapter 14                                       //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define _WIN32_WINNT 0x0500
  16. #define NOCRYPT
  17.  
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include <tchar.h>
  21. #include <math.h>
  22.  
  23. #include "..\..\include\win.h"
  24. #include "..\..\include\Canvas.h"
  25. #include "..\..\include\Toolbar.h"
  26. #include "..\..\include\Status.h"
  27. #include "..\..\include\FrameWnd.h"
  28. #include "..\..\include\ScrollCanvas.h"
  29. #include "..\..\include\ListView.h"
  30. #include "..\..\include\MVC.h"
  31. #include "..\..\include\logfont.h"
  32.  
  33. #include "CharSet.h"
  34.  
  35. #include "Resource.h"
  36. #include "Raster.h"
  37. #include "TrueType.h"
  38. #include "FontFamily.h"
  39.  
  40. ///////////////// Raster Font View /////////////////
  41.  
  42. class KRasterFontView : public KView
  43. {
  44.     TCHAR    m_nFontName[MAX_PATH];
  45.  
  46.     virtual int OnDraw(HDC hDC, const RECT * rcPaint)
  47.     {
  48.         int height = DecodeRasterFont(hDC, m_nFontName);
  49.  
  50.         if ( height > m_nPixelHeight )
  51.         {
  52.             m_nPixelHeight = height;
  53.             return View_Resize;
  54.         }
  55.  
  56.         return View_NoChange;
  57.     }
  58.  
  59. public:
  60.  
  61.     virtual int OnCommand(int cmd, HWND hWnd)
  62.     {
  63.         return View_NoChange;
  64.     }
  65.     
  66.     KRasterFontView(const TCHAR * fontname)
  67.     {
  68.         if ( fontname )
  69.             _tcscpy(m_nFontName, fontname);
  70.         else
  71.             m_nFontName[0] = 0;
  72.     }
  73. };
  74.  
  75.  
  76. void ZoomRect(HDC hDC, int x0, int y0, int x1, int y1, int dx, int dy, int zoom)
  77. {
  78.     // use black pen for border
  79.     HGDIOBJ hOld = SelectObject(hDC, GetStockObject(BLACK_PEN));
  80.  
  81.     for (int y=y0; y<y1; y++)
  82.     for (int x=x0; x<x1; x++)
  83.     {
  84.         COLORREF c = GetPixel(hDC, x, y);
  85.  
  86.         HBRUSH  hBrush = CreateSolidBrush(c);
  87.         HGDIOBJ hOld   = SelectObject(hDC, hBrush);
  88.  
  89.         Rectangle(hDC, dx+(x-x0)*(zoom+1), dy+(y-y0)*(zoom+1), 
  90.             dx+(x-x0)*(zoom+1)+zoom+2, 
  91.             dy+(y-y0)*(zoom+1)+zoom+2);
  92.         SelectObject(hDC, hOld);
  93.         DeleteObject(hBrush);
  94.     }
  95.  
  96.     SelectObject(hDC, hOld);
  97. }
  98.  
  99.  
  100. class KTrueTypeFontView : public KView
  101. {
  102.     LOGFONT      m_LogFont;
  103.     KTrueType m_tt;
  104.     int       m_option;
  105.     
  106.     int          m_Start;
  107.     int          m_PageSize;
  108.  
  109.     virtual int OnDraw(HDC hDC, const RECT * rcPaint)
  110.     {
  111.         int i;
  112.         double scale;
  113.  
  114.         switch ( m_option )
  115.         {
  116.             case IDM_VIEW_SMALL:
  117.                 scale = 32 * m_tt.GetScale();
  118.                 for (i=0; i<256; i++)
  119.                     m_tt.DrawTTGlyph(hDC, 20+(i%16)*42, 40+(i/16)*42, m_Start+i, scale, 0);
  120.                 break;
  121.  
  122.             case IDM_VIEW_MEDIUM:
  123.                 scale = 96 * m_tt.GetScale();
  124.                 for (i=0; i<70; i++)
  125.                     m_tt.DrawTTGlyph(hDC, 50+(i%10)*96, 80+(i/10)*96, m_Start+i, scale, 0);
  126.                 break;
  127.  
  128.             case IDM_VIEW_LARGE:
  129.             case IDM_VIEW_LARGEPOINT:
  130.             case IDM_VIEW_METRICS:
  131.                 scale = 384 * m_tt.GetScale();
  132.                 m_tt.DrawTTGlyph(hDC, 200, 500, m_Start, scale, m_option);
  133.                 break;
  134.  
  135.  
  136.             case IDM_VIEW_COMPARE:
  137.                 // compare simple rasterization with TrueType font engine
  138.                 scale = 32 * m_tt.GetScale(); // 32 point
  139.                 
  140.                 m_tt.DrawTTGlyph(hDC, 20,    40, 36, scale, false); // ABC
  141.                 m_tt.DrawTTGlyph(hDC, 20+26, 40, 37, scale, false); // ABC
  142.                 m_tt.DrawTTGlyph(hDC, 20+49, 40, 38, scale, false); // ABC
  143.                 
  144.                 ZoomRect(hDC, 18, 17, 92, 17+25, 100,  10, 4);
  145.                 
  146.                 {
  147.                     HFONT hFont = CreateFont(- 36 /** GetDeviceCaps(hDC, LOGPIXELSY) / 72*/,
  148.                              0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, 
  149.                              ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
  150.                              PROOF_QUALITY, VARIABLE_PITCH, "Times New Roman");
  151.                     HGDIOBJ hOld = SelectObject(hDC, hFont);
  152.  
  153.                     TextOut(hDC, 20, 145,"ABC", 3);
  154.                     SelectObject(hDC, hOld);
  155.                     DeleteObject(hFont);
  156.                 }
  157.  
  158.                 ZoomRect(hDC, 18, 145+7, 92, 145+7+26, 100, 150, 4);
  159.                 
  160.                 scale = 32 * 5 * m_tt.GetScale();
  161.  
  162.                 m_tt.DrawTTGlyph(hDC, 500,      180, 36, scale, false); // ABCD
  163.                 m_tt.DrawTTGlyph(hDC, 500+24*5, 180, 37, scale, false); // ABCD
  164.                 m_tt.DrawTTGlyph(hDC, 500+45*5, 180, 38, scale, false); // ABCD
  165.         }
  166.  
  167.         return View_NoChange;
  168.     }
  169.  
  170. public:
  171.  
  172.     virtual int OnCommand(int cmd, HWND hWnd)
  173.     {
  174.         if ( cmd==m_option )
  175.             return View_NoChange;
  176.  
  177.         switch ( cmd )
  178.         {
  179.             case IDM_VIEW_COMPARE:
  180.             case IDM_VIEW_SMALL : m_PageSize = 256; m_option = cmd; break;
  181.             
  182.             case IDM_VIEW_MEDIUM: m_PageSize = 70;  m_option = cmd; break;
  183.             
  184.             case IDM_VIEW_LARGEPOINT:
  185.             case IDM_VIEW_METRICS:
  186.             case IDM_VIEW_LARGE : m_PageSize = 1;   m_option = cmd; break;
  187.             
  188.             case IDM_VIEW_PAGEUP  : m_Start = max(0, m_Start- m_PageSize); break;
  189.             case IDM_VIEW_PAGEDOWN: m_Start += m_PageSize; break;
  190.  
  191.             default:
  192.                 return View_NoChange;
  193.         }
  194.         
  195.         return View_Redraw;
  196.     }
  197.     
  198.     int OnKey(int vkey)
  199.     {
  200.         switch ( vkey )
  201.         {
  202.             case VK_PRIOR   : m_Start = max(0, m_Start- m_PageSize); break;
  203.             case VK_NEXT    : m_Start += m_PageSize; break;
  204.             
  205.             case VK_LEFT    :
  206.             case VK_UP      : m_Start = max(0, m_Start-1); break;
  207.  
  208.             case VK_DOWN    :
  209.             case VK_RIGHT   : m_Start ++; break;
  210.  
  211.             default            : return View_NoChange;
  212.         }
  213.  
  214.         return View_Redraw;
  215.     }
  216.  
  217.     KTrueTypeFontView(const LOGFONT * pLogFont, HINSTANCE hInst)
  218.     {
  219.         m_option   = IDM_VIEW_SMALL;
  220.         m_Start    = 0;
  221.         m_PageSize = 256;
  222.  
  223.         m_LogFont = * pLogFont;
  224.  
  225.         m_tt.Load(m_LogFont);
  226.  
  227.         LogTableDirectory(m_tt, hInst, m_LogFont.lfFaceName);
  228.     }
  229. };
  230.  
  231.  
  232. //////// GLYPH View ///////////
  233.  
  234. class KGlyphView : public KView
  235. {
  236.     int        m_nCommand;
  237.  
  238.     void TestCharGlyph(HDC hDC, const RECT * rcPaint);
  239.     void TestGlyphDesign(HDC hDC, const RECT * rcPaint);
  240.  
  241.     virtual int OnDraw(HDC hDC, const RECT * rcPaint)
  242.     {
  243.         switch ( m_nCommand )
  244.         {
  245.             case IDM_VIEW_CHARGLYPH:
  246.                 TestCharGlyph(hDC, rcPaint);
  247.                 break;
  248.  
  249.             case IDM_VIEW_GLYPHDESIGN:
  250.                 TestGlyphDesign(hDC, rcPaint);
  251.                 break;
  252.         }
  253.         
  254.         return View_NoChange;
  255.     }
  256.  
  257. public:
  258.  
  259.     virtual int OnCommand(int cmd, HWND hWnd)
  260.     {
  261.         if ( ((cmd==IDM_VIEW_CHARGLYPH) || (cmd==IDM_VIEW_GLYPHDESIGN)) && (cmd!=m_nCommand) )
  262.         {
  263.             m_nCommand = cmd;
  264.             return View_Redraw;
  265.         }
  266.  
  267.         return View_NoChange;
  268.     }
  269.     
  270.     KGlyphView(void)
  271.     {
  272.         m_nCommand  = IDM_VIEW_CHARGLYPH;
  273.     }
  274. };
  275.  
  276.  
  277. const char * TypeFaces[] =
  278. {
  279.     "Georgia",
  280.     "Times New Roman",
  281.     "Clarendon",
  282.     "Bodoni Black",
  283.  
  284.     "Arial",
  285.     "Microsoft Sans Serif",
  286.     "Verdana",
  287.     "Eras Demi ITC",
  288.  
  289.     "Curier New",
  290.     "Dark Courier",
  291.     "Lucica Console",
  292.     "Letter Gothic",
  293.  
  294.     "Vivaldi",
  295.     "Tempus Sans ITC",
  296.     "Viner Hand ITC",
  297.     "Comic Sans MS",
  298.  
  299.     "Old English",
  300.     "BD Renaissance",
  301.     "TreeHouse",
  302.     "Unicorn"
  303. };
  304.  
  305.  
  306. const char * TypeFamily[]=
  307. {
  308.     "Roman",
  309.     "Swiss",
  310.     "Modern",
  311.     "Script",
  312.     "Decorative"
  313. };
  314.  
  315.  
  316. void TextOutWH(HDC hDC, int x, int y, WCHAR text[], int len)
  317. {
  318.     TEXTMETRIC tm;
  319.  
  320.     GetTextMetrics(hDC, & tm);
  321.  
  322.     for (int i=0; i<len; i++)
  323.     {
  324.         TextOutW(hDC, x, y, & text[i], 1);
  325.     
  326.         if (i==0) y+=40; else y+= 45;
  327.     }
  328. }
  329.  
  330.  
  331. void KGlyphView::TestCharGlyph(HDC hDC, const RECT * rcPaint)
  332. {
  333.     int xx = 10;
  334.  
  335.     SetTextAlign(hDC, TA_BASELINE);
  336.  
  337.     for (int i=0; i<sizeof(TypeFaces)/sizeof(TypeFaces[i]); i++)
  338.     {
  339.         KLogFont logfont(52, TypeFaces[i]);
  340.         HFONT hFont = logfont.Create();
  341.  
  342.         SelectObject(hDC, hFont);
  343.  
  344.         int width = 0 ;
  345.         GetCharWidth(hDC, 'A', 'A', & width);
  346.  
  347.         TextOut(hDC, xx, 50, "A", 1);
  348.         xx += width + 5;
  349.  
  350.         TextOut(hDC, 20+(i%4)*220, 100+(i/4)*50, TypeFamily[i/4], strlen(TypeFamily[i/4]));
  351.         SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  352.         DeleteObject(hFont);
  353.     }
  354.  
  355.     {
  356.         KLogFont logfont(52, "MingLiu");
  357.         logfont.SetCharSet(GB2312_CHARSET);
  358.  
  359.         HFONT hFont = logfont.Create();
  360.         SelectObject(hDC, hFont);
  361.  
  362.         // glyph sharing
  363.         WCHAR Share[] = { 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, ' ', ' ',
  364.             0x5CAD, 0x5CF0, 0x5CFB, 0x5CED, 0x5CFD, 0x5D1A, 0
  365.         };
  366.  
  367.         TextOutW(hDC, 10, 400, Share, wcslen(Share));
  368.  
  369.         // ligature
  370.         WCHAR Ligature[] = { 'A', '+', 'E', '=', 0xC6, ' ', ' ',
  371.             'C', '+', 'E', '=', 0x8C, ' ', ' ',
  372.             'f', '+', 'i', '=', 0xFB01, ' ', ' ',
  373.             'f', '+', 'l', '=', 0xFB02, 0 };
  374.  
  375.         TextOutW(hDC, 10, 460, Ligature, wcslen(Ligature));
  376.  
  377.         // context
  378.         WCHAR Context[] = { '(', 0x6A2A, ')', ' ',     0x3010, 0x6A2A, 0x3011, 0 };
  379.  
  380.         WCHAR Context2[] = { 0xFE35, 0x7AD6, 0xFE36, 0 };
  381.         WCHAR Context3[] = { 0xFE3B, 0x7AD6, 0xFE3C, 0 };
  382.         
  383.         TextOutW(hDC,   10, 540, Context, wcslen(Context));
  384.         TextOutWH(hDC, 250, 500, Context2, wcslen(Context2));
  385.         TextOutWH(hDC, 350, 500, Context3, wcslen(Context3));
  386.  
  387.         SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  388.         DeleteObject(hFont);
  389.     }
  390.  
  391.     {
  392.         KLogFont logfont(52, "Tahoma");
  393.         logfont.SetCharSet(ARABIC_CHARSET);
  394.  
  395.         HFONT hFont = logfont.Create();
  396.         SelectObject(hDC, hFont);
  397.  
  398.         // context
  399.         WCHAR Context[] = { 0xFB56, ' ', 0xFB57, ' ', 0xFB58, ' ', 0xFB59, ' ', ' ', 
  400.                             0xFB7A, ' ', 0xFB7B, ' ', 0xFB7C, ' ', 0xFB7D, ' ', ' ',
  401.                             0xFB8E, ' ', 0xFB8F, ' ', 0xFB90, ' ', 0xFB91, ' ', ' ', 0 };
  402.         
  403.         TextOutW(hDC, 10, 620, Context, wcslen(Context));
  404.  
  405.         SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  406.         DeleteObject(hFont);
  407.  
  408.     }
  409. }
  410.  
  411.  
  412. void KGlyphView::TestGlyphDesign(HDC hDC, const RECT * rcPaint)
  413. {
  414.     KLogFont logfont(200, "Times New Roman");
  415.  
  416.     HFONT hFont = logfont.Create();
  417.     SelectObject(hDC, hFont);
  418.  
  419.     TextOut(hDC, 10, 10, "Glyph Design", 12);
  420.  
  421.     SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  422.     DeleteObject(hFont);
  423.  
  424. /*    HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0xFF, 0, 0));
  425.     SelectObject(hDC, hPen);
  426.     MoveToEx(hDC, 0, 200, NULL);
  427.     LineTo(hDC, 100, 200);
  428.  
  429.     SelectObject(hDC, GetStockObject(BLACK_PEN));
  430.     MoveToEx(hDC, 10, 0, NULL);
  431.     LineTo(hDC, 12, 200);
  432.     LineTo(hDC, 14, 0);
  433.     LineTo(hDC, 10, 0);
  434. */
  435. }
  436.  
  437.  
  438. ////////////////////////// MDI Frame Window
  439.  
  440. const int Translate[] =
  441. {
  442.     IDM_FILE_CLOSE,
  443.     IDM_FILE_EXIT,
  444.     IDM_WINDOW_TILE,
  445.     IDM_WINDOW_CASCADE,
  446.     IDM_WINDOW_ARRANGE,
  447.     IDM_WINDOW_CLOSEALL
  448. };
  449.  
  450.  
  451. class KMyMDIFrame : public KMDIFrame
  452. {
  453.     void GetWndClassEx(WNDCLASSEX & wc)
  454.     {
  455.         KMDIFrame::GetWndClassEx(wc);
  456.  
  457.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_FONT));
  458.     }
  459.  
  460.     void CreateMDIChild(KCanvas * canvas, const TCHAR * klass, const TCHAR * title)
  461.     {
  462.         MDICREATESTRUCT mdic;
  463.  
  464.         mdic.szClass = klass;
  465.         mdic.szTitle = title;
  466.         mdic.hOwner  = m_hInst;
  467.         mdic.x       = CW_USEDEFAULT;
  468.         mdic.y       = CW_USEDEFAULT;
  469.         mdic.cx      = CW_USEDEFAULT;
  470.         mdic.cy      = CW_USEDEFAULT;
  471.         mdic.style   = WS_VISIBLE | WS_BORDER;
  472.         mdic.lParam  = (LPARAM) canvas;
  473.  
  474.         HWND hWnd = (HWND) SendMessage(m_hMDIClient, WM_MDICREATE, 0, (LPARAM) & mdic);
  475.     }
  476.  
  477.     void CreateListViewCanvas(bool bFamily)
  478.     {
  479.         KListViewCanvas * pList = new KListViewCanvas(bFamily);
  480.  
  481.         if ( pList )
  482.             if ( pList->Initialize(m_hInst, m_pStatus, m_hWnd) )
  483.                 if ( bFamily )
  484.                     CreateMDIChild(pList, _T("ListViewCanvas"), _T("Font Families"));
  485.                 else
  486.                     CreateMDIChild(pList, _T("ListViewCanvas"), _T("Fonts"));
  487.             else
  488.                 delete pList;
  489.     }
  490.  
  491.     BOOL CreateCanvas(KView * pView, const TCHAR * Title)
  492.     {
  493.         if ( pView==NULL )
  494.             return FALSE;
  495.  
  496.         KMDICanvas   * pCanvas = new KMDICanvas();
  497.  
  498.         if ( pCanvas )
  499.         {
  500.             if ( pCanvas->Initialize(m_hInst, m_pStatus, pView, IDR_DIBVIEW, IDI_FONT) )
  501.             {
  502.                 CreateMDIChild(pCanvas, pCanvas->GetClassName(), Title);
  503.                 return TRUE;
  504.             }
  505.  
  506.             delete pCanvas;
  507.         }
  508.  
  509.         delete pView;
  510.         return FALSE;
  511.     }
  512.  
  513.     virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
  514.     {
  515.         switch ( LOWORD(wParam) )
  516.         {
  517.             case IDM_FILE_FONTFAMILY:
  518.                 CreateListViewCanvas(true);
  519.                 return TRUE;
  520.  
  521.             case IDM_FILE_FONT:
  522.                 CreateListViewCanvas(false);
  523.                 return TRUE;
  524.  
  525.             case IDM_FILE_CODEPAGE:
  526.                 CreateCanvas(new KCharSetView(), _T("Code Page"));
  527.                 return TRUE;
  528.  
  529.             case IDM_FILE_GLYPH:
  530.                 CreateCanvas(new KGlyphView(), _T("Glyph"));
  531.                 return TRUE;
  532.         }
  533.  
  534.         return FALSE;
  535.     }
  536.  
  537.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  538.     {
  539.         if ( uMsg == WM_USER+1 )
  540.             CreateCanvas(new KRasterFontView((const TCHAR *) lParam), "Raster Font");
  541.  
  542.         if ( uMsg == WM_USER+2 )
  543.             CreateCanvas(new KTrueTypeFontView((const LOGFONT *) lParam, m_hInst), "TrueType Font");
  544.  
  545.         return KMDIFrame::WndProc(hWnd, uMsg, wParam, lParam);
  546.     }
  547.  
  548. public:
  549.     KMyMDIFrame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
  550.         KToolbar * pToolbar, KStatusWindow * pStatus) :
  551.         KMDIFrame(hInstance, pButtons, nCount, pToolbar, pStatus, Translate)
  552.     {
  553.     }
  554. };
  555.  
  556.  
  557. const TBBUTTON tbButtons[] =
  558. {
  559.     { STD_FILENEW,     IDM_FILE_NEW,   TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILENEW,  0 },
  560.     { STD_FILEOPEN,  IDM_FILE_OPEN,  TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILEOPEN, 0 }
  561. };
  562.  
  563.  
  564. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
  565. {
  566.     KToolbar      toolbar;
  567.     KStatusWindow status;
  568.  
  569.     KMyMDIFrame frame(hInst, tbButtons, 2, & toolbar, & status);
  570.  
  571.     frame.CreateEx(0, _T("ClassName"), _T("Font"),
  572.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  573.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  574.         NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
  575.  
  576.     frame.ShowWindow(nShow);
  577.     frame.UpdateWindow();
  578.  
  579.     frame.MessageLoop();
  580.  
  581.     return 0;
  582. }
  583.