|
|
1.1 ! root 1: #include "windows.h" ! 2: #include <windowsx.h> ! 3: #include "fontedit.h" ! 4: #include "fcntl.h" ! 5: #include "memory.h" ! 6: #include "stdio.h" ! 7: #include "commdlg.h" ! 8: ! 9: ! 10: /****************************************************************************/ ! 11: /* Shared Variables */ ! 12: /****************************************************************************/ ! 13: extern CHAR *PASCAL VerifyHeaderContents();/* checks integrity of header */ ! 14: ! 15: extern FontHeaderType font; /* Structure of Font File Header */ ! 16: extern LONG lSizeOfOldGlyph20; /* Old packed 2.0 glyph info size. */ ! 17: extern LONG lSizeOfOldGlyph30; /* Old packed 3.0 glyph info size. */ ! 18: extern LONG lSizeOfOldFontHeader; /* Old packed font header size. */ ! 19: extern LONG lSizeOfOldFontHeader30; /* Old 3.0 packed font header size. */ ! 20: extern CHAR szFaceName[]; /* Face Name of Font */ ! 21: extern DWORD offsets[]; /* Offsets Table */ ! 22: ! 23: extern BOOL fReadOnly; ! 24: extern BOOL fChanged; /* Note if we did anything */ ! 25: extern BOOL fLoaded; /* Set if a font is loaded */ ! 26: extern INT iFontFormatPrev; /* Set to the id of prev.font format */ ! 27: extern INT iFontFormat; /* Set to the id of current font format */ ! 28: ! 29: extern HWND hFont; /* Handle to Show window */ ! 30: extern HWND hBox; /* Handle to Edit Window */ ! 31: extern HDC hMemDC; /* Handle to Memory Display Context */ ! 32: extern HBITMAP hBitmap; /* Handle to our work bit map */ ! 33: extern CHAR matBox [wBoxLim] [kBoxLim]; /* array to hold Box */ ! 34: ! 35: extern CHAR *vrgsz[]; /* string table */ ! 36: extern OFSTRUCT ofstrFile; ! 37: extern BOOL NewFile; /* flag indicating if file was opened ! 38: by selecting NEW on menu */ ! 39: FontHeaderType fontBuffer; /* temporary buffer of Font File Header */ ! 40: WORD cHeader, cTable; ! 41: HFILE nNewFile; /* NT file handle */ ! 42: ! 43: ! 44: /****************************************************************************/ ! 45: /* Local Variables */ ! 46: /****************************************************************************/ ! 47: ! 48: DWORD Proport(DWORD, DWORD, DWORD, DWORD); /* Reproportions a value */ ! 49: ! 50: CHAR *lpFontBody = NULL; /* Pointer to Font Body */ ! 51: CHAR *lpWork = NULL; /* Pointer to Work Area */ ! 52: HDC hNewMemDC; ! 53: HDC hBoxMemDC; ! 54: HBITMAP hNewBitmap; ! 55: HBITMAP hBoxBitmap; ! 56: HCURSOR hOldCursor = NULL; /* Holds Arrow while we show Hourglass */ ! 57: HCURSOR hHourGlass = NULL; ! 58: DWORD oldMode; /* For StretchBltMode */ ! 59: BYTE *lp1, *lp2; /* Pointers to bitmaps in format N */ ! 60: ! 61: FontHeader30 font30; ! 62: ! 63: #define ALPHA_CNT 26 ! 64: #define TOTAL_WEIGHTS 1000 ! 65: #define FSF_FIXED 0x0001 ! 66: #define FSF_PROPORTIONAL 0x0002 ! 67: ! 68: SHORT widthweights[ALPHA_CNT + 1] = ! 69: { ! 70: 64, /* a ! 71: 14, /* b */ ! 72: 27, /* c */ ! 73: 35, /* d */ ! 74: 100, /* e */ ! 75: 20, /* f */ ! 76: 14, /* g */ ! 77: 42, /* h */ ! 78: 63, /* i */ ! 79: 3 , /* j */ ! 80: 6 , /* k */ ! 81: 35, /* l */ ! 82: 20, /* m */ ! 83: 56, /* n */ ! 84: 56, /* o */ ! 85: 17, /* p */ ! 86: 4 , /* q */ ! 87: 49, /* r */ ! 88: 56, /* s */ ! 89: 71, /* t */ ! 90: 31, /* u */ ! 91: 10, /* v */ ! 92: 18, /* w */ ! 93: 3 , /* x */ ! 94: 18, /* y */ ! 95: 2 , /* z */ ! 96: 166, /* space, must be last, to use with the following ! 97: code */ ! 98: }; ! 99: ! 100: /****************************************************************************/ ! 101: /* Local Functions */ ! 102: /****************************************************************************/ ! 103: ! 104: VOID NewAverage(VOID); ! 105: BOOL GetNewMap(DWORD, DWORD); ! 106: VOID UseNewMap(VOID); ! 107: VOID ShrinkFont(DWORD, DWORD); ! 108: ! 109: /**************************************************************************** ! 110: * WORD ConvertToBitmapFormat(width, phase, height) ! 111: * ! 112: * purpose : Takes a part of the font file and converts it to a string of ! 113: * bytes for a single scan of bitmap for a character. ! 114: * ! 115: * params : WORD width : width of the character in pixels(bits) ! 116: * WORD phase : current deviation from byte alignment (pixels) ! 117: * WORD height: height of character(pixels) ! 118: * ! 119: * returns : WORD phase : new deviation from byte alignment (pixels) ! 120: * ! 121: * side effects : modifies pointers lp1 and lp2 (pointing to work space and ! 122: * font body respectively) ! 123: * ! 124: ****************************************************************************/ ! 125: DWORD PASCAL ! 126: ConvertToBitmapFormat( ! 127: DWORD width, /* width of the character in pixels(bits) */ ! 128: DWORD phase, /* current deviation from byte alignment (pixels) */ ! 129: DWORD height /* height of character(pixels) */ ! 130: ) ! 131: { ! 132: INT w; ! 133: WORD j; ! 134: ! 135: /* in the font file format characters are stored consecutively in ! 136: column-major ordering (columns of char 1 followed by columns of char ! 137: 2 ... etc.). lp2 points to start of columns of current character. ! 138: lp1 points to start of row of bitmap for character. */ ! 139: ! 140: for (w = width; w > 0; w -= 8){ ! 141: if (phase == 0){ ! 142: /* easy case */ ! 143: *lp1++ = *lp2; ! 144: ! 145: if (w < 8) ! 146: phase = w; ! 147: } ! 148: else{ ! 149: ! 150: --lp1; ! 151: j = (WORD)*lp1; ! 152: j <<= 8; ! 153: j |= (((WORD)*lp2) << (8 - phase)); ! 154: *lp1++ = (BYTE)(j >> 8); ! 155: *lp1++ = (BYTE)j; ! 156: if (w < 8){ ! 157: phase += w; ! 158: if (phase <= 8) ! 159: lp1--; /* back up pointer */ ! 160: phase &= 7; ! 161: } ! 162: } ! 163: lp2 += height; /* move to next column */ ! 164: } ! 165: return phase; ! 166: } ! 167: ! 168: /**************************************************************************** ! 169: * char * VerifyTableContents() ! 170: * ! 171: * purpose : scan the offsets table of file just read and check if ! 172: * width and offsets lie within limits ! 173: * ! 174: * params : none ! 175: * ! 176: * returns : char * szError : ptr to Error message if table not OK ! 177: * NULL otherwise ! 178: * ! 179: * side effects : none ! 180: * ! 181: ****************************************************************************/ ! 182: CHAR * PASCAL ! 183: VerifyTableContents( ! 184: VOID ! 185: ) ! 186: { ! 187: PBYTE pjGlyphData; ! 188: GLYPHINFO_20 gi2T20; /* temp ptr to a 2.0 style table*/ ! 189: GLYPHINFO_30 gi3T30; /* temp ptr to a 2.0 style table*/ ! 190: INT i; ! 191: ! 192: /* separate loops written for the 2.0 and 3.0 font processing because ! 193: a single loop would involve too many checks (of font type) within ! 194: the loop and slow down processing */ ! 195: if (iFontFormat == ID_FORMAT2){ ! 196: pjGlyphData = (lpFontBody +1); ! 197: ! 198: /* view table as 2.0 table */ ! 199: ! 200: /* check that each and every width and offset lie within limits */ ! 201: ! 202: for (i=0; i < (fontBuffer.LastChar - fontBuffer.FirstChar + 1); i++) { ! 203: ! 204: vGlyphInfo20FromBuffer (pjGlyphData, &gi2T20); ! 205: ! 206: if (gi2T20.GIwidth > 64) ! 207: return vszTableWidthsBad; ! 208: ! 209: if ((gi2T20.GIoffset > (UINT)WORD_LIMIT) || ! 210: (gi2T20.GIoffset < 0) ) ! 211: return vszTableOffsetsBad; ! 212: ! 213: pjGlyphData += lSizeOfOldGlyph20; ! 214: } ! 215: } ! 216: else{ ! 217: ! 218: pjGlyphData = lpFontBody; ! 219: ! 220: /* view table as 3.0 table */ ! 221: /* check that each and every width and offset lie within limits */ ! 222: ! 223: for (i=0; i< (fontBuffer.LastChar - fontBuffer.FirstChar +1); i++) { ! 224: ! 225: vGlyphInfo30FromBuffer (pjGlyphData, &gi3T30); ! 226: ! 227: if (gi3T30.GIwidth > 64) ! 228: return vszTableWidthsBad; ! 229: ! 230: if (gi3T30.GIoffset < (DWORD)0) ! 231: return vszTableOffsetsBad; ! 232: ! 233: pjGlyphData += lSizeOfOldGlyph30; ! 234: } ! 235: } ! 236: return NULL; ! 237: } ! 238: ! 239: /**************************************************************************** ! 240: * char * FontLoad() ! 241: * ! 242: * purpose: reads in the specified font file and creates a work bitmap for ! 243: * the editor. Also creates a local bitmap-offset table for easy ! 244: * access to the characters in the bitmap ! 245: * ! 246: * params : pszFileName - File Name to open. ! 247: * ! 248: * returns: ptr to NULL string if Open goes off OK ! 249: * ptr to error message string otherwise ! 250: * ! 251: * side effects: lots ! 252: * ! 253: ****************************************************************************/ ! 254: CHAR * ! 255: FontLoad( ! 256: CHAR *pszFileName, ! 257: OFSTRUCT *pofsReOpenInfo ! 258: ) ! 259: { ! 260: ! 261: CHAR *lpFontBodySav = NULL; /* local pointer to font body */ ! 262: DWORD len, fontlen; /* length of font body (bytes)*/ ! 263: UINT i; ! 264: INT mf; /* menu function ID */ ! 265: DWORD iWorkLen; /* length of work area (bytes) */ ! 266: HDC hDC; ! 267: CHAR * pszError; /* error msg if header is messed up */ ! 268: ! 269: DWORD row, height, width,phase; ! 270: DWORD offset; ! 271: GLYPHINFO_20 gi2GlyphTable20; /* Pointer into 2.0 style offsets table */ ! 272: GLYPHINFO_30 gi3GlyphTable30; /* Pointer into 3.0 style offsets table */ ! 273: PBYTE pjGlyphData; /* Pointer to Glyph information buffer. */ ! 274: ! 275: BYTE cDummy [CCHEXTRA]; /* dummy buffer for unneeded 3.0 header ! 276: * info ! 277: */ ! 278: ! 279: /* Put up an hourglass ... this may take a while */ ! 280: if (!hHourGlass) ! 281: hHourGlass = LoadCursor(NULL, IDC_WAIT); /* Get Hourglass */ ! 282: hOldCursor = SetCursor(hHourGlass); /* Show hourglass */ ! 283: ! 284: /* open file for read. */ ! 285: nNewFile = (HFILE)OpenFile (pszFileName, pofsReOpenInfo, OF_READ); ! 286: ! 287: if (nNewFile < 0) { ! 288: ! 289: return vszErrorOpeningFile; ! 290: } ! 291: ! 292: //- ReadFile: Here is where we need to make some adjustments in order to ! 293: //- read the file in to a new DWORD aligned format. ! 294: { ! 295: BYTE jBuffer [200]; ! 296: ! 297: ! 298: /* Read the header */ ! 299: if (_lread ((HFILE) nNewFile, (LPSTR)&jBuffer, lSizeOfOldFontHeader) != ! 300: (UINT)lSizeOfOldFontHeader) { ! 301: ! 302: _lclose((HFILE)nNewFile); ! 303: return vszErrorReadingHdr; ! 304: } ! 305: ! 306: // ! 307: // Call conversion routine to give us a properly aligned buffer. ! 308: // ! 309: ! 310: vFontStructFromBuffer ( ! 311: (PBYTE)&jBuffer, ! 312: &fontBuffer ! 313: ); ! 314: ! 315: } ! 316: ! 317: /* Check the version number -- make sure it's a font */ ! 318: switch (fontBuffer.Version) ! 319: { ! 320: case 0x200: ! 321: iFontFormat = ID_FORMAT2; ! 322: break; ! 323: case 0x300: /* added 1/19/88 */ ! 324: iFontFormat = ID_FORMAT3; ! 325: /* read in the extra fields into a dummy buffer ... they don't ! 326: * mean anything to us at this stage. ! 327: */ ! 328: if ((_lread((HFILE)nNewFile, (LPSTR)cDummy, CCHEXTRA)) ! 329: != CCHEXTRA){ ! 330: _lclose((HFILE)nNewFile); ! 331: return vszErrorReadingHdr; ! 332: } ! 333: ! 334: break; ! 335: default: /* Anything else -- toughies */ ! 336: _lclose((HFILE)nNewFile); ! 337: return vszUnknownFormat; ! 338: } ! 339: ! 340: /* check if contents of font header are sensible. If not, ! 341: give an error message and quit */ ! 342: ! 343: if ((pszError = VerifyHeaderContents()) != NULL) { ! 344: ! 345: _lclose((HFILE)nNewFile); ! 346: return pszError; ! 347: } ! 348: ! 349: /* Ready to load -- Check if we will be overwriting */ ! 350: if (fLoaded) ! 351: { ! 352: DeleteGlobalBitmap(); ! 353: fLoaded = FALSE; ! 354: } ! 355: ! 356: /* Allocate space for font body and Face Name and read them in */ ! 357: len= (fontBuffer.Size - lSizeOfOldFontHeader); /* Compute size */ ! 358: ! 359: if ((lpFontBody = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, (LONG)len)) == 0) { ! 360: ! 361: _lclose((HFILE)nNewFile); ! 362: return vszNotEnoughMem; /* Get Handle to space */ ! 363: } ! 364: ! 365: if (iFontFormat == ID_FORMAT3) ! 366: fontlen = len - CCHEXTRA; ! 367: else ! 368: fontlen = len; ! 369: ! 370: lpFontBodySav = lpFontBody; /* save ptr to font body */ ! 371: while (fontlen >= (DWORD)SEGMENT_SIZE) { ! 372: ! 373: /* file read method if font file size is 64k bytes or greater. ! 374: file is read in in chunks of 65536 (SEGMENT_SIZE), taking care to ! 375: position buffer ptr at 64k boundary each time */ ! 376: ! 377: /* First read in the maximum number of bytes _lread can read (65534) */ ! 378: if ((_lread((HFILE)nNewFile, lpFontBodySav, WORD_LIMIT)) == WORD_LIMIT) { ! 379: ! 380: lpFontBodySav += WORD_LIMIT; /* buffer ptr moved up by 64k bytes */ ! 381: fontlen -= WORD_LIMIT; /* fontlen = no of bytes left to read */ ! 382: ! 383: } else { ! 384: ! 385: GlobalFree (lpFontBody); ! 386: _lclose((HFILE)nNewFile); ! 387: return vszErrorReadingBody; ! 388: } ! 389: ! 390: /* read in an additional two bytes to reach end of segment */ ! 391: if ((_lread((HFILE)nNewFile, lpFontBodySav, 2)) == 2) { ! 392: ! 393: lpFontBodySav += 2; /* buffer ptr moved up by 2 bytes */ ! 394: fontlen -= 2; /* fontlen = no of bytes left to read */ ! 395: ! 396: } else { ! 397: ! 398: GlobalFree (lpFontBody); ! 399: _lclose((HFILE)nNewFile); ! 400: return vszErrorReadingBody; ! 401: } ! 402: } ! 403: ! 404: /* read the partially filled segment */ ! 405: if ((_lread((HFILE)nNewFile, lpFontBodySav, (DWORD)fontlen)) != (UINT) fontlen) { ! 406: ! 407: GlobalFree (lpFontBody); ! 408: _lclose((HFILE)nNewFile); ! 409: return vszErrorReadingBody; ! 410: } ! 411: ! 412: /* Close the file */ ! 413: _lclose((HFILE)nNewFile); ! 414: ! 415: /* check if the offset table entries are within allowable limits. ! 416: If not give an error message, clean up and quit */ ! 417: if ((pszError = VerifyTableContents()) != NULL) { ! 418: ! 419: GlobalFree (lpFontBody); ! 420: return pszError; ! 421: } ! 422: ! 423: /* now that everything has been checked, move buffer to font */ ! 424: font = fontBuffer; ! 425: ! 426: /* Make local copies of FaceName and Device Name */ ! 427: if (font.Face){ ! 428: ! 429: lstrcpy((LPSTR)szFaceName, lpFontBody + font.Face - ! 430: (iFontFormat == ID_FORMAT2 ? ! 431: lSizeOfOldFontHeader : ! 432: lSizeOfOldFontHeader30-1)); ! 433: } else { ! 434: ! 435: lstrcpy((LPSTR)szFaceName, (LPSTR)""); ! 436: } ! 437: ! 438: for (i = 0; i <= 256; i++) /* Zero offsets Table for below */ ! 439: offsets[i] = 0; ! 440: ! 441: /* compute work space needed if a 3.0 file. This has to be done since ! 442: 3.0 files are compressed versions of 2.0 files and may need a ! 443: work bitmap bigger than the actual font body size */ ! 444: ! 445: if (iFontFormat == ID_FORMAT3) { ! 446: ! 447: cTable = (WORD) (6 * (font.LastChar - font.FirstChar + 2)); ! 448: iWorkLen = 0; ! 449: ! 450: pjGlyphData = lpFontBody; ! 451: ! 452: /* work bitmap size = sum of sizes of all characters in font */ ! 453: ! 454: for (i = font.FirstChar; i <= font.LastChar; i++) { ! 455: ! 456: vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); ! 457: ! 458: iWorkLen += ((gi3GlyphTable30.GIwidth +7) >> 3) * font.PixHeight; ! 459: ! 460: pjGlyphData += lSizeOfOldGlyph30; ! 461: } ! 462: ! 463: } else { /* 2.0 file */ ! 464: ! 465: cTable = (WORD)(4 * (font.LastChar - font.FirstChar + 2)); ! 466: /* compute table length */ ! 467: iWorkLen = len; /* work space for a 2.0 file is the same as the ! 468: length of the font body */ ! 469: } ! 470: ! 471: //- Add some extra space for dword alignment. ! 472: iWorkLen += (font.PixHeight * sizeof (DWORD)); ! 473: /* Get work space */ ! 474: ! 475: if ((lpWork = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (LONG)iWorkLen)) == 0) { ! 476: ! 477: GlobalFree (lpFontBody); ! 478: return vszNotEnoughMem; ! 479: } ! 480: ! 481: lp1 = lpWork; ! 482: ! 483: height = (DWORD) font.PixHeight; ! 484: offset = 0; ! 485: /* put the font file into bitmap format */ ! 486: if (iFontFormat == ID_FORMAT2){ /* table in 2.0 format */ ! 487: for (row = 0; row < height; row++){ ! 488: ! 489: /* view table as a 2.0 style table */ ! 490: pjGlyphData = lpFontBody + 1; ! 491: ! 492: phase = 0; ! 493: ! 494: for (i = 0; i < (UINT)(font.LastChar - font.FirstChar + 1); i++) { ! 495: ! 496: vGlyphInfo20FromBuffer (pjGlyphData, &gi2GlyphTable20); ! 497: ! 498: width = (DWORD) gi2GlyphTable20.GIwidth; ! 499: ! 500: /* size of each table element = 4bytes */ ! 501: lp2 = lpFontBody + (gi2GlyphTable20.GIoffset - ! 502: lSizeOfOldFontHeader) + row; ! 503: ! 504: pjGlyphData += lSizeOfOldGlyph20; ! 505: ! 506: /* offset ends up as the sum of the widths */ ! 507: if (row == 0) /* Once is enough */ ! 508: offsets[i + font.FirstChar + 1] = offset += width; ! 509: ! 510: /* create a single scan of bitmap for character */ ! 511: phase = ConvertToBitmapFormat (width, phase, height); ! 512: } ! 513: if ((lp1 - lpWork) & 1) ! 514: *lp1++ = 0; /* Round lp1 up to Word Boundary */ ! 515: #ifdef DWORDROUND ! 516: if ((lp1 - lpWork) & 2) { ! 517: *lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 518: *lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 519: } ! 520: #endif ! 521: //if (((offset + 7) >> 3) & 1) ! 522: //*lp1++ = 0; /* Round lp1 up to Word Boundary */ ! 523: //if (((offset + 7) >> 3) & 2) { ! 524: //*lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 525: //*lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 526: //} ! 527: } ! 528: } ! 529: /* separate loops written for the 2.0 and 3.0 font processing because ! 530: a single loop would involve too many checks (of font type) within ! 531: the loop and slow down processing */ ! 532: else { /* table in 3.0 format */ ! 533: ! 534: for (row = 0; row < height; row++){ ! 535: ! 536: phase = 0; ! 537: /* view table as a 3.0 style table */ ! 538: pjGlyphData = lpFontBody; ! 539: ! 540: for (i = 0; i < (UINT)(font.LastChar - font.FirstChar + 1); i++) { ! 541: ! 542: vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); ! 543: ! 544: width = gi3GlyphTable30.GIwidth; ! 545: ! 546: /* size of each table element = 6bytes */ ! 547: lp2 = lpFontBody + (gi3GlyphTable30.GIoffset - ! 548: lSizeOfOldFontHeader30 +1) + row; ! 549: ! 550: pjGlyphData += lSizeOfOldGlyph30; ! 551: ! 552: /* offset ends up as the sum of the widths */ ! 553: if (row == 0) /* Once is enough */ ! 554: offsets[i + font.FirstChar + 1] = offset += width; ! 555: ! 556: /* create a single scan of bitmap for character */ ! 557: phase = ConvertToBitmapFormat (width, phase, height); ! 558: } ! 559: if ((lp1 - lpWork) & 1) ! 560: *lp1++ = 0; /* Round lp1 up to Word Boundary */ ! 561: #ifdef DWORDROUND ! 562: if ((lp1 - lpWork) & 2) { ! 563: *lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 564: *lp1++ = 0; /* Round lp1 up to DWord Boundary */ ! 565: } ! 566: #endif ! 567: } ! 568: } ! 569: font.WidthBytes = (WORD) (((offset + 15) >> 4) << 1); ! 570: /* fixup NEWFON error */ ! 571: ! 572: GlobalFree(lpFontBody); ! 573: lpFontBody = lpWork; /* So that below we free the other buffer */ ! 574: /* Create a WINDOWS bitmap to move the font definition bits into */ ! 575: ! 576: hDC = GetDC (hFont); /* DC to be compatible with */ ! 577: hBitmap = CreateBitmap( ! 578: (INT)font.WidthBytes << 3, /* Width of font in pixels */ ! 579: (INT)font.PixHeight, ! 580: 1, 1, (LPBYTE)NULL); ! 581: hMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 582: SelectObject(hMemDC, hBitmap); /* Relate the two of them */ ! 583: ReleaseDC(hFont, hDC); /* Done with font DC */ ! 584: ! 585: /* Move the bits in */ ! 586: SetBitmapBits(hBitmap, ! 587: (DWORD)font.WidthBytes * (DWORD)font.PixHeight,(CHAR *)lpWork); ! 588: ! 589: /* Free up the space we loaded the file into */ ! 590: GlobalFree(lpFontBody); ! 591: fLoaded = TRUE; ! 592: { ! 593: HMENU hMenu; ! 594: ! 595: hMenu = GetMenu(hBox); /* Gray menu if no clipboard bitmap */ ! 596: mf = (font.Family & 1) ? MF_ENABLED : MF_GRAYED; ! 597: EnableMenuItem(hMenu, FONT_SAVE, MF_ENABLED); ! 598: EnableMenuItem(hMenu, FONT_SAVEAS, MF_ENABLED); ! 599: EnableMenuItem(hMenu, 1, MF_BYPOSITION | MF_ENABLED); ! 600: EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); ! 601: EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); ! 602: EnableMenuItem(hMenu, 4, MF_BYPOSITION | mf); ! 603: EnableMenuItem(hMenu, 5, MF_BYPOSITION | MF_ENABLED); ! 604: EnableMenuItem(hMenu, 6, MF_BYPOSITION | MF_ENABLED); ! 605: DrawMenuBar(hBox); ! 606: } ! 607: SetCursor(hOldCursor); /* Restore regular cursor */ ! 608: return ""; ! 609: } ! 610: ! 611: /************************************** ! 612: * compares nBytes bytes of s1 and s2 * ! 613: **************************************/ ! 614: BOOL ! 615: ByteCompare ( ! 616: CHAR *s1, ! 617: CHAR *s2, ! 618: DWORD nBytes ! 619: ) ! 620: { ! 621: for ( ; nBytes > 0; nBytes--) ! 622: if (*s1++ != *s2++) ! 623: return FALSE; ! 624: return TRUE; ! 625: } ! 626: ! 627: /*********************************** ! 628: * copies nBytes bytes of s2 to s1 * ! 629: ***********************************/ ! 630: BOOL ! 631: ByteCopy( ! 632: CHAR *s1, ! 633: CHAR *s2, ! 634: LONG nBytes ! 635: ) ! 636: { ! 637: for ( ; nBytes > 0; nBytes--) ! 638: *s1++ = *s2++; ! 639: return TRUE; ! 640: } ! 641: ! 642: /**************************************************************************** ! 643: * VOID ConvertToFileFormat(width, phase, height) ! 644: * ! 645: * purpose : Takes a part of the bitmap (corresponding to a single character) ! 646: * and converts it to a string of bytes in the font file format ! 647: * ! 648: * params : WORD width : width of the character in pixels(bits) ! 649: * WORD phase : current deviation from byte alignment (pixels) ! 650: * WORD height: height of character(pixels) ! 651: * ! 652: * returns: WORD phase : new deviation from byte alignment (pixels) ! 653: * ! 654: * side effects : modifies pointers lp1 and lp2 (pointing to font body and work ! 655: * space respectively) ! 656: * ! 657: ****************************************************************************/ ! 658: DWORD PASCAL ! 659: ConvertToFileFormat( ! 660: DWORD width, ! 661: DWORD phase, ! 662: DWORD height ! 663: ) ! 664: { ! 665: INT w; ! 666: ! 667: for (w = width; w > 0; w -= 8){ /* for each byte of font */ ! 668: if (phase == 0){ /* easy case */ ! 669: ! 670: BYTE b; ! 671: ! 672: b = *lp1++; ! 673: if (w < 8){ ! 674: ! 675: phase = (DWORD) w; ! 676: b >>= 8 - w; /* Clear left side bits */ ! 677: b <<= 8 - w; ! 678: } ! 679: *lp2 = b; ! 680: } ! 681: else{ ! 682: ! 683: DWORD j; ! 684: ! 685: lp1--; /* Re-read byte prevously read */ ! 686: //j = (DWORD) ((BYTE)*lp1++ << 8) | ((BYTE)*lp1++); ! 687: j = (DWORD)((BYTE)*lp1++ << 8); ! 688: j |= (DWORD) ((BYTE)*lp1++); ! 689: if (w < 8){ ! 690: ! 691: j >>= 16 - phase - (w & 7); /* shove it right */ ! 692: j <<= 8 - (w & 7); /* Left justify in low byte */ ! 693: phase += (DWORD) w; ! 694: if (phase <= 8) ! 695: lp1--; /* back up pointer */ ! 696: phase &= 7; ! 697: } ! 698: else ! 699: j >>= 8 - phase; ! 700: *lp2 = (BYTE)j; ! 701: } ! 702: lp2 += height; /* move to next column */ ! 703: } ! 704: return phase; ! 705: } ! 706: ! 707: /**************************************************************************** ! 708: * char * FontSave() ! 709: * ! 710: * purpose: saves the work bitmap in the required font file format (2.0 or ! 711: * 3.0 and cleans up ! 712: * ! 713: * params : none ! 714: * ! 715: * returns: ptr to a NULL string if Save goes off OK ! 716: * ptr to error message string otherwise ! 717: * ! 718: * side effects: lots ! 719: * ! 720: ****************************************************************************/ ! 721: ! 722: CHAR * ! 723: FontSave( ! 724: CHAR *pszFileName, ! 725: OFSTRUCT *pofsReOpenInfo ! 726: ) ! 727: { ! 728: DWORD bytecount; /* number of bytes returned by lwrite */ ! 729: DWORD size; /* total size of font */ ! 730: ! 731: WORD height, row; ! 732: DWORD i, fontlen; ! 733: DWORD cBody, cFont,cFontsav, cFace; ! 734: CHAR *lpFont; /* ponter to font body */ ! 735: CHAR * sz; ! 736: DWORD iMax; ! 737: WORD widthsav; ! 738: PBYTE pjGlyphData; ! 739: PBYTE pjGlyphSave; ! 740: GLYPHINFO_20 gi2GlyphTable20; /* 2.0 style Glyph data struct */ ! 741: GLYPHINFO_30 gi3GlyphTable30; /* 3.0 style Glyph data struct */ ! 742: ! 743: NewAverage(); /* force ave width to be recomputed 8/17/87 BobM */ ! 744: ! 745: /* reset file pointer */ ! 746: nNewFile = (HFILE)OpenFile (pszFileName, pofsReOpenInfo, OF_WRITE | OF_REOPEN); ! 747: ! 748: if (nNewFile < (HFILE) 0) { ! 749: ! 750: return vszErrorOpeningFile; ! 751: } ! 752: ! 753: /* Put up an houglass ... this may take a while */ ! 754: if (!hHourGlass) ! 755: hHourGlass = LoadCursor (NULL, IDC_WAIT); /* Get Hourglass */ ! 756: hOldCursor = SetCursor (hHourGlass); /* Show hourglass */ ! 757: ! 758: height = font.PixHeight; ! 759: cBody = (DWORD)height * (DWORD)font.WidthBytes; ! 760: ! 761: /* Recompute file size and update header */ ! 762: if (iFontFormat == ID_FORMAT2) ! 763: cHeader = (WORD)(lSizeOfOldFontHeader +1); ! 764: else ! 765: cHeader = (WORD)(lSizeOfOldFontHeader30 - 1); ! 766: ! 767: /* if of 2.0 type, check if size will exceed 64kbytes. If yes, saving ! 768: in 2.0 format will result in loss of information (because offset table ! 769: of 2.0 file is composed of 16bit words). Warn user and ask if file can ! 770: be saved as a 3.0 file */ ! 771: ! 772: if (iFontFormat == ID_FORMAT2) ! 773: { ! 774: if (((DWORD)cHeader + (DWORD)(lSizeOfOldGlyph20 * (font.LastChar - ! 775: font.FirstChar+2)) + (DWORD)cBody) >= WORD_LIMIT) ! 776: if (MessageBox(hBox, vszTooBigFor20, vszWarning, ! 777: IDOK | IDCANCEL |IDNO) == IDYES) ! 778: iFontFormat = ID_FORMAT3; ! 779: } ! 780: ! 781: if (iFontFormat == ID_FORMAT2) { ! 782: ! 783: /* allocate space for a 2.0 style offsets table */ ! 784: cTable = (WORD)(lSizeOfOldGlyph20 * ! 785: (font.LastChar - font.FirstChar + 2)); ! 786: ! 787: } else { ! 788: ! 789: /* allocate space for a 3.0 style offsets table */ ! 790: cTable = (WORD)(lSizeOfOldGlyph30 * ! 791: (font.LastChar - font.FirstChar + 2)); ! 792: } ! 793: ! 794: pjGlyphData = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (DWORD)cTable); ! 795: ! 796: if (pjGlyphData == 0) { ! 797: ! 798: _lclose((HFILE)nNewFile); ! 799: return vszNotEnoughMem; ! 800: } ! 801: ! 802: pjGlyphSave = pjGlyphData; ! 803: ! 804: size = cHeader + cTable; ! 805: iMax = font.LastChar - font.FirstChar + 1; ! 806: ! 807: /* create offsets table of font file */ ! 808: for (i = 0; i <= iMax; i++){ ! 809: ! 810: DWORD width, charSize; ! 811: ! 812: width = offsets[i + font.FirstChar + 1] - offsets[i + font.FirstChar]; ! 813: ! 814: if (i == iMax) { ! 815: width = 8; /* Sentinal blank */ ! 816: } ! 817: ! 818: if (iFontFormat == ID_FORMAT2){ ! 819: ! 820: gi2GlyphTable20.GIwidth = (SHORT)width; ! 821: gi2GlyphTable20.GIoffset = (SHORT)size; ! 822: ! 823: vBufferFromGlyphInfo20 (&gi2GlyphTable20, pjGlyphData); ! 824: ! 825: pjGlyphData += lSizeOfOldGlyph20; ! 826: ! 827: } else { ! 828: ! 829: gi3GlyphTable30.GIwidth = (SHORT)width; ! 830: gi3GlyphTable30.GIoffset = (INT)size; ! 831: ! 832: vBufferFromGlyphInfo30 (&gi3GlyphTable30, pjGlyphData); ! 833: ! 834: pjGlyphData += lSizeOfOldGlyph30; ! 835: } ! 836: ! 837: charSize = height * ((width + 7) >> 3); /* size in bytes */ ! 838: ! 839: if ((size + charSize) < size){ /* Overflow? */ ! 840: ! 841: GlobalFree (pjGlyphData); ! 842: _lclose((HFILE)nNewFile); ! 843: return vszFileTooLarge; ! 844: ! 845: } ! 846: size += charSize; ! 847: } ! 848: ! 849: /* Update stuff in the header */ ! 850: ! 851: font.Face = (DWORD)size; ! 852: cFace = (WORD)lstrlen (szFaceName) + 1; /* Allow for \0 */ ! 853: size += cFace; ! 854: font.Size = (DWORD)size; /* new file size */ ! 855: font.BitsOffset = (DWORD)(cHeader + cTable); ! 856: font.Device = (DWORD)NULL; /* Device Name must be NULL */ ! 857: cFontsav = size - cHeader - cTable; ! 858: cFont =cFontsav; ! 859: ! 860: /* alloc extra byte for lp1 in case it needs it */ ! 861: if (!(lpFontBody = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (LONG)cBody + ! 862: height * 4))) { ! 863: ! 864: _lclose((HFILE)nNewFile); ! 865: return vszNotEnoughMem; ! 866: } ! 867: ! 868: GetBitmapBits (hBitmap, (DWORD)cBody, lpFontBody); ! 869: ! 870: /* save current WidthBytes */ ! 871: widthsav = font.WidthBytes; ! 872: ! 873: /* MD - reset WidthBytes from computed width */ ! 874: font.WidthBytes = (WORD) (cFont - cFace)/ height; ! 875: ! 876: /* Allocate a block to put bitmap into */ ! 877: if ((lpFont = lpWork = GlobalAlloc (GMEM_ZEROINIT,(LONG)cFont)) == 0) ! 878: { ! 879: GlobalFree (lpFontBody); ! 880: _lclose((HFILE)nNewFile); ! 881: return vszNotEnoughMem; ! 882: } ! 883: ! 884: lp1 = lpFontBody; ! 885: ! 886: /* convert bitmap to file format */ ! 887: if (iFontFormat == ID_FORMAT2){ /* offsets table in 2.0 format */ ! 888: INT nChars; ! 889: nChars = font.LastChar - font.FirstChar +1; ! 890: ! 891: for (row = 0; row < height; row++){ ! 892: ! 893: DWORD phase; ! 894: ! 895: phase = 0; ! 896: ! 897: pjGlyphData = pjGlyphSave; ! 898: ! 899: for (i = 0; i < (DWORD) nChars; i++) { ! 900: ! 901: INT width; ! 902: ! 903: vGlyphInfo20FromBuffer (pjGlyphData, &gi2GlyphTable20); ! 904: ! 905: width = gi2GlyphTable20.GIwidth; ! 906: ! 907: lp2 = (BYTE *)(lpWork + (gi2GlyphTable20.GIoffset - ! 908: cHeader - cTable + row)); ! 909: ! 910: pjGlyphData += lSizeOfOldGlyph20; ! 911: ! 912: phase = ConvertToFileFormat (width, phase, height); ! 913: } ! 914: if ((lp1 - lpWork) & 1) ! 915: lp1++; /* Round lp1 up to Word Boundary */ ! 916: #ifdef DWORDROUND ! 917: if ((lp1 - lpWork) & 2) { ! 918: lp1++; /* Round lp1 up to DWord Boundary */ ! 919: lp1++; /* Round lp1 up to DWord Boundary */ ! 920: } ! 921: #endif ! 922: //if(((offsets[font.LastChar + 1] + 7) >> 3) & 1) ! 923: //lp1++; /* Round lp1 up to Word Boundary */ ! 924: } ! 925: } ! 926: /* separate loops written for the 2.0 and 3.0 font processing because ! 927: a single loop would involve too many checks (of font type) within ! 928: the loop and slow down processing */ ! 929: else{ /* table in 3.0 format */ ! 930: ! 931: INT nChars; ! 932: nChars = font.LastChar - font.FirstChar +1; ! 933: for (row = 0; row < height; row++){ ! 934: ! 935: DWORD phase; ! 936: ! 937: phase = 0; ! 938: pjGlyphData = pjGlyphSave; ! 939: ! 940: for (i = 0; i < (DWORD) nChars; i++) { ! 941: ! 942: INT width; ! 943: ! 944: vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); ! 945: ! 946: width = gi3GlyphTable30.GIwidth; ! 947: ! 948: lp2 = (BYTE *)(lpWork + (gi3GlyphTable30.GIoffset - ! 949: cHeader - cTable + row)); ! 950: ! 951: pjGlyphData += lSizeOfOldGlyph30; ! 952: ! 953: phase = ConvertToFileFormat (width, phase, height); ! 954: } ! 955: if ((lp1 - lpWork) & 1) ! 956: lp1++; /* Round lp1 up to Word Boundary */ ! 957: #ifdef DWORDROUND ! 958: if ((lp1 - lpWork) & 2) { ! 959: lp1++; /* Round lp1 up to DWord Boundary */ ! 960: lp1++; /* Round lp1 up to DWord Boundary */ ! 961: } ! 962: #endif ! 963: //if(((offsets[font.LastChar + 1] + 7) >> 3) & 1) ! 964: //lp1++; /* Round lp1 up to Word Boundary */ ! 965: } ! 966: } ! 967: ! 968: /* Restore start of data. */ ! 969: pjGlyphData = pjGlyphSave; ! 970: ! 971: lp2 -= height - 1; /* Back up to start of character */ ! 972: for (i = 0; i < height; i++) ! 973: *lp2++ = 0; /* Fill in guaranteed blank character */ ! 974: ! 975: font.Version = 0x200; ! 976: ! 977: /****** code for compaction in 3.0 fmt borrowed from CMPCTFON ******/ ! 978: if (iFontFormat== ID_FORMAT3){ ! 979: DWORD iDefBitmapSize = 0; /* size of default char */ ! 980: DWORD cch = 0; /* count of number of default char */ ! 981: #if 0 ! 982: GLYPHINFO_30 *cur_char; /* current element of offset table */ ! 983: GLYPHINFO_30 *move_char; ! 984: /* element from which moving is to be done */ ! 985: LONG iDefBitmapOffset; /* offset of default char */ ! 986: INT iDefBitmapWidth; /* width of default char */ ! 987: static LONG iEndOfBitmaps; /* address of end of font body */ ! 988: INT iFirstC; /* first char in font */ ! 989: INT iLastC; /* last char in font */ ! 990: INT i,j; ! 991: WORD width; ! 992: CHAR *rgbFont; /* pointer to font body */ ! 993: DWORD Offset; ! 994: ! 995: GDI seems to understand compressed 2.0 external formats but not ! 996: compressed 3.0 formats, and this is causing it to crash loading a 3.0 ! 997: format compressed font. Since compression does not affect the ! 998: validity of the font, This code is disabled temporarily till ! 999: this problem is verified. Again, the font is perfectly usable in this ! 1000: form, though a trifle bigger than desired - LR 20/26/90 ! 1001: ! 1002: ! 1003: Note that this will now not work after the conversion to NT. ! 1004: the glyph table needs to accessed as above. t-davema 8/20/91 ! 1005: ! 1006: iFirstC = font.FirstChar & 0x0ff; ! 1007: iLastC = font.LastChar & 0x0ff; ! 1008: ! 1009: iEndOfBitmaps = (LONG)font.BitsOffset+((LONG)font.WidthBytes * ! 1010: (LONG)font.PixHeight); ! 1011: rgbFont = (CHAR *)lpFont; /* start of font body */ ! 1012: cur_char =(GLYPHINFO_30 *) lpTable; /* start of offset table */ ! 1013: ! 1014: /* calculate some parameters for the default char */ ! 1015: iDefBitmapOffset = cur_char[font.DefaultChar].GIoffset; ! 1016: iDefBitmapWidth = cur_char[font.DefaultChar].GIwidth; ! 1017: iDefBitmapSize = (DWORD)cur_char[font.DefaultChar+1].GIoffset ! 1018: - (DWORD)iDefBitmapOffset; ! 1019: ! 1020: /* scan the font body via the offsets table. If a default char ! 1021: is recognised, move all the bytes to it's right left by the ! 1022: size of the default char.Make all offset table entries of default ! 1023: char point to one image of the char (the earliest occuring image) */ ! 1024: for (i = iFirstC; i <= iLastC; ++i) { ! 1025: ! 1026: /* important: Check for limiting conditions (in case break char ! 1027: was modified?)*/ ! 1028: if (cur_char->GIoffset == iDefBitmapOffset){ ! 1029: cur_char++; ! 1030: continue; ! 1031: } ! 1032: ! 1033: Offset = cur_char->GIoffset -cHeader -cTable; ! 1034: /* proceed to compare images only if widths are equal */ ! 1035: if ((cur_char->GIwidth == iDefBitmapWidth) && ! 1036: (ByteCompare (&rgbFont [Offset], ! 1037: &rgbFont[iDefBitmapOffset-cHeader-cTable], ! 1038: (DWORD)iDefBitmapSize) == TRUE)){ ! 1039: ! 1040: /* set offset to earliest occurence of the default char */ ! 1041: if (cur_char->GIoffset < iDefBitmapOffset){ ! 1042: iDefBitmapOffset = cur_char->GIoffset; ! 1043: } ! 1044: else { ! 1045: if (i != iLastC){ ! 1046: /* move bytes to right of default char left by the ! 1047: size of the char */ ! 1048: ByteCopy (&rgbFont [ Offset], ! 1049: &rgbFont [ Offset+ iDefBitmapSize], ! 1050: (LONG)(iEndOfBitmaps - ! 1051: ((cur_char + 1)->GIoffset))); ! 1052: ! 1053: /* correct the offset table entries */ ! 1054: move_char = cur_char + 1; ! 1055: for (j=i; j < iLastC; ++j){ ! 1056: move_char->GIoffset -= (LONG)iDefBitmapSize; ! 1057: move_char++; ! 1058: } ! 1059: } ! 1060: iEndOfBitmaps -= iDefBitmapSize; ! 1061: /* move End-of-font to the left */ ! 1062: cur_char->GIoffset = iDefBitmapOffset; ! 1063: /* point offset of cuurent char to default char */ ! 1064: cch++; ! 1065: } ! 1066: } ! 1067: cur_char++; ! 1068: } ! 1069: #endif ! 1070: /* recalculate some font attributes */ ! 1071: lp2 -= (cch * iDefBitmapSize + height); ! 1072: for (i = 0; i < height; i++) ! 1073: *lp2++ = 0; /* Fill in guaranteed blank character */ ! 1074: ! 1075: cFont -= cch * iDefBitmapSize; ! 1076: font.WidthBytes = (WORD) (cFont - cFace)/ height; ! 1077: font.Size = (DWORD) (cFont + cHeader + cTable); ! 1078: font.Face = font.Size - cFace ; ! 1079: font.Version = 0x300; ! 1080: ! 1081: /* copy info into 3.0 (new) format header and set the additional ! 1082: fields */ ! 1083: ByteCopy ((LPSTR)&font30, (LPSTR)&font, (DWORD)sizeof (font)); ! 1084: font30.fsFlags = 0; ! 1085: font30.fsFlags = (font.Family & 1 ? FSF_PROPORTIONAL : FSF_FIXED); ! 1086: font30.fsAspace = 0; ! 1087: font30.fsBspace = 0; ! 1088: font30.fsCspace = 0; ! 1089: font30.fsColorPointer = 0L; ! 1090: for (i = 0; i < 4 ; i++) ! 1091: font30.fsReserved[i] = 0L; ! 1092: } ! 1093: ! 1094: /* Add the FaceName, if any, to the end of the bitmap */ ! 1095: lstrcpy((LPSTR)lp2, (LPSTR)szFaceName); ! 1096: ! 1097: /* ! 1098: * Again we need to do some tricky things to get the header output ! 1099: * correct. We want to run it through the conversion backwards until ! 1100: * we get the packed structure. ! 1101: */ ! 1102: { ! 1103: BYTE jOutputBuffer [sizeof (font30)]; ! 1104: ! 1105: if (iFontFormat == ID_FORMAT2) { ! 1106: ! 1107: vBufferFromFontStruct (&font, (PBYTE)&jOutputBuffer); ! 1108: ! 1109: } else { ! 1110: ! 1111: vBufferFromFont30Struct (&font30, (PBYTE)&jOutputBuffer); ! 1112: } ! 1113: ! 1114: bytecount = _lwrite((HFILE)nNewFile, (PBYTE)&jOutputBuffer, (DWORD)cHeader); ! 1115: } ! 1116: ! 1117: /* Write out Header Information */ ! 1118: if (bytecount == cHeader) { ! 1119: ! 1120: /* Write out OffsetsTable */ ! 1121: if (cTable == 0 || (_lwrite((HFILE)nNewFile, pjGlyphData, (DWORD)cTable) ! 1122: == (UINT)cTable)){ ! 1123: /* Write out Body */ ! 1124: fontlen = cFont; ! 1125: while (fontlen >= SEGMENT_SIZE){ ! 1126: ! 1127: /* file write method if font size is 64k or greater ! 1128: file is written in chunks of 65536 bytes (SEGMENT_SIZE)-lr */ ! 1129: ! 1130: /* First write as many bytes as _lwrite will allow(65534) */ ! 1131: if (_lwrite((HFILE)nNewFile, (CHAR *)lpFont, WORD_LIMIT) == ! 1132: WORD_LIMIT){ ! 1133: fontlen -= WORD_LIMIT; ! 1134: /* fontlen = no of bytes left to write*/ ! 1135: lpFont+= WORD_LIMIT; /* buffer ptr moved up by 64k */ ! 1136: } ! 1137: else ! 1138: sz = vszErrorWritingBody; ! 1139: ! 1140: /* write the two bytes remaining in the segment */ ! 1141: if (_lwrite((HFILE)nNewFile, (CHAR *)lpFont, 2) == 2){ ! 1142: fontlen -= 2; /* fontlen = no of bytes left to write*/ ! 1143: lpFont+= 2; /* buffer ptr moved up by 2 */ ! 1144: } ! 1145: else ! 1146: sz = vszErrorWritingBody; ! 1147: } ! 1148: /* segment only partially filled. Write the remaining bytes */ ! 1149: if (_lwrite((HFILE)nNewFile, (CHAR *)lpFont, (DWORD)fontlen) == ! 1150: (UINT) fontlen){ ! 1151: fChanged = FALSE; ! 1152: sz= ""; ! 1153: } ! 1154: else ! 1155: sz = vszErrorWritingBody; ! 1156: } ! 1157: else ! 1158: sz = vszErrorWritingOffsets; ! 1159: } ! 1160: else ! 1161: sz = vszErrorWritingHdr; ! 1162: ! 1163: /* hack: Restore saved value of widthbytes, eliminating a variety ! 1164: of minor scrolling problems that follow after a File/Save */ ! 1165: font.WidthBytes = widthsav; ! 1166: ! 1167: _lclose((HFILE)nNewFile); ! 1168: ! 1169: /* Tidy up */ ! 1170: ! 1171: GlobalFree(lpFontBody); ! 1172: GlobalFree(pjGlyphData); ! 1173: GlobalFree(lpWork); ! 1174: ! 1175: SetCursor(hOldCursor); /* Restore regular cursor */ ! 1176: ! 1177: return sz; ! 1178: } ! 1179: ! 1180: /**************************************************************************** ! 1181: * BOOL ResizeWidths(wChar) ! 1182: * ! 1183: * params : WORD wChar : new width of a single character ! 1184: * ! 1185: * purpose: resize work bitmap according to new character width by stretching/ ! 1186: * compressing all characters as neccesary ! 1187: * ! 1188: * returns: none ! 1189: * ! 1190: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1191: * altered as well ! 1192: ****************************************************************************/ ! 1193: ! 1194: ! 1195: BOOL ! 1196: ResizeWidths( ! 1197: DWORD wChar ! 1198: ) ! 1199: { ! 1200: DWORD width; ! 1201: DWORD offset, i; ! 1202: ! 1203: /* Create a new bitmap to move the font definition bits into */ ! 1204: width = (font.LastChar - font.FirstChar + 1) * wChar; /* In pixels */ ! 1205: width = (width + 15) >> 4 << 1; /* In even bytes */ ! 1206: if (!GetNewMap(width, font.PixHeight)) ! 1207: return (FALSE); ! 1208: ! 1209: /* Move the bits in */ ! 1210: offset = 0; ! 1211: oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); ! 1212: for (i = font.FirstChar; i <= font.LastChar; i++) ! 1213: { ! 1214: ! 1215: StretchBlt(hNewMemDC, offset, 0, ! 1216: wChar, font.PixHeight, /* New character */ ! 1217: hMemDC, offsets[i], 0, ! 1218: font.PixWidth, font.PixHeight, /* Old character */ ! 1219: SRCCOPY); ! 1220: offsets[i] = offset; ! 1221: offset += wChar; ! 1222: } ! 1223: SetStretchBltMode(hNewMemDC, oldMode); ! 1224: offsets[font.LastChar + 1] = offset; ! 1225: ! 1226: UseNewMap(); /* Switch Pointers and release the space */ ! 1227: ! 1228: font.HorizRes = (WORD) Proport(font.HorizRes, wChar, font.PixWidth, 999); ! 1229: font.WidthBytes = (WORD) width; /* Misc. ajustments */ ! 1230: font.PixWidth = font.AvgWidth = (font.MaxWidth = (WORD) wChar); ! 1231: ! 1232: return (TRUE); ! 1233: } ! 1234: ! 1235: ! 1236: /**************************************************************************** ! 1237: * BOOL SpreadWidths(wChar) ! 1238: * ! 1239: * purpose: spread/compress work bitmap (with variable width characters) ! 1240: * in proportion with the maximum character width ! 1241: * ! 1242: * params : WORD wChar : new width of a character ! 1243: * ! 1244: * returns: none ! 1245: * ! 1246: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1247: * altered as well ! 1248: ****************************************************************************/ ! 1249: ! 1250: BOOL ! 1251: SpreadWidths( ! 1252: DWORD wChar ! 1253: ) ! 1254: { ! 1255: DWORD offset, i; ! 1256: DWORD width, oldWidth, newWidths[257]; ! 1257: ! 1258: /* Create a new bitmap to move the font definition bits into */ ! 1259: width = 0; /* Compute the new width */ ! 1260: for (i = (DWORD) font.FirstChar; i <= (DWORD) font.LastChar; i++) ! 1261: { ! 1262: oldWidth = offsets[i + 1] - offsets[i]; ! 1263: /* Compute new width to nearest whole number */ ! 1264: newWidths[i] = Proport(oldWidth, wChar, font.MaxWidth, wBoxLim - 1); ! 1265: width += newWidths[i]; ! 1266: } ! 1267: width = (width + 15) >> 4 << 1; /* In even bytes */ ! 1268: if (!GetNewMap(width, font.PixHeight)) ! 1269: return(FALSE); ! 1270: ! 1271: /* Move the bits in */ ! 1272: offset = 0; ! 1273: oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); ! 1274: for (i = font.FirstChar; i <= font.LastChar; i++) ! 1275: { ! 1276: oldWidth = offsets[i + 1] - offsets[i]; ! 1277: StretchBlt(hNewMemDC, offset, 0, ! 1278: newWidths[i], font.PixHeight, /* New character */ ! 1279: hMemDC, offsets[i], 0, ! 1280: oldWidth, font.PixHeight, /* Old character */ ! 1281: SRCCOPY); ! 1282: offsets[i] = offset; ! 1283: offset += newWidths[i]; ! 1284: } ! 1285: SetStretchBltMode(hNewMemDC, oldMode); ! 1286: offsets[font.LastChar + 1] = offset; ! 1287: ! 1288: UseNewMap(); /* Switch Pointers and release the space */ ! 1289: font.HorizRes = (WORD) Proport(font.HorizRes, wChar, font.MaxWidth, 999); ! 1290: font.WidthBytes = (WORD) width; /* Misc. ajustments */ ! 1291: font.MaxWidth = (WORD) wChar; ! 1292: NewAverage(); /* Compute new average width */ ! 1293: ! 1294: return (TRUE); ! 1295: } ! 1296: ! 1297: ! 1298: /**************************************************************************** ! 1299: * NewAverage() ! 1300: * ! 1301: * purpose: recalculate average width of a character in font ! 1302: * ! 1303: * params : none ! 1304: * ! 1305: * returns: none ! 1306: * ! 1307: * side effects: alters the average width parameter in font header ! 1308: * ! 1309: ****************************************************************************/ ! 1310: VOID ! 1311: NewAverage( ! 1312: VOID ! 1313: ) ! 1314: { ! 1315: #ifdef FOO ! 1316: WORD i, totalwidth; ! 1317: /* 12/23/85 -- use weighted avg of lower case letters (mikecr) */ ! 1318: ! 1319: /* width of the space */ ! 1320: totalwidth = (offsets[' ' + 1] - offsets[' ']) * widthweights[ALPHA_CNT]; ! 1321: ! 1322: for (i = 0; i < ALPHA_CNT; i++) ! 1323: totalwidth += (offsets['a' + i + 1] - offsets['a' + i]) * ! 1324: widthweights[i]; ! 1325: ! 1326: font.AvgWidth = totalwidth / TOTAL_WEIGHTS; ! 1327: ! 1328: /* round up if necessary */ ! 1329: if (totalwidth % TOTAL_WEIGHTS >= (TOTAL_WEIGHTS >> 1)) ! 1330: font.AvgWidth++; ! 1331: ! 1332: #endif ! 1333: ! 1334: /* lets do a simple average here */ ! 1335: font.AvgWidth = (WORD) (((offsets[font.LastChar+1] - ! 1336: offsets[font.FirstChar]) + (font.LastChar - font.FirstChar)/2) / ! 1337: (font.LastChar - font.FirstChar + 1)); ! 1338: ! 1339: if (font.AvgWidth == 0) { ! 1340: font.AvgWidth++; ! 1341: } ! 1342: } ! 1343: ! 1344: ! 1345: /**************************************************************************** ! 1346: * BOOL ResizeBody(width, height) ! 1347: * ! 1348: * purpose: adjust work bitmap according to new specified dimensions ! 1349: * ! 1350: * params : WORD width : new width of font in pixels ! 1351: * WORD height : new height of font in pixels ! 1352: * ! 1353: * returns: none ! 1354: * ! 1355: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1356: * altered as well ! 1357: ****************************************************************************/ ! 1358: ! 1359: BOOL ! 1360: ResizeBody( ! 1361: DWORD width, ! 1362: DWORD height ! 1363: ) ! 1364: { ! 1365: ! 1366: /* Create a new bitmap to move the font definition bits into */ ! 1367: if (!GetNewMap(width, height)) ! 1368: return(FALSE); ! 1369: ! 1370: /* Move the bits in */ ! 1371: oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); ! 1372: StretchBlt(hNewMemDC, 0, 0, ! 1373: width << 3, height, /* New Char. */ ! 1374: hMemDC, 0, 0, ! 1375: width << 3, font.PixHeight, /* Old Char. */ ! 1376: SRCCOPY); ! 1377: SetStretchBltMode(hNewMemDC, oldMode); ! 1378: ! 1379: UseNewMap(); /* Switch Pointers and release the space */ ! 1380: ! 1381: font.ExtLeading = (WORD) Proport(font.ExtLeading, height, font.PixHeight, 999); ! 1382: font.IntLeading = (WORD) Proport(font.IntLeading, height, font.PixHeight, 999); ! 1383: font.Ascent = (WORD) Proport(font.Ascent, height, font.PixHeight, 32); ! 1384: font.VertRes = (WORD) Proport(font.VertRes, height, font.PixHeight, 999); ! 1385: font.Points = (WORD) Proport(font.Points, height, font.PixHeight, 999); ! 1386: font.PixHeight = (WORD) height; /* Fix misc. header values */ ! 1387: font.WidthBytes = (WORD) width; ! 1388: ! 1389: return (TRUE); ! 1390: } ! 1391: ! 1392: ! 1393: /**************************************************************************** ! 1394: * BOOL NewFirstChar(first) ! 1395: * ! 1396: * purpose: redefines first character in font and resizes work bitmap ! 1397: * accordingly ! 1398: * ! 1399: * params : WORD first : new first character to be defined ! 1400: * ! 1401: * returns: none ! 1402: * ! 1403: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1404: * altered as well ! 1405: ****************************************************************************/ ! 1406: ! 1407: BOOL ! 1408: NewFirstChar( ! 1409: DWORD first ! 1410: ) ! 1411: { ! 1412: DWORD width, wDefault; ! 1413: DWORD offset, i; ! 1414: INT dw; ! 1415: ! 1416: if (first > font.FirstChar) /* Smaller? */ ! 1417: { ! 1418: ShrinkFont(first, font.LastChar); ! 1419: font.FirstChar = (BYTE) first; ! 1420: /*return(FALSE);*/ ! 1421: return(TRUE); ! 1422: } ! 1423: ! 1424: /* If not smaller we must pad with the default character */ ! 1425: wDefault = offsets[font.DefaultChar + 1] - offsets[font.DefaultChar]; ! 1426: dw = wDefault * (font.FirstChar - first); /* Extra width */ ! 1427: width = offsets[font.LastChar + 1] + dw; /* New width (pixels) */ ! 1428: width = (width + 15) >> 4 << 1; /* Width - even bytes */ ! 1429: if (!GetNewMap(width, font.PixHeight)) ! 1430: return(FALSE); /* New work area */ ! 1431: ! 1432: /* Move it in in two parts */ ! 1433: /* First move in default characters */ ! 1434: offset = 0; ! 1435: for (i = first; i < font.FirstChar; i++) ! 1436: { ! 1437: BitBlt(hNewMemDC, offset, 0, ! 1438: wDefault, font.PixHeight, ! 1439: hMemDC, offsets[font.DefaultChar], 0, ! 1440: SRCCOPY); ! 1441: offsets[i] = offset; ! 1442: offset += wDefault; ! 1443: } ! 1444: /* Now move in the rest */ ! 1445: BitBlt(hNewMemDC, offset, 0, ! 1446: offsets[font.LastChar + 1], font.PixHeight, ! 1447: hMemDC, 0, 0, ! 1448: SRCCOPY); ! 1449: ! 1450: UseNewMap(); /* Switch Pointers and release the space */ ! 1451: ! 1452: /* Now fix up offsets table */ ! 1453: for (i = font.FirstChar; i <= (DWORD)(font.LastChar + 1); i++) ! 1454: offsets[i] = offsets[i] + dw; /* Shift the rest right */ ! 1455: font.WidthBytes = (WORD) width; ! 1456: font.FirstChar = (BYTE) first; ! 1457: ! 1458: return (TRUE); ! 1459: } ! 1460: ! 1461: ! 1462: /**************************************************************************** ! 1463: * ShrinkFont(first, last) ! 1464: * ! 1465: * purpose: redefine the first and last charcter in the font and shrink ! 1466: * work bitmap accordingly ! 1467: * ! 1468: * params : WORD first : new first character to be defined ! 1469: * WORD last : new last character " " " ! 1470: * ! 1471: * returns: none ! 1472: * ! 1473: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1474: * altered as well ! 1475: ****************************************************************************/ ! 1476: ! 1477: VOID ! 1478: ShrinkFont( ! 1479: DWORD first, ! 1480: DWORD last ! 1481: ) ! 1482: { ! 1483: DWORD width, widthPixels; ! 1484: DWORD i; ! 1485: INT dw; ! 1486: ! 1487: dw = offsets[first] - offsets[font.FirstChar]; /* left shift if any */ ! 1488: widthPixels = offsets[last + 1] - offsets[first]; /* Width in pixels */ ! 1489: width = (widthPixels + 15) >> 4 << 1; /* Width - even bytes */ ! 1490: if (!GetNewMap(width, font.PixHeight)) ! 1491: return; /* New work area.*/ ! 1492: ! 1493: /* Now move the font into the reduced space */ ! 1494: ! 1495: BitBlt(hNewMemDC, 0, 0, ! 1496: widthPixels, font.PixHeight, ! 1497: hMemDC, offsets[first], 0, ! 1498: SRCCOPY); ! 1499: ! 1500: UseNewMap(); /* Switch Pointers and release the space */ ! 1501: ! 1502: if (dw) /* Ajust offsets */ ! 1503: { ! 1504: for (i = first; i <= last + 1; i++) ! 1505: offsets[i] -= dw; ! 1506: } ! 1507: ! 1508: font.WidthBytes = (WORD) width; ! 1509: ! 1510: } ! 1511: ! 1512: ! 1513: /**************************************************************************** ! 1514: * BOOL NewLastChar(last) ! 1515: * ! 1516: * purpose: redefines the last character in the font ! 1517: * ! 1518: * params : WORD last : number of character to be made the last character ! 1519: * ! 1520: * returns: none ! 1521: * ! 1522: * side effects: Work bitmap changes.Some header info (regarding font dimensions ! 1523: * altered as well ! 1524: * ! 1525: ****************************************************************************/ ! 1526: ! 1527: BOOL ! 1528: NewLastChar( ! 1529: DWORD last ! 1530: ) ! 1531: { ! 1532: DWORD width, wDefault; ! 1533: DWORD offset, i; ! 1534: INT dw; ! 1535: ! 1536: if (last < font.LastChar) /* Smaller? */ ! 1537: { ! 1538: ShrinkFont(font.FirstChar, last); ! 1539: font.LastChar = (BYTE) last; ! 1540: return(FALSE); ! 1541: } ! 1542: ! 1543: /* If not smaller we must pad with the default character */ ! 1544: wDefault = offsets[font.DefaultChar + 1] - offsets[font.DefaultChar]; ! 1545: dw = wDefault * (last - font.LastChar); /* Extra width */ ! 1546: offset = offsets[font.LastChar + 1]; /* Current end */ ! 1547: width = offset + dw; /* New width (pixels) */ ! 1548: width = (width + 15) >> 4 << 1; /* Width - even bytes */ ! 1549: if (!GetNewMap(width, font.PixHeight)) ! 1550: return(FALSE); /* New work area */ ! 1551: ! 1552: /* Move it in in two parts */ ! 1553: /* First move in the existing font */ ! 1554: BitBlt(hNewMemDC, 0, 0, ! 1555: offset, font.PixHeight, ! 1556: hMemDC, 0, 0, ! 1557: SRCCOPY); ! 1558: /* Then move in default characters */ ! 1559: for (i = font.LastChar + 1; i <= last;) ! 1560: { ! 1561: BitBlt(hNewMemDC, offset, 0, ! 1562: wDefault, font.PixHeight, ! 1563: hMemDC, offsets[font.DefaultChar], 0, ! 1564: SRCCOPY); ! 1565: offset += wDefault; ! 1566: offsets[++i] = offset; ! 1567: } ! 1568: ! 1569: UseNewMap(); /* Switch Pointers and release the space */ ! 1570: ! 1571: font.WidthBytes = (WORD) width; ! 1572: font.LastChar = (BYTE) last; ! 1573: ! 1574: return (TRUE); ! 1575: } ! 1576: ! 1577: ! 1578: /**************************************************************************** ! 1579: * BOOL CharWidth(iChar, wBox) ! 1580: * ! 1581: * purpose: resizes selected char according to new dimensions. (only for ! 1582: * variable pitch) ! 1583: * ! 1584: * params : BYTE iChar : character to resize ! 1585: * WORD wBox : new width of char in pixels ! 1586: * ! 1587: * returns: none ! 1588: * ! 1589: * side effects: work bitmap pixel values and header info(regarding font ! 1590: * dimensions) altered ! 1591: * ! 1592: ****************************************************************************/ ! 1593: ! 1594: BOOL ! 1595: CharWidth( ! 1596: BYTE iChar, /* Character to change */ ! 1597: DWORD wBox /* New width */ ! 1598: ) ! 1599: { ! 1600: DWORD width, nChars; ! 1601: DWORD w1, w2, i; ! 1602: INT dw; ! 1603: ! 1604: nChars = font.LastChar - font.FirstChar + 1; /* Character count */ ! 1605: dw = wBox - (offsets[iChar + 1] - offsets[iChar]); /* Width change */ ! 1606: width = offsets[font.LastChar + 1] + dw; /* New width (pixels) */ ! 1607: width = (width + 15) >> 4 << 1; /* Width - even bytes */ ! 1608: if (!GetNewMap(width, font.PixHeight)) ! 1609: return(FALSE); /* New work area */ ! 1610: ! 1611: /* Move it in in two parts */ ! 1612: /* First move up to and including iChar */ ! 1613: w1 = offsets[iChar + 1]; /* Width (in pixels) to move */ ! 1614: BitBlt(hNewMemDC, 0, 0, ! 1615: w1 + dw, font.PixHeight, ! 1616: hMemDC, 0, 0, ! 1617: SRCCOPY); ! 1618: /* Now move in the rest */ ! 1619: if (iChar < (BYTE) font.LastChar) /* Part to right of elision */ ! 1620: { ! 1621: w2 = offsets[font.LastChar + 1] - offsets[iChar + 1]; ! 1622: BitBlt(hNewMemDC, offsets[iChar] + wBox, 0, ! 1623: w2, font.PixHeight, ! 1624: hMemDC, offsets[iChar + 1], 0, ! 1625: SRCCOPY); ! 1626: } ! 1627: ! 1628: UseNewMap(); /* Switch Pointers and release the space */ ! 1629: ! 1630: /* Now fix up offsets table */ ! 1631: for (i = iChar + 1; /* Where changes start */ ! 1632: i <= (DWORD)(font.LastChar + 1); i++) /* Ajust offsets */ ! 1633: offsets[i] = offsets[i] + dw; /* .. by adding dw */ ! 1634: font.WidthBytes = (WORD) width; ! 1635: NewAverage(); ! 1636: ! 1637: return (TRUE); ! 1638: } ! 1639: ! 1640: /**************************************************************************** ! 1641: * BoxToClipboard(ptA, width, height) ! 1642: * ! 1643: * purpose: write char (or part of it) to clipboard ! 1644: * ! 1645: * params : POINT ptA : upper left coordinate ! 1646: * DWORD width : width of char in pixels ! 1647: * DWORD height : height of char in pixels ! 1648: * returns: none ! 1649: * ! 1650: * side effects: none ! 1651: * ! 1652: ****************************************************************************/ ! 1653: VOID ! 1654: BoxToClipboard( ! 1655: POINT ptA, /* Upper left point */ ! 1656: DWORD width, ! 1657: DWORD height /* Size */ ! 1658: ) ! 1659: { ! 1660: HDC hDC; ! 1661: DWORD x, y; ! 1662: ! 1663: hDC = GetDC(hFont); /* DC to be compatible with */ ! 1664: hNewBitmap = CreateBitmap( ! 1665: width, height, ! 1666: 1, 1, (LPBYTE)NULL); ! 1667: hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 1668: SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ ! 1669: ReleaseDC(hFont, hDC); /* Done with font DC */ ! 1670: ! 1671: for (x = 0; x < width; x++) ! 1672: for (y = 0; y < height; y++) ! 1673: SetPixel(hNewMemDC, x, y, matBox[x + ptA.x][y + ptA.y] == TRUE ? ! 1674: BLACK : WHITE); ! 1675: ! 1676: /* Now wake up Clipboard and empty it */ ! 1677: if (!OpenClipboard(hFont)) ! 1678: ErrorBox(hBox, vszCannotOpenClip); // , vszCopyingToClip); ! 1679: else /* Ok: We got the Clipboard */ ! 1680: { ! 1681: EmptyClipboard(); ! 1682: SetClipboardData(CF_BITMAP, hNewBitmap); /* Tell Clipboard */ ! 1683: } ! 1684: ! 1685: /* Tidy things up */ ! 1686: CloseClipboard(); ! 1687: DeleteDC(hNewMemDC); ! 1688: } ! 1689: ! 1690: ! 1691: /**************************************************************************** ! 1692: * WORD ClipboardToBox(ptA, width, height, fFit) ! 1693: * ! 1694: * purpose: copies char (or part of char ) from clipboard to work bitmap ! 1695: * stretching it if need be ! 1696: * ! 1697: * params : PIONT ptA : upper left coordinate ! 1698: * DWORD width : width of char in pixels ! 1699: * DWORD height : height of char in pixels ! 1700: * BOOL fFit : flag to indicate if default width is to be used ! 1701: * returns: none ! 1702: * ! 1703: * side effects: pixel values of bitmap may change for char ! 1704: * ! 1705: ****************************************************************************/ ! 1706: ! 1707: DWORD ! 1708: ClipboardToBox( ! 1709: POINT ptA, /* Upper left point */ ! 1710: DWORD width, ! 1711: DWORD height, /* Size */ ! 1712: BOOL fFit /* Use default width if TRUE */ ! 1713: ) ! 1714: { ! 1715: BITMAP bitmap; ! 1716: HDC hDC; ! 1717: DWORD x, y; ! 1718: HANDLE hT; ! 1719: ! 1720: if (!OpenClipboard(hFont)) { ! 1721: ErrorBox(hBox, vszCannotOpenClip); ! 1722: return 0; ! 1723: } ! 1724: hNewBitmap = GetClipboardData(CF_BITMAP); ! 1725: ! 1726: /* Check if we got something like a character */ ! 1727: if (GetObject(hNewBitmap, sizeof(BITMAP), (LPSTR)&bitmap) != sizeof(BITMAP)) ! 1728: { /* What did we get */ ! 1729: ErrorBox(hBox, vszErrorClip); ! 1730: CloseClipboard(); ! 1731: return 0; ! 1732: } ! 1733: ! 1734: ! 1735: if (fFit && ((WORD)bitmap.bmWidth <= font.MaxWidth)) ! 1736: width = bitmap.bmWidth; ! 1737: ! 1738: hDC = GetDC(hFont); /* DC to be compatible with */ ! 1739: hBoxBitmap = CreateBitmap( ! 1740: width, height, ! 1741: 1, 1, (LPBYTE)NULL); ! 1742: hBoxMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 1743: hT = SelectObject(hBoxMemDC, hBoxBitmap); /* Relate them */ ! 1744: if (hT == NULL || hDC == NULL || hBoxBitmap == NULL || hBoxMemDC == NULL) { ! 1745: ErrorBox(hBox, vszErrorClip); ! 1746: CloseClipboard(); ! 1747: DeleteDC(hBoxMemDC); ! 1748: DeleteObject(hBoxBitmap); ! 1749: return 0; ! 1750: } ! 1751: ! 1752: /* Get a DC to relate to the Bitmap we just got */ ! 1753: hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 1754: hT = SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ ! 1755: ReleaseDC(hFont, hDC); /* Done with font DC */ ! 1756: if (hT == NULL || hNewMemDC == NULL) { ! 1757: ErrorBox(hBox, vszErrorClip); ! 1758: CloseClipboard(); ! 1759: DeleteDC(hNewMemDC); ! 1760: DeleteDC(hBoxMemDC); ! 1761: DeleteObject(hBoxBitmap); ! 1762: return 0; ! 1763: } ! 1764: ! 1765: /* Now StretchBlt whatever was on the clipboard into the character */ ! 1766: oldMode = SetStretchBltMode(hBoxMemDC, COLORONCOLOR); ! 1767: fFit = StretchBlt(hBoxMemDC, 0, 0, width, height, ! 1768: hNewMemDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY); ! 1769: if (!fFit || !oldMode) { ! 1770: ErrorBox(hBox, vszErrorClip); ! 1771: CloseClipboard(); ! 1772: DeleteDC(hNewMemDC); ! 1773: DeleteDC(hBoxMemDC); ! 1774: DeleteObject(hBoxBitmap); ! 1775: return 0; ! 1776: } ! 1777: (void)SetStretchBltMode(hBoxMemDC, oldMode); ! 1778: for (x = 0; x < width; x++) ! 1779: for (y = 0; y < height; y++) ! 1780: matBox[x + ptA.x] [y + ptA.y] = (CHAR)(GetPixel(hBoxMemDC, x, y) ? ! 1781: 0 : 1); ! 1782: /* Tidy things up */ ! 1783: DeleteDC(hNewMemDC); ! 1784: DeleteDC(hBoxMemDC); ! 1785: DeleteObject(hBoxBitmap); ! 1786: CloseClipboard(); ! 1787: return(width); ! 1788: } ! 1789: ! 1790: ! 1791: /**************************************************************************** ! 1792: * ToClipboard(iChar, width, height) ! 1793: * ! 1794: * purpose: write char in edit box to clipboard ! 1795: * ! 1796: * params : BYTE iChar : number of char to be copied to clipboard ! 1797: * DWORD width : width of char in pixels ! 1798: * DWORD height : height of char in pixels ! 1799: * ! 1800: * returns: none ! 1801: * ! 1802: * side effects: none ! 1803: * ! 1804: ****************************************************************************/ ! 1805: ! 1806: VOID ! 1807: ToClipboard( ! 1808: BYTE iChar, ! 1809: DWORD width, /* Here in Pixels */ ! 1810: DWORD height /* Also in Pixels */ ! 1811: ) ! 1812: { ! 1813: HDC hDC; ! 1814: ! 1815: hDC = GetDC(hFont); /* DC to be compatible with */ ! 1816: hNewBitmap = CreateBitmap( ! 1817: width, /* Width of font in pixels */ ! 1818: height, ! 1819: 1, 1, (LPBYTE)NULL); ! 1820: hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 1821: SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ ! 1822: ReleaseDC(hFont, hDC); /* Done with font DC */ ! 1823: ! 1824: BitBlt(hNewMemDC, 0, 0, width, height, /* Move Character in */ ! 1825: hMemDC, offsets[iChar], 0, NOTSRCCOPY); ! 1826: ! 1827: /* Now wake up Clipboard and empty it */ ! 1828: if (!OpenClipboard(hFont)) ! 1829: ErrorBox(hBox, vszCannotOpenClip); // , vszCopyingToClip); ! 1830: else /* Ok: We got the Clipboard */ ! 1831: { ! 1832: EmptyClipboard(); ! 1833: SetClipboardData(CF_BITMAP, hNewBitmap); /* Tell Clipboard */ ! 1834: } ! 1835: ! 1836: /* Tidy things up */ ! 1837: CloseClipboard(); ! 1838: DeleteDC(hNewMemDC); ! 1839: } ! 1840: ! 1841: ! 1842: /**************************************************************************** ! 1843: * GetNewMap(width, height) ! 1844: * ! 1845: * purpose: create new bitmap of the given width and height. ! 1846: * ! 1847: * params : WORD width : width of bitmap in pixels ! 1848: * WORD height : height of bitmap in pixels ! 1849: * ! 1850: * returns: TRUE if successful, FALSE otherwise ! 1851: * ! 1852: * side effects: Handle and DC values of new DC assigned ! 1853: * ! 1854: ****************************************************************************/ ! 1855: ! 1856: BOOL ! 1857: GetNewMap( ! 1858: DWORD width, ! 1859: DWORD height /* New size */ ! 1860: ) ! 1861: { ! 1862: HDC hDC; ! 1863: ! 1864: if (height==0) /* Check if something stupid is happening */ ! 1865: height=font.PixHeight; /* Fix it */ ! 1866: ! 1867: /* Put up an houglass ... this may take a while */ ! 1868: if (!hHourGlass) ! 1869: hHourGlass = LoadCursor(NULL, IDC_WAIT); /* Get Hourglass */ ! 1870: hOldCursor = SetCursor(hHourGlass); /* Show hourglass */ ! 1871: ! 1872: /* Create a new bitmap to move the font definition bits into */ ! 1873: hDC = GetDC(hFont); /* DC to be compatible with */ ! 1874: hNewBitmap = CreateBitmap( ! 1875: width << 3, /* Width of font in pixels */ ! 1876: height, ! 1877: 1, 1, (LPBYTE)NULL); ! 1878: if (!hNewBitmap) ! 1879: { ! 1880: ErrorBox(hBox, vszNotEnoughMem); // , vszAllocatingSpace); ! 1881: ReleaseDC(hFont, hDC); /* bug# 2380 */ ! 1882: return FALSE; ! 1883: } ! 1884: ! 1885: hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ ! 1886: SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ ! 1887: ReleaseDC(hFont, hDC); /* Done with font DC */ ! 1888: PatBlt(hNewMemDC, 0, 0, width << 3, height, BLACKNESS); /* Clear it */ ! 1889: return TRUE; ! 1890: } ! 1891: ! 1892: ! 1893: /**************************************************************************** ! 1894: * UseNewMap() ! 1895: * ! 1896: * params : none ! 1897: * ! 1898: * purpose: discard old bitmap and replace it with new one ! 1899: * ! 1900: * returns: none ! 1901: * ! 1902: * side effects: Handle to old bitmap and handle to old bitmap DC replaced ! 1903: * by those of new bitmap respectively ! 1904: * ! 1905: ****************************************************************************/ ! 1906: ! 1907: VOID ! 1908: UseNewMap( ! 1909: VOID ! 1910: ) ! 1911: { ! 1912: DeleteDC(hMemDC); ! 1913: DeleteObject(hBitmap); /* Release old space */ ! 1914: hBitmap = hNewBitmap; ! 1915: hMemDC = hNewMemDC; /* Release old space */ ! 1916: SetCursor(hOldCursor); /* Restore regular cursor */ ! 1917: } ! 1918: ! 1919: ! 1920: ! 1921: VOID ! 1922: DeleteGlobalBitmap( ! 1923: VOID ! 1924: ) ! 1925: { ! 1926: if (hMemDC) ! 1927: DeleteDC(hMemDC); ! 1928: if (hBitmap) ! 1929: DeleteObject(hBitmap); ! 1930: } ! 1931: ! 1932: ! 1933: DWORD ! 1934: Proport( ! 1935: DWORD value, ! 1936: DWORD top, ! 1937: DWORD bottom, ! 1938: DWORD limit ! 1939: ) ! 1940: /* Reproportion a value by the ratio top/bottom to the nearest integer ! 1941: * and make sure we are still in range */ ! 1942: { ! 1943: return min(limit, (DWORD)((1 + 2 * value * top) / (2 * bottom))); ! 1944: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.