Annotation of mstools/samples/sdktools/fontedit/fontload.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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