home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_14 / Font / FontFamily.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-12  |  9.0 KB  |  331 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   : fontfamily.cpp                                                         //
  10. //  Description: Font family enumeration                                             //
  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\ListView.h"
  26. #include "..\..\include\LogWindow.h"
  27.  
  28. #include "Resource.h"
  29. #include "TrueType.h"
  30. #include "FontFamily.h"
  31.  
  32. typedef struct
  33. {
  34.     unsigned    mask;
  35.     unsigned    flag;
  36.     const char *name;
  37. }    WordDef;
  38.  
  39.  
  40. const WordDef NTM_Flags[]    =
  41. {
  42.     {    0xFFFFFFFF, NTM_ITALIC,            "Italic"                },
  43.     {    0xFFFFFFFF, NTM_BOLD,            "Bold"                    },
  44.     {    0xFFFFFFFF, NTM_REGULAR,        "Regular"                },
  45.     {    0xFFFFFFFF, NTM_NONNEGATIVE_AC,    "Nonnegative AC"        },
  46.     {    0xFFFFFFFF, NTM_PS_OPENTYPE,    "Postscript OpenType"    },
  47.     {    0xFFFFFFFF, NTM_TT_OPENTYPE,    "TrueType OpenType"        },
  48.     {    0xFFFFFFFF, NTM_MULTIPLEMASTER,    "Multiple Master"        },
  49.     {    0xFFFFFFFF, NTM_TYPE1,            "Type 1 Font"            },
  50.     {    0xFFFFFFFF, NTM_DSIG,            "Digital Signature"        },
  51.     {    0xFFFFFFFF, 0,                    NULL                    }
  52. };
  53.  
  54.  
  55. const WordDef NTM_Family[] = 
  56. {
  57.     {    0x0F,    DEFAULT_PITCH,        "Default Pitch"        },
  58.     {    0x0F,    FIXED_PITCH,        "Fixed Pitch"        },
  59.     {    0x0F,    VARIABLE_PITCH,        "Variable Pitch"    },
  60.     {    0x0F,    MONO_FONT,            "Mono Font"            },
  61.     
  62.     {    0xFF0,    FF_DONTCARE,        "Dont Care"            },    
  63.     {    0xFF0,    FF_DECORATIVE,        "Decorative"        },
  64.     {    0xFF0,    FF_MODERN,            "Modern"            },
  65.     {    0xFF0,    FF_ROMAN,            "Roman"                },
  66.     {    0xFF0,    FF_SCRIPT,            "Script"            },
  67.     {    0xFF0,    FF_SWISS,            "Swiss"                },
  68.     {    0xFF0,    0,                    NULL                }
  69. };
  70.  
  71.  
  72. void DecodeFlag(unsigned flag, const WordDef * dic, TCHAR * result)
  73. {
  74.     result[0] = 0;
  75.  
  76.     for (; dic->name; dic ++)
  77.         if ( (flag & dic->mask)==dic->flag )
  78.         {
  79.             if ( result[0] )
  80.                 _tcscat(result, _T(", "));
  81.             _tcscat(result, dic->name);
  82.         }
  83. }
  84.  
  85.  
  86. void ListFonts(KListView * pList)
  87. {
  88.     const TCHAR Key_Fonts[] = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
  89.  
  90.     HKEY hKey;
  91.  
  92.     if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key_Fonts, 0, KEY_READ, & hKey)==ERROR_SUCCESS )
  93.     {
  94.         for (int i=0; ; i++)
  95.         {
  96.             TCHAR szValueName[MAX_PATH];
  97.             BYTE  szValueData[MAX_PATH];
  98.  
  99.             DWORD nValueNameLen = MAX_PATH;
  100.             DWORD nValueDataLen = MAX_PATH;
  101.             DWORD dwType;
  102.  
  103.             if ( RegEnumValue(hKey, i, szValueName, & nValueNameLen, NULL,
  104.                     & dwType, szValueData, & nValueDataLen) != ERROR_SUCCESS )
  105.                 break;
  106.  
  107.             pList->AddItem(0, szValueName);
  108.             pList->AddItem(1, (const char *) szValueData);
  109.         }
  110.         RegCloseKey(hKey);
  111.     }
  112. }
  113.  
  114.  
  115. int KEnumFontFamily::EnumProc(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, int FontType)
  116. {
  117.     if ( (FontType & m_nType)==0 )
  118.         return TRUE;
  119.  
  120.     if ( m_nLogFont < MAX_LOGFONT )
  121.         m_LogFont[m_nLogFont ++] = lpelfe->elfLogFont;
  122.  
  123.     m_pList->AddItem(0, (const char *) lpelfe->elfFullName);
  124.     m_pList->AddItem(1, (const char *) lpelfe->elfScript);
  125.     m_pList->AddItem(2, (const char *) lpelfe->elfStyle);
  126.     m_pList->AddItem(3, (const char *) lpelfe->elfLogFont.lfFaceName);
  127.  
  128.     m_pList->AddItem(4, lpelfe->elfLogFont.lfHeight);
  129.     m_pList->AddItem(5, lpelfe->elfLogFont.lfWidth);
  130.     m_pList->AddItem(6, lpelfe->elfLogFont.lfWeight);
  131.  
  132.     TCHAR Result[MAX_PATH];
  133.  
  134.     DecodeFlag(lpntme->ntmTm.ntmFlags, NTM_Flags, Result);
  135.     m_pList->AddItem(7, Result);
  136.  
  137.     DecodeFlag(lpelfe->elfLogFont.lfPitchAndFamily, NTM_Family, Result);
  138.     m_pList->AddItem(8, Result);
  139.  
  140.     return TRUE;
  141. }
  142.  
  143.  
  144. void KEnumFontFamily::EnumFontFamilies(HDC hdc, KListView * pList, BYTE charset, 
  145.                                        TCHAR * FaceName, unsigned type)
  146. {
  147.     m_pList       = pList;
  148.     m_nLogFont = 0;
  149.     m_nType    = type;
  150.  
  151.     LOGFONT lf;
  152.     memset(& lf, 0, sizeof(lf));
  153.     lf.lfCharSet        = charset;
  154.     lf.lfFaceName[0]    = 0;
  155.  
  156.     if ( FaceName )
  157.         _tcscpy(lf.lfFaceName, FaceName);
  158.  
  159.     lf.lfPitchAndFamily = 0;
  160.  
  161.     EnumFontFamiliesEx(hdc, & lf, (FONTENUMPROC) EnumFontFamExProc, (LPARAM) this, 0); 
  162. }
  163.  
  164.  
  165. void KListViewCanvas::DecodeFontFile(const TCHAR * fontfile)
  166. {
  167.     TCHAR fullname[MAX_PATH];
  168.  
  169.     if ( _tcschr(fontfile, ':') )
  170.         _tcscpy(fullname, fontfile);
  171.     else
  172.     {
  173.         GetWindowsDirectory(fullname, MAX_PATH);
  174.         _tcscat(fullname, "\\Fonts\\");
  175.         _tcscat(fullname, fontfile);
  176.     }
  177.  
  178.     // ask frame window to create a new MDI child window to decode a font
  179.     SendMessage(m_hFrame, WM_USER+1, 0, (LPARAM) fullname);
  180. }
  181.  
  182.  
  183. void UnicodeRange(LOGFONT * pLogFont, HINSTANCE hInstance)
  184. {
  185.     HFONT hFont  = CreateFontIndirect(pLogFont);
  186.     HDC   hDC     = GetDC(NULL);
  187.     HGDIOBJ hOld = SelectObject(hDC, hFont);
  188.  
  189.     // query for size
  190.     DWORD size = GetFontUnicodeRanges(hDC, NULL);
  191.  
  192.     GLYPHSET * pGlyphSet = (GLYPHSET *) new BYTE[size];
  193.  
  194.     // get real data
  195.     pGlyphSet->cbThis = size;
  196.     size = GetFontUnicodeRanges(hDC, pGlyphSet);
  197.  
  198.     KLogWindow * pLog = new KLogWindow;
  199.  
  200.     assert(pLog);
  201.  
  202.     pLog->Create(hInstance, "UNICODE Range");
  203.  
  204.     pLog->Log("%s \r\n", pLogFont->lfFaceName);
  205.  
  206.     pLog->Log("cbSize   %d\r\n",            pGlyphSet->cbThis);
  207.     pLog->Log("flAccel  %d\r\n",            pGlyphSet->flAccel);
  208.     pLog->Log("cGlyphsSupported %d\r\n",  pGlyphSet->cGlyphsSupported);
  209.     pLog->Log("cRanges          %d\r\n",  pGlyphSet->cRanges);
  210.  
  211.     for (unsigned i=0; i<pGlyphSet->cRanges; i++)
  212.         pLog->Log("%3d %04x..%04x (%d)\r\n", i, 
  213.             pGlyphSet->ranges[i].wcLow, 
  214.             pGlyphSet->ranges[i].wcLow + pGlyphSet->ranges[i].cGlyphs -1,
  215.             pGlyphSet->ranges[i].cGlyphs);
  216.  
  217.     WORD gi[10];
  218.     size = GetGlyphIndices(hDC, "A Quick Brown Fox", 10, gi, GGI_MARK_NONEXISTING_GLYPHS);
  219.  
  220.     delete [] (BYTE *) pGlyphSet;
  221.  
  222.     SelectObject(hDC, hOld);
  223.     ReleaseDC(NULL, hDC);
  224.     DeleteObject(hFont);
  225. }
  226.  
  227.  
  228. LRESULT KListViewCanvas::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  229. {
  230.     switch( uMsg )
  231.     {
  232.         case WM_CREATE:
  233.             m_hWnd        = hWnd;
  234.             m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_DIBVIEW));
  235.  
  236.             {
  237.                 RECT rect;
  238.  
  239.                 GetClientRect(m_hWnd, & rect);
  240.                 m_Fonts.Create(hWnd, 101, 0, 0, rect.right, rect.bottom, m_hInst);
  241.             }
  242.  
  243. //            m_Fonts.AddIcon(LVSIL_SMALL, m_hInst, IDI_EMPTY);
  244. //          m_Fonts.AddIcon(LVSIL_SMALL, m_hInst, IDI_EQUAL);
  245. //          m_Fonts.AddIcon(LVSIL_SMALL, m_hInst, IDI_CHANGE);
  246.  
  247.             if ( m_bFamily )
  248.             {
  249.                 m_Fonts.AddColumn(0, 100, "Full Name");
  250.                 m_Fonts.AddColumn(1, 100, "Script");
  251.                 m_Fonts.AddColumn(2, 100, "Style");
  252.     
  253.                 m_Fonts.AddColumn(3, 80,  "Face Name");
  254.                 m_Fonts.AddColumn(4, 60,  "Height");
  255.                 m_Fonts.AddColumn(5, 60,  "Width");
  256.                 m_Fonts.AddColumn(6, 60,  "Weight");
  257.                 m_Fonts.AddColumn(7, 130, "Flags");
  258.                 m_Fonts.AddColumn(8, 130, "Family");
  259.  
  260.                 {
  261.                     HDC hdc = GetDC(NULL);
  262.                     enumfont.EnumFontFamilies(hdc, & m_Fonts, DEFAULT_CHARSET, NULL);
  263.                     ReleaseDC(NULL, hdc);
  264.                 }
  265.             }
  266.             else 
  267.             {
  268.                 m_Fonts.AddColumn(0, 100, "Name");
  269.                 m_Fonts.AddColumn(1, 100, "File");
  270.  
  271.                 ListFonts(& m_Fonts);
  272.             }
  273.  
  274.             return 0;
  275.  
  276.         case WM_SIZE:
  277.             MoveWindow(m_Fonts.GetHWND(), 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);    
  278.             return 0;
  279.  
  280.         case WM_NOTIFY:
  281.             if (wParam == 101)
  282.             {
  283.                 NM_LISTVIEW * pInfo = (NM_LISTVIEW *) lParam;
  284.                 
  285.                 if ( (pInfo->hdr.code == NM_RCLICK) && (pInfo->iItem != -1) ) 
  286.                 {                    
  287.                     POINT pt = pInfo->ptAction;
  288.                     
  289.                     ClientToScreen(m_hWnd, & pt);
  290.                     
  291.                     HMENU hMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_POPUP));
  292.  
  293.                     int id = TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_RIGHTBUTTON | TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY,
  294.                                  pt.x, pt.y, 0, m_hWnd, NULL);
  295.  
  296.                     DestroyMenu(hMenu);
  297.  
  298.                     if ( id==IDM_POP_DECODE )
  299.                     {
  300.                         if ( m_bFamily )
  301.                         {
  302.                             // ask frame window to create a new MDI child window to decode a font
  303.                             SendMessage(m_hFrame, WM_USER+2, 0, (LPARAM) & enumfont.m_LogFont[pInfo->iItem]);
  304.                         }
  305.                         else
  306.                         {
  307.                             TCHAR fontname[MAX_PATH];
  308.  
  309.                             m_Fonts.GetItemText(pInfo->iItem, 1, fontname, MAX_PATH);
  310.  
  311.                             DecodeFontFile(fontname);
  312.                         }
  313.  
  314.                         return TRUE;
  315.                     }
  316.  
  317.                     if ( id==IDM_POP_UNICODERANGE )
  318.                     {
  319.                         if ( m_bFamily )
  320.                             UnicodeRange(& enumfont.m_LogFont[pInfo->iItem], m_hInst);
  321.                     
  322.                         return TRUE;
  323.                     }
  324.                 }
  325.             }
  326.  
  327.         default:
  328.             return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
  329.     }
  330. }
  331.