Annotation of q_a/samples/printer/paint.c, revision 1.1.1.1

1.1       root        1: /******************************************************************************\
                      2: *
                      3: *  MODULE:      PAINT.C
                      4: *
                      5: *  PURPOSE:     Given an HDC and a pointer to a bounding rectangle
                      6: *               draw all graphics/fonts based on the flags set in
                      7: *               the dwGraphicsOptions global variable.
                      8: *
                      9: *  FUNTIONS:    Paint()               - main painting routine
                     10: *               GetFirstGraphicSlot() - computes bounding rect of 1st
                     11: *                                       graphic
                     12: *               GetNextGraphicSlot()  - computes bounding rect of next
                     13: *                                       graphic
                     14: *               DrawFonts()           - draws enumerated fonts
                     15: *               BuildFontList()       - builds a list of fonts of fonts
                     16: *                                       supported by a given DC
                     17: *               MyEnumFaces()         - enumerates the font facenames
                     18: *                                       supported by a given DC
                     19: *               MyEnumCopy()          - copies LOGFONT & TEXTMETRIC info
                     20: *                                       to a global variable
                     21: *               MyEnumCount()         - counts total number of fonts
                     22: *                                       supported by a given DC
                     23: *               FreeFontList()        - frees a (BuildFontList-) font list
                     24: *
                     25: *  COMMENTS:    Most of the font-enumeration code "lifted" from NTF.EXE
                     26: *               sample. For more complete documentation have a look a
                     27: *               that.
                     28: *
                     29: \******************************************************************************/
                     30: 
                     31: #include <windows.h>
                     32: #include <string.h>
                     33: #include "lookup.h"
                     34: #include "paint.h"
                     35: #include "vars.h"
                     36: 
                     37: 
                     38: /******************************************************************************\
                     39: *
                     40: *  FUNCTION:    Paint
                     41: *
                     42: *  INPUTS:      hdc - device context to paint
                     43: *               lpR - bounding rectangle of device to paint
                     44: *
                     45: *  RETURNS:     TRUE if painting went ok, or
                     46: *               FALSE if error while painting
                     47: *
                     48: *  GLOBAL VARS: dwGraphicsOptions - current graphics options
                     49: *
                     50: *  LOCAL VARS:  ri - a scratch rectangle with integer elements
                     51: *
                     52: \******************************************************************************/
                     53: 
                     54: BOOL Paint (HDC hdc, LPRECT lpR)
                     55: {
                     56:   RECTI ri;
                     57: 
                     58:   if (dwGraphicsOptions & ENUMFONTS)
                     59:   {
                     60:     DrawFonts (hdc, lpR);
                     61:     return TRUE;
                     62:   }
                     63: 
                     64:   iDeltaX = (int) ((lpR->right - BORDER)/NUM_GRAPHICS_XSLOTS);
                     65:   iDeltaY = (int) ((lpR->bottom- BORDER)/NUM_GRAPHICS_YSLOTS);
                     66: 
                     67:   GetFirstGraphicSlot (&ri);
                     68: 
                     69:   if (dwGraphicsOptions & ARC)
                     70:   {
                     71:     Arc (hdc, ri.left, ri.top, ri.right, ri.bottom,
                     72:               ri.left, ri.top, ri.right-10, ri.bottom-10);
                     73:     GetNextGraphicSlot (&ri);
                     74:   }
                     75: 
                     76:   if (dwGraphicsOptions & ELLIPSE)
                     77:   {
                     78:     SelectObject (hdc, GetStockObject (DKGRAY_BRUSH));
                     79:     Ellipse (hdc, ri.left, ri.top, ri.right, ri.bottom);
                     80:     GetNextGraphicSlot (&ri);
                     81:   }
                     82: 
                     83:   if (dwGraphicsOptions & LINETO)
                     84:   {
                     85:     int i;
                     86: 
                     87:     for (i = PS_SOLID; i <= PS_DASHDOTDOT; i++)
                     88:     {
                     89:       HPEN hpenSave;
                     90:       HPEN hpen = CreatePen (i, i+1, RGB(0,0,0));
                     91: 
                     92:       hpenSave = SelectObject (hdc, hpen);
                     93:       MoveToEx (hdc, ri.left, ri.top + (i+1)*iDeltaY/7, NULL);
                     94:       LineTo   (hdc, ri.right, ri.top + (i+1)*iDeltaY/7);
                     95:       SelectObject (hdc, hpenSave);
                     96:       DeleteObject (hpen);
                     97:     }
                     98:     GetNextGraphicSlot (&ri);
                     99:   }
                    100: 
                    101:   if (dwGraphicsOptions & PIE)
                    102:   {
                    103:     SelectObject (hdc, GetStockObject (LTGRAY_BRUSH));
                    104:     Pie (hdc, ri.left, ri.top, ri.right, ri.bottom,
                    105:               ri.left, ri.top, ri.right-10, ri.bottom-10);
                    106:     GetNextGraphicSlot (&ri);
                    107:   }
                    108: 
                    109:   if (dwGraphicsOptions & POLYBEZIER)
                    110:   {
                    111:     POINT ap[4];
                    112: 
                    113:     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
                    114:     ap[1].x  = (LONG) ri.left;    ap[1].y = (LONG) ri.bottom;
                    115:     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
                    116:     ap[3].x  = (LONG) ri.right;   ap[3].y = (LONG) ri.bottom;
                    117: 
                    118:     PolyBezier (hdc, ap, 4);
                    119:     GetNextGraphicSlot (&ri);
                    120:   }
                    121: 
                    122:   if (dwGraphicsOptions & POLYGON)
                    123:   {
                    124:     POINT ap[5];
                    125: 
                    126:     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
                    127:     ap[1].x  = (LONG) ri.right;   ap[1].y = (LONG) ri.bottom;
                    128:     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
                    129:     ap[3].x  = (LONG) ri.left;    ap[3].y = (LONG) ri.bottom;
                    130:     ap[4].x  = (LONG) ri.left;    ap[4].y = (LONG) ri.top;
                    131: 
                    132:     SelectObject (hdc, GetStockObject (BLACK_BRUSH));
                    133:     Polygon (hdc, ap, 4);
                    134:     GetNextGraphicSlot (&ri);
                    135:   }
                    136: 
                    137:   if (dwGraphicsOptions & POLYLINE)
                    138:   {
                    139:     POINT ap[4];
                    140: 
                    141:     ap[0].x  = (LONG) ri.left;    ap[0].y = (LONG) ri.top;
                    142:     ap[1].x  = (LONG) ri.left;    ap[1].y = (LONG) ri.bottom;
                    143:     ap[2].x  = (LONG) ri.right;   ap[2].y = (LONG) ri.top;
                    144:     ap[3].x  = (LONG) ri.right;   ap[3].y = (LONG) ri.bottom;
                    145: 
                    146:     Polyline (hdc, ap, 4);
                    147:     GetNextGraphicSlot (&ri);
                    148:   }
                    149: 
                    150:   if (dwGraphicsOptions & POLYPOLYGON)
                    151:   {
                    152:     POINT ap[8];
                    153:     int ai[2] = { 4, 4 };
                    154: 
                    155:     ap[0].x = (LONG) ri.left;
                    156:     ap[0].y = (LONG) ri.top;
                    157:     ap[1].x = (LONG) (ri.left + iDeltaX/4);
                    158:     ap[1].y = (LONG) ri.top;
                    159:     ap[2].x = (LONG) (ri.left + iDeltaX/4);
                    160:     ap[2].y = (LONG) (ri.top + iDeltaY/4);
                    161:     ap[3].x = (LONG) ri.left;
                    162:     ap[3].y = (LONG) (ri.top + iDeltaY/4);
                    163:     ap[4].x = (LONG) (ri.right - 2*iDeltaX/3);
                    164:     ap[4].y = (LONG) (ri.bottom - 2*iDeltaY/3);
                    165:     ap[5].x = (LONG) ri.right;
                    166:     ap[5].y = (LONG) (ri.bottom - 2*iDeltaY/3);
                    167:     ap[6].x = (LONG) ri.right;
                    168:     ap[6].y = (LONG) ri.bottom;
                    169:     ap[7].x = (LONG) (ri.right - 2*iDeltaX/3);
                    170:     ap[7].y = (LONG) ri.bottom;
                    171: 
                    172:     SelectObject (hdc, GetStockObject (BLACK_BRUSH));
                    173:     PolyPolygon (hdc, ap, ai, 2);
                    174:     GetNextGraphicSlot (&ri);
                    175:   }
                    176: 
                    177:   if (dwGraphicsOptions & RECTANGLE)
                    178:   {
                    179:     SelectObject (hdc, GetStockObject (LTGRAY_BRUSH));
                    180:     Rectangle (hdc, ri.left, ri.top, ri.right, ri.bottom);
                    181:     GetNextGraphicSlot (&ri);
                    182:   }
                    183: 
                    184:   if (dwGraphicsOptions & ROUNDRECT)
                    185:   {
                    186:     SelectObject (hdc, GetStockObject (DKGRAY_BRUSH));
                    187:     RoundRect (hdc, ri.left, ri.top, ri.right, ri.bottom, 12, 19);
                    188:     GetNextGraphicSlot (&ri);
                    189:   }
                    190: 
                    191:   if (dwGraphicsOptions & STRETCH_BLT)
                    192:   {
                    193:     HBITMAP hbm;
                    194:     BITMAP  bm;
                    195:     HDC     hdcMem;
                    196: 
                    197:     hbm = LoadBitmap (hInst, "printer");
                    198:     hdcMem = CreateCompatibleDC (hdc);
                    199:     SelectObject (hdcMem, hbm);
                    200:     SetMapMode (hdcMem, GetMapMode(hdc));
                    201: 
                    202:     GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
                    203:     StretchBlt (hdc, ri.left, ri.top, ri.right-ri.left,
                    204:                 ri.bottom - ri.top, hdcMem, 0, 0,
                    205:                 bm.bmWidth, bm.bmHeight, SRCCOPY);
                    206: 
                    207:     DeleteDC(hdcMem);
                    208:     GetNextGraphicSlot (&ri);
                    209:   }
                    210: 
                    211:   if (dwGraphicsOptions & TEXTOUT)
                    212:   {
                    213:     TextOut (hdc, ri.left, ri.top + iDeltaY/2, "TextOut", 7);
                    214:     GetNextGraphicSlot (&ri);
                    215:   }
                    216: 
                    217:   return TRUE;
                    218: }
                    219: 
                    220: 
                    221: 
                    222: /******************************************************************************\
                    223: *
                    224: *  FUNCTION:    GetFirstGraphicSlot
                    225: *
                    226: *  INPUTS:      pri - pointer to a RECTI
                    227: *
                    228: *  GLOBAL VARS: column  - current grpahics column/slot
                    229: *               iDeltax - width of grahics slots
                    230: *               iDeltaY - height of grahics slots
                    231: *
                    232: \******************************************************************************/
                    233: 
                    234: void GetFirstGraphicSlot (PRECTI pri)
                    235: {
                    236:   pri->left   = BORDER;
                    237:   pri->top    = BORDER;
                    238:   pri->right  = iDeltaX;
                    239:   pri->bottom = iDeltaY;
                    240: 
                    241:   column = 1;
                    242: }
                    243: 
                    244: 
                    245: 
                    246: /******************************************************************************\
                    247: *
                    248: *  FUNCTION:    GetNextGraphicSlot
                    249: *
                    250: *  INPUTS:      pri - pointer to a RECTI
                    251: *
                    252: *  GLOBAL VARS: column  - current grpahics column/slot
                    253: *               iDeltax - width of grahics slots
                    254: *               iDeltaY - height of grahics slots
                    255: *
                    256: \******************************************************************************/
                    257: 
                    258: void GetNextGraphicSlot (PRECTI pri)
                    259: {
                    260:   if (++column <= NUM_GRAPHICS_XSLOTS)
                    261:   {
                    262:     pri->left  += iDeltaX;
                    263:     pri->right += iDeltaX;
                    264:   }
                    265:   else
                    266:   {
                    267:     column = 1;
                    268:     pri->left   =  BORDER;
                    269:     pri->top    += iDeltaY;
                    270:     pri->right  =  iDeltaX;
                    271:     pri->bottom += iDeltaY;
                    272:   }
                    273: }
                    274: 
                    275: 
                    276: 
                    277: /******************************************************************************\
                    278: *
                    279: *  FUNCTION:    DrawFonts
                    280: *
                    281: *  LOCAL VARS:  i, j       - loop variables
                    282: *               xText      - starting x position to draw text
                    283: *               yText      - starting y position to draw text
                    284: *               iMaxStrLen - length in pels of string to draw
                    285: *
                    286: \******************************************************************************/
                    287: 
                    288: void DrawFonts (HDC hdc, LPRECT lpR)
                    289: {
                    290:   int      i, j, xText, yText, iMaxStrLen = 0;
                    291:   PARFONTS paf;
                    292: 
                    293:   paf = BuildFontList (hdc);
                    294:   xText = yText = 2;
                    295:   for (i = 0; i < nFaces; i++)
                    296:   {
                    297:     for (j = 0; j < (paf + i)->nFonts; j++)
                    298:     {
                    299:       HFONT      hFont, hSaveFont;
                    300:       SIZE       size;
                    301:       TEXTMETRIC *pNextTM;
                    302:       POINT      LogPtBtmRt;
                    303: 
                    304:       LogPtBtmRt.x = lpR->right;
                    305:       LogPtBtmRt.y = lpR->bottom;
                    306:       if (GetDeviceCaps (hdc, TECHNOLOGY) & DT_RASDISPLAY)
                    307:        LogPtBtmRt.y += TOOLBARHEIGHT;
                    308:       DPtoLP (hdc, &LogPtBtmRt, 1);
                    309: 
                    310:       hFont = CreateFontIndirect ((paf + i)->lf + j);
                    311:       hSaveFont = SelectObject (hdc, hFont);
                    312:       TextOut (hdc, xText, yText, ((paf + i)->lf + j)->lfFaceName,
                    313:                strlen(((paf + i)->lf + j)->lfFaceName));
                    314: 
                    315:       GetTextExtentPoint (hdc, ((paf + i)->lf + j)->lfFaceName,
                    316:                           strlen(((paf+i)->lf+j)->lfFaceName),
                    317:                           &size);
                    318:       size.cx += 2;
                    319:       iMaxStrLen = iMaxStrLen > (int)size.cx ? iMaxStrLen:
                    320:                                                (int) size.cx;
                    321: 
                    322:       if (!(i == (nFaces - 1) && j == ((paf + i)->nFonts - 1)))
                    323:       {
                    324:         pNextTM = j < ((paf+i)->nFonts-1) ?
                    325:                           (paf+i)->tm+j+1 : (paf+i+1)->tm;
                    326: 
                    327:         if ((yText += (int) ((paf + i)->tm + j)->tmHeight) +
                    328:                (int) pNextTM->tmHeight  > (int) LogPtBtmRt.y)
                    329:         {
                    330:           yText = 2;
                    331:           xText += iMaxStrLen + 2;
                    332:           iMaxStrLen = 0;
                    333:         }
                    334:       }
                    335: 
                    336:       SelectObject (hdc, hSaveFont);
                    337:       DeleteObject (hFont);
                    338:       if (xText > (int) LogPtBtmRt.x)
                    339:       {
                    340:         if (GetDeviceCaps (hdc, TECHNOLOGY) & DT_RASDISPLAY)
                    341:         {
                    342:           /********************************************************************\
                    343:           *  If we're drawing to the screen & have run out of
                    344:           *  room then tell user how many fonts there are left
                    345:           *  (that we haven't displayed
                    346:           \********************************************************************/
                    347: 
                    348:           int   k;
                    349:           int   iFontsLeft = (paf + i)->nFonts - j - 1;
                    350:           char  buf[40];
                    351:           SIZE  size;
                    352: 
                    353:           for (k = i + 1; k < nFaces; k++)
                    354:             iFontsLeft += (paf + k)->nFonts;
                    355: 
                    356:           wsprintf (buf, "%ld more display fonts (not listed)",
                    357:                     iFontsLeft);
                    358: 
                    359:           GetTextExtentPoint (hdc, buf, strlen(buf), &size);
                    360:           TextOut (hdc, lpR->right - size.cx, lpR->bottom - size.cy,
                    361:                    buf, strlen(buf));
                    362:           goto done_enumfonts;
                    363:         }
                    364:         else
                    365:         {
                    366:           /********************************************************************\
                    367:           *  Else we're drawing to a printer & have filled up
                    368:           *  the first page. If there's any fonts left to draw
                    369:           *  then start a new page.
                    370:           \********************************************************************/
                    371: 
                    372:           if (!(i == nFaces - 1 && j == (paf + i)->nFonts - 1))
                    373:           { EndPage   (hdc);
                    374:             xText = yText = 2;
                    375:             StartPage (hdc);
                    376:           }
                    377:         }
                    378:       }
                    379:     }
                    380:   }
                    381: done_enumfonts:
                    382:   FreeFontList (paf);
                    383: }
                    384: 
                    385: 
                    386: 
                    387: 
                    388: /*  In the callback functions from the enumerations, there is a limited
                    389:  *  ability to pass in parameters.  For that reason, declare the following
                    390:  *  global variables to be used by any of the call back functions.
                    391:  *
                    392:  *        HDC      hdcGlobal;
                    393:  *        PARFONTS parFontsGlobal;
                    394:  *        int      iFace,jFont;
                    395:  *        int      nFaces;
                    396:  *
                    397:  *
                    398:  * General call structure:
                    399:  *
                    400:  *  BuildFontList()
                    401:  *      EnumFonts
                    402:  *          MyEnumCount()
                    403:  *      LocalAlloc
                    404:  *      EnumFonts
                    405:  *          MyEnumFaces()
                    406:  *              EnumFonts
                    407:  *                  MyEnumCount()
                    408:  *              LocalAlloc
                    409:  *              LocalAlloc
                    410:  *              LocalAlloc
                    411:  *              EnumFonts
                    412:  *                  MyEnumCopy()
                    413:  */
                    414: 
                    415: 
                    416: 
                    417: /******************************************************************************\
                    418: *
                    419: *  FUNCTION:    BuildFontList
                    420: *
                    421: *  GLOBAL VARS: (see above)
                    422: *
                    423: \******************************************************************************/
                    424: 
                    425: PARFONTS BuildFontList (HDC hdcIn)
                    426: {
                    427:   nFaces = 0;
                    428: 
                    429:   hdcGlobal = hdcIn;
                    430: 
                    431:   /****************************************************************************\
                    432:   *  count the total number of face names.
                    433:   \****************************************************************************/
                    434: 
                    435:   EnumFonts (hdcGlobal, NULL, (PROC)MyEnumCount, (LPARAM)&nFaces);
                    436: 
                    437:   /****************************************************************************\
                    438:   *  allocate the pointer to the array of PArFont structures.
                    439:   \****************************************************************************/
                    440: 
                    441:   parFontsGlobal = LocalAlloc (LPTR, sizeof(ARFONTS) * (nFaces+1));
                    442: 
                    443:   /****************************************************************************\
                    444:   *  step through all fonts again.  For each one fill a LOGFONT and
                    445:   *  a TEXTMETRIC stucture.
                    446:   \****************************************************************************/
                    447: 
                    448:   iFace = 0;
                    449:   EnumFonts (hdcGlobal, NULL, (PROC)MyEnumFaces, NULL);
                    450: 
                    451:   return parFontsGlobal;
                    452: }
                    453: 
                    454: 
                    455: 
                    456: /******************************************************************************\
                    457: *
                    458: *  FUNCTION:    MyEnumFaces
                    459: *
                    460: *  GLOBAL VARS: (see above)
                    461: *
                    462: \******************************************************************************/
                    463: 
                    464: int APIENTRY MyEnumFaces (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
                    465:                           DWORD fFontType, LPVOID  lpData)
                    466: {
                    467:   int nFonts;
                    468: 
                    469:   nFonts = 0;
                    470:   EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (PROC)MyEnumCount,
                    471:              (LPARAM)&nFonts);
                    472: 
                    473:   parFontsGlobal[iFace].lf   = LocalAlloc (LPTR,
                    474:                                            sizeof(LOGFONT)    * nFonts);
                    475:   parFontsGlobal[iFace].tm   = LocalAlloc (LPTR,
                    476:                                            sizeof(TEXTMETRIC) * nFonts);
                    477:   parFontsGlobal[iFace].Type = LocalAlloc (LPTR,
                    478:                                            sizeof(int)        * nFonts);
                    479: 
                    480:   if ((parFontsGlobal[iFace].lf   == NULL) ||
                    481:       (parFontsGlobal[iFace].tm   == NULL) ||
                    482:       (parFontsGlobal[iFace].Type == NULL)) {
                    483:     MessageBox (NULL, "alloc failed", "HEY!", MB_ICONSTOP | MB_OK);
                    484:     return FALSE;
                    485:   }
                    486: 
                    487:   parFontsGlobal[iFace].nFonts = nFonts;
                    488: 
                    489:   jFont = 0;
                    490:   EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (PROC)MyEnumCopy, NULL);
                    491: 
                    492:   iFace++;
                    493: 
                    494:   return TRUE;
                    495: }
                    496: 
                    497: 
                    498: 
                    499: /******************************************************************************\
                    500: *
                    501: *  FUNCTION:    MyEnumCopy
                    502: *
                    503: *  GLOBAL VARS: (see above)
                    504: *
                    505: \******************************************************************************/
                    506: 
                    507: int APIENTRY MyEnumCopy (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
                    508:                          DWORD fFontType, LPVOID  lpData)
                    509: {
                    510:   LOGFONT    *lplf;
                    511:   TEXTMETRIC *lptm;
                    512:   int        *pType;
                    513: 
                    514:   lplf  = parFontsGlobal[iFace].lf;
                    515:   lptm  = parFontsGlobal[iFace].tm;
                    516:   pType = parFontsGlobal[iFace].Type;
                    517: 
                    518:   lplf[jFont]  = *lpLogFont;
                    519:   lptm[jFont]  = *lpTEXTMETRICs;
                    520:   pType[jFont] = fFontType;
                    521: 
                    522:   jFont++;
                    523:   return TRUE;
                    524: }
                    525: 
                    526: 
                    527: 
                    528: /******************************************************************************\
                    529: *
                    530: *  FUNCTION:    MyEnumCount
                    531: *
                    532: *  GLOBAL VARS: (see above)
                    533: *
                    534: \******************************************************************************/
                    535: 
                    536: int APIENTRY MyEnumCount (LPLOGFONT lpLogFont, LPTEXTMETRIC lpTEXTMETRICs,
                    537:                           DWORD fFontType, LPVOID lpData)
                    538: {
                    539:   (*(LPINT)lpData)++;
                    540:   return TRUE;
                    541: }
                    542: 
                    543: 
                    544: 
                    545: /******************************************************************************\
                    546: *
                    547: *  FUNCTION:    FreeFontList
                    548: *
                    549: *  INPUTS:      paf - pointer to ARFONTS struct to free
                    550: *
                    551: *  LOCAL VARS:  i - loop variable
                    552: *
                    553: \******************************************************************************/
                    554: 
                    555: void FreeFontList (PARFONTS paf)
                    556: {
                    557:   int i;
                    558: 
                    559:   for (i = 0; i < nFaces; i++)
                    560:   { LocalFree (LocalHandle ((LPSTR) ((paf + i)->lf  )));
                    561:     LocalFree (LocalHandle ((LPSTR) ((paf + i)->tm  )));
                    562:     LocalFree (LocalHandle ((LPSTR) ((paf + i)->Type)));
                    563:   }
                    564:   LocalFree (LocalHandle ((LPSTR) paf));
                    565: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.