home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / w3_prog / s13382.arj / TTDMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-25  |  57.3 KB  |  1,956 lines

  1. //*************************************************************
  2. //  File name: ttdmp.c
  3. //
  4. //  Description:
  5. //
  6. //      WinMain and window procedure routines.
  7. //
  8. // This sample demonstrates the usage of new TrueType API available
  9. // in Windows 3.10.  The sample demonstrates the TrueType functions
  10. // GetOutlineTextMetrics() and GetRasterizerCaps() functions.  The
  11. // sample has the ability to dump the OUTLINETEXTMETRIC structure,
  12. // the NEWTEXTMETRIC structure, the PANOSE structure and the ENUMLOGFONT
  13. // structure for a TrueType font.  Also, the sample demonstrates the
  14. // use of the EnumFontFamilies() which is new to Win 3.10.  This
  15. // function can retrieve the new ENUMLOGFONT and NEWTEXTMETRIC 
  16. // information.
  17. //
  18. //
  19. // The sample also demonstrates how to use the ChooseFont and Print
  20. // common dialogs.  The sample allows the user to pick a font and
  21. // display a line of text using that font to the screen.  Also, the
  22. // user can print out the same line of text to a printer selected
  23. // through the Print common dialog.
  24. //
  25. // Development Team:
  26. //
  27. //      Don Miller
  28. //
  29. //
  30. // Written by Microsoft Product Support Services, Windows Developer Support
  31. // Copyright (c) 1992 Microsoft Corporation. All rights reserved.
  32. //*************************************************************
  33. #define PRINTING                    // needed so constants are defined
  34.  
  35. #ifndef _GLOBALINC
  36. #include "global.h"
  37. #endif
  38. #include <string.h>
  39. #include <drivinit.h>               // contains printing constants
  40. #include "tt.h"
  41.  
  42. // globals 
  43. HANDLE  ghInst            = NULL;
  44. HWND    ghWndMain         = NULL;
  45. char    szMainMenu[]      = "MainMenu";
  46. char    szMainClass[]     = "ttdmpClass";
  47. int     iCurrStructChoice = IDM_OTM;
  48.  
  49. //*************************************************************
  50. //
  51. //  WinMain()
  52. //
  53. //  Purpose:
  54. //
  55. //        Entry point for all Windows applications.
  56. //
  57. //
  58. //  Parameters:
  59. //
  60. //      HANDLE hInstance     - Handle to current instance
  61. //      HANDLE hPrevInstance - Handle to previous instance
  62. //      LPSTR  lpCmdLine     - Command-line arguments
  63. //      int    nCmdShow      - How window is initially displayed
  64. //      
  65. //
  66. //  Return: (int PASCAL)
  67. //
  68. //
  69. //  Comments:
  70. //
  71. //
  72. //  History:    Date       Author     Comment
  73. //              1/2/92     Don Miller Created
  74. //
  75. //*************************************************************
  76.  
  77. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  78. {
  79.     MSG msg;
  80.  
  81.     if (!hPrevInstance && !InitApplication(hInstance))
  82.             return(FALSE);       
  83.  
  84.     if (!InitInstance(hInstance, nCmdShow))
  85.         return(FALSE);
  86.  
  87.     while (GetMessage(&msg, NULL, NULL, NULL))
  88.     {
  89.         TranslateMessage(&msg);      
  90.         DispatchMessage(&msg);       
  91.     }
  92.     return(msg.wParam);      
  93.  
  94. } //*** WinMain
  95.  
  96. //*************************************************************
  97. //
  98. //  MainWndProc()
  99. //
  100. //  Purpose:
  101. //
  102. //        Main Window procedure.
  103. //
  104. //
  105. //  Parameters:
  106. //
  107. //      HWND     hWnd   - Handle to main window
  108. //      unsigned msg    - Message passed to application
  109. //      WORD     wParam - Additional message information
  110. //      LONG     lParam - Additional message information
  111. //      
  112. //
  113. //  Return: (long FAR PASCAL)
  114. //
  115. //
  116. //  Comments:
  117. //
  118. //
  119. //  History:    Date       Author     Comment
  120. //              1/2/92     Don Miller Created
  121. //
  122. //*************************************************************
  123.  
  124. long FAR PASCAL MainWndProc (HWND hWnd, unsigned msg, WORD wParam, LONG lParam)
  125. {
  126.     FARPROC lpProc;
  127.     static BOOL bTTAvail = FALSE, bTTCheck = FALSE;
  128.  
  129.     switch (msg) 
  130.     {
  131.         case WM_CREATE:
  132.         {
  133.             HMENU hMenu;
  134.  
  135.             // set global handles to NULL
  136.             pis.hCurrDevMode  = NULL;
  137.             pis.hCurrDevNames = NULL;
  138.             pis.hPrinterFont  = NULL;
  139.  
  140.             // check default struct menu choice
  141.             hMenu = GetMenu(hWnd);
  142.             CheckMenuItem(hMenu, iCurrStructChoice, MF_CHECKED);
  143.  
  144.             // set default text color to black
  145.             sis.crTextColor = RGB(0,0,0);
  146.  
  147.         }
  148.         break;
  149.  
  150.         case WM_PAINT:
  151.             {
  152.             PAINTSTRUCT       ps;
  153.             int               iOldMode;
  154.             HFONT             hOldFont;
  155.             DWORD             dwOldColor;
  156.  
  157.             BeginPaint(hWnd, &ps);
  158.  
  159.             // set so text background color is same as window backround color
  160.             iOldMode = SetBkMode(ps.hdc, TRANSPARENT);
  161.  
  162.             // check to see if TT is enabled; do only once
  163.             if (!bTTCheck)
  164.             {
  165.                bTTCheck = TRUE;
  166.  
  167.                // disable menu options if TT not available
  168.                if (!(bTTAvail = IsTTAvail(ps.hdc)))
  169.                {
  170.                   HMENU hMenu = GetMenu(hWnd);
  171.  
  172.                   // disable appropriate menu choices
  173.                   EnableMenuItem(hMenu, IDM_PRINT, MF_GRAYED);
  174.  
  175.                   CheckMenuItem(hMenu, iCurrStructChoice, MF_UNCHECKED);
  176.                   EnableMenuItem(hMenu, IDM_OTM, MF_GRAYED);
  177.                   EnableMenuItem(hMenu, IDM_TM, MF_GRAYED);
  178.                   EnableMenuItem(hMenu, IDM_PANOSE, MF_GRAYED);
  179.                   EnableMenuItem(hMenu, IDM_LF, MF_GRAYED);
  180.                }
  181.                else
  182.                {
  183.                   // tell user to pick a font
  184.                   TextOut(ps.hdc, 10, 10, "Choose a font from the File Fonts menu.", 39);
  185.  
  186.                }
  187.             }
  188.             // check to see if TT enabled
  189.             if (bTTAvail)
  190.             {
  191.                // if a screen font has been made use it
  192.                if (sis.hScreenFont != NULL)
  193.                   hOldFont = SelectObject(ps.hdc, sis.hScreenFont);
  194.  
  195.                // set text color to color selected by ChooseFont dialog
  196.                dwOldColor = SetTextColor(ps.hdc, sis.crTextColor);
  197.  
  198.                // dump struct menu choice
  199.                switch (iCurrStructChoice)
  200.                {
  201.                   case IDM_OTM:
  202.                      // dump OUTLINETEXTMETRIC stuff
  203.                      DumpOTMInfo(hWnd, ps.hdc);
  204.                      break;
  205.  
  206.                   case IDM_TM:
  207.                      // dump TEXTMETRIC stuff
  208.                      DumpTMInfo(hWnd, ps.hdc);
  209.                      break;
  210.  
  211.                   case IDM_PANOSE:
  212.                      // dump PANOSE stuff
  213.                      DumpPanoseInfo(hWnd, ps.hdc);
  214.                      break;
  215.  
  216.                   case IDM_LF:
  217.                      // dump LOGFONT stuff
  218.                      DumpLFInfo(hWnd, ps.hdc);
  219.                      break;
  220.  
  221.                   default:
  222.                      break;
  223.                }
  224.  
  225.                // reset text color
  226.                SetTextColor(ps.hdc, dwOldColor);
  227.  
  228.                // reselect old font back in to dc
  229.                if (sis.hScreenFont != NULL)
  230.                   SelectObject(ps.hdc, hOldFont);
  231.  
  232.             } // if TTAvail
  233.  
  234.             // reset background mode back to previous mode
  235.             SetBkMode(ps.hdc, iOldMode);
  236.  
  237.             EndPaint(hWnd, &ps);
  238.             }
  239.             break;
  240.  
  241.         case WM_COMMAND: 
  242.             switch ( wParam )
  243.             {
  244.                 case IDM_FONTS:
  245.                      // show ChooseFont common dialog box
  246.                      ShowFontBox(hWnd);
  247.                      break;
  248.  
  249.                 case IDM_PRINT:
  250.                      // show Print common dialog box
  251.                      ShowPrintBox(hWnd);
  252.                      break;
  253.  
  254.                 case IDM_PRINTSETUP:
  255.                      // show Print Setup common dialog box
  256.                      ShowPrintSetup(hWnd);
  257.                      break;
  258.  
  259.                 case IDM_EXIT:
  260.                      PostMessage( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L );
  261.                      break;
  262.  
  263.                 case IDM_ABOUT:
  264.                     // display About dialog box
  265.                     lpProc = MakeProcInstance(About, ghInst);
  266.                     DialogBox(ghInst, "AboutBox", hWnd, lpProc);    
  267.                     FreeProcInstance(lpProc);
  268.                     break;
  269.  
  270.                 case IDM_OTM:
  271.                 case IDM_TM:
  272.                 case IDM_PANOSE:
  273.                 case IDM_LF:
  274.                 {
  275.                   HMENU hMenu;
  276.  
  277.                   hMenu = GetMenu(hWnd);
  278.  
  279.                   // check appropriate menu choice
  280.                   CheckMenuItem(hMenu, iCurrStructChoice, MF_UNCHECKED);
  281.                   iCurrStructChoice = wParam;
  282.                   CheckMenuItem(hMenu, iCurrStructChoice, MF_CHECKED);
  283.  
  284.                   // force repaint
  285.                   InvalidateRect(hWnd, NULL, TRUE);
  286.                   }
  287.                   break;
  288.             }
  289.         break;
  290.  
  291.         case WM_DESTROY:
  292.             // clean up printer font 
  293.             if (pis.hPrinterFont != NULL)
  294.                 DeleteObject(pis.hPrinterFont);
  295.  
  296.             // clean up screen font
  297.             if (sis.hScreenFont != NULL)
  298.                 DeleteObject(sis.hScreenFont);
  299.  
  300.             // had to keep around until app is done using the info 
  301.             if (pis.hCurrDevMode != NULL)
  302.                 GlobalFree(pis.hCurrDevMode);
  303.  
  304.             // had to keep around until app is done using the info 
  305.             if (pis.hCurrDevNames != NULL)
  306.                 GlobalFree(pis.hCurrDevNames);
  307.  
  308.             PostQuitMessage(0);
  309.         break;
  310.     }
  311.     return(DefWindowProc(hWnd, msg, wParam, lParam));
  312.  
  313. } //*** MainWndProc
  314.  
  315. //*************************************************************
  316. //
  317. //  About()
  318. //
  319. //  Purpose:
  320. //
  321. //        The About dialog box procedure.
  322. //
  323. //
  324. //  Parameters:
  325. //
  326. //      HWND     hDlg   - Handle to dialog window
  327. //      unsigned msg    - Message passed to dialog window
  328. //      WORD     wParam - Additional message information
  329. //      LONG     lParam - Additional message information
  330. //      
  331. //
  332. //  Return: (BOOL FAR PASCAL)
  333. //
  334. //      TRUE  - About dialog procedure handled the message.
  335. //      FALSE - About dialog procedure did not handle the message.
  336. //
  337. //  Comments:
  338. //
  339. //
  340. //  History:    Date       Author     Comment
  341. //              1/2/92     Don Miller Created
  342. //
  343. //*************************************************************
  344.  
  345. BOOL FAR PASCAL About (HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  346. {
  347.     switch (msg) 
  348.     {
  349.         case WM_INITDIALOG: 
  350.             return(TRUE);
  351.  
  352.         case WM_COMMAND:
  353.             if (wParam == IDOK || wParam == IDCANCEL) 
  354.             {
  355.                 EndDialog(hDlg, TRUE);         
  356.                 return(TRUE);
  357.             }
  358.         break;
  359.     }
  360.     return(FALSE);      // Didn't process a message
  361.  
  362. } //*** About
  363.  
  364.  
  365. //*************************************************************
  366. //
  367. //  ShowPrintSetup
  368. //
  369. //  Purpose:
  370. //        
  371. //    Function responsible for displaying Print Setup common
  372. //    dialog box.  Stores a handle to the current DEVMODE and a
  373. //    handle to the current DEVNAMES in a global PRINTINFOSTRUCT.
  374. //
  375. //  Parameters:
  376. //      HWND hWnd
  377. //      
  378. //
  379. //  Return: (BOOL)
  380. //
  381. //
  382. //  Comments:
  383. //
  384. //
  385. //  History:    Date       Author     Comment
  386. //              1/6/92     Don Miller Created
  387. //*************************************************************
  388.  
  389. BOOL ShowPrintSetup(HWND hWnd)
  390. {
  391.     PRINTDLG pdPrint;
  392.     BOOL     bResult;
  393.  
  394.     pdPrint.lStructSize = sizeof(PRINTDLG);           // size of structure
  395.     pdPrint.hwndOwner   = hWnd;                       // common dialog's owner
  396.     pdPrint.hDevMode    = (HANDLE)pis.hCurrDevMode;   // handle to DEVMODE struct
  397.     pdPrint.hDevNames   = (HANDLE)pis.hCurrDevNames;  // handle to DEVNAMES struct
  398.     pdPrint.Flags       = PD_PRINTSETUP;              // flags used to bring up Setup
  399.     pdPrint.hInstance   = (HANDLE)ghInst;             // instance handle
  400.  
  401.     // display Print Setup common dialog
  402.     bResult = PrintDlg(&pdPrint);
  403.  
  404.     // set global handles
  405.     pis.hCurrDevMode   = pdPrint.hDevMode;
  406.     pis.hCurrDevNames  = pdPrint.hDevNames;
  407.  
  408.     return bResult;
  409.  
  410. } //*** ShowPrintSetup
  411.  
  412.  
  413. //*************************************************************
  414. //
  415. //  ShowFontBox
  416. //
  417. //  Purpose:
  418. //        
  419. //    Function is responsible for displaying ChooseFont common
  420. //    dialog.  Also, the function creates a printer font and a 
  421. //    screen font and stores them in their respective global
  422. //    structures.
  423. //
  424. //  Parameters:
  425. //      HWND hWnd
  426. //      
  427. //
  428. //  Return: (void)
  429. //
  430. //
  431. //  Comments:
  432. //
  433. //
  434. //  History:    Date       Author     Comment
  435. //              1/6/92     Don Miller Created
  436. //*************************************************************
  437.  
  438. void ShowFontBox(HWND hWnd)
  439. {
  440.     HDC        hPrnDC;
  441.     LOGFONT    lfTemp;
  442.     int        nyLogPix; 
  443.  
  444.     if ((hPrnDC = GetPrinterDC ()) != NULL)
  445.     {
  446.         cf.lStructSize      = sizeof(CHOOSEFONT);   // struct size
  447.         cf.hwndOwner        = hWnd;                 // common dialog's owner
  448.         cf.hDC              = hPrnDC;               // Printer DC used for device fonts
  449.         cf.lpLogFont        = &pis.lfCurrFont;      // LOGFONT to initialize font info
  450.         cf.Flags            = CF_TTONLY | CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_USESTYLE;
  451.         cf.lCustData        = 0L;                   // no custom data
  452.         cf.rgbColors        = sis.crTextColor;      // text color
  453.         cf.lpfnHook         = (FARPROC)NULL;        // No hook function
  454.         cf.lpTemplateName   = (LPSTR)NULL;          // No dialog template
  455.         cf.hInstance        = ghInst;               // instance handle
  456.         cf.lpszStyle        = (LPSTR)fi.szFontStyles;  // Buffer contains current font's styles
  457.         cf.nFontType        = SCREEN_FONTTYPE;         // font type
  458.         cf.nSizeMin         = 0;                       // No min size
  459.         cf.nSizeMax         = 0;                       // No max size
  460.  
  461.         // bring up Font common dialog
  462.         if (ChooseFont(&cf))
  463.         {
  464.             // get rid of old screen font, if one 
  465.             if (sis.hScreenFont != NULL)
  466.             {
  467.                 DeleteObject(sis.hScreenFont);
  468.                 sis.hScreenFont = NULL;
  469.             }
  470.             // store text color for screen
  471.             sis.crTextColor = (COLORREF)cf.rgbColors;
  472.  
  473.             // set LOGFONT Precision field to always pick a TT font
  474.             pis.lfCurrFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  475.  
  476.             //create screen font
  477.             sis.hScreenFont = CreateFontIndirect(&pis.lfCurrFont);
  478.  
  479.             // save LOGFONT in screen info struct
  480.             sis.lfCurrFont = pis.lfCurrFont;
  481.  
  482.             // create printer font
  483.             // use temp logfont because global logfont is for screen */
  484.             lfTemp = pis.lfCurrFont;
  485.  
  486.             // adjust font height for correct point size on printer */
  487.             nyLogPix = GetDeviceCaps(hPrnDC, LOGPIXELSY);
  488.             lfTemp.lfHeight = -((cf.iPointSize/10) * nyLogPix)/72;
  489.  
  490.             // get rid of old printer font, if one
  491.             if (pis.hPrinterFont != NULL)
  492.             {
  493.                 DeleteObject(pis.hPrinterFont);
  494.                 pis.hPrinterFont = NULL;
  495.             }
  496.             pis.hPrinterFont = CreateFontIndirect(&lfTemp);
  497.  
  498.             // redraw the client
  499.             InvalidateRect(hWnd, NULL, TRUE);
  500.         }
  501.         DeleteDC(hPrnDC);
  502.     }
  503. } //*** ShowFontBox
  504.  
  505. //*************************************************************
  506. //
  507. //  ShowPrintBox
  508. //
  509. //  Purpose:
  510. //        
  511. //    Function responsible for displaying Print  common
  512. //    dialog box.  Stores a handle to the current DEVMODE and a
  513. //    handle to the current DEVNAMES in a global PRINTINFOSTRUCT.
  514. //
  515. //  Parameters:
  516. //      HWND hWnd
  517. //      
  518. //
  519. //  Return: (BOOL)
  520. //
  521. //
  522. //  Comments:
  523. //
  524. //
  525. //  History:    Date       Author     Comment
  526. //              1/6/92     Don Miller Created
  527. //*************************************************************
  528.  
  529. BOOL ShowPrintBox(HWND hWnd)
  530. {
  531.     PRINTDLG pdPrint;
  532.     BOOL     bResult;
  533.  
  534.     pdPrint.lStructSize = sizeof(PRINTDLG);           // struct size
  535.     pdPrint.hwndOwner   = hWnd;                       // dialog's owner
  536.     pdPrint.hDevMode    = (HANDLE)pis.hCurrDevMode;   // handle to DEVMODE struct
  537.     pdPrint.hDevNames   = (HANDLE)pis.hCurrDevNames;  // handle to DEVNAMES struct
  538.     pdPrint.nCopies     = 1;                          // number of copies to print
  539.     pdPrint.Flags       = PD_ALLPAGES | PD_NOPAGENUMS | PD_COLLATE |
  540.                           PD_NOSELECTION | PD_HIDEPRINTTOFILE;
  541.  
  542.     pdPrint.hInstance   = (HANDLE)ghInst;             // instance handle
  543.  
  544.     // bring up Print common dialog
  545.     bResult = PrintDlg(&pdPrint);
  546.  
  547.     // set global handles
  548.     pis.hCurrDevMode   = pdPrint.hDevMode;
  549.     pis.hCurrDevNames  = pdPrint.hDevNames;
  550.  
  551.     // send printdlg info to printing routines
  552.     if (bResult)
  553.         bResult = PrintIt(hWnd, &pdPrint);
  554.  
  555.     return bResult;
  556.  
  557. } //*** ShowPrintBox
  558.  
  559.  
  560. //*************************************************************
  561. //
  562. //  GetPrinterDC
  563. //
  564. //  Purpose:
  565. //        
  566. //    Function that retrieves a printer dc.  Retrieves a dc with
  567. //    respect to the data in the current DEVMODE and DEVNAMES.
  568. //
  569. //  Parameters:
  570. //      void
  571. //      
  572. //
  573. //  Return: (HDC)
  574. //
  575. //
  576. //  Comments:
  577. //
  578. //
  579. //  History:    Date       Author     Comment
  580. //              1/6/92     Don Miller Created
  581. //*************************************************************
  582.  
  583. HDC GetPrinterDC(void)
  584. {
  585.    LPDEVMODE  lpdmDevMode   = NULL;
  586.    LPDEVNAMES lpdnDevNames  = NULL;
  587.    LPSTR      lpstrDevNames = NULL;
  588.  
  589.    // lock handle to DEVMODE struct and send info to CreateDC 
  590.    // This causes a DC to be created that will have the same
  591.    // DEVMODE attributes as what the user picked in the Print
  592.    // Setup dialog.  
  593.  
  594.    if (pis.hCurrDevMode != NULL)
  595.        lpdmDevMode = (LPDEVMODE)GlobalLock(pis.hCurrDevMode);
  596.  
  597.    // lock handle to DEVNAMES struct and send info to CreateDC
  598.    // This causes a DC to be created and linked to the device
  599.    // (printer) that the user selected in the Print Setup 
  600.    // dialog.  If hCurrDevNames is NULL then we create a DC
  601.    // linked to the default printer.
  602.  
  603.    if (pis.hCurrDevNames != NULL)
  604.    {
  605.        lpdnDevNames = (LPDEVNAMES)GlobalLock(pis.hCurrDevNames);
  606.        pis.szDevice = (LPSTR)lpdnDevNames + lpdnDevNames->wDeviceOffset;
  607.        pis.szDriver = (LPSTR)lpdnDevNames + lpdnDevNames->wDriverOffset;
  608.        pis.szOutput = (LPSTR)lpdnDevNames + lpdnDevNames->wOutputOffset;
  609.  
  610.        return CreateDC (pis.szDriver, pis.szDevice, pis.szOutput, (LPSTR)lpdmDevMode);
  611.    }
  612.    else    // get default printer from WIN.INI
  613.    {
  614.        GetProfileString ("windows", "device", "", pis.szPrinter, 64) ;
  615.  
  616.        if ((pis.szDevice = (LPSTR)strtok (pis.szPrinter, "," )) &&
  617.            (pis.szDriver = (LPSTR)strtok (NULL,      ", ")) && 
  618.            (pis.szOutput = (LPSTR)strtok (NULL,      ", ")))
  619.            return CreateDC (pis.szDriver, pis.szDevice, pis.szOutput, (LPSTR)lpdmDevMode);
  620.    }
  621.    return NULL;
  622. } //*** GetPrinterDC
  623.  
  624.  
  625. //*************************************************************
  626. //
  627. //  PrintIt
  628. //
  629. //  Purpose:
  630. //        
  631. //    Function that handles all the printing.  Manual banding is
  632. //    not implemented.
  633. //
  634. //  Parameters:
  635. //      HWND hWnd
  636. //      
  637. //
  638. //  Return: (BOOL)
  639. //
  640. //
  641. //  Comments:
  642. //
  643. //
  644. //  History:    Date       Author     Comment
  645. //              1/6/92     Don Miller Created
  646. //*************************************************************
  647.  
  648. BOOL PrintIt(HWND hWnd, LPPRINTDLG lpPD)
  649. {
  650.     HDC        hPrnDC;
  651.     DOCINFO    di;
  652.     FARPROC    lpAbortProc, lpAbortDlg;
  653.     HFONT      hOldFont;
  654.     TEXTMETRIC tm;
  655.     WORD       wMaxXExtent;
  656.     DWORD      dwTextExt;
  657.     int        nxLogPix, nyLogPix, dxPrinter, dyPrinter, iPageNum,
  658.                iCopyNum, iPos, i, iyChar, iyPos;
  659.     char       szBuffer[64], szBuffer2[255];
  660.  
  661.     // get a printer dc 
  662.     if ((hPrnDC = GetPrinterDC ()) == NULL)
  663.     {
  664.          MessageBox(hWnd, "Cannot create printer DC!", "ERROR",
  665.                     MB_APPLMODAL|MB_ICONSTOP|MB_OK);
  666.          return FALSE;
  667.     }
  668.  
  669.     // set user abort flag 
  670.     pis.bAbort = FALSE;
  671.  
  672.     // Initialize the abort procedure. 
  673.     lpAbortProc = MakeProcInstance((FARPROC)PrintAbortProc, ghInst);
  674.     lpAbortDlg  = MakeProcInstance((FARPROC)PrintAbortDlg,  ghInst);
  675.  
  676.     // disable main application window 
  677.     EnableWindow(hWnd, FALSE);
  678.  
  679.     // display abort dialog 
  680.     pis.hDlgAbort = CreateDialog(ghInst, "PrintDLG", hWnd, (FARPROC)lpAbortDlg);
  681.  
  682.     // set abort procedure 
  683.     if (SetAbortProc(hPrnDC, lpAbortProc) < 0)
  684.     {
  685.          MessageBox(NULL, "The SetAbortProc function failed.", "ERROR",
  686.                     MB_APPLMODAL|MB_ICONSTOP|MB_OK);
  687.  
  688.          DeleteDC(hPrnDC);
  689.          return FALSE;
  690.     }
  691.  
  692.     // need for StartDoc 
  693.     di.cbSize      = sizeof(DOCINFO);
  694.     di.lpszDocName = (LPSTR)"ttdmp";
  695.     di.lpszOutput  = NULL;
  696.  
  697.     // issue STARTDOC 
  698.     if (StartDoc(hPrnDC, &di) < 0)
  699.     {
  700.          MessageBox(NULL, "STARTDOC escape problem", "ERROR",
  701.                     MB_APPLMODAL|MB_ICONSTOP|MB_OK);
  702.  
  703.          DeleteDC(hPrnDC);
  704.          return FALSE;
  705.     }
  706.  
  707.     // get logical pixels per inch 
  708.     nxLogPix  = GetDeviceCaps(hPrnDC, LOGPIXELSX);
  709.     nyLogPix  = GetDeviceCaps(hPrnDC, LOGPIXELSY);
  710.  
  711.     // get page resolution 
  712.     dxPrinter = GetDeviceCaps(hPrnDC, HORZRES);
  713.     dyPrinter = GetDeviceCaps(hPrnDC, VERTRES);
  714.  
  715.     // select font in
  716.     if (pis.hPrinterFont != NULL)
  717.        hOldFont = SelectObject(hPrnDC, pis.hPrinterFont);
  718.  
  719.     // get text information
  720.     GetTextMetrics(hPrnDC, &tm);
  721.     iyChar = tm.tmHeight + tm.tmExternalLeading;
  722.  
  723.     // compute max extent  (width of page - 2inches)
  724.     wMaxXExtent = dxPrinter-(2*nxLogPix);
  725.  
  726.     // do the number of collated copies
  727.     for (iCopyNum=1; iCopyNum <= (int)lpPD->nCopies; iCopyNum++)
  728.     {
  729.       for (iPageNum=1; iPageNum <= 1 && !pis.bAbort; iPageNum++)
  730.       {
  731.          // update abort dialog box page number
  732.          wsprintf((LPSTR)szBuffer, "Now printing Page %d of", iPageNum);
  733.          SetDlgItemText(pis.hDlgAbort, 100, (LPSTR)szBuffer); 
  734.  
  735.          // select font in printer dc
  736.          if (pis.hPrinterFont != NULL)
  737.             SelectObject(hPrnDC, pis.hPrinterFont);
  738.  
  739.          // start printing a page
  740.          StartPage(hPrnDC);
  741.  
  742.          // set position counters
  743.          iPos=0;
  744.          iyPos = nyLogPix;
  745.  
  746.          // copy facename, styles, and point size to buffer
  747.          wsprintf((LPSTR)szBuffer2, "%s %s %d pt", (LPSTR)pis.lfCurrFont.lfFaceName,
  748.                   (LPSTR)cf.lpszStyle, cf.iPointSize/10); 
  749.  
  750.          // print facename, styles, and point size 
  751.          TextOut(hPrnDC, nxLogPix, iyPos, (LPSTR)szBuffer2, lstrlen((LPSTR)szBuffer2));
  752.  
  753.          iyPos += 2*iyChar;
  754.  
  755.          // write ascii table to printer 
  756.          for (i=1; i < 224; i++)
  757.          {
  758.             // place character into buffer
  759.             szBuffer2[iPos++] = (char)(i+32);
  760.  
  761.             // place a space in buffer
  762.             szBuffer2[iPos++] = (char)32;
  763.  
  764.             // get width of string in buffer
  765.             dwTextExt = GetTextExtent(hPrnDC, (LPSTR)szBuffer2, iPos);
  766.  
  767.             // check to see if buffer is wider than max x extent
  768.             if (LOWORD(dwTextExt) > wMaxXExtent) 
  769.             {
  770.                // print out string in buffer
  771.                TextOut(hPrnDC, nxLogPix, iyPos, (LPSTR)szBuffer2, iPos-2);
  772.  
  773.                // place the last character back in buffer
  774.                szBuffer2[0] = (char)(i+32);
  775.  
  776.                // adjust position counters
  777.                iPos=1;
  778.                iyPos += iyChar;
  779.             }
  780.          }
  781.          // print last line
  782.          if (iPos > 0)
  783.             TextOut(hPrnDC, nxLogPix, iyPos, (LPSTR)szBuffer2, iPos);
  784.  
  785.          // end the page; resets the dc to normal defaults
  786.          EndPage(hPrnDC);
  787.       }
  788.     }
  789.     // only do if user has not aborted 
  790.     if (!pis.bAbort)
  791.     {
  792.       if (EndDoc(hPrnDC) < 0)    // end the document
  793.       {
  794.              MessageBox(NULL, "EndDoc function problem", "ERROR",
  795.                         MB_APPLMODAL|MB_ICONSTOP|MB_OK);
  796.  
  797.              return FALSE;
  798.       }
  799.     }
  800.  
  801.     // enable main application window 
  802.     EnableWindow(hWnd, TRUE);
  803.  
  804.     // get rid of abort dialog 
  805.     DestroyWindow(pis.hDlgAbort);
  806.  
  807.     // clean up 
  808.     FreeProcInstance(lpAbortProc);
  809.     FreeProcInstance(lpAbortDlg); 
  810.  
  811.     // deselect font, if changed 
  812.     if (pis.hPrinterFont != NULL)
  813.       SelectObject(hPrnDC, hOldFont);
  814.       
  815.     DeleteDC(hPrnDC);
  816. } //*** PrintIt
  817.  
  818.  
  819. // -------------------- Abort Routines --------------------
  820.  
  821. //*************************************************************
  822. //
  823. //  PrintAbortProc
  824. //
  825. //  Purpose:
  826. //        
  827. //    Function is used to give application some "multi-tasking"
  828. //    through the use of a PeekMessage().  Also, it gives the 
  829. //    application some error control during printing.
  830. //
  831. //  Parameters:
  832. //      HDC hDC
  833. //      short code
  834. //      
  835. //
  836. //  Return: (BOOL FAR PASCAL)
  837. //
  838. //
  839. //  Comments:
  840. //
  841. //
  842. //  History:    Date       Author     Comment
  843. //              1/6/92     Don Miller Created
  844. //*************************************************************
  845.  
  846. BOOL FAR PASCAL PrintAbortProc(HDC hDC, short code)
  847. {
  848.    MSG msg;
  849.  
  850.    while (!pis.bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  851.       if (!IsDialogMessage(pis.hDlgAbort, &msg))
  852.          {
  853.          TranslateMessage(&msg);
  854.          DispatchMessage(&msg);
  855.          }
  856.    return (!pis.bAbort);
  857. }  //*** PrintAbortProc
  858.  
  859.  
  860. //*************************************************************
  861. //
  862. //  PrintAbortDlg
  863. //
  864. //  Purpose:
  865. //        
  866. //    Dialog procedure for print abort dialog.
  867. //
  868. //  Parameters:
  869. //      HWND hWnd
  870. //      unsigned msg
  871. //      WORD wParam
  872. //      LONG lParam
  873. //      
  874. //
  875. //  Return: (int FAR PASCAL)
  876. //
  877. //
  878. //  Comments:
  879. //
  880. //
  881. //  History:    Date       Author     Comment
  882. //              1/6/92     Don Miller Created
  883. //*************************************************************
  884.  
  885. int FAR PASCAL PrintAbortDlg(HWND hWnd, unsigned msg, WORD wParam, LONG lParam)
  886. {
  887.    char szMsgBuffer[64];
  888.  
  889.    switch (msg)
  890.       {
  891.       case WM_INITDIALOG:
  892.          SetFocus(hWnd);
  893.          EnableMenuItem(GetSystemMenu(hWnd, FALSE), SC_CLOSE, MF_GRAYED);
  894.  
  895.          // set printing info to abort dialog 
  896.          SetDlgItemText(hWnd, 100, "Now printing Page 1 of");
  897.          
  898.          wsprintf((LPSTR)szMsgBuffer, "'%.25s' on the", (LPSTR)"ttdmp"); 
  899.          SetDlgItemText(hWnd, 101, (LPSTR)szMsgBuffer);
  900.  
  901.          wsprintf((LPSTR)szMsgBuffer, "%.20s on %.20s",(LPSTR)pis.szDevice,(LPSTR)pis.szOutput); 
  902.          SetDlgItemText(hWnd, 102, (LPSTR)szMsgBuffer);
  903.  
  904.          return TRUE;
  905.  
  906.       case WM_COMMAND:
  907.          pis.bAbort = TRUE;
  908.          return TRUE;
  909.       }
  910.  
  911.    return FALSE;
  912. }  // PrintAbortDlg() 
  913.  
  914.  
  915. //*************************************************************
  916. //
  917. //  DumpOTMInfo
  918. //
  919. //  Purpose:  This function is responsible for dumping the 
  920. //            OUTLINETEXTMETRICS information to the screen.  The
  921. //            function uses the new 3.1 function
  922. //            GetOutlineTextMetrics().
  923. //        
  924. //
  925. //  Parameters:
  926. //      HWND hWnd
  927. //      HDC hDC
  928. //      
  929. //
  930. //  Return: (void)
  931. //
  932. //
  933. //  Comments:
  934. //
  935. //
  936. //  History:    Date       Author     Comment
  937. //              2/14/92    Don Miller Created
  938. //*************************************************************
  939.  
  940. void DumpOTMInfo(HWND hWnd, HDC hDC)
  941. {
  942.    int                 ixPos, iyPos, ixChar, iyChar, i;   
  943.    LPOUTLINETEXTMETRIC lpOTM;
  944.    HANDLE              hOTM;
  945.    DWORD               dwOTMsize, dwRet;
  946.    char                szBuffer[256];
  947.    HFONT               hTTFont;
  948.    TEXTMETRIC          tm;
  949.    LPSTR               lpstrOTMStr;
  950.  
  951.    // find size of OTM structure
  952.    if ((dwOTMsize = GetOutlineTextMetrics(hDC, 0, NULL)) == 0)
  953.    {
  954.       // only do if GetOutlineTextMetrics fails
  955.       if (sis.hScreenFont)
  956.       {
  957.          hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  958.          TextOut(hDC, 10, 10, "No OTM information!", 19);
  959.          SelectObject(hDC, hTTFont);
  960.       }
  961.       return;
  962.    }
  963.  
  964.    // allocate buffer for OTM
  965.    hOTM  = GlobalAlloc(GMEM_MOVEABLE, dwOTMsize);
  966.  
  967.    // lock buffer
  968.    lpOTM = (LPOUTLINETEXTMETRIC) GlobalLock(hOTM);
  969.  
  970.    // fill OTM structure
  971.    dwRet = GetOutlineTextMetrics(hDC, (UINT)dwOTMsize, lpOTM);
  972.  
  973.    // use fixed font for field names
  974.    hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  975.  
  976.    // get character width and height
  977.    GetTextMetrics(hDC, &tm);
  978.    ixPos = ixChar = tm.tmAveCharWidth;
  979.    iyPos = iyChar = tm.tmHeight + tm.tmExternalLeading;
  980.  
  981.    // display header in caption bar
  982.    wsprintf((LPSTR)szBuffer, "%s - OUTLINETEXTMETRIC structure", (LPSTR)sis.lfCurrFont.lfFaceName);
  983.    SetWindowText(hWnd, (LPSTR)szBuffer);
  984.  
  985.    // display table 
  986.    for (i=0; i < 32; i++)
  987.    {
  988.       // set positions for second column
  989.       if (i == 15)
  990.       {
  991.          ixPos = 10*ixChar + LOWORD(GetTextExtent(hDC, (LPSTR)szOTM[22], lstrlen((LPSTR)szOTM[22])));
  992.          iyPos = iyChar;
  993.       }
  994.  
  995.       switch(i)
  996.       {
  997.          case 0:
  998.             // size of OUTLINETEXTMETRIC structure
  999.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmSize);
  1000.             break;
  1001.  
  1002.          case 1:
  1003.             // otmTextMetrics field
  1004.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)"See Structures menu");
  1005.             break;
  1006.  
  1007.          case 2:
  1008.             // otmFiller field
  1009.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (BYTE)lpOTM->otmFiller);
  1010.             break;
  1011.  
  1012.          case 3:
  1013.             // otmPanoseNumber field
  1014.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)"See Structures menu");
  1015.             break;
  1016.  
  1017.          case 4:
  1018.          // otmfsSelection field
  1019.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmfsSelection);
  1020.             break;
  1021.  
  1022.          case 5:
  1023.             // otmfsType field
  1024.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmfsType);
  1025.             break;
  1026.  
  1027.          case 6:
  1028.             // otmsCharSlopeRise field
  1029.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsCharSlopeRise);
  1030.             break;
  1031.  
  1032.          case 7:
  1033.             // otmsCharSlopeRun field
  1034.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsCharSlopeRun);
  1035.             break;
  1036.  
  1037.          case 8:
  1038.             // otmItalicAngle field
  1039.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmItalicAngle);
  1040.             break;
  1041.  
  1042.          case 9:
  1043.             // otmEMSquare field
  1044.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmEMSquare);
  1045.             break;
  1046.  
  1047.          case 10:
  1048.             // otmAscent field
  1049.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmAscent);
  1050.             break;
  1051.  
  1052.          case 11:
  1053.             // otmDescent field
  1054.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmDescent);
  1055.             break;
  1056.  
  1057.          case 12:
  1058.             // otmLineGap field
  1059.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmLineGap);
  1060.             break;
  1061.  
  1062.          case 13:
  1063.             // otmsXHeight field
  1064.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsXHeight);
  1065.             break;
  1066.  
  1067.          case 14:
  1068.             // otmsCapEmHeight field
  1069.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsCapEmHeight);
  1070.             break;
  1071.  
  1072.          case 15:
  1073.             // otmrcFontBox field
  1074.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmrcFontBox);
  1075.             break;
  1076.  
  1077.          case 16:
  1078.             /// otmMacAscent field
  1079.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmMacAscent);
  1080.             break;
  1081.  
  1082.          case 17:
  1083.             // otmMacDescent field
  1084.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmMacDescent);
  1085.             break;
  1086.  
  1087.          case 18:
  1088.             // otmMacLineGap field
  1089.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmMacLineGap);
  1090.             break;
  1091.  
  1092.          case 19:
  1093.             // otmusMinimumPPEM field
  1094.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmusMinimumPPEM);
  1095.             break;
  1096.  
  1097.          case 20:
  1098.             // otmptSubscriptSize field
  1099.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmptSubscriptSize.x, lpOTM->otmptSubscriptSize.y);
  1100.             break;
  1101.  
  1102.          case 21:
  1103.             // otmptSubscriptOffset field
  1104.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmptSubscriptOffset.x, lpOTM->otmptSubscriptOffset.y);
  1105.             break;
  1106.  
  1107.          case 22:
  1108.             // otmptSuperscriptSize field
  1109.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmptSuperscriptSize.x, lpOTM->otmptSuperscriptSize.y);
  1110.             break;
  1111.  
  1112.          case 23:
  1113.             // otmptSuperscriptOffset field
  1114.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmptSuperscriptOffset.x, lpOTM->otmptSuperscriptOffset.y);
  1115.             break;
  1116.  
  1117.          case 24:
  1118.             // otmsStrikeoutSize field
  1119.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsStrikeoutSize);
  1120.             break;
  1121.  
  1122.          case 25:
  1123.             // otmsStrikeoutPosition field
  1124.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsStrikeoutPosition);
  1125.             break;
  1126.  
  1127.          case 26:
  1128.             // otmsUnderscoreSize field
  1129.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsUnderscoreSize);
  1130.             break;
  1131.  
  1132.          case 27:
  1133.             // otmsUnderscorePosition field
  1134.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], lpOTM->otmsUnderscorePosition);
  1135.             break;
  1136.  
  1137.          case 28:
  1138.             // otmpFamilyName field
  1139.             lpstrOTMStr = (LPSTR)(lpOTM);
  1140.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)(lpstrOTMStr + (int)lpOTM->otmpFamilyName));
  1141.             break;
  1142.  
  1143.          case 29:
  1144.             // otmpFaceName field
  1145.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)(lpstrOTMStr + (int)lpOTM->otmpFaceName));
  1146.             break;
  1147.  
  1148.          case 30:
  1149.             // otmpStyleName field
  1150.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)(lpstrOTMStr + (int)lpOTM->otmpStyleName));
  1151.             break;
  1152.  
  1153.          case 31:
  1154.             // otmpFullName field
  1155.             wsprintf((LPSTR)szBuffer, (LPSTR)szOTM[i], (LPSTR)(lpstrOTMStr + (int)lpOTM->otmpFullName));
  1156.             ixPos = ixChar;
  1157.             break;
  1158.  
  1159.          default:
  1160.             break;
  1161.       }
  1162.       // print buffer
  1163.       TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1164.       iyPos += iyChar;
  1165.    }
  1166.  
  1167.    // diplay a line of text in TT font
  1168.    SelectObject(hDC, hTTFont);
  1169.    wsprintf((LPSTR)szBuffer, "%s %s %d pt - %s", (LPSTR)pis.lfCurrFont.lfFaceName,
  1170.             (LPSTR)cf.lpszStyle, cf.iPointSize/10, (LPSTR)"AaBbCcDdEe0123456789"); 
  1171.  
  1172.    TextOut(hDC, ixChar, 19*iyChar, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1173.  
  1174.    // clean up
  1175.    GlobalUnlock(hOTM);
  1176.    GlobalFree(hOTM);
  1177.  
  1178. } //*** DumpTTInfo
  1179.  
  1180.  
  1181. //*************************************************************
  1182. //
  1183. //  DumpTMInfo
  1184. //
  1185. //  Purpose: This function is responsible for dumping the 
  1186. //               TEXTMETRICS information stored in the
  1187. //           OUTLINETEXTMETRICS structure.  The function uses
  1188. //           the new 3.1 function GetOutlineTextMetrics().
  1189. //
  1190. //
  1191. //  Parameters:
  1192. //      HWND hWnd
  1193. //      HDC hDC
  1194. //      
  1195. //
  1196. //  Return: (void)
  1197. //
  1198. //
  1199. //  Comments:
  1200. //
  1201. //
  1202. //  History:    Date       Author     Comment
  1203. //              2/14/92    Don Miller Created
  1204. //*************************************************************
  1205.  
  1206. void DumpTMInfo(HWND hWnd, HDC hDC)
  1207. {
  1208.    int                 ixPos, iyPos, ixChar, iyChar, i;   
  1209.    LPOUTLINETEXTMETRIC lpOTM;
  1210.    HANDLE              hOTM;
  1211.    DWORD               dwOTMsize, dwRet;
  1212.    char                szBuffer[128];
  1213.    HFONT               hTTFont;
  1214.    TEXTMETRIC          tm;
  1215.    NEWTEXTMETRIC       ntm;
  1216.    FARPROC             lpfnEnumFamProc;
  1217.  
  1218.    // find size of OTM structure
  1219.    if ((dwOTMsize = GetOutlineTextMetrics(hDC, 0, NULL)) == 0)
  1220.    {
  1221.       // only do if GetOutlineTextMetrics fails
  1222.       if (sis.hScreenFont)
  1223.       {
  1224.          hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1225.          TextOut(hDC, 10, 10, "No OTM information!", 19);
  1226.          SelectObject(hDC, hTTFont);
  1227.       }
  1228.       return;
  1229.    }
  1230.  
  1231.    // allocate buffer for OTM
  1232.    hOTM  = GlobalAlloc(GMEM_MOVEABLE, dwOTMsize);
  1233.  
  1234.    // lock buffer
  1235.    lpOTM = (LPOUTLINETEXTMETRIC) GlobalLock(hOTM);
  1236.  
  1237.    // fill OTM structure in order to get TEXTMETRIC info for current TT
  1238.    // font in hDC
  1239.    dwRet = GetOutlineTextMetrics(hDC, (UINT)dwOTMsize, lpOTM);
  1240.  
  1241.    // use fixed font for field names
  1242.    hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1243.  
  1244.    // get character width and height
  1245.    GetTextMetrics(hDC, &tm);
  1246.    ixPos = ixChar = tm.tmAveCharWidth;
  1247.    iyPos = iyChar = tm.tmHeight + tm.tmExternalLeading;
  1248.  
  1249.    // display header in caption bar
  1250.    wsprintf((LPSTR)szBuffer, "%s - NEWTEXTMETRIC structure", (LPSTR)sis.lfCurrFont.lfFaceName);
  1251.    SetWindowText(hWnd, (LPSTR)szBuffer);
  1252.  
  1253.  
  1254.    // get NEWTEXTMETRIC info from EnumFontFamilies()
  1255.    lpfnEnumFamProc = MakeProcInstance(EnumFontFamProc1, ghInst); 
  1256.    EnumFontFamilies(hDC, (LPCSTR)sis.lfCurrFont.lfFaceName, (FONTENUMPROC)lpfnEnumFamProc, (LPSTR)&ntm);
  1257.    FreeProcInstance(lpfnEnumFamProc);
  1258.  
  1259.    // display table 
  1260.    for (i=0; i < 24; i++)
  1261.    {
  1262.       switch(i)
  1263.       {
  1264.          case 0:
  1265.             // tmHeight field
  1266.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmHeight);
  1267.             break;
  1268.  
  1269.          case 1:
  1270.             // tmAscent field
  1271.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmAscent);
  1272.             break;
  1273.  
  1274.          case 2:
  1275.             // tmDescent field
  1276.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmDescent);
  1277.             break;
  1278.  
  1279.          case 3:
  1280.             //tmInternalLeading field
  1281.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmInternalLeading);
  1282.             break;
  1283.  
  1284.          case 4:
  1285.             // tmExternalLeading field
  1286.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmExternalLeading);
  1287.             break;
  1288.  
  1289.          case 5:
  1290.             // tmAveCharWidth field
  1291.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmAveCharWidth);
  1292.             break;
  1293.  
  1294.          case 6:
  1295.             // tmMaxCharWidth field
  1296.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmMaxCharWidth);
  1297.             break;
  1298.  
  1299.          case 7:
  1300.             // tmWeight field
  1301.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmWeight);
  1302.             break;
  1303.  
  1304.          case 8:
  1305.             // tmItalic field
  1306.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmItalic);
  1307.             break;
  1308.  
  1309.          case 9:
  1310.             // tmUnderlined field
  1311.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmUnderlined);
  1312.             break;
  1313.  
  1314.          case 10:
  1315.             // tmStruckOut field
  1316.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmStruckOut);
  1317.             break;
  1318.  
  1319.          case 11:
  1320.             // tmFirstChar field
  1321.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmFirstChar);
  1322.             break;
  1323.  
  1324.          case 12:
  1325.             // tmLastChar field
  1326.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmLastChar);
  1327.             break;
  1328.  
  1329.          case 13:
  1330.             // tmDefaultChar field
  1331.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmDefaultChar);
  1332.             break;
  1333.  
  1334.          case 14:
  1335.             // tmBreakChar field
  1336.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmBreakChar);
  1337.             break;
  1338.  
  1339.          case 15:
  1340.             // tmPitchAndFamily field
  1341.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmPitchAndFamily);
  1342.             break;
  1343.  
  1344.          case 16:
  1345.             // tmCharSet field
  1346.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmCharSet);
  1347.             break;
  1348.  
  1349.          case 17:
  1350.             // tmOverhang field
  1351.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmOverhang);
  1352.             break;
  1353.  
  1354.          case 18:
  1355.             // tmDigitizedAspectX field
  1356.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmDigitizedAspectX);
  1357.             break;
  1358.  
  1359.          case 19:
  1360.             // tmDigitizedAspectY field
  1361.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], lpOTM->otmTextMetrics.tmDigitizedAspectY);
  1362.             break;
  1363.  
  1364.          // NEWTEXTMETRIC stuff is filled in by EnumFontFamProc1
  1365.          case 20:
  1366.             // ntmFlags field
  1367.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], ntm.ntmFlags);
  1368.             break;
  1369.  
  1370.          case 21:
  1371.             // ntmEMSize field
  1372.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], ntm.ntmSizeEM);
  1373.             break;
  1374.  
  1375.          case 22:
  1376.             // ntmCellHeight field
  1377.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], ntm.ntmCellHeight);
  1378.             break;
  1379.  
  1380.          case 23:
  1381.             // ntmAveWidth field
  1382.             wsprintf((LPSTR)szBuffer, (LPSTR)szTextMetric[i], ntm.ntmAvgWidth);
  1383.             break;
  1384.  
  1385.          default:
  1386.             break;
  1387.  
  1388.       }
  1389.       TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1390.       iyPos += iyChar; 
  1391.    }
  1392.  
  1393.    // display a line of text in TT font
  1394.    SelectObject(hDC, hTTFont);
  1395.  
  1396.    wsprintf((LPSTR)szBuffer, "%s %s %d pt - %s", (LPSTR)pis.lfCurrFont.lfFaceName,
  1397.             (LPSTR)cf.lpszStyle, cf.iPointSize/10, (LPSTR)"AaBbCcDdEe0123456789"); 
  1398.  
  1399.    TextOut(hDC, ixChar, 26*iyChar, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1400.  
  1401.    // clean up
  1402.    GlobalUnlock(hOTM);
  1403.    GlobalFree(hOTM);
  1404.  
  1405. } //*** DumpTMInfo
  1406.  
  1407.  
  1408. //*************************************************************
  1409. //
  1410. //  DumpPanoseInfo
  1411. //
  1412. //  Purpose: This function is responsible for dumping the 
  1413. //               PANOSE information stored in the
  1414. //           OUTLINETEXTMETRICS structure.  The function uses
  1415. //           the new 3.1 function GetOutlineTextMetrics().
  1416. //
  1417. //
  1418. //  Parameters:
  1419. //      HWND hWnd
  1420. //      HDC hDC
  1421. //      
  1422. //
  1423. //  Return: (void)
  1424. //
  1425. //
  1426. //  Comments:
  1427. //
  1428. //
  1429. //  History:    Date       Author     Comment
  1430. //              2/14/92    Don Miller Created
  1431. //*************************************************************
  1432.  
  1433. void DumpPanoseInfo(HWND hWnd, HDC hDC)
  1434. {
  1435.    int                 ixPos, iyPos, ixChar, iyChar, i;   
  1436.    LPOUTLINETEXTMETRIC lpOTM;
  1437.    HANDLE              hOTM;
  1438.    DWORD               dwOTMsize, dwRet;
  1439.    char                szBuffer[128];
  1440.    HFONT               hTTFont;
  1441.    TEXTMETRIC          tm;
  1442.  
  1443.    // find size of OTM structure
  1444.    if ((dwOTMsize = GetOutlineTextMetrics(hDC, 0, NULL)) == 0)
  1445.    {
  1446.       // only do if GetOutlineTextMetrics fails
  1447.       if (sis.hScreenFont)
  1448.       {
  1449.          hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1450.          TextOut(hDC, 10, 10, "No OTM information!", 19);
  1451.          SelectObject(hDC, hTTFont);
  1452.       }
  1453.       return;
  1454.    }
  1455.  
  1456.    // allocate buffer for OTM
  1457.    hOTM  = GlobalAlloc(GMEM_MOVEABLE, dwOTMsize);
  1458.  
  1459.    // lock buffer
  1460.    lpOTM = (LPOUTLINETEXTMETRIC) GlobalLock(hOTM);
  1461.  
  1462.    // fill OTM structure
  1463.    dwRet = GetOutlineTextMetrics(hDC, (UINT)dwOTMsize, lpOTM);
  1464.  
  1465.    // use fixed font for field names
  1466.    hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1467.  
  1468.    // get character width and height
  1469.    GetTextMetrics(hDC, &tm);
  1470.    ixPos = ixChar = tm.tmAveCharWidth;
  1471.    iyPos = iyChar = tm.tmHeight + tm.tmExternalLeading;
  1472.  
  1473.    // display header in caption bar
  1474.    wsprintf((LPSTR)szBuffer, "%s - PANOSE structure", (LPSTR)sis.lfCurrFont.lfFaceName);
  1475.    SetWindowText(hWnd, (LPSTR)szBuffer);
  1476.  
  1477.    // display table 
  1478.    for (i=0; i < 10; i++)
  1479.    {
  1480.       switch(i)
  1481.       {
  1482.          case 0:
  1483.             // bFamilyType field
  1484.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bFamilyType,
  1485.                      (LPSTR)szPanFamily[lpOTM->otmPanoseNumber.bFamilyType]);
  1486.             break;
  1487.  
  1488.          case 1:
  1489.             // bSerifStyle field
  1490.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bSerifStyle,
  1491.                      (LPSTR)szPanSerif[lpOTM->otmPanoseNumber.bSerifStyle]);
  1492.             break;
  1493.  
  1494.          case 2:
  1495.             // bWeight field
  1496.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bWeight,
  1497.                      (LPSTR)szPanWeight[lpOTM->otmPanoseNumber.bWeight]);
  1498.             break;
  1499.  
  1500.          case 3:
  1501.             // bProportion field
  1502.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bProportion,
  1503.                      (LPSTR)szPanProportion[lpOTM->otmPanoseNumber.bProportion]);
  1504.             break;
  1505.  
  1506.          case 4:
  1507.             // bContrast field
  1508.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bContrast,
  1509.                      (LPSTR)szPanContrast[lpOTM->otmPanoseNumber.bContrast]);
  1510.             break;
  1511.  
  1512.          case 5:
  1513.             // bStrokeVariable field
  1514.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bStrokeVariation,
  1515.                      (LPSTR)szPanStrokeVar[lpOTM->otmPanoseNumber.bStrokeVariation]);
  1516.             break;
  1517.  
  1518.          case 6:
  1519.             // bArmStyle field
  1520.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bArmStyle,
  1521.                      (LPSTR)szPanArmStyle[lpOTM->otmPanoseNumber.bArmStyle]);
  1522.             break;
  1523.  
  1524.          case 7:
  1525.             // bLetterform field
  1526.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bLetterform,
  1527.                      (LPSTR)szPanLetterForm[lpOTM->otmPanoseNumber.bLetterform]);
  1528.             break;
  1529.  
  1530.          case 8:
  1531.             // bMidline field
  1532.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bMidline,
  1533.                      (LPSTR)szPanMidline[lpOTM->otmPanoseNumber.bMidline]);
  1534.             break;
  1535.  
  1536.          case 9:
  1537.             // bXHeight field
  1538.             wsprintf((LPSTR)szBuffer, (LPSTR)szPanose[i], lpOTM->otmPanoseNumber.bXHeight,
  1539.                      (LPSTR)szPanXHeight[lpOTM->otmPanoseNumber.bXHeight]);
  1540.             break;
  1541.  
  1542.          default:
  1543.             break;
  1544.  
  1545.       }
  1546.       TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1547.       iyPos += iyChar;
  1548.    }
  1549.  
  1550.    // display a line of text in TT font
  1551.    SelectObject(hDC, hTTFont);
  1552.  
  1553.    wsprintf((LPSTR)szBuffer, "%s %s %d pt - %s", (LPSTR)pis.lfCurrFont.lfFaceName,
  1554.             (LPSTR)cf.lpszStyle, cf.iPointSize/10, (LPSTR)"AaBbCcDdEe0123456789"); 
  1555.  
  1556.    TextOut(hDC, ixChar, 12*iyChar, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1557.  
  1558.    // clean up
  1559.    GlobalUnlock(hOTM);
  1560.    GlobalFree(hOTM);
  1561.  
  1562. } //*** DumpPanoseInfo
  1563.  
  1564.  
  1565. //*************************************************************
  1566. //
  1567. //  DumpLFInfo
  1568. //
  1569. //  Purpose: This function is responsible for dumping the 
  1570. //               LOGFONT information that is returned from the
  1571. //           ChooseFont() function.
  1572. //
  1573. //
  1574. //  Parameters:
  1575. //      HWND hWnd
  1576. //      HDC hDC
  1577. //      
  1578. //
  1579. //  Return: (void)
  1580. //
  1581. //
  1582. //  Comments:
  1583. //
  1584. //
  1585. //  History:    Date       Author     Comment
  1586. //              2/14/92    Don Miller Created
  1587. //*************************************************************
  1588.  
  1589. void DumpLFInfo(HWND hWnd, HDC hDC)
  1590. {
  1591.    HFONT       hTTFont;
  1592.    TEXTMETRIC  tm;
  1593.    int         i, ixPos, iyPos, ixChar, iyChar;
  1594.    char        szBuffer[80];
  1595.    FARPROC     lpfnEnumFamProc;
  1596.    ENUMLOGFONT elf;
  1597.  
  1598.    // get current LOGFONT
  1599.    if (sis.hScreenFont)
  1600.    {
  1601.       // use fixed font for field names
  1602.       hTTFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1603.  
  1604.       // get character width and height
  1605.       GetTextMetrics(hDC, &tm);
  1606.       ixPos = ixChar = tm.tmAveCharWidth;
  1607.       iyPos = iyChar = tm.tmHeight + tm.tmExternalLeading;
  1608.  
  1609.       // display header in caption bar
  1610.       wsprintf((LPSTR)szBuffer, "%s - ENUMLOGFONT structure", (LPSTR)sis.lfCurrFont.lfFaceName);
  1611.       SetWindowText(hWnd, (LPSTR)szBuffer);
  1612.  
  1613.       // get ENUMLOGFONT info 
  1614.       lpfnEnumFamProc = MakeProcInstance(EnumFontFamProc2, ghInst); 
  1615.       EnumFontFamilies(hDC, (LPCSTR)sis.lfCurrFont.lfFaceName, (FONTENUMPROC)lpfnEnumFamProc, (LPSTR)&elf);
  1616.       FreeProcInstance(lpfnEnumFamProc);
  1617.  
  1618.       // display table
  1619.       for (i=0; i < 16; i++)
  1620.       {
  1621.          switch(i)
  1622.          {
  1623.             case 0:
  1624.                // lfHeight field
  1625.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfHeight);
  1626.                break;
  1627.  
  1628.             case 1:
  1629.                // lfWidth field
  1630.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfWidth);
  1631.                break;
  1632.  
  1633.             case 2:
  1634.                // lfEscapement field
  1635.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfEscapement);
  1636.                break;
  1637.  
  1638.             case 3:
  1639.                // lfOrientation field
  1640.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfOrientation);
  1641.                break;
  1642.  
  1643.             case 4:
  1644.                // lfWeight field
  1645.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfWeight);
  1646.                break;
  1647.  
  1648.             case 5:
  1649.                // lfItalic field
  1650.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfItalic);
  1651.                break;
  1652.  
  1653.             case 6:
  1654.                // lfUnderline field
  1655.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfUnderline);
  1656.                break;
  1657.  
  1658.             case 7:
  1659.                // lfStrikeOut field
  1660.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfStrikeOut);
  1661.                break;
  1662.  
  1663.             case 8:
  1664.                // lfCharSet field
  1665.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfCharSet);
  1666.                break;
  1667.  
  1668.             case 9:
  1669.                //lfOutPrecision field
  1670.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfOutPrecision);
  1671.                break;
  1672.  
  1673.             case 10:
  1674.                // lfClipPrecision field
  1675.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfClipPrecision);
  1676.                break;
  1677.  
  1678.             case 11:
  1679.                // lfQuality field
  1680.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfQuality);
  1681.                break;
  1682.  
  1683.             case 12:
  1684.                // lfPitchAndFamily field
  1685.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], sis.lfCurrFont.lfPitchAndFamily);
  1686.                break;
  1687.  
  1688.             case 13:
  1689.                // lfFaceName field
  1690.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], (LPSTR)sis.lfCurrFont.lfFaceName);
  1691.                break;
  1692.  
  1693.             // ENUMLOGFONT stuff is filled in by EnumFontFamProc2
  1694.             case 14:
  1695.                // elfFullName field
  1696.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], (LPSTR)elf.elfFullName);
  1697.                break;
  1698.  
  1699.             case 15:
  1700.                // elfStyle field
  1701.                wsprintf((LPSTR)szBuffer, (LPSTR)szLF[i], (LPSTR)elf.elfStyle);
  1702.                break;
  1703.  
  1704.             default:
  1705.                break;
  1706.             
  1707.          }     
  1708.          TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1709.          iyPos += iyChar;
  1710.       }
  1711.  
  1712.       // display a line of text in TT font
  1713.       SelectObject(hDC, hTTFont);
  1714.       wsprintf((LPSTR)szBuffer, "%s %s %d pt - %s", (LPSTR)pis.lfCurrFont.lfFaceName,
  1715.                (LPSTR)cf.lpszStyle, cf.iPointSize/10, (LPSTR)"AaBbCcDdEe0123456789"); 
  1716.  
  1717.       TextOut(hDC, ixChar, 18*iyChar, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));
  1718.    }
  1719.  
  1720. } //*** DumpLFInfo
  1721.  
  1722.  
  1723. //*************************************************************
  1724. //
  1725. //  IsTTAvail
  1726. //
  1727. //  Purpose: This function is responsible for checking to see
  1728. //           if TrueType is enabled and that at least one TrueType
  1729. //           font is installed on the system.
  1730. //        
  1731. //
  1732. //
  1733. //  Parameters:
  1734. //      HDC hDC
  1735. //      
  1736. //
  1737. //  Return: (BOOL)
  1738. //
  1739. //
  1740. //  Comments:
  1741. //
  1742. //
  1743. //  History:    Date       Author     Comment
  1744. //              2/14/92    Don Miller Created
  1745. //*************************************************************
  1746.  
  1747. BOOL IsTTAvail(HDC hDC)
  1748. {
  1749.    RASTERIZER_STATUS rs;
  1750.    BOOL              bTTAvail = TRUE;
  1751.    int               ixPos, iyPos;
  1752.    TEXTMETRIC        tm;
  1753.    HFONT             hOldFont;
  1754.  
  1755.  
  1756.    // select in fixed font
  1757.    hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
  1758.  
  1759.    //get fixed font character dims
  1760.    GetTextMetrics(hDC, &tm);
  1761.  
  1762.    ixPos = tm.tmAveCharWidth;
  1763.    iyPos = tm.tmHeight + tm.tmExternalLeading;
  1764.  
  1765.    // get TT flags
  1766.    GetRasterizerCaps(&rs, sizeof(RASTERIZER_STATUS));
  1767.  
  1768.    // check to see if TT fonts are installed
  1769.    if (!(rs.wFlags & TT_AVAILABLE))
  1770.    {
  1771.       TextOut(hDC, ixPos, iyPos, "No TrueType fonts installed!", 28);
  1772.       iyPos += iyPos;
  1773.       bTTAvail = FALSE;
  1774.    }
  1775.  
  1776.    // check to see if TT engine is enabled
  1777.    if (!(rs.wFlags & TT_ENABLED))
  1778.    {
  1779.       TextOut(hDC, ixPos, iyPos, "TrueType not enabled!", 21);
  1780.       bTTAvail = FALSE;
  1781.    }
  1782.  
  1783.    // restore the dc
  1784.    SelectObject(hDC, hOldFont);
  1785.  
  1786.    return (bTTAvail);
  1787.  
  1788. } //*** IsTTAvail
  1789.  
  1790.  
  1791. //*************************************************************
  1792. //
  1793. //  EnumFontFamProc1
  1794. //
  1795. //  Purpose: To enumerate the current TT type face and find a
  1796. //           style match.  Once the style match is found, the
  1797. //           new NEWTEXTMETRIC stuff is copied to a ptr passed in
  1798. //           the lParam parameter.
  1799. //        
  1800. //
  1801. //
  1802. //  Parameters:
  1803. //      LOGFONT FAR *lpnlf
  1804. //      TEXTMETRIC FAR *lpntm
  1805. //      int iFontType
  1806. //      LPARAM lParam
  1807. //      
  1808. //
  1809. //  Return: (int CALLBACK)
  1810. //
  1811. //
  1812. //  Comments:
  1813. //
  1814. //
  1815. //  History:    Date       Author     Comment
  1816. //              2/27/92    Don Miller Created
  1817. //*************************************************************
  1818.  
  1819. int CALLBACK EnumFontFamProc1(LOGFONT FAR *lpnlf, TEXTMETRIC FAR *lpntm, int iFontType, LPARAM lParam)
  1820. {
  1821.    LPNEWTEXTMETRIC lpNTM, lpVisitingNTM;
  1822.    static BYTE bNTMCurrStyleMask = 0;
  1823.    static BYTE bNTMSelStyleMask  = 0;
  1824.  
  1825.    // get style masks
  1826.    bNTMCurrStyleMask = GetStyleMask(lpnlf);
  1827.    bNTMSelStyleMask  = GetStyleMask((LOGFONT FAR *)&sis.lfCurrFont);
  1828.  
  1829.    // styles match
  1830.    if (bNTMCurrStyleMask == bNTMSelStyleMask)
  1831.    {
  1832.       // fill in NEWTEXTMETRIC stuff
  1833.       lpNTM = (LPNEWTEXTMETRIC)lpntm;
  1834.  
  1835.       lpVisitingNTM = (LPNEWTEXTMETRIC)lParam;
  1836.  
  1837.       lpVisitingNTM->ntmFlags      = lpNTM->ntmFlags;
  1838.  
  1839.       lpVisitingNTM->ntmSizeEM     = lpNTM->ntmSizeEM;  
  1840.  
  1841.       lpVisitingNTM->ntmCellHeight = lpNTM->ntmCellHeight;  
  1842.  
  1843.       lpVisitingNTM->ntmAvgWidth   = lpNTM->ntmAvgWidth;
  1844.  
  1845.       // reset masks 
  1846.       bNTMCurrStyleMask = 0;
  1847.       bNTMSelStyleMask  = 0;
  1848.  
  1849.       // quit enumerating
  1850.       return 0;
  1851.    }
  1852.    else
  1853.       return 1;  // continue enumerating
  1854. }
  1855.  
  1856. //*************************************************************
  1857. //
  1858. //  EnumFontFamProc2
  1859. //
  1860. //  Purpose: To enumerate the current TT type face and find a
  1861. //           style match.  Once the style match is found, the
  1862. //           new ENUMLOGFONT stuff is copied to a ptr passed in
  1863. //           the lParam parameter.
  1864. //        
  1865. //
  1866. //
  1867. //  Parameters:
  1868. //      LOGFONT FAR *lpnlf
  1869. //      TEXTMETRIC FAR *lpntm
  1870. //      int iFontType
  1871. //      LPARAM lParam
  1872. //      
  1873. //
  1874. //  Return: (int CALLBACK)
  1875. //
  1876. //
  1877. //  Comments:
  1878. //
  1879. //
  1880. //  History:    Date       Author     Comment
  1881. //              2/27/92    Don Miller Created
  1882. //*************************************************************
  1883.  
  1884. int CALLBACK EnumFontFamProc2(LOGFONT FAR *lpnlf, TEXTMETRIC FAR *lpntm, int iFontType, LPARAM lParam)
  1885. {
  1886.    LPENUMLOGFONT lpELF;
  1887.    LPENUMLOGFONT lpVisitingELF;
  1888.    static BYTE bELFCurrStyleMask = 0;
  1889.    static BYTE bELFSelStyleMask  = 0;
  1890.  
  1891.    // get style masks
  1892.    bELFCurrStyleMask = GetStyleMask(lpnlf);
  1893.    bELFSelStyleMask  = GetStyleMask((LOGFONT FAR *)&sis.lfCurrFont);
  1894.  
  1895.    // styles match
  1896.    if (bELFCurrStyleMask == bELFSelStyleMask)
  1897.    {
  1898.       // do ENUMLOGFONT stuff
  1899.       lpELF = (LPENUMLOGFONT)lpnlf;
  1900.       lpVisitingELF = (LPENUMLOGFONT)lParam;
  1901.  
  1902.       lstrcpy((LPSTR)lpVisitingELF->elfFullName, (LPSTR)lpELF->elfFullName);
  1903.       lstrcpy((LPSTR)lpVisitingELF->elfStyle, (LPSTR)lpELF->elfStyle);
  1904.  
  1905.       // reset masks 
  1906.       bELFCurrStyleMask = 0;
  1907.       bELFSelStyleMask  = 0;
  1908.  
  1909.       // quit enumerating
  1910.       return 0;
  1911.    }
  1912.    else
  1913.       return 1;
  1914. }
  1915.  
  1916. //*************************************************************
  1917. //
  1918. //  GetStyleMask
  1919. //
  1920. //  Purpose: To find what kind of styles are in a LOGFONT.  This
  1921. //           function returns a BYTE mask that is used in the 
  1922. //           EnumFontFamilyProc's
  1923. //
  1924. //
  1925. //  Parameters:
  1926. //      LOGFONT FAR *lf
  1927. //      
  1928. //
  1929. //  Return: (BYTE)
  1930. //
  1931. //
  1932. //  Comments:
  1933. //
  1934. //
  1935. //  History:    Date       Author     Comment
  1936. //              2/27/92    Don Miller Created
  1937. //*************************************************************
  1938.  
  1939. BYTE GetStyleMask(LOGFONT FAR *lf)
  1940. {
  1941.    BYTE bMask = 0;
  1942.    // set low bit if bold
  1943.    if (lf->lfWeight > 400)
  1944.       bMask |= 1;
  1945.    
  1946.    // set second lowest bit if italic
  1947.    if (lf->lfItalic)
  1948.       bMask |= 2;
  1949.  
  1950.    return bMask;
  1951.  
  1952. } //*** GetStyleMask
  1953.  
  1954. /*** EOF: ttdmp.c ***/
  1955.  
  1956.