home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / gdi / printer / paint.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  19KB  |  683 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /******************************************************************************\
  13. *
  14. *  MODULE:      PAINT.C
  15. *
  16. *  PURPOSE:     Given an HDC and a pointer to a bounding rectangle
  17. *               draw all graphics/fonts based on the flags set in
  18. *               the dwGraphicsOptions global variable.
  19. *
  20. *  FUNTIONS:    Paint              - main painting routine
  21. *               GetFirstGraphicSlot- computes bounding rect of 1st
  22. *                                      graphic
  23. *               GetNextGraphicSlot - computes bounding rect of next
  24. *                                      graphic
  25. *               DrawFonts          - draws enumerated fonts
  26. *               BuildFontList      - builds a list of fonts of fonts
  27. *                                      supported by a given DC
  28. *               MyEnumFaces        - enumerates the font facenames
  29. *                                      supported by a given DC
  30. *               MyEnumCopy         - copies LOGFONT & TEXTMETRIC info
  31. *                                      to a global variable
  32. *               MyEnumCount        - counts total number of fonts
  33. *                                      supported by a given DC
  34. *               FreeFontList       - frees a (BuildFontList-) font list
  35. *
  36. *  COMMENTS:    Most of the font-enumeration code "lifted" from NTF.EXE
  37. *               sample. For more complete documentation have a look a
  38. *               that.
  39. *
  40. \******************************************************************************/
  41.  
  42. #include <windows.h>
  43. #include <string.h>
  44. #include "common.h"
  45. #include "paint.h"
  46.  
  47.  
  48.  
  49. /******************************************************************************\
  50. *
  51. *  FUNCTION:    Paint
  52. *
  53. *  INPUTS:      hdc    - device context to paint
  54. *               lpRect - bounding rectangle of device to paint
  55. *
  56. *  RETURNS:     TRUE if painting went ok, or
  57. *               FALSE if error while painting
  58. *
  59. \******************************************************************************/
  60.  
  61. BOOL Paint (HDC hdc, LPRECT lpRect)
  62. {
  63.   RECT  rect;
  64.   HPEN  hpenSave;
  65.   RECTI ri;
  66.  
  67.   if (gdwGraphicsOptions & DRAWAXIS)
  68.   {
  69.  
  70.     //
  71.     // draw axis
  72.     //
  73.  
  74.     rect = *lpRect;
  75.  
  76.     hpenSave = SelectObject (hdc, GetStockObject (BLACK_PEN));
  77.  
  78.     //
  79.     // if giMapMode == MM_TEXT, MM_ANISOTROPIC then (0,0) is upper left corner
  80.     //
  81.  
  82.     if (giMapMode == MM_TEXT || giMapMode == MM_ANISOTROPIC)
  83.     {
  84.       MoveToEx (hdc, rect.left - glcyMenu/2, rect.bottom, NULL);
  85.       LineTo   (hdc, rect.left,  rect.bottom + glcyMenu/2);
  86.       LineTo   (hdc, rect.left + glcyMenu/2,  rect.bottom);
  87.  
  88.       MoveToEx (hdc, rect.left,  rect.bottom + glcyMenu/2, NULL);
  89.       LineTo   (hdc, rect.left,  rect.top);
  90.       LineTo   (hdc, rect.right + glcyMenu/2, rect.top);
  91.  
  92.       MoveToEx (hdc, rect.right, rect.top - glcyMenu/2, NULL);
  93.       LineTo   (hdc, rect.right + glcyMenu/2,  rect.top);
  94.       LineTo   (hdc, rect.right,  rect.top + glcyMenu/2);
  95.     }
  96.  
  97.     //
  98.     // else (0,0) is lower left corner
  99.     //
  100.  
  101.     else
  102.     {
  103.       MoveToEx (hdc, rect.left - glcyMenu/2, rect.bottom, NULL);
  104.       LineTo   (hdc, rect.left,  rect.bottom + glcyMenu/2);
  105.       LineTo   (hdc, rect.left + glcyMenu/2,  rect.bottom);
  106.  
  107.       MoveToEx (hdc, rect.left,  rect.bottom + glcyMenu/2, NULL);
  108.       LineTo   (hdc, rect.left,  rect.top);
  109.       LineTo   (hdc, rect.right + glcyMenu/2, rect.top);
  110.  
  111.       MoveToEx (hdc, rect.right, rect.top + glcyMenu/2, NULL);
  112.       LineTo   (hdc, rect.right + glcyMenu/2, rect.top);
  113.       LineTo   (hdc, rect.right, rect.top - glcyMenu/2);
  114.     }
  115.   }
  116.  
  117.   SelectObject (hdc, hpenSave);
  118.  
  119.   //
  120.   // look at bits in gdwGraphicsOptions & determine which graphics to draw
  121.   //
  122.  
  123.   if (gdwGraphicsOptions & ENUMFONTS)
  124.   {
  125.     DrawFonts (hdc, lpRect);
  126.     return TRUE;
  127.   }
  128.  
  129.   giDeltaX = (int) ((lpRect->right - BORDER) / NUM_GRAPHICS_XSLOTS);
  130.   giDeltaY = (int) ((lpRect->bottom - lpRect->top - BORDER)
  131.                                              / NUM_GRAPHICS_YSLOTS);
  132.  
  133.   GetFirstGraphicSlot (lpRect, &ri);
  134.  
  135.   if (gdwGraphicsOptions & ARC)
  136.   {
  137.     Arc (hdc, ri.left, ri.top, ri.right, ri.bottom,
  138.               ri.left, ri.top, ri.right-10, ri.bottom-10);
  139.     GetNextGraphicSlot (&ri);
  140.   }
  141.  
  142.   if (gdwGraphicsOptions & ELLIPSE)
  143.   {
  144.     Ellipse (hdc, ri.left, ri.top, ri.right, ri.bottom);
  145.     GetNextGraphicSlot (&ri);
  146.   }
  147.  
  148.   if (gdwGraphicsOptions & LINETO)
  149.   {
  150.     int i;
  151.  
  152.     for (i = PS_SOLID; i <= PS_DASHDOTDOT; i++)
  153.     {
  154.       MoveToEx (hdc, ri.left, ri.top + (i+1)*giDeltaY/7, NULL);
  155.       LineTo   (hdc, ri.right, ri.top + (i+1)*giDeltaY/7);
  156.     }
  157.     GetNextGraphicSlot (&ri);
  158.   }
  159.  
  160.   if (gdwGraphicsOptions & PIE)
  161.   {
  162.     Pie (hdc, ri.left, ri.top, ri.right, ri.bottom,
  163.               ri.left, ri.top, ri.right-10, ri.bottom-10);
  164.     GetNextGraphicSlot (&ri);
  165.   }
  166.  
  167.   if (gdwGraphicsOptions & PLG_BLT)
  168.   {
  169.     HBITMAP hbm;
  170.     BITMAP  bm;
  171.     HDC     hdcMem;
  172.     POINT   ap[3];
  173.  
  174.     hbm = LoadBitmap (ghInst, "printer");
  175.     hdcMem = CreateCompatibleDC (hdc);
  176.     SelectObject (hdcMem, hbm);
  177.  
  178.     GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
  179.  
  180.     //
  181.     // special case here because PlgBlt requires coordinates
  182.     //   of upper left, upper right, & lower left
  183.     //
  184.  
  185.     ap[0].x = (LONG) (ri.left + (ri.right - ri.left)/4);
  186.     ap[0].y = (LONG) (ri.top + (ri.bottom - ri.top)/4);
  187.     ap[1].x = (LONG) ri.right;
  188.     ap[1].y = (LONG) ri.top;
  189.     ap[2].x = (LONG) ri.left;
  190.     ap[2].y = (LONG) ri.bottom;
  191.  
  192.     PlgBlt (hdc, ap, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, NULL, 0, 0);
  193.  
  194.     DeleteDC(hdcMem);
  195.     GetNextGraphicSlot (&ri);
  196.  
  197.   }
  198.  
  199.   if (gdwGraphicsOptions & POLYBEZIER)
  200.   {
  201.     POINT ap[4];
  202.  
  203.     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
  204.     ap[1].x  = (LONG) ri.left;    ap[1].y = (LONG) ri.bottom;
  205.     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
  206.     ap[3].x  = (LONG) ri.right;   ap[3].y = (LONG) ri.bottom;
  207.  
  208.     PolyBezier (hdc, ap, 4);
  209.     GetNextGraphicSlot (&ri);
  210.   }
  211.  
  212.   if (gdwGraphicsOptions & POLYGON)
  213.   {
  214.     POINT ap[5];
  215.  
  216.     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
  217.     ap[1].x  = (LONG) ri.right;   ap[1].y = (LONG) ri.bottom;
  218.     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
  219.     ap[3].x  = (LONG) ri.left;    ap[3].y = (LONG) ri.bottom;
  220.     ap[4].x  = (LONG) ri.left;    ap[4].y = (LONG) ri.top;
  221.  
  222.     Polygon (hdc, ap, 4);
  223.     GetNextGraphicSlot (&ri);
  224.   }
  225.  
  226.   if (gdwGraphicsOptions & POLYLINE)
  227.   {
  228.     POINT ap[4];
  229.  
  230.     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
  231.     ap[1].x  = (LONG) ri.left;    ap[1].y = (LONG) ri.bottom;
  232.     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
  233.     ap[3].x  = (LONG) ri.right;   ap[3].y = (LONG) ri.bottom;
  234.  
  235.     Polyline (hdc, ap, 4);
  236.     GetNextGraphicSlot (&ri);
  237.   }
  238.  
  239.   if (gdwGraphicsOptions & POLYPOLYGON)
  240.   {
  241.     POINT ap[8];
  242.     int ai[2] = { 4, 4 };
  243.  
  244.     ap[0].x = (LONG)  ri.left;
  245.     ap[0].y = (LONG)  ri.top;
  246.     ap[1].x = (LONG) (ri.left + giDeltaX/4);
  247.     ap[1].y = (LONG)  ri.top;
  248.     ap[2].x = (LONG) (ri.left + giDeltaX/4);
  249.     ap[2].y = (LONG) (ri.top  + giDeltaY/4);
  250.     ap[3].x = (LONG)  ri.left;
  251.     ap[3].y = (LONG) (ri.top  + giDeltaY/4);
  252.     ap[4].x = (LONG) (ri.right  - 2*giDeltaX/3);
  253.     ap[4].y = (LONG) (ri.bottom - 2*giDeltaY/3);
  254.     ap[5].x = (LONG)  ri.right;
  255.     ap[5].y = (LONG) (ri.bottom - 2*giDeltaY/3);
  256.     ap[6].x = (LONG)  ri.right;
  257.     ap[6].y = (LONG)  ri.bottom;
  258.     ap[7].x = (LONG) (ri.right  - 2*giDeltaX/3);
  259.     ap[7].y = (LONG)  ri.bottom;
  260.  
  261.     PolyPolygon (hdc, ap, ai, 2);
  262.     GetNextGraphicSlot (&ri);
  263.   }
  264.  
  265.   if (gdwGraphicsOptions & RECTANGLE)
  266.   {
  267.     Rectangle (hdc, ri.left, ri.top, ri.right, ri.bottom);
  268.     GetNextGraphicSlot (&ri);
  269.   }
  270.  
  271.   if (gdwGraphicsOptions & ROUNDRECT)
  272.   {
  273.     RoundRect (hdc, ri.left, ri.top, ri.right, ri.bottom, 15, 25);
  274.     GetNextGraphicSlot (&ri);
  275.   }
  276.  
  277.   if (gdwGraphicsOptions & STRETCH_BLT)
  278.   {
  279.     HBITMAP hbm;
  280.     BITMAP  bm;
  281.     HDC     hdcMem;
  282.  
  283.     hbm = LoadBitmap (ghInst, "printer");
  284.     hdcMem = CreateCompatibleDC (hdc);
  285.     SelectObject (hdcMem, hbm);
  286.  
  287.     GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
  288.  
  289.     StretchBlt (hdc, ri.left, ri.top, ri.right-ri.left,
  290.                 ri.bottom - ri.top, hdcMem, 0, 0,
  291.                 bm.bmWidth, bm.bmHeight, SRCCOPY);
  292.  
  293.     DeleteDC(hdcMem);
  294.     GetNextGraphicSlot (&ri);
  295.  
  296.   }
  297.  
  298.   return TRUE;
  299. }
  300.  
  301.  
  302.  
  303. /******************************************************************************\
  304. *
  305. *  FUNCTION:    GetFirstGraphicSlot
  306. *
  307. *  INPUTS:      pri - pointer to a RECTI
  308. *
  309. \******************************************************************************/
  310.  
  311. void GetFirstGraphicSlot (LPRECT lpRect, PRECTI pri)
  312. {
  313.   pri->left   = BORDER;
  314.   pri->top    = lpRect->top + BORDER;
  315.   pri->right  = giDeltaX;
  316.   pri->bottom = giDeltaY;
  317.  
  318.   giColumn = 1;
  319. }
  320.  
  321.  
  322.  
  323. /******************************************************************************\
  324. *
  325. *  FUNCTION:    GetNextGraphicSlot
  326. *
  327. *  INPUTS:      pri - pointer to a RECTI
  328. *
  329. \******************************************************************************/
  330.  
  331. void GetNextGraphicSlot (PRECTI pri)
  332. {
  333.   if (++giColumn <= NUM_GRAPHICS_XSLOTS)
  334.   {
  335.     pri->left  += giDeltaX;
  336.     pri->right += giDeltaX;
  337.   }
  338.   else
  339.   {
  340.     giColumn = 1;
  341.  
  342.     pri->left   =  BORDER;
  343.     pri->top    += giDeltaY;
  344.     pri->right  =  giDeltaX;
  345.     pri->bottom += giDeltaY;
  346.   }
  347. }
  348.  
  349.  
  350.  
  351. /******************************************************************************\
  352. *
  353. *  FUNCTION:    DrawFonts
  354. *
  355. *  INPUTS:      hdc   - device context to enumerate from & draw on
  356. *               pRect - pointer to bounding rect to draw fonts in
  357. *
  358. *  LOCAL VARS:  i, j       - loop variables
  359. *               xText      - starting x position to draw text
  360. *               yText      - starting y position to draw text
  361. *               iMaxStrLen - length in pels of string to draw
  362. *
  363. \******************************************************************************/
  364.  
  365. void DrawFonts (HDC hdc, LPRECT lpRect)
  366. {
  367.   int      i, j, xText, yText, iMaxStrLen = 0;
  368.   PARFONTS paf;
  369.  
  370.   paf = BuildFontList (hdc);
  371.  
  372.   xText = yText = 2;
  373.  
  374.   //
  375.   // set the appropriate text align mode depending on
  376.   //   whether we're drawing from top down or bottom up
  377.   //
  378.  
  379.   if (giMapMode == MM_TEXT | giMapMode == MM_ANISOTROPIC)
  380.  
  381.     SetTextAlign (hdc, TA_TOP);
  382.  
  383.   else
  384.  
  385.     SetTextAlign (hdc, TA_BOTTOM);
  386.  
  387.   for (i = 0; i < nFaces; i++)
  388.   {
  389.     for (j = 0; j < (paf + i)->nFonts; j++)
  390.     {
  391.       HFONT      hFont, hSaveFont;
  392.       SIZE       size;
  393.       POINT      LogPtExtent;
  394.  
  395.       LogPtExtent.x = lpRect->right;
  396.       LogPtExtent.y = lpRect->bottom;
  397.  
  398.       hFont = CreateFontIndirect ((paf + i)->lf + j);
  399.  
  400.       hSaveFont = SelectObject (hdc, hFont);
  401.  
  402.       TextOut (hdc, xText, yText, ((paf + i)->lf + j)->lfFaceName,
  403.                strlen(((paf + i)->lf + j)->lfFaceName));
  404.  
  405.       GetTextExtentPoint (hdc, ((paf + i)->lf + j)->lfFaceName,
  406.                           strlen(((paf+i)->lf+j)->lfFaceName),
  407.                           &size);
  408.       size.cx += 2;
  409.       iMaxStrLen = iMaxStrLen > (int)size.cx ? iMaxStrLen: (int) size.cx;
  410.  
  411.       if (!(i == (nFaces - 1) && j == ((paf + i)->nFonts - 1)))
  412.       {
  413.         TEXTMETRIC *pNextTM;
  414.  
  415.         pNextTM = j < ((paf+i)->nFonts-1) ?
  416.                           (paf+i)->tm+j+1 : (paf+i+1)->tm;
  417.  
  418.         //
  419.         // add in the height of the face name we just drew
  420.         //
  421.  
  422.         yText += (int) ((paf + i)->tm + j)->tmHeight;
  423.  
  424.         //
  425.         // if the next facename will be drawn outside the bounding rect then
  426.         //   start at first line of next column
  427.         //
  428.  
  429.         if (yText + (int) pNextTM->tmHeight > (int) LogPtExtent.y)
  430.         {
  431.           yText = 2;
  432.           xText += iMaxStrLen + 2;
  433.           iMaxStrLen = 0;
  434.         }
  435.       }
  436.  
  437.       SelectObject (hdc, hSaveFont);
  438.       DeleteObject (hFont);
  439.  
  440.       if (xText > (int) LogPtExtent.x)
  441.       {
  442.         if (GetDeviceCaps (hdc, TECHNOLOGY) & DT_RASDISPLAY)
  443.         {
  444.           //
  445.           // If we're drawing to the screen & have run out of
  446.           //   room then tell user how many fonts there are left
  447.           //   (that we haven't displayed)
  448.           //
  449.  
  450.           int   k;
  451.           int   iFontsLeft = (paf + i)->nFonts - j - 1;
  452.           char  buf[40];
  453.           SIZE  size;
  454.  
  455.  
  456.           for (k = i + 1; k < nFaces; k++)
  457.  
  458.             iFontsLeft += (paf + k)->nFonts;
  459.  
  460.           wsprintf (buf, GetStringRes(IDS_FMT_MOREDSPFNTNL),
  461.                     iFontsLeft);
  462.  
  463.           GetTextExtentPoint (hdc, buf, strlen(buf), &size);
  464.  
  465.           if ((xText = lpRect->right - size.cx) < glcyMenu + 1)
  466.  
  467.             xText = glcyMenu/2 + 1;
  468.  
  469.           TextOut (hdc, xText, lpRect->bottom, buf, strlen(buf));
  470.  
  471.           goto done_enumfonts;
  472.         }
  473.  
  474.         else
  475.         {
  476.           //
  477.           // Else we're drawing to a printer & have filled up
  478.           //   the first page. If there's any fonts left to draw
  479.           //   then start a new page.
  480.           //
  481.  
  482.           if (!(i == nFaces - 1 && j == (paf + i)->nFonts - 1))
  483.           {
  484.             EndPage   (hdc);
  485.             xText = yText = 2;
  486.             StartPage (hdc);
  487.           }
  488.         }
  489.       }
  490.     }
  491.   }
  492.  
  493. done_enumfonts:
  494.  
  495.   FreeFontList (paf);
  496. }
  497.  
  498.  
  499.  
  500.  
  501. /*  In the callback functions for the enumerations, there is a limited
  502.  *  ability to pass in parameters.  For that reason, declare the following
  503.  *  global variables to be used by any of the call back functions.
  504.  *
  505.  *        HDC      hdcGlobal;
  506.  *        PARFONTS parFontsGlobal;
  507.  *        int      iFace,jFont;
  508.  *        int      nFaces;
  509.  *
  510.  *
  511.  * General call structure:
  512.  *
  513.  *        BuildFontList
  514.  *            EnumFonts
  515.  *                MyEnumCount
  516.  *            LocalAlloc
  517.  *            EnumFonts
  518.  *                MyEnumFaces
  519.  *                    EnumFonts
  520.  *                        MyEnumCount
  521.  *                    LocalAlloc
  522.  *                    LocalAlloc
  523.  *                    LocalAlloc
  524.  *                    EnumFonts
  525.  *                        MyEnumCopy
  526.  */
  527.  
  528.  
  529.  
  530. /******************************************************************************\
  531. *
  532. *  FUNCTION:    BuildFontList
  533. *
  534. *  GLOBAL VARS: (see above)
  535. *
  536. \******************************************************************************/
  537.  
  538. PARFONTS BuildFontList (HDC hdcIn)
  539. {
  540.   nFaces = 0;
  541.  
  542.   hdcGlobal = hdcIn;
  543.  
  544.   //
  545.   // count the total number of face names.
  546.   //
  547.  
  548.   EnumFonts (hdcGlobal, NULL, (FONTENUMPROC)MyEnumCount, (LPARAM)&nFaces);
  549.  
  550.   //
  551.   // allocate the pointer to the array of PArFont structures.
  552.   //
  553.  
  554.   parFontsGlobal = (PARFONTS) LocalAlloc (LPTR, sizeof(ARFONTS) * (nFaces+1));
  555.  
  556.   //
  557.   // step through all fonts again.  For each one fill a LOGFONT and
  558.   //   a TEXTMETRIC stucture.
  559.   //
  560.  
  561.   iFace = 0;
  562.   EnumFonts (hdcGlobal, NULL, (FONTENUMPROC)MyEnumFaces, 0);
  563.  
  564.   return parFontsGlobal;
  565. }
  566.  
  567.  
  568.  
  569. /******************************************************************************\
  570. *
  571. *  FUNCTION:    MyEnumFaces
  572. *
  573. *  GLOBAL VARS: (see above)
  574. *
  575. \******************************************************************************/
  576.  
  577. int CALLBACK MyEnumFaces (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
  578.                           DWORD fFontType, LPVOID  lpData)
  579. {
  580.   int nFonts;
  581.  
  582.   nFonts = 0;
  583.   EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (FONTENUMPROC)MyEnumCount,
  584.              (LPARAM)&nFonts);
  585.  
  586.   parFontsGlobal[iFace].lf   = (LOGFONT *)    LocalAlloc (LPTR,
  587.                                                           sizeof(LOGFONT) *
  588.                                                             nFonts);
  589.   parFontsGlobal[iFace].tm   = (TEXTMETRIC *) LocalAlloc (LPTR,
  590.                                                           sizeof(TEXTMETRIC) *
  591.                                                             nFonts);
  592.   parFontsGlobal[iFace].Type = (int *)        LocalAlloc (LPTR,
  593.                                                           sizeof(int) *
  594.                                                             nFonts);
  595.  
  596.   if ((parFontsGlobal[iFace].lf   == NULL) ||
  597.       (parFontsGlobal[iFace].tm   == NULL) ||
  598.       (parFontsGlobal[iFace].Type == NULL))
  599.   {
  600.     ErrMsgBox (GetStringRes(IDS_LALLOCFAIL), ERR_MOD_NAME);
  601.     return FALSE;
  602.   }
  603.  
  604.   parFontsGlobal[iFace].nFonts = nFonts;
  605.  
  606.   jFont = 0;
  607.   EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (FONTENUMPROC)MyEnumCopy, 0);
  608.  
  609.   iFace++;
  610.  
  611.   return TRUE;
  612. }
  613.  
  614.  
  615.  
  616. /******************************************************************************\
  617. *
  618. *  FUNCTION:    MyEnumCopy
  619. *
  620. *  GLOBAL VARS: (see above)
  621. *
  622. \******************************************************************************/
  623.  
  624. int CALLBACK MyEnumCopy (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
  625.                          DWORD fFontType, LPVOID  lpData)
  626. {
  627.   LOGFONT    *lplf;
  628.   TEXTMETRIC *lptm;
  629.   int        *pType;
  630.  
  631.   lplf  = parFontsGlobal[iFace].lf;
  632.   lptm  = parFontsGlobal[iFace].tm;
  633.   pType = parFontsGlobal[iFace].Type;
  634.  
  635.   lplf[jFont]  = *lpLogFont;
  636.   lptm[jFont]  = *lpTEXTMETRICs;
  637.   pType[jFont] = fFontType;
  638.  
  639.   jFont++;
  640.   return TRUE;
  641. }
  642.  
  643.  
  644.  
  645. /******************************************************************************\
  646. *
  647. *  FUNCTION:    MyEnumCount
  648. *
  649. *  GLOBAL VARS: (see above)
  650. *
  651. \******************************************************************************/
  652.  
  653. int CALLBACK MyEnumCount (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
  654.                           DWORD fFontType, LPVOID lpData)
  655. {
  656.   (*(LPINT)lpData)++;
  657.   return TRUE;
  658. }
  659.  
  660.  
  661.  
  662. /******************************************************************************\
  663. *
  664. *  FUNCTION:    FreeFontList
  665. *
  666. *  INPUTS:      paf - pointer to ARFONTS struct to free
  667. *
  668. \******************************************************************************/
  669.  
  670. void FreeFontList (PARFONTS paf)
  671. {
  672.   int i;
  673.  
  674.   for (i = 0; i < nFaces; i++)
  675.   {
  676.     LocalFree (LocalHandle ((LPSTR) ((paf + i)->lf  )));
  677.     LocalFree (LocalHandle ((LPSTR) ((paf + i)->tm  )));
  678.     LocalFree (LocalHandle ((LPSTR) ((paf + i)->Type)));
  679.   }
  680.   LocalFree (LocalHandle ((LPSTR) paf));
  681. }
  682.  
  683.