Annotation of mstools/samples/sdktools/fontedit/fontload.c, revision 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.