|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.