Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

983 lines
26 KiB

/******************************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");
}