/******************************Module*Header*******************************\ * Module Name: simulate.c * * routines associated with simulated faces i.e. emboldened * and/or italicized faces * * Created: 17-Apr-1991 08:31:18 * Author: Bodin Dresevic [BodinD] * * Copyright (c) 1990 Microsoft Corporation * \**************************************************************************/ #include "fd.h" #ifdef SAVE_FOR_HISTORICAL_REASONS /******************************Public*Routine******************************\ * * VOID vEmboldenBitmap(RASTERGLYPH * pgldtSrc,RASTERGLYPH * pgldtDst,LONG culDst) * * modifies an original glyph bitmap for the default face * to produce the bitmap that corresponds to an emboldened char. * Emboldened bitmap is simply an original bitmap offsetted to the right * by one pel and OR-ed with the original bitmap itself. * * History: * 22-Apr-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vEmboldenBitmap( RASTERGLYPH * prgSrc, RASTERGLYPH * prgDst ) { ULONG cxSrc = prgSrc->gb.sizlBitmap.cx; ULONG cy = prgSrc->gb.sizlBitmap.cy; // same for src and dst ULONG cxDst = cxSrc + 1; // + 1 for emboldening PBYTE pjSrc = prgSrc->gb.aj; PBYTE pjDst = prgDst->gb.aj; ULONG iScan,iByte; // loop indices PBYTE pjS,pjD; // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned) ULONG cjScanDst = CJ_SCAN(cxDst); ULONG cjScanSrc = CJ_SCAN(cxSrc); ULONG cjBmp = cjScanDst * cy; ULONG cjScanDst = CJ_SCAN(cxDst); ULONG cjScanSrc = CJ_SCAN(cxSrc); BYTE jCarry; // carry bit from shifting Src byte by 1; GLYPHDATA *pgldtSrc = &prgSrc->gd; GLYPHDATA *pgldtDst = &prgDst->gd; #ifdef DUMPCALL DbgPrint("\nvEmboldenBitmap("); DbgPrint("\n RASTERGLYPH *prgSrc = %-#8lx",prgSrc); DbgPrint("\n RASTERGLYPH *prgDst = %-#8lx",prgDst); DbgPrint("\n )\n"); #endif RtlCopyMemory(prgDst, prgSrc, offsetof(RASTERGLYPH,gb) + offsetof(GLYPHBITS,sizlBitmap)); // if engine requested memory that is zero-ed out we would not have to do it // ourselves RtlZeroMemory(pjDst, cjBmp); // make necessary changes to the fields of GLYPHDATA which // are affected by emboldening pgldtDst->gdf.pgb = &prgDst->gb; pgldtDst->rclInk.right += (LONG)1; // pre and post bearings have not changed nor bmp origin, only inked box pgldtDst->fxD = LTOFX(cxDst); pgldtDst->ptqD.x.HighPart = (LONG)pgldtDst->fxD; pgldtDst->fxAB = pgldtDst->fxD; // right edge of the black box // this needs to be changed a bit since aulBMData will not live // in the GLYPHDATA structure any more prgDst->gb.sizlBitmap.cx = cxDst; prgDst->gb.sizlBitmap.cy = cy; // embolden bitmap scan by scan for (iScan = 0L; iScan < cy; iScan++) { pjS = pjSrc; pjD = pjDst; // embolden individual scans jCarry = (BYTE)0; // no carry to the first byte in the row for(iByte = 0L; iByte < cjScanSrc; iByte++, pjS++, pjD++) { *pjD = (BYTE)(*pjS | ((*pjS >> 1) | jCarry)); // remember the rightmost bit and shift it to the leftmost position jCarry = (BYTE)(*pjS << 7); } if ((cxSrc & 7L) == 0L) *pjD = jCarry; // advance to the next scan of the src and dst pjSrc += cjScanSrc; pjDst += cjScanDst; } } #endif // SAVE_FOR_HISTORICAL_REASONS /******************************Public*Routine******************************\ * cjGlyphDataSimulated * * Computes the size of the glyphdata for the simulated face given cx and cy * for the corresponding char in the default face * * History: * 22-Apr-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ #ifdef FE_SB // cjGlyphDataSimulated(): LONG cjGlyphDataSimulated( FONTOBJ *pfo, ULONG cxNoSim, // cx for the same char of the default face ULONG cyNoSim, // cy for the same char of the default face ULONG *pcxSim, ULONG ulRotate // Rotation degree ) #else LONG cjGlyphDataSimulated( FONTOBJ *pfo, ULONG cxNoSim, // cx for the same char of the default face ULONG cyNoSim, // cy for the same char of the default face ULONG *pcxSim ) #endif { ULONG cxSim; #ifdef DUMPCALL DbgPrint("\ncjGlyphDataSimulated("); DbgPrint("\n ULONG cxNoSim = %-#8lx",cxNoSim); DbgPrint("\n ULONG cyNoSim = %-#8lx",cyNoSim); DbgPrint("\n ULONG *pcxSim = %-#8lx",pcxSim ); DbgPrint("\n )\n"); #endif if (cxNoSim == 0) { // blank 1x1 bitmap cxSim = 1; cyNoSim = 1; } else { switch( pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC) ) { case 0: cxSim = cxNoSim; break; case FO_SIM_BOLD: cxSim = cxNoSim + 1; break; case FO_SIM_ITALIC: cxSim = cxNoSim + (cyNoSim - 1) / 2; break; default: // here we have used that // (k - 1) / 2 + 1 == (k + 1) / 2 for every integer k, (k == cy) cxSim = cxNoSim + (cyNoSim + 1) / 2; break; } } if (pcxSim != (ULONG *)NULL) { *pcxSim = cxSim; } #ifdef FE_SB // cjGlyphDataSimulated(): #ifdef DBG_MORE DbgPrint("cxSim - 0x%x\n : cyNoSim - 0x%x\n",cxSim , cyNoSim); #endif // DBG_MORE switch( ulRotate ) { case 0L : case 1800L : return(CJ_GLYPHDATA(cxSim, cyNoSim)); case 900L : case 2700L : return(CJ_GLYPHDATA(cyNoSim, cxSim)); default : /* we should never be here */ return(CJ_GLYPHDATA(cxSim, cyNoSim)); } #else return(CJ_GLYPHDATA(cxSim, cyNoSim)); #endif } /******************************Public*Routine******************************\ * * cFacesRes * * History: * 13-May-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ ULONG cFacesRes( PRES_ELEM pre ) { FSHORT fs = fsSelectionFlags((PBYTE)pre->pvResData); #ifdef DUMPCALL DbgPrint("\ncFacesRes("); DbgPrint("\n PRES_ELEM pre = %-#8lx", pre); DbgPrint("\n )\n"); #endif // kill all the bits but BOLD and ITALIC fs = fs & (FSHORT)(FM_SEL_BOLD | FM_SEL_ITALIC); //!!! DbgPrint("fsSelection = 0x%lx\n", (ULONG)fs); if (fs == 0) // default face is NORMAL return(4L); if ((fs == FM_SEL_BOLD) || (fs == FM_SEL_ITALIC)) return(2L); if (fs == (FM_SEL_BOLD | FM_SEL_ITALIC)) return(1L); /* we should never be here */ return (4L); } /******************************Public*Routine******************************\ * VOID vDefFace * * History: * 13-May-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vDefFace( FACEINFO *pfai, RES_ELEM *pre ) { // kill all bits but BOLD and ITALIC bits that should remain unchanged FSHORT fs = (FSHORT)( fsSelectionFlags((PBYTE) pre->pvResData) & (FM_SEL_BOLD | FM_SEL_ITALIC) ); switch (fs) { case 0: pfai->iDefFace = FF_FACE_NORMAL; return; case FM_SEL_BOLD: pfai->iDefFace = FF_FACE_BOLD; return; case FM_SEL_ITALIC: pfai->iDefFace = FF_FACE_ITALIC; return; case (FM_SEL_ITALIC | FM_SEL_BOLD): pfai->iDefFace = FF_FACE_BOLDITALIC; return; default: RIP("bmfd!_which ape has messed up the code ?\n"); return; } } #if 0 /* This function is never used, and ignores memory accesses outside the mapped file. */ /******************************Public*Routine******************************\ * * ULONG cFacesFON // no. of faces associated with this FON file * * History: * January 2002 -by- Jay Krell [JayKrell] * #if 0'ed out. * 13-May-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ ULONG cFacesFON( PWINRESDATA pwrd ) { ULONG cFace; ULONG iRes; RES_ELEM re; #ifdef DUMPCALL DbgPrint("\ncFacesFON("); DbgPrint("\n PWINRESDATA pwrd = %-#8lx", pwrd); DbgPrint("\n )\n"); #endif // this function should have not been called if there are no // font resources associated with this pwrd ASSERTGDI(pwrd->cFntRes != 0L, "No font resources\n"); cFace = 0L; // init the sum for (iRes = 0L; iRes < pwrd->cFntRes; iRes++) { if (bGetFntResource(pwrd,iRes,&re)) cFace += cFacesRes(&re); } return(cFace); } #endif /******************************Public*Routine******************************\ * * vComputeSimulatedGLYPHDATA * * History: * 06-Oct-1992 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vComputeSimulatedGLYPHDATA( GLYPHDATA *pgldt , PBYTE pjBitmap , ULONG cxNoSim , ULONG cy , ULONG yBaseLine, ULONG cxScale, ULONG cyScale, FONTOBJ *pfo ) { ULONG cxSim; // cx for the bitmap LONG xCharInc; // x component of the char inc vector // the following coords refer to bitmap coord system, i.e. the one in which // the BM origin has coors (0,0) ULONG yTopIncMin; // min over non zero raws ULONG yBottomExcMax; // max+1 over non zero raws #ifdef DUMPCALL DbgPrint("\nvComputeSimulatedGLYPHDATA("); DbgPrint("\n GLYPHDATA *pgldt = %-#8lx",pgldt ); DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap ); DbgPrint("\n ULONG cxNoSim = %-#8lx",cxNoSim ); DbgPrint("\n ULONG cy = %-#8lx",cy ); DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine ); DbgPrint("\n FONTOBJ *pfo = %-#8lx",pfo ); DbgPrint("\n )\n"); #endif // compute top and bottom by looking into the bitmap in the row format: vFindTAndB ( pjBitmap, // pointer to the bitmap in *.fnt column format cxNoSim, cy, &yTopIncMin, &yBottomExcMax ); if( cyScale != 1 ) { yTopIncMin *= cyScale; yBottomExcMax *= cyScale; cy *= cyScale; yBaseLine *= cyScale; } cxNoSim *= cxScale; pgldt->gdf.pgb = NULL; if (yTopIncMin == yBottomExcMax) // no ink at all { // this is a tricky point. We are dealing with a blank bitmap. // The first thought would be to report the zero inked box. It // then ambiguous what an A and C spaces should be. The right way to // think of this bitmap (this is in fact the break char) is that the // inked box is the whole bitmap, just the "color" of the ink happens // to be invisible. This is important when dealing with strings // which have break character as the first or the last char in the string. // If the inked box was reported as zero, text extent for such a string // would be computed incorrectly when the corrections for the first A // and last C are taken into account yTopIncMin = 0L; // coincides with the top yBottomExcMax = cy * cyScale; // coincides with the bottom } // these have to be correct, important for computing char inc for esc != 0 pgldt->rclInk.top = (LONG)(yTopIncMin - yBaseLine); pgldt->rclInk.bottom = (LONG)(yBottomExcMax - yBaseLine); // minus sign is because the scalar product is supposed to be taken with // a unit ascender vector pgldt->fxInkTop = -LTOFX(pgldt->rclInk.top); pgldt->fxInkBottom = -LTOFX(pgldt->rclInk.bottom); switch(pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC)) { case 0: cxSim = cxNoSim; xCharInc = (LONG)cxNoSim; break; case FO_SIM_BOLD: cxSim = cxNoSim + 1; xCharInc = (LONG)(cxNoSim + 1); break; case FO_SIM_ITALIC: cxSim = cxNoSim + (cy - 1) / 2; xCharInc = (LONG)cxNoSim; break; case (FO_SIM_BOLD | FO_SIM_ITALIC): // here we have used that // (k - 1) / 2 + 1 == (k + 1) / 2 for every integer k, (k == cy) cxSim = cxNoSim + (cy + 1) / 2; xCharInc = (LONG)(cxNoSim + 1); break; default: // to silence prefix cxSim = 1; RIP("BMFD!BAD SIM FLAG\n"); } if (cxNoSim == 0) { cxSim = 1; // 1X1 blank box xCharInc = 0; } pgldt->fxD = LTOFX(xCharInc); pgldt->ptqD.x.HighPart = (LONG)pgldt->fxD; pgldt->ptqD.x.LowPart = 0; pgldt->ptqD.y.HighPart = 0; pgldt->ptqD.y.LowPart = 0; // in this crude picture we are luying about x extents of the black box // and report the whole bitmap width as an extent pgldt->rclInk.left = 0; // rclInk.left == lhs of the bitmap, => A < 0 pgldt->rclInk.right = (LONG)cxSim; // the rhs of the bitmap => c < 0 // compute bearings, remember the rule A + B + C == char inc // where B is the size of the inked box. For the horizontal case: // A == ePreBearing , C == ePostBearing // In view of these sum rules and the definitions of A,B,C we have // B = rclInk.right - rclInk.left; // A = rclInk.left; // C = xCharInc - rclInk.right; // The sum rule is trivially obeyed. pgldt->fxA = LTOFX(pgldt->rclInk.left); // fxA pgldt->fxAB = LTOFX(pgldt->rclInk.right); // right edge of the black box } /******************************Public*Routine******************************\ * * VOID vCvtToBmp * * Effects: takes the bitmap in the original *.fnt column format and converts * it to the Bmp format. * * History: * 25-Nov-1990 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vCvtToBmp ( GLYPHBITS *pgb, GLYPHDATA *pgd, PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format ULONG cx, ULONG cy, ULONG yBaseLine ) { ULONG cjScan = CJ_SCAN(cx); // # of bytes per scan of the Bmp // pjColumn points to one of the bytes in the first ROW of the Bmp PBYTE pjColumn, pjColumnEnd; PBYTE pjDst, pjDstEnd; // current destination byte #ifdef DUMPCALL DbgPrint("\nvCvtToDIB("); DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb ); DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd ); DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap ); DbgPrint("\n ULONG cx = %-#8lx",cx ); DbgPrint("\n ULONG cy = %-#8lx",cy ); DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine); DbgPrint("\n )\n"); #endif // store cx and cy at the top, before Bits pgb->sizlBitmap.cx = cx; pgb->sizlBitmap.cy = cy; // this is character independent for BM fonts pgb->ptlOrigin.x = 0L; pgb->ptlOrigin.y = -(LONG)yBaseLine; RtlZeroMemory(pgb->aj, cjScan * cy); // we shall fill the Bmp column by column, thus traversing the src a byte at // the time: for ( pjColumn = pgb->aj, pjColumnEnd = pjColumn + cjScan; pjColumn < pjColumnEnd; pjColumn++ ) { for ( pjDst = pjColumn, pjDstEnd = pjColumn + cy * cjScan; pjDst < pjDstEnd; pjDst += cjScan, pjBitmap++ ) { *pjDst = *pjBitmap; } } } /******************************Public*Routine******************************\ * * vCvtToBoldBmp * * History: * 06-Oct-1992 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vCvtToBoldBmp ( GLYPHBITS *pgb, GLYPHDATA *pgd, PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format ULONG cxSrc, ULONG cy, ULONG yBaseLine ) { PBYTE pjSrc; PBYTE pjDst; ULONG cxDst = cxSrc + 1; // + 1 for emboldening ULONG iScan,iByte; // loop indices PBYTE pjS,pjD; // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned) ULONG cjScanDst = CJ_SCAN(cxDst); ULONG cjScanSrc = CJ_SCAN(cxSrc); BYTE jCarry; // carry bit from shifting Src byte by 1; #ifdef DUMPCALL DbgPrint("\nVOID"); DbgPrint("\nvCvtToBoldDIB("); DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb ); DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd ); DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap ); DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc ); DbgPrint("\n ULONG cy = %-#8lx",cy ); DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine); DbgPrint("\n )\n"); #endif // this is character independent for BM fonts pgb->ptlOrigin.x = 0L; pgb->ptlOrigin.y = -(LONG)yBaseLine; pgb->sizlBitmap.cx = cxDst; pgb->sizlBitmap.cy = cy; // init the loop over scans pjSrc = pjBitmap; pjDst = pgb->aj; // embolden bitmap scan by scan // if engine requested memory that is zero-ed out we would not have to do it // ourselves RtlZeroMemory(pjDst, cjScanDst * cy); for (iScan = 0L; iScan < cy; iScan++) { pjS = pjSrc; pjD = pjDst; // embolden individual scans jCarry = (BYTE)0; // no carry to the first byte in the row for ( iByte = 0L; iByte < cjScanSrc; iByte++, pjS += cy, pjD++ ) { *pjD = (BYTE)(*pjS | ((*pjS >> 1) | jCarry)); // remember the rightmost bit and shift it to the leftmost position jCarry = (BYTE)(*pjS << 7); } if ((cxSrc & 7L) == 0L) *pjD = jCarry; // advance to the next scan of the src and dst pjSrc++; pjDst += cjScanDst; } } /******************************Public*Routine******************************\ * * vCvtToItalicBmp * * History: * 06-Oct-1992 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vCvtToItalicBmp ( GLYPHBITS *pgb, GLYPHDATA *pgd, PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format ULONG cxSrc, ULONG cy, ULONG yBaseLine ) { ULONG cxDst = cxSrc + (ULONG)(cy - 1) / 2; // add correction for the PBYTE pjSrcScan, pjS; PBYTE pjDstScan, pjD; LONG iScan,iByte; // loop indices // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned) ULONG cjScanDst = CJ_SCAN(cxDst); LONG cjScanSrc = (LONG)CJ_SCAN(cxSrc); LONG lShift; BYTE jCarry; // carry from shifting Src byte by lShift; LONG cjEmpty; // number of untouched bytes at the begining of the dest scans #ifdef DUMPCALL DbgPrint("\nVOID"); DbgPrint("\nvCvtToItalicDIB("); DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb ); DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd ); DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap ); DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc ); DbgPrint("\n ULONG cy = %-#8lx",cy ); DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine); DbgPrint("\n )\n"); #endif // this is character independent for BM fonts pgb->ptlOrigin.x = 0; pgb->ptlOrigin.y = -(LONG)yBaseLine; pgb->sizlBitmap.cx = cxDst; pgb->sizlBitmap.cy = cy; // init the loop over scans pjSrcScan = pjBitmap; pjDstScan = pgb->aj; // italicize bitmap row by row lShift = ((cy - 1) / 2) & (LONG)7; cjEmpty = ((cy - 1) / 2) >> 3; #ifdef DEBUGITAL DbgPrint("cy = %ld, yBaseLine = %ld, lShift = %ld, cjEmpty = %ld\n", cy, -pgldtSrc->ptlBmpOrigin.y, lShift, cjEmpty); DbgPrint("cxSrc = %ld, cxDst = %ld, cjScanSrc = %ld, cjScanDst = %ld\n", cxSrc, cxDst, cjScanSrc, cjScanDst); DbgPrint("cy = %ld, cjScanSrc = %ld, \n", cy, cjScanSrc); #endif // DEBUGITAL // if engine requested memory that is zero-ed out we would not have to do it // ourselves RtlZeroMemory(pjDstScan , cjScanDst * cy); for (iScan = 0L; iScan < (LONG)cy; iScan++) { if (lShift < 0L) { lShift = 7L; cjEmpty--; } ASSERTGDI(cjEmpty >= 0L, "cjEmpty\n"); #ifdef DEBUGITALIC DbgPrint("iScan = %ld, lShift = %ld\n", iScan, lShift); #endif // DEBUGITALIC pjS = pjSrcScan; pjD = pjDstScan + cjEmpty; // italicize individual scans jCarry = (BYTE)0; // no carry to the first byte in the row for ( iByte = 0L; iByte < cjScanSrc; iByte++, pjS += cy, pjD++ ) { *pjD = (BYTE)((*pjS >> lShift) | jCarry); // remember the lShift rightmost bits and move them over to the left jCarry = (BYTE)(*pjS << (8 - lShift)); } // see if an extra bit in the destination has to be used to store info if ((LONG)((8 - (cxSrc & 7L)) & 7L) < lShift) *pjD = jCarry; // advance to the next scan pjSrcScan++; pjDstScan += cjScanDst; // decrease shift if switching to the next row (row = 2 scans) lShift -= (iScan & 1); } ASSERTGDI(lShift <= 0L, "vItalicizeBitmap: lShift > 0\n"); } /******************************Public*Routine******************************\ * * vCvtToBoldItalicBmp * * History: * 06-Oct-1992 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ VOID vCvtToBoldItalicBmp ( GLYPHBITS *pgb, GLYPHDATA *pgd, PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format ULONG cxSrc, ULONG cy, ULONG yBaseLine ) { // This is the length in pels for the destination for italicizing // which serves as a source for subsequent emboldening // This length is a length in pels of the "virtual" // italicized source that is to be emboldened. ULONG cxSrcItalic = cxSrc + (cy - 1) / 2; // + slope of italic chars // length in pels of the true emboldened and italicized destination ULONG cxDst = cxSrcItalic + 1; // + 1 for emboldening PBYTE pjSrcScan, pjS; PBYTE pjDstScan, pjD; LONG iScan,iByte; // loop indices // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned) ULONG cjScanDst = CJ_SCAN(cxDst); ULONG cjScanSrc = CJ_SCAN(cxSrc); LONG lShift; // shift used to italicize; BYTE jCarry; // carry from shifting Src byte by lShift; LONG cjEmpty; // number of untouched bytes at the begining of the dest scans BYTE jSrcItalic; BYTE jCarryBold; #ifdef DUMPCALL DbgPrint("\nVOID"); DbgPrint("\nvCvtToBoldItalicDIB("); DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb ); DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd ); DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap ); DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc ); DbgPrint("\n ULONG cy = %-#8lx",cy ); DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine); DbgPrint("\n )\n"); #endif // this is character independent for BM fonts pgb->ptlOrigin.x = 0; pgb->ptlOrigin.y = -(LONG)yBaseLine; pgb->sizlBitmap.cx = cxDst; pgb->sizlBitmap.cy = cy; // init the loop over scans pjSrcScan = pjBitmap; pjDstScan = pgb->aj; // embold and italicize bitmap row by row (row = 2 scans) lShift = ((cy - 1) / 2) & (LONG)7; cjEmpty = ((cy - 1) / 2) >> 3; #ifdef DEBUGBOLDITAL DbgPrint("cy = %ld, yBaseLine = %ld, lShift = %ld, cjEmpty = %ld\n", cy, -pgldtSrc->ptlBmpOrigin.y, lShift, cjEmpty); DbgPrint("cxSrc = %ld, cxDst = %ld, cjScanSrc = %ld, cjScanDst = %ld\n", cxSrc, cxDst, cjScanSrc, cjScanDst); DbgPrint("cy = %ld, cjScanSrc = %ld\n", cy, cjScanSrc); #endif // DEBUGBOLDITAL // if engine requested memory that is zero-ed out we would not have to do it // ourselves RtlZeroMemory(pjDstScan , cjScanDst * cy); for (iScan = 0L; iScan < (LONG)cy; iScan++) { if (lShift < 0L) { lShift = 7L; cjEmpty--; } #ifdef DEBUGBOLDITAL DbgPrint("iScan = %ld, lShift = %ld\n", iScan, lShift); #endif // DEBUGBOLDITAL ASSERTGDI(cjEmpty >= 0L, "cjEmpty\n"); pjS = pjSrcScan; pjD = pjDstScan + cjEmpty; // embolden individual scans jCarry = (BYTE)0; // no carry to the first byte in the row jCarryBold = (BYTE)0; for ( iByte = 0L; iByte < (LONG)cjScanSrc; iByte++, pjS += cy, pjD++ ) { jSrcItalic = (BYTE)((*pjS >> lShift) | jCarry); *pjD = (BYTE)(jSrcItalic | (jSrcItalic >> 1) | jCarryBold); // remember the lShift rightmost bits and move them over to the left jCarry = (BYTE)(*pjS << (8 - lShift)); jCarryBold = (BYTE)(jSrcItalic << 7); } // see if an extra bit in the destination has to be used to store info if ((LONG)((8 - (cxSrc & 7L)) & 7L) < lShift) { jSrcItalic = jCarry; *pjD = (BYTE)(jSrcItalic | (jSrcItalic >> 1) | jCarryBold); jCarryBold = (BYTE)(jSrcItalic << 7); if ((cxSrcItalic & 7L) == 0L) { pjD++; *pjD = jCarryBold; } } // advance to the next scan pjSrcScan++; pjDstScan += cjScanDst; // change the value of the shift if doing the next row lShift -= (iScan & 1); } ASSERTGDI(lShift <= 0L, "vBoldItalicizeBitmap: lShift > 0\n"); }