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

  1. /******************************Module*Header*******************************\
  2. * Module Name: simulate.c
  3. *
  4. * routines associated with simulated faces i.e. emboldened
  5. * and/or italicized faces
  6. *
  7. * Created: 17-Apr-1991 08:31:18
  8. * Author: Bodin Dresevic [BodinD]
  9. *
  10. * Copyright (c) 1990 Microsoft Corporation
  11. *
  12. \**************************************************************************/
  13. #include "fd.h"
  14. #ifdef SAVE_FOR_HISTORICAL_REASONS
  15. /******************************Public*Routine******************************\
  16. *
  17. * VOID vEmboldenBitmap(RASTERGLYPH * pgldtSrc,RASTERGLYPH * pgldtDst,LONG culDst)
  18. *
  19. * modifies an original glyph bitmap for the default face
  20. * to produce the bitmap that corresponds to an emboldened char.
  21. * Emboldened bitmap is simply an original bitmap offsetted to the right
  22. * by one pel and OR-ed with the original bitmap itself.
  23. *
  24. * History:
  25. * 22-Apr-1991 -by- Bodin Dresevic [BodinD]
  26. * Wrote it.
  27. \**************************************************************************/
  28. VOID
  29. vEmboldenBitmap(
  30. RASTERGLYPH * prgSrc,
  31. RASTERGLYPH * prgDst
  32. )
  33. {
  34. ULONG cxSrc = prgSrc->gb.sizlBitmap.cx;
  35. ULONG cy = prgSrc->gb.sizlBitmap.cy; // same for src and dst
  36. ULONG cxDst = cxSrc + 1; // + 1 for emboldening
  37. PBYTE pjSrc = prgSrc->gb.aj;
  38. PBYTE pjDst = prgDst->gb.aj;
  39. ULONG iScan,iByte; // loop indices
  40. PBYTE pjS,pjD;
  41. // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned)
  42. ULONG cjScanDst = CJ_SCAN(cxDst);
  43. ULONG cjScanSrc = CJ_SCAN(cxSrc);
  44. ULONG cjBmp = cjScanDst * cy;
  45. ULONG cjScanDst = CJ_SCAN(cxDst);
  46. ULONG cjScanSrc = CJ_SCAN(cxSrc);
  47. BYTE jCarry; // carry bit from shifting Src byte by 1;
  48. GLYPHDATA *pgldtSrc = &prgSrc->gd;
  49. GLYPHDATA *pgldtDst = &prgDst->gd;
  50. #ifdef DUMPCALL
  51. DbgPrint("\nvEmboldenBitmap(");
  52. DbgPrint("\n RASTERGLYPH *prgSrc = %-#8lx",prgSrc);
  53. DbgPrint("\n RASTERGLYPH *prgDst = %-#8lx",prgDst);
  54. DbgPrint("\n )\n");
  55. #endif
  56. RtlCopyMemory(prgDst,
  57. prgSrc,
  58. offsetof(RASTERGLYPH,gb) + offsetof(GLYPHBITS,sizlBitmap));
  59. // if engine requested memory that is zero-ed out we would not have to do it
  60. // ourselves
  61. RtlZeroMemory(pjDst, cjBmp);
  62. // make necessary changes to the fields of GLYPHDATA which
  63. // are affected by emboldening
  64. pgldtDst->gdf.pgb = &prgDst->gb;
  65. pgldtDst->rclInk.right += (LONG)1;
  66. // pre and post bearings have not changed nor bmp origin, only inked box
  67. pgldtDst->fxD = LTOFX(cxDst);
  68. pgldtDst->ptqD.x.HighPart = (LONG)pgldtDst->fxD;
  69. pgldtDst->fxAB = pgldtDst->fxD; // right edge of the black box
  70. // this needs to be changed a bit since aulBMData will not live
  71. // in the GLYPHDATA structure any more
  72. prgDst->gb.sizlBitmap.cx = cxDst;
  73. prgDst->gb.sizlBitmap.cy = cy;
  74. // embolden bitmap scan by scan
  75. for (iScan = 0L; iScan < cy; iScan++)
  76. {
  77. pjS = pjSrc;
  78. pjD = pjDst;
  79. // embolden individual scans
  80. jCarry = (BYTE)0; // no carry to the first byte in the row
  81. for(iByte = 0L; iByte < cjScanSrc; iByte++, pjS++, pjD++)
  82. {
  83. *pjD = (BYTE)(*pjS | ((*pjS >> 1) | jCarry));
  84. // remember the rightmost bit and shift it to the leftmost position
  85. jCarry = (BYTE)(*pjS << 7);
  86. }
  87. if ((cxSrc & 7L) == 0L)
  88. *pjD = jCarry;
  89. // advance to the next scan of the src and dst
  90. pjSrc += cjScanSrc;
  91. pjDst += cjScanDst;
  92. }
  93. }
  94. #endif // SAVE_FOR_HISTORICAL_REASONS
  95. /******************************Public*Routine******************************\
  96. * cjGlyphDataSimulated
  97. *
  98. * Computes the size of the glyphdata for the simulated face given cx and cy
  99. * for the corresponding char in the default face
  100. *
  101. * History:
  102. * 22-Apr-1991 -by- Bodin Dresevic [BodinD]
  103. * Wrote it.
  104. \**************************************************************************/
  105. #ifdef FE_SB // cjGlyphDataSimulated():
  106. LONG
  107. cjGlyphDataSimulated(
  108. FONTOBJ *pfo,
  109. ULONG cxNoSim, // cx for the same char of the default face
  110. ULONG cyNoSim, // cy for the same char of the default face
  111. ULONG *pcxSim,
  112. ULONG ulRotate // Rotation degree
  113. )
  114. #else
  115. LONG
  116. cjGlyphDataSimulated(
  117. FONTOBJ *pfo,
  118. ULONG cxNoSim, // cx for the same char of the default face
  119. ULONG cyNoSim, // cy for the same char of the default face
  120. ULONG *pcxSim
  121. )
  122. #endif
  123. {
  124. ULONG cxSim;
  125. #ifdef DUMPCALL
  126. DbgPrint("\ncjGlyphDataSimulated(");
  127. DbgPrint("\n ULONG cxNoSim = %-#8lx",cxNoSim);
  128. DbgPrint("\n ULONG cyNoSim = %-#8lx",cyNoSim);
  129. DbgPrint("\n ULONG *pcxSim = %-#8lx",pcxSim );
  130. DbgPrint("\n )\n");
  131. #endif
  132. if (cxNoSim == 0)
  133. {
  134. // blank 1x1 bitmap
  135. cxSim = 1;
  136. cyNoSim = 1;
  137. }
  138. else
  139. {
  140. switch( pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC) )
  141. {
  142. case 0:
  143. cxSim = cxNoSim;
  144. break;
  145. case FO_SIM_BOLD:
  146. cxSim = cxNoSim + 1;
  147. break;
  148. case FO_SIM_ITALIC:
  149. cxSim = cxNoSim + (cyNoSim - 1) / 2;
  150. break;
  151. default:
  152. // here we have used that
  153. // (k - 1) / 2 + 1 == (k + 1) / 2 for every integer k, (k == cy)
  154. cxSim = cxNoSim + (cyNoSim + 1) / 2;
  155. break;
  156. }
  157. }
  158. if (pcxSim != (ULONG *)NULL)
  159. {
  160. *pcxSim = cxSim;
  161. }
  162. #ifdef FE_SB // cjGlyphDataSimulated():
  163. #ifdef DBG_MORE
  164. DbgPrint("cxSim - 0x%x\n : cyNoSim - 0x%x\n",cxSim , cyNoSim);
  165. #endif // DBG_MORE
  166. switch( ulRotate )
  167. {
  168. case 0L :
  169. case 1800L :
  170. return(CJ_GLYPHDATA(cxSim, cyNoSim));
  171. case 900L :
  172. case 2700L :
  173. return(CJ_GLYPHDATA(cyNoSim, cxSim));
  174. default :
  175. /* we should never be here */
  176. return(CJ_GLYPHDATA(cxSim, cyNoSim));
  177. }
  178. #else
  179. return(CJ_GLYPHDATA(cxSim, cyNoSim));
  180. #endif
  181. }
  182. /******************************Public*Routine******************************\
  183. *
  184. * cFacesRes
  185. *
  186. * History:
  187. * 13-May-1991 -by- Bodin Dresevic [BodinD]
  188. * Wrote it.
  189. \**************************************************************************/
  190. ULONG
  191. cFacesRes(
  192. PRES_ELEM pre
  193. )
  194. {
  195. FSHORT fs = fsSelectionFlags((PBYTE)pre->pvResData);
  196. #ifdef DUMPCALL
  197. DbgPrint("\ncFacesRes(");
  198. DbgPrint("\n PRES_ELEM pre = %-#8lx", pre);
  199. DbgPrint("\n )\n");
  200. #endif
  201. // kill all the bits but BOLD and ITALIC
  202. fs = fs & (FSHORT)(FM_SEL_BOLD | FM_SEL_ITALIC);
  203. //!!! DbgPrint("fsSelection = 0x%lx\n", (ULONG)fs);
  204. if (fs == 0) // default face is NORMAL
  205. return(4L);
  206. if ((fs == FM_SEL_BOLD) || (fs == FM_SEL_ITALIC))
  207. return(2L);
  208. if (fs == (FM_SEL_BOLD | FM_SEL_ITALIC))
  209. return(1L);
  210. /* we should never be here */
  211. return (4L);
  212. }
  213. /******************************Public*Routine******************************\
  214. * VOID vDefFace
  215. *
  216. * History:
  217. * 13-May-1991 -by- Bodin Dresevic [BodinD]
  218. * Wrote it.
  219. \**************************************************************************/
  220. VOID
  221. vDefFace(
  222. FACEINFO *pfai,
  223. RES_ELEM *pre
  224. )
  225. {
  226. // kill all bits but BOLD and ITALIC bits that should remain unchanged
  227. FSHORT fs = (FSHORT)(
  228. fsSelectionFlags((PBYTE) pre->pvResData) &
  229. (FM_SEL_BOLD | FM_SEL_ITALIC)
  230. );
  231. switch (fs)
  232. {
  233. case 0:
  234. pfai->iDefFace = FF_FACE_NORMAL;
  235. return;
  236. case FM_SEL_BOLD:
  237. pfai->iDefFace = FF_FACE_BOLD;
  238. return;
  239. case FM_SEL_ITALIC:
  240. pfai->iDefFace = FF_FACE_ITALIC;
  241. return;
  242. case (FM_SEL_ITALIC | FM_SEL_BOLD):
  243. pfai->iDefFace = FF_FACE_BOLDITALIC;
  244. return;
  245. default:
  246. RIP("bmfd!_which ape has messed up the code ?\n");
  247. return;
  248. }
  249. }
  250. #if 0 /* This function is never used, and ignores memory accesses outside the mapped file. */
  251. /******************************Public*Routine******************************\
  252. *
  253. * ULONG cFacesFON // no. of faces associated with this FON file
  254. *
  255. * History:
  256. * January 2002 -by- Jay Krell [JayKrell]
  257. * #if 0'ed out.
  258. * 13-May-1991 -by- Bodin Dresevic [BodinD]
  259. * Wrote it.
  260. \**************************************************************************/
  261. ULONG
  262. cFacesFON(
  263. PWINRESDATA pwrd
  264. )
  265. {
  266. ULONG cFace;
  267. ULONG iRes;
  268. RES_ELEM re;
  269. #ifdef DUMPCALL
  270. DbgPrint("\ncFacesFON(");
  271. DbgPrint("\n PWINRESDATA pwrd = %-#8lx", pwrd);
  272. DbgPrint("\n )\n");
  273. #endif
  274. // this function should have not been called if there are no
  275. // font resources associated with this pwrd
  276. ASSERTGDI(pwrd->cFntRes != 0L, "No font resources\n");
  277. cFace = 0L; // init the sum
  278. for (iRes = 0L; iRes < pwrd->cFntRes; iRes++)
  279. {
  280. if (bGetFntResource(pwrd,iRes,&re))
  281. cFace += cFacesRes(&re);
  282. }
  283. return(cFace);
  284. }
  285. #endif
  286. /******************************Public*Routine******************************\
  287. *
  288. * vComputeSimulatedGLYPHDATA
  289. *
  290. * History:
  291. * 06-Oct-1992 -by- Bodin Dresevic [BodinD]
  292. * Wrote it.
  293. \**************************************************************************/
  294. VOID
  295. vComputeSimulatedGLYPHDATA(
  296. GLYPHDATA *pgldt ,
  297. PBYTE pjBitmap ,
  298. ULONG cxNoSim ,
  299. ULONG cy ,
  300. ULONG yBaseLine,
  301. ULONG cxScale,
  302. ULONG cyScale,
  303. FONTOBJ *pfo
  304. )
  305. {
  306. ULONG cxSim; // cx for the bitmap
  307. LONG xCharInc; // x component of the char inc vector
  308. // the following coords refer to bitmap coord system, i.e. the one in which
  309. // the BM origin has coors (0,0)
  310. ULONG yTopIncMin; // min over non zero raws
  311. ULONG yBottomExcMax; // max+1 over non zero raws
  312. #ifdef DUMPCALL
  313. DbgPrint("\nvComputeSimulatedGLYPHDATA(");
  314. DbgPrint("\n GLYPHDATA *pgldt = %-#8lx",pgldt );
  315. DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap );
  316. DbgPrint("\n ULONG cxNoSim = %-#8lx",cxNoSim );
  317. DbgPrint("\n ULONG cy = %-#8lx",cy );
  318. DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine );
  319. DbgPrint("\n FONTOBJ *pfo = %-#8lx",pfo );
  320. DbgPrint("\n )\n");
  321. #endif
  322. // compute top and bottom by looking into the bitmap in the row format:
  323. vFindTAndB (
  324. pjBitmap, // pointer to the bitmap in *.fnt column format
  325. cxNoSim,
  326. cy,
  327. &yTopIncMin,
  328. &yBottomExcMax
  329. );
  330. if( cyScale != 1 )
  331. {
  332. yTopIncMin *= cyScale;
  333. yBottomExcMax *= cyScale;
  334. cy *= cyScale;
  335. yBaseLine *= cyScale;
  336. }
  337. cxNoSim *= cxScale;
  338. pgldt->gdf.pgb = NULL;
  339. if (yTopIncMin == yBottomExcMax) // no ink at all
  340. {
  341. // this is a tricky point. We are dealing with a blank bitmap.
  342. // The first thought would be to report the zero inked box. It
  343. // then ambiguous what an A and C spaces should be. The right way to
  344. // think of this bitmap (this is in fact the break char) is that the
  345. // inked box is the whole bitmap, just the "color" of the ink happens
  346. // to be invisible. This is important when dealing with strings
  347. // which have break character as the first or the last char in the string.
  348. // If the inked box was reported as zero, text extent for such a string
  349. // would be computed incorrectly when the corrections for the first A
  350. // and last C are taken into account
  351. yTopIncMin = 0L; // coincides with the top
  352. yBottomExcMax = cy * cyScale; // coincides with the bottom
  353. }
  354. // these have to be correct, important for computing char inc for esc != 0
  355. pgldt->rclInk.top = (LONG)(yTopIncMin - yBaseLine);
  356. pgldt->rclInk.bottom = (LONG)(yBottomExcMax - yBaseLine);
  357. // minus sign is because the scalar product is supposed to be taken with
  358. // a unit ascender vector
  359. pgldt->fxInkTop = -LTOFX(pgldt->rclInk.top);
  360. pgldt->fxInkBottom = -LTOFX(pgldt->rclInk.bottom);
  361. switch(pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC))
  362. {
  363. case 0:
  364. cxSim = cxNoSim;
  365. xCharInc = (LONG)cxNoSim;
  366. break;
  367. case FO_SIM_BOLD:
  368. cxSim = cxNoSim + 1;
  369. xCharInc = (LONG)(cxNoSim + 1);
  370. break;
  371. case FO_SIM_ITALIC:
  372. cxSim = cxNoSim + (cy - 1) / 2;
  373. xCharInc = (LONG)cxNoSim;
  374. break;
  375. case (FO_SIM_BOLD | FO_SIM_ITALIC):
  376. // here we have used that
  377. // (k - 1) / 2 + 1 == (k + 1) / 2 for every integer k, (k == cy)
  378. cxSim = cxNoSim + (cy + 1) / 2;
  379. xCharInc = (LONG)(cxNoSim + 1);
  380. break;
  381. default:
  382. // to silence prefix
  383. cxSim = 1;
  384. RIP("BMFD!BAD SIM FLAG\n");
  385. }
  386. if (cxNoSim == 0)
  387. {
  388. cxSim = 1; // 1X1 blank box
  389. xCharInc = 0;
  390. }
  391. pgldt->fxD = LTOFX(xCharInc);
  392. pgldt->ptqD.x.HighPart = (LONG)pgldt->fxD;
  393. pgldt->ptqD.x.LowPart = 0;
  394. pgldt->ptqD.y.HighPart = 0;
  395. pgldt->ptqD.y.LowPart = 0;
  396. // in this crude picture we are luying about x extents of the black box
  397. // and report the whole bitmap width as an extent
  398. pgldt->rclInk.left = 0; // rclInk.left == lhs of the bitmap, => A < 0
  399. pgldt->rclInk.right = (LONG)cxSim; // the rhs of the bitmap => c < 0
  400. // compute bearings, remember the rule A + B + C == char inc
  401. // where B is the size of the inked box. For the horizontal case:
  402. // A == ePreBearing , C == ePostBearing
  403. // In view of these sum rules and the definitions of A,B,C we have
  404. // B = rclInk.right - rclInk.left;
  405. // A = rclInk.left;
  406. // C = xCharInc - rclInk.right;
  407. // The sum rule is trivially obeyed.
  408. pgldt->fxA = LTOFX(pgldt->rclInk.left); // fxA
  409. pgldt->fxAB = LTOFX(pgldt->rclInk.right); // right edge of the black box
  410. }
  411. /******************************Public*Routine******************************\
  412. *
  413. * VOID vCvtToBmp
  414. *
  415. * Effects: takes the bitmap in the original *.fnt column format and converts
  416. * it to the Bmp format.
  417. *
  418. * History:
  419. * 25-Nov-1990 -by- Bodin Dresevic [BodinD]
  420. * Wrote it.
  421. \**************************************************************************/
  422. VOID vCvtToBmp
  423. (
  424. GLYPHBITS *pgb,
  425. GLYPHDATA *pgd,
  426. PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format
  427. ULONG cx,
  428. ULONG cy,
  429. ULONG yBaseLine
  430. )
  431. {
  432. ULONG cjScan = CJ_SCAN(cx); // # of bytes per scan of the Bmp
  433. // pjColumn points to one of the bytes in the first ROW of the Bmp
  434. PBYTE pjColumn, pjColumnEnd;
  435. PBYTE pjDst, pjDstEnd; // current destination byte
  436. #ifdef DUMPCALL
  437. DbgPrint("\nvCvtToDIB(");
  438. DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb );
  439. DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd );
  440. DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap );
  441. DbgPrint("\n ULONG cx = %-#8lx",cx );
  442. DbgPrint("\n ULONG cy = %-#8lx",cy );
  443. DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine);
  444. DbgPrint("\n )\n");
  445. #endif
  446. // store cx and cy at the top, before Bits
  447. pgb->sizlBitmap.cx = cx;
  448. pgb->sizlBitmap.cy = cy;
  449. // this is character independent for BM fonts
  450. pgb->ptlOrigin.x = 0L;
  451. pgb->ptlOrigin.y = -(LONG)yBaseLine;
  452. RtlZeroMemory(pgb->aj, cjScan * cy);
  453. // we shall fill the Bmp column by column, thus traversing the src a byte at
  454. // the time:
  455. for
  456. (
  457. pjColumn = pgb->aj, pjColumnEnd = pjColumn + cjScan;
  458. pjColumn < pjColumnEnd;
  459. pjColumn++
  460. )
  461. {
  462. for
  463. (
  464. pjDst = pjColumn, pjDstEnd = pjColumn + cy * cjScan;
  465. pjDst < pjDstEnd;
  466. pjDst += cjScan, pjBitmap++
  467. )
  468. {
  469. *pjDst = *pjBitmap;
  470. }
  471. }
  472. }
  473. /******************************Public*Routine******************************\
  474. *
  475. * vCvtToBoldBmp
  476. *
  477. * History:
  478. * 06-Oct-1992 -by- Bodin Dresevic [BodinD]
  479. * Wrote it.
  480. \**************************************************************************/
  481. VOID vCvtToBoldBmp
  482. (
  483. GLYPHBITS *pgb,
  484. GLYPHDATA *pgd,
  485. PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format
  486. ULONG cxSrc,
  487. ULONG cy,
  488. ULONG yBaseLine
  489. )
  490. {
  491. PBYTE pjSrc;
  492. PBYTE pjDst;
  493. ULONG cxDst = cxSrc + 1; // + 1 for emboldening
  494. ULONG iScan,iByte; // loop indices
  495. PBYTE pjS,pjD;
  496. // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned)
  497. ULONG cjScanDst = CJ_SCAN(cxDst);
  498. ULONG cjScanSrc = CJ_SCAN(cxSrc);
  499. BYTE jCarry; // carry bit from shifting Src byte by 1;
  500. #ifdef DUMPCALL
  501. DbgPrint("\nVOID");
  502. DbgPrint("\nvCvtToBoldDIB(");
  503. DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb );
  504. DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd );
  505. DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap );
  506. DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc );
  507. DbgPrint("\n ULONG cy = %-#8lx",cy );
  508. DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine);
  509. DbgPrint("\n )\n");
  510. #endif
  511. // this is character independent for BM fonts
  512. pgb->ptlOrigin.x = 0L;
  513. pgb->ptlOrigin.y = -(LONG)yBaseLine;
  514. pgb->sizlBitmap.cx = cxDst;
  515. pgb->sizlBitmap.cy = cy;
  516. // init the loop over scans
  517. pjSrc = pjBitmap;
  518. pjDst = pgb->aj;
  519. // embolden bitmap scan by scan
  520. // if engine requested memory that is zero-ed out we would not have to do it
  521. // ourselves
  522. RtlZeroMemory(pjDst, cjScanDst * cy);
  523. for (iScan = 0L; iScan < cy; iScan++)
  524. {
  525. pjS = pjSrc;
  526. pjD = pjDst;
  527. // embolden individual scans
  528. jCarry = (BYTE)0; // no carry to the first byte in the row
  529. for
  530. (
  531. iByte = 0L;
  532. iByte < cjScanSrc;
  533. iByte++, pjS += cy, pjD++
  534. )
  535. {
  536. *pjD = (BYTE)(*pjS | ((*pjS >> 1) | jCarry));
  537. // remember the rightmost bit and shift it to the leftmost position
  538. jCarry = (BYTE)(*pjS << 7);
  539. }
  540. if ((cxSrc & 7L) == 0L)
  541. *pjD = jCarry;
  542. // advance to the next scan of the src and dst
  543. pjSrc++;
  544. pjDst += cjScanDst;
  545. }
  546. }
  547. /******************************Public*Routine******************************\
  548. *
  549. * vCvtToItalicBmp
  550. *
  551. * History:
  552. * 06-Oct-1992 -by- Bodin Dresevic [BodinD]
  553. * Wrote it.
  554. \**************************************************************************/
  555. VOID vCvtToItalicBmp
  556. (
  557. GLYPHBITS *pgb,
  558. GLYPHDATA *pgd,
  559. PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format
  560. ULONG cxSrc,
  561. ULONG cy,
  562. ULONG yBaseLine
  563. )
  564. {
  565. ULONG cxDst = cxSrc + (ULONG)(cy - 1) / 2; // add correction for the
  566. PBYTE pjSrcScan, pjS;
  567. PBYTE pjDstScan, pjD;
  568. LONG iScan,iByte; // loop indices
  569. // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned)
  570. ULONG cjScanDst = CJ_SCAN(cxDst);
  571. LONG cjScanSrc = (LONG)CJ_SCAN(cxSrc);
  572. LONG lShift;
  573. BYTE jCarry; // carry from shifting Src byte by lShift;
  574. LONG cjEmpty; // number of untouched bytes at the begining of the dest scans
  575. #ifdef DUMPCALL
  576. DbgPrint("\nVOID");
  577. DbgPrint("\nvCvtToItalicDIB(");
  578. DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb );
  579. DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd );
  580. DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap );
  581. DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc );
  582. DbgPrint("\n ULONG cy = %-#8lx",cy );
  583. DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine);
  584. DbgPrint("\n )\n");
  585. #endif
  586. // this is character independent for BM fonts
  587. pgb->ptlOrigin.x = 0;
  588. pgb->ptlOrigin.y = -(LONG)yBaseLine;
  589. pgb->sizlBitmap.cx = cxDst;
  590. pgb->sizlBitmap.cy = cy;
  591. // init the loop over scans
  592. pjSrcScan = pjBitmap;
  593. pjDstScan = pgb->aj;
  594. // italicize bitmap row by row
  595. lShift = ((cy - 1) / 2) & (LONG)7;
  596. cjEmpty = ((cy - 1) / 2) >> 3;
  597. #ifdef DEBUGITAL
  598. DbgPrint("cy = %ld, yBaseLine = %ld, lShift = %ld, cjEmpty = %ld\n",
  599. cy, -pgldtSrc->ptlBmpOrigin.y, lShift, cjEmpty);
  600. DbgPrint("cxSrc = %ld, cxDst = %ld, cjScanSrc = %ld, cjScanDst = %ld\n",
  601. cxSrc, cxDst, cjScanSrc, cjScanDst);
  602. DbgPrint("cy = %ld, cjScanSrc = %ld, \n",
  603. cy, cjScanSrc);
  604. #endif // DEBUGITAL
  605. // if engine requested memory that is zero-ed out we would not have to do it
  606. // ourselves
  607. RtlZeroMemory(pjDstScan , cjScanDst * cy);
  608. for (iScan = 0L; iScan < (LONG)cy; iScan++)
  609. {
  610. if (lShift < 0L)
  611. {
  612. lShift = 7L;
  613. cjEmpty--;
  614. }
  615. ASSERTGDI(cjEmpty >= 0L, "cjEmpty\n");
  616. #ifdef DEBUGITALIC
  617. DbgPrint("iScan = %ld, lShift = %ld\n", iScan, lShift);
  618. #endif // DEBUGITALIC
  619. pjS = pjSrcScan;
  620. pjD = pjDstScan + cjEmpty;
  621. // italicize individual scans
  622. jCarry = (BYTE)0; // no carry to the first byte in the row
  623. for
  624. (
  625. iByte = 0L;
  626. iByte < cjScanSrc;
  627. iByte++, pjS += cy, pjD++
  628. )
  629. {
  630. *pjD = (BYTE)((*pjS >> lShift) | jCarry);
  631. // remember the lShift rightmost bits and move them over to the left
  632. jCarry = (BYTE)(*pjS << (8 - lShift));
  633. }
  634. // see if an extra bit in the destination has to be used to store info
  635. if ((LONG)((8 - (cxSrc & 7L)) & 7L) < lShift)
  636. *pjD = jCarry;
  637. // advance to the next scan
  638. pjSrcScan++;
  639. pjDstScan += cjScanDst;
  640. // decrease shift if switching to the next row (row = 2 scans)
  641. lShift -= (iScan & 1);
  642. }
  643. ASSERTGDI(lShift <= 0L, "vItalicizeBitmap: lShift > 0\n");
  644. }
  645. /******************************Public*Routine******************************\
  646. *
  647. * vCvtToBoldItalicBmp
  648. *
  649. * History:
  650. * 06-Oct-1992 -by- Bodin Dresevic [BodinD]
  651. * Wrote it.
  652. \**************************************************************************/
  653. VOID vCvtToBoldItalicBmp
  654. (
  655. GLYPHBITS *pgb,
  656. GLYPHDATA *pgd,
  657. PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format
  658. ULONG cxSrc,
  659. ULONG cy,
  660. ULONG yBaseLine
  661. )
  662. {
  663. // This is the length in pels for the destination for italicizing
  664. // which serves as a source for subsequent emboldening
  665. // This length is a length in pels of the "virtual"
  666. // italicized source that is to be emboldened.
  667. ULONG cxSrcItalic = cxSrc + (cy - 1) / 2; // + slope of italic chars
  668. // length in pels of the true emboldened and italicized destination
  669. ULONG cxDst = cxSrcItalic + 1; // + 1 for emboldening
  670. PBYTE pjSrcScan, pjS;
  671. PBYTE pjDstScan, pjD;
  672. LONG iScan,iByte; // loop indices
  673. // number of bytes in one scan of the Dst or Src bitmaps. (dword aligned)
  674. ULONG cjScanDst = CJ_SCAN(cxDst);
  675. ULONG cjScanSrc = CJ_SCAN(cxSrc);
  676. LONG lShift; // shift used to italicize;
  677. BYTE jCarry; // carry from shifting Src byte by lShift;
  678. LONG cjEmpty; // number of untouched bytes at the begining of the dest scans
  679. BYTE jSrcItalic;
  680. BYTE jCarryBold;
  681. #ifdef DUMPCALL
  682. DbgPrint("\nVOID");
  683. DbgPrint("\nvCvtToBoldItalicDIB(");
  684. DbgPrint("\n GLYPHBITS pgb = %-#8lx",pgb );
  685. DbgPrint("\n GLYPHDATA pgd = %-#8lx",pgd );
  686. DbgPrint("\n PBYTE pjBitmap = %-#8lx",pjBitmap );
  687. DbgPrint("\n ULONG cxSrc = %-#8lx",cxSrc );
  688. DbgPrint("\n ULONG cy = %-#8lx",cy );
  689. DbgPrint("\n ULONG yBaseLine = %-#8lx",yBaseLine);
  690. DbgPrint("\n )\n");
  691. #endif
  692. // this is character independent for BM fonts
  693. pgb->ptlOrigin.x = 0;
  694. pgb->ptlOrigin.y = -(LONG)yBaseLine;
  695. pgb->sizlBitmap.cx = cxDst;
  696. pgb->sizlBitmap.cy = cy;
  697. // init the loop over scans
  698. pjSrcScan = pjBitmap;
  699. pjDstScan = pgb->aj;
  700. // embold and italicize bitmap row by row (row = 2 scans)
  701. lShift = ((cy - 1) / 2) & (LONG)7;
  702. cjEmpty = ((cy - 1) / 2) >> 3;
  703. #ifdef DEBUGBOLDITAL
  704. DbgPrint("cy = %ld, yBaseLine = %ld, lShift = %ld, cjEmpty = %ld\n",
  705. cy, -pgldtSrc->ptlBmpOrigin.y, lShift, cjEmpty);
  706. DbgPrint("cxSrc = %ld, cxDst = %ld, cjScanSrc = %ld, cjScanDst = %ld\n",
  707. cxSrc, cxDst, cjScanSrc, cjScanDst);
  708. DbgPrint("cy = %ld, cjScanSrc = %ld\n",
  709. cy, cjScanSrc);
  710. #endif // DEBUGBOLDITAL
  711. // if engine requested memory that is zero-ed out we would not have to do it
  712. // ourselves
  713. RtlZeroMemory(pjDstScan , cjScanDst * cy);
  714. for (iScan = 0L; iScan < (LONG)cy; iScan++)
  715. {
  716. if (lShift < 0L)
  717. {
  718. lShift = 7L;
  719. cjEmpty--;
  720. }
  721. #ifdef DEBUGBOLDITAL
  722. DbgPrint("iScan = %ld, lShift = %ld\n", iScan, lShift);
  723. #endif // DEBUGBOLDITAL
  724. ASSERTGDI(cjEmpty >= 0L, "cjEmpty\n");
  725. pjS = pjSrcScan;
  726. pjD = pjDstScan + cjEmpty;
  727. // embolden individual scans
  728. jCarry = (BYTE)0; // no carry to the first byte in the row
  729. jCarryBold = (BYTE)0;
  730. for
  731. (
  732. iByte = 0L;
  733. iByte < (LONG)cjScanSrc;
  734. iByte++, pjS += cy, pjD++
  735. )
  736. {
  737. jSrcItalic = (BYTE)((*pjS >> lShift) | jCarry);
  738. *pjD = (BYTE)(jSrcItalic | (jSrcItalic >> 1) | jCarryBold);
  739. // remember the lShift rightmost bits and move them over to the left
  740. jCarry = (BYTE)(*pjS << (8 - lShift));
  741. jCarryBold = (BYTE)(jSrcItalic << 7);
  742. }
  743. // see if an extra bit in the destination has to be used to store info
  744. if ((LONG)((8 - (cxSrc & 7L)) & 7L) < lShift)
  745. {
  746. jSrcItalic = jCarry;
  747. *pjD = (BYTE)(jSrcItalic | (jSrcItalic >> 1) | jCarryBold);
  748. jCarryBold = (BYTE)(jSrcItalic << 7);
  749. if ((cxSrcItalic & 7L) == 0L)
  750. {
  751. pjD++;
  752. *pjD = jCarryBold;
  753. }
  754. }
  755. // advance to the next scan
  756. pjSrcScan++;
  757. pjDstScan += cjScanDst;
  758. // change the value of the shift if doing the next row
  759. lShift -= (iScan & 1);
  760. }
  761. ASSERTGDI(lShift <= 0L, "vBoldItalicizeBitmap: lShift > 0\n");
  762. }