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.

1645 lines
48 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdquery.c
  3. *
  4. * (Brief description)
  5. *
  6. * Created: 08-Nov-1990 11:57:35
  7. * Author: Bodin Dresevic [BodinD]
  8. *
  9. * Copyright (c) 1990 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "fd.h"
  12. ULONG
  13. cjBmfdDeviceMetrics (
  14. PFONTCONTEXT pfc,
  15. FD_DEVICEMETRICS *pdevm
  16. );
  17. VOID
  18. vStretchCvtToBitmap
  19. (
  20. GLYPHBITS *pgb,
  21. PBYTE pjBitmap, // bitmap in *.fnt form
  22. ULONG cx, // unscaled width
  23. ULONG cy, // unscaled height
  24. ULONG yBaseline,
  25. PBYTE pjLineBuffer, // preallocated buffer for use by stretch routines
  26. ULONG cxScale, // horizontal scaling factor
  27. ULONG cyScale, // vertical scaling factor
  28. ULONG flSim // simulation flags
  29. );
  30. #ifdef FE_SB // Rotation
  31. VOID
  32. vFill_RotateGLYPHDATA (
  33. GLYPHDATA *pDistinationGlyphData,
  34. PVOID SourceGLYPHBITS,
  35. PVOID DistinationGLYPHBITS,
  36. UINT RotateDegree
  37. );
  38. #endif
  39. /******************************Public*Routine******************************\
  40. * BmfdQueryFont
  41. *
  42. * Returns:
  43. * Pointer to IFIMETRICS. Returns NULL if an error occurs.
  44. *
  45. * History:
  46. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  47. * IFI/DDI merge.
  48. *
  49. * 19-Nov-1990 -by- Bodin Dresevic [BodinD]
  50. * Wrote it.
  51. \**************************************************************************/
  52. PIFIMETRICS
  53. BmfdQueryFont (
  54. DHPDEV dhpdev,
  55. HFF hff,
  56. ULONG iFace,
  57. ULONG_PTR *pid
  58. )
  59. {
  60. FACEINFO *pfai;
  61. DONTUSE(dhpdev);
  62. DONTUSE(pid);
  63. //
  64. // Validate handle.
  65. //
  66. if (hff == HFF_INVALID)
  67. return (PIFIMETRICS) NULL;
  68. //
  69. // We assume the iFace is within range.
  70. //
  71. ASSERTGDI(
  72. (iFace >= 1L) && (iFace <= PFF(hff)->cFntRes),
  73. "gdisrv!BmfdQueryFont: iFace out of range\n"
  74. );
  75. //
  76. // Get ptr to the appropriate FACEDATA struct, take into account that
  77. // iFace values are 1 based.
  78. //
  79. pfai = &PFF(hff)->afai[iFace - 1];
  80. //
  81. // Return the pointer to IFIMETRICS.
  82. //
  83. return pfai->pifi;
  84. }
  85. /******************************Public*Routine******************************\
  86. * BmfdQueryFontTree
  87. *
  88. * This function returns pointers to per-face information.
  89. *
  90. * Parameters:
  91. *
  92. * dhpdev Not used.
  93. *
  94. * hff Handle to a font file.
  95. *
  96. * iFace Index of a face in the font file.
  97. *
  98. * iMode This is a 32-bit number that must be one of the following
  99. * values:
  100. *
  101. * Allowed ulMode values:
  102. * ----------------------
  103. *
  104. * QFT_LIGATURES -- returns a pointer to the ligature map.
  105. *
  106. * QFT_KERNPAIRS -- return a pointer to the kerning pair table.
  107. *
  108. * QFT_GLYPHSET -- return a pointer to the WC->HGLYPH mapping table.
  109. *
  110. * pid Not used.
  111. *
  112. * Returns:
  113. a Returns a pointer to the requested data. This data will not change
  114. * until BmfdFree is called on the pointer. Caller must not attempt to
  115. * modify the data. NULL is returned if an error occurs.
  116. *
  117. * History:
  118. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  119. * Wrote it.
  120. \**************************************************************************/
  121. PVOID
  122. BmfdQueryFontTree (
  123. DHPDEV dhpdev,
  124. HFF hff,
  125. ULONG iFace,
  126. ULONG iMode,
  127. ULONG_PTR *pid
  128. )
  129. {
  130. FACEINFO *pfai;
  131. DONTUSE(dhpdev);
  132. DONTUSE(pid);
  133. //
  134. // Validate parameters.
  135. //
  136. if (hff == HFF_INVALID)
  137. return ((PVOID) NULL);
  138. // Note: iFace values are index-1 based.
  139. if ((iFace < 1L) || (iFace > PFF(hff)->cFntRes))
  140. {
  141. RETURN("gdisrv!BmfdQueryFontTree()\n", (PVOID) NULL);
  142. }
  143. //
  144. // Which mode?
  145. //
  146. switch (iMode)
  147. {
  148. case QFT_LIGATURES:
  149. case QFT_KERNPAIRS:
  150. //
  151. // There are no ligatures or kerning pairs for the bitmap fonts,
  152. // therefore we return NULL
  153. //
  154. return ((PVOID) NULL);
  155. case QFT_GLYPHSET:
  156. //
  157. // Find glyphset structure corresponding to this iFace:
  158. //
  159. pfai = &PFF(hff)->afai[iFace - 1];
  160. return ((PVOID) &pfai->pcp->gset);
  161. default:
  162. //
  163. // Should never get here.
  164. //
  165. RIP("gdisrv!BmfdQueryFontTree(): unknown iMode\n");
  166. return ((PVOID) NULL);
  167. }
  168. }
  169. /******************************Public*Routine******************************\
  170. *
  171. * BOOL bReconnectBmfdFont(FONTFILE *pff)
  172. *
  173. *
  174. * Effects: If the file is marked gone, we try to reconnect and see if we can
  175. * use it again. We clear the exception bit so that the system will
  176. * be able to use this font again.
  177. *
  178. * History:
  179. * 17-Aug-1994 -by- Bodin Dresevic [BodinD]
  180. * Wrote it.
  181. \**************************************************************************/
  182. BOOL bReconnectBmfdFont(FONTFILE *pff)
  183. {
  184. INT i;
  185. PVOID pvView;
  186. COUNT cjView;
  187. EngAcquireSemaphore(ghsemBMFD);
  188. if (pff->fl & FF_EXCEPTION_IN_PAGE_ERROR)
  189. {
  190. if (!EngMapFontFileFD(pff->iFile, (PULONG*) &pvView, &cjView))
  191. {
  192. WARNING("BMFD! can not reconnect this bm font file!!!\n");
  193. EngReleaseSemaphore(ghsemBMFD);
  194. return FALSE;
  195. }
  196. for (i = 0; i < (INT)pff->cFntRes; i++)
  197. {
  198. pff->afai[i].re.pvResData = (PVOID) (
  199. (BYTE*)pvView + pff->afai[i].re.dpResData
  200. );
  201. }
  202. // everything is fine again, clear the bit
  203. pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
  204. }
  205. EngReleaseSemaphore(ghsemBMFD);
  206. return TRUE;
  207. }
  208. /******************************Public*Routine******************************\
  209. *
  210. * Routine Name:
  211. *
  212. * vBmfdScrubGLYPHBITS
  213. *
  214. * Routine Description:
  215. *
  216. * This procedure will mask off the last byte of each row so that there
  217. * are no pixels set outside the boundary of the glyph. This problem
  218. * has been detected in a Bitstream font named ncd0018.fon.
  219. * This particular font is in the form of a 32-bit resource.
  220. * The problem came to light because the ATI driver relies
  221. * on the fact that the glyphs are "scrubbed" and contain no
  222. * extraneous bits, even outside the glyph boundary.
  223. *
  224. * Arguments:
  225. *
  226. * pGb - a pointer to a GLYPHBITS structure
  227. *
  228. * Called by:
  229. *
  230. * BmfdQueryFontData
  231. *
  232. * Return Value:
  233. *
  234. * None.
  235. *
  236. \**************************************************************************/
  237. void vBmfdScrubGLYPHBITS(GLYPHBITS *pGb)
  238. {
  239. int dp; // number of bytes in each scan
  240. int cx; // number of pixels per row
  241. BYTE jMask; // mask for last byte of each row;
  242. BYTE *pj; // pointer to last byte of row;
  243. BYTE *pjLast; // sentinel pointer
  244. static BYTE ajMonoMask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
  245. cx = pGb->sizlBitmap.cx;
  246. if ( jMask = ajMonoMask[cx & 7] )
  247. {
  248. dp = (cx + 7) / 8;
  249. pj = pGb->aj + dp - 1;
  250. pjLast = pj + dp * pGb->sizlBitmap.cy;
  251. for ( ; pj < pjLast; pj += dp )
  252. {
  253. *pj &= jMask;
  254. }
  255. }
  256. }
  257. /******************************Public*Routine******************************\
  258. * BmfdQueryFontData
  259. *
  260. * pfo Pointer to a FONTOBJ.
  261. *
  262. * iMode This is a 32-bit number that must be one of the following
  263. * values:
  264. *
  265. * Allowed ulMode values:
  266. * ----------------------
  267. *
  268. * QFD_GLYPH -- return glyph metrics only
  269. *
  270. * QFD_GLYPHANDBITMAP -- return glyph metrics and bitmap
  271. *
  272. * QFD_GLYPHANDOUTLINE -- return glyph metrics and outline
  273. *
  274. * QFD_MAXEXTENTS -- return FD_DEVICEMETRICS structure
  275. *
  276. * QFD_MAXGLYPHBITMAP -- return size of largest glyph AND its metrics
  277. *
  278. * cData Count of data items in the pvIn buffer.
  279. *
  280. * pvIn An array of glyph handles.
  281. *
  282. * pvOut Output buffer.
  283. *
  284. * Returns:
  285. * If mode is QFD_MAXGLYPHBITMAP, then size of glyph metrics plus
  286. * largest bitmap is returned.
  287. *
  288. * Otherwise, if pvOut is NULL, function will return size of the buffer
  289. * needed to copy the data requested; else, the function will return the
  290. * number of bytes written.
  291. *
  292. * FD_ERROR is returned if an error occurs.
  293. *
  294. * History:
  295. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  296. * Wrote it. Contructed from pieces of BodinD's original
  297. * BmfdQueryGlyphBitmap() and BmfdQueryOutline() functions.
  298. \**************************************************************************/
  299. LONG
  300. BmfdQueryFontData (
  301. FONTOBJ *pfo,
  302. ULONG iMode,
  303. HGLYPH hg,
  304. GLYPHDATA *pgd,
  305. PVOID pv,
  306. ULONG cjSize
  307. )
  308. {
  309. PFONTCONTEXT pfc;
  310. LONG cjGlyphData = 0;
  311. LONG cjAllData = 0;
  312. PCVTFILEHDR pcvtfh;
  313. PBYTE pjBitmap; // raw bitmap in the resource file
  314. ULONG cxNoSim; // bm width in pels before simulations
  315. FWORD sAscent;
  316. #ifdef FE_SB // BmfdQueryFontData()
  317. PVOID pvDst = NULL;
  318. LONG cjGlyphDataNoRotate;
  319. #endif // FE_SB
  320. // The net connection died on us, but maybe it is alive again:
  321. if (!bReconnectBmfdFont(PFF(pfo->iFile)))
  322. {
  323. WARNING("bmfd!bmfdQueryFontData: this file is gone\n");
  324. return FD_ERROR;
  325. }
  326. // If pfo->pvProducer is NULL, then we need to open a font context.
  327. //
  328. if ( pfo->pvProducer == (PVOID) NULL )
  329. pfo->pvProducer = (PVOID) BmfdOpenFontContext(pfo);
  330. pfc = PFC(pfo->pvProducer);
  331. if ( pfc == (PFONTCONTEXT) NULL )
  332. {
  333. WARNING("gdisrv!bmfdQueryFontData(): cannot create font context\n");
  334. return FD_ERROR;
  335. }
  336. // What mode?
  337. switch (iMode)
  338. {
  339. case QFD_GLYPHANDBITMAP:
  340. //
  341. // This code is left all inline for better performance.
  342. //
  343. pcvtfh = &(pfc->pfai->cvtfh);
  344. sAscent = pfc->pfai->pifi->fwdWinAscender;
  345. pjBitmap = pjRawBitmap(hg, pcvtfh, &pfc->pfai->re, &cxNoSim);
  346. #ifdef FE_SB // BmfdQueryFontDate(): Compute size of RASTERGLYPH for ROTATION
  347. //
  348. // Compute the size of the RASTERGLYPH. ( GLYPHBITS structure size )
  349. //
  350. // Compute No Rotated GLYPHBITS size.
  351. cjGlyphDataNoRotate = cjGlyphDataSimulated (
  352. pfo,
  353. cxNoSim * pfc->ptlScale.x,
  354. pcvtfh->cy * pfc->ptlScale.y,
  355. (PULONG) NULL,
  356. 0L
  357. );
  358. // Compute Rotated GLYPHBITS size.
  359. switch( pfc->ulRotate )
  360. {
  361. case 0L :
  362. case 1800L :
  363. cjGlyphData = cjGlyphDataNoRotate;
  364. break;
  365. case 900L :
  366. case 2700L :
  367. cjGlyphData = cjGlyphDataSimulated (
  368. pfo,
  369. cxNoSim * pfc->ptlScale.x,
  370. pcvtfh->cy * pfc->ptlScale.y,
  371. (PULONG) NULL,
  372. pfc->ulRotate
  373. );
  374. break;
  375. }
  376. //
  377. // Allocate Buffer for Rotation
  378. //
  379. if( pfc->ulRotate != 0L && pv != NULL )
  380. {
  381. // We have to rotate this bitmap. below here , we keep data in temp Buffer
  382. // And will write this data into pv ,when rotate bitmap.
  383. // We can't use original pv directly. Because original pv size is computed
  384. // for Rotated bitmap. If we use this. it may causes access violation.
  385. // hideyukn 08-Feb-1993
  386. // Keep Master pv
  387. pvDst = pv;
  388. // Allocate New pv
  389. pv = (PVOID)EngAllocMem(0, cjGlyphDataNoRotate, 'dfmB');
  390. if( pv == NULL )
  391. {
  392. WARNING("BMFD:LocalAlloc for No Rotated bitmap is fail\n");
  393. return( FD_ERROR );
  394. }
  395. }
  396. else
  397. {
  398. // This Routine is for at ulRotate != 0 && pv == NULL
  399. //
  400. // If User want to only GLYPHDATA , We do not do anything for glyphbits
  401. // at vFill_RotateGLYPHDATA
  402. //
  403. // pvDst is only used in case of ulRotate is Non-Zero
  404. ;
  405. }
  406. #else
  407. //
  408. // Compute the size of the RASTERGLYPH.
  409. //
  410. cjGlyphData = cjGlyphDataSimulated (
  411. pfo,
  412. cxNoSim * pfc->ptlScale.x,
  413. pcvtfh->cy * pfc->ptlScale.y,
  414. (PULONG) NULL
  415. );
  416. #endif
  417. #ifdef FE_SB
  418. // !!!
  419. // !!! Following vComputeSimulatedGLYPHDATA function will set up GLYPHDATA
  420. // !!! structure with NO Rotation. If We want to Rotate bitmap , We have to
  421. // !!! re-setup this GLYPHDATA structure. Pls look into end of this function.
  422. // !!! But No need to ratate bitmap , We don't need to re-set up it.
  423. // !!! hideyukn 08-Feb-1993
  424. // !!!
  425. #endif // FE_SB
  426. //
  427. // Fill in the GLYPHDATA portion (metrics) of the RASTERGLYPH.
  428. //
  429. if ( pgd != (GLYPHDATA *)NULL )
  430. {
  431. vComputeSimulatedGLYPHDATA (
  432. pgd,
  433. pjBitmap,
  434. cxNoSim,
  435. pcvtfh->cy,
  436. (ULONG)sAscent,
  437. pfc->ptlScale.x,
  438. pfc->ptlScale.y,
  439. pfo
  440. );
  441. pgd->hg = hg;
  442. }
  443. //
  444. // Fill in the bitmap portion of the RASTERGLYPH.
  445. //
  446. if ( pv != NULL )
  447. {
  448. if (cxNoSim == 0)
  449. {
  450. // stolen from ttfd:
  451. GLYPHBITS *pgb = (GLYPHBITS *)pv;
  452. pgb->ptlOrigin.x = 0;
  453. pgb->ptlOrigin.y = -sAscent;
  454. pgb->sizlBitmap.cx = 1; // cheating
  455. pgb->sizlBitmap.cy = 1; // cheating
  456. *((ULONG *)pgb->aj) = 0; // fill in a blank 1x1 dib
  457. }
  458. else
  459. {
  460. if (pfc->flStretch & FC_DO_STRETCH)
  461. {
  462. BYTE ajStretchBuffer[CJ_STRETCH];
  463. if (pfc->flStretch & FC_STRETCH_WIDE)
  464. {
  465. EngAcquireSemaphore(ghsemBMFD);
  466. // need to put try/except here so as to release the semaphore
  467. // in case the file disappeares [bodind]
  468. #ifndef BMFD_NO_TRY_EXCEPT
  469. try
  470. {
  471. #endif
  472. vStretchCvtToBitmap(
  473. pv,
  474. pjBitmap,
  475. cxNoSim ,
  476. pcvtfh->cy ,
  477. (ULONG)sAscent ,
  478. pfc->ajStretchBuffer,
  479. pfc->ptlScale.x,
  480. pfc->ptlScale.y,
  481. pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC));
  482. #ifndef BMFD_NO_TRY_EXCEPT
  483. }
  484. except (EXCEPTION_EXECUTE_HANDLER)
  485. {
  486. WARNING("bmfd! exception while stretching a glyph\n");
  487. vBmfdMarkFontGone(
  488. (FONTFILE *)pfc->hff,
  489. GetExceptionCode()
  490. );
  491. }
  492. #endif
  493. EngReleaseSemaphore(ghsemBMFD);
  494. }
  495. else
  496. {
  497. // we are protected by higher level try/excepts
  498. vStretchCvtToBitmap(
  499. pv,
  500. pjBitmap,
  501. cxNoSim ,
  502. pcvtfh->cy ,
  503. (ULONG)sAscent ,
  504. ajStretchBuffer,
  505. pfc->ptlScale.x,
  506. pfc->ptlScale.y,
  507. pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC));
  508. }
  509. }
  510. else
  511. {
  512. switch (pfo->flFontType & (FO_SIM_BOLD | FO_SIM_ITALIC))
  513. {
  514. case 0:
  515. vCvtToBmp(
  516. pv ,
  517. pgd ,
  518. pjBitmap ,
  519. cxNoSim ,
  520. pcvtfh->cy ,
  521. (ULONG)sAscent
  522. );
  523. break;
  524. case FO_SIM_BOLD:
  525. vCvtToBoldBmp(
  526. pv ,
  527. pgd ,
  528. pjBitmap ,
  529. cxNoSim ,
  530. pcvtfh->cy ,
  531. (ULONG)sAscent
  532. );
  533. break;
  534. case FO_SIM_ITALIC:
  535. vCvtToItalicBmp(
  536. pv ,
  537. pgd ,
  538. pjBitmap ,
  539. cxNoSim ,
  540. pcvtfh->cy ,
  541. (ULONG)sAscent
  542. );
  543. break;
  544. case (FO_SIM_BOLD | FO_SIM_ITALIC):
  545. vCvtToBoldItalicBmp(
  546. pv ,
  547. pgd ,
  548. pjBitmap ,
  549. cxNoSim ,
  550. pcvtfh->cy ,
  551. (ULONG)sAscent
  552. );
  553. break;
  554. default:
  555. RIP("BMFD!WRONG SIMULATION REQUEST\n");
  556. }
  557. }
  558. }
  559. // Record the pointer to the RASTERGLYPH in the pointer table.
  560. if ( pgd != NULL )
  561. {
  562. pgd->gdf.pgb = (GLYPHBITS *)pv;
  563. }
  564. vBmfdScrubGLYPHBITS((GLYPHBITS*)pv);
  565. }
  566. #ifdef FE_SB // BmfdQueryFontData(): Set up GLYPHDATA and GLYPHBITS for Rotation
  567. // Check rotation
  568. if( pfc->ulRotate != 0L )
  569. {
  570. // Rotate GLYPHDATA and GLYPHBITS
  571. // if pv and pvDst is NULL , We only set up GLYPHDATA only
  572. // and if pgd is NULL , we only set up pvDst
  573. if (pvDst)
  574. memset(pvDst, 0, cjSize);
  575. vFill_RotateGLYPHDATA(
  576. pgd, // GLYPHDATA *pDistinationGlyphData
  577. pv, // PVOID SourceGLYPHBITS
  578. pvDst, // PVOID DistinationGLYPHBITS
  579. pfc->ulRotate // UINT Rotate degree
  580. );
  581. // Free GLYPHBITS tenmorary buffer
  582. // !!! Now pvDst is Original buffer from GRE.
  583. if( pv != NULL ) VFREEMEM( pv );
  584. }
  585. #endif // FE_SB
  586. return cjGlyphData;
  587. case QFD_MAXEXTENTS:
  588. //
  589. // If buffer NULL, return size.
  590. //
  591. if ( pv == (PVOID) NULL )
  592. return (sizeof(FD_DEVICEMETRICS));
  593. //
  594. // Otherwise, copy the data structure.
  595. //
  596. else
  597. return cjBmfdDeviceMetrics(pfc, (FD_DEVICEMETRICS *) pv);
  598. case QFD_GLYPHANDOUTLINE:
  599. default:
  600. WARNING("gdisrv!BmfdQueryFontData(): unsupported mode\n");
  601. return FD_ERROR;
  602. }
  603. }
  604. /******************************Public*Routine******************************\
  605. * BmfdQueryAdvanceWidths *
  606. * *
  607. * Queries the advance widths for a range of glyphs. *
  608. * *
  609. * Sat 16-Jan-1993 22:28:41 -by- Charles Whitmer [chuckwh] *
  610. * Wrote it. The code is repeated to avoid multiplies wherever possible. *
  611. * The crazy loop unrolling cuts the time of this routine by 25%. *
  612. \**************************************************************************/
  613. typedef struct _TYPE2TABLE
  614. {
  615. USHORT cx;
  616. USHORT offData;
  617. } TYPE2TABLE;
  618. typedef struct _TYPE3TABLE
  619. {
  620. USHORT cx;
  621. USHORT offDataLo;
  622. USHORT offDataHi;
  623. } TYPE3TABLE;
  624. BOOL BmfdQueryAdvanceWidths
  625. (
  626. FONTOBJ *pfo,
  627. ULONG iMode,
  628. HGLYPH *phg,
  629. LONG *plWidths,
  630. ULONG cGlyphs
  631. )
  632. {
  633. USHORT *psWidths = (USHORT *) plWidths; // True for the cases we handle.
  634. FONTCONTEXT *pfc ;
  635. FACEINFO *pfai ;
  636. CVTFILEHDR *pcvtfh ;
  637. BYTE *pjTable ;
  638. USHORT xScale ;
  639. USHORT cxExtra ;
  640. USHORT cx;
  641. if (!bReconnectBmfdFont(PFF(pfo->iFile)))
  642. {
  643. WARNING("bmfd!bmfdQueryAdvanceWidths: this file is gone\n");
  644. return FD_ERROR;
  645. }
  646. // If pfo->pvProducer is NULL, then we need to open a font context.
  647. //
  648. if ( pfo->pvProducer == (PVOID) NULL )
  649. pfo->pvProducer = (PVOID) BmfdOpenFontContext(pfo);
  650. pfc = PFC(pfo->pvProducer);
  651. if ( pfc == (PFONTCONTEXT) NULL )
  652. {
  653. WARNING("bmfd!bmfdQueryAdvanceWidths: cannot create font context\n");
  654. return FD_ERROR;
  655. }
  656. pfai = pfc->pfai;
  657. pcvtfh = &(pfai->cvtfh);
  658. pjTable = (BYTE *) pfai->re.pvResData + pcvtfh->dpOffsetTable;
  659. xScale = (USHORT) (pfc->ptlScale.x << 4);
  660. cxExtra = (pfc->flFontType & FO_SIM_BOLD) ? 16 : 0;
  661. if (iMode > QAW_GETEASYWIDTHS)
  662. return(GDI_ERROR);
  663. // Retrieve widths from type 2 tables.
  664. if (pcvtfh->iVersion == 0x00000200)
  665. {
  666. TYPE2TABLE *p2t = (TYPE2TABLE *) pjTable;
  667. if (xScale == 16)
  668. {
  669. while (cGlyphs > 3)
  670. {
  671. cx = p2t[phg[0]].cx;
  672. psWidths[0] = (cx << 4) + cxExtra;
  673. cx = p2t[phg[1]].cx;
  674. psWidths[1] = (cx << 4) + cxExtra;
  675. cx = p2t[phg[2]].cx;
  676. psWidths[2] = (cx << 4) + cxExtra;
  677. cx = p2t[phg[3]].cx;
  678. psWidths[3] = (cx << 4) + cxExtra;
  679. phg += 4; psWidths += 4; cGlyphs -= 4;
  680. }
  681. while (cGlyphs)
  682. {
  683. cx = p2t[*phg].cx;
  684. *psWidths = (cx << 4) + cxExtra;
  685. phg++,psWidths++,cGlyphs--;
  686. }
  687. }
  688. else
  689. {
  690. while (cGlyphs)
  691. {
  692. cx = p2t[*phg].cx;
  693. *psWidths = (cx * xScale) + cxExtra;
  694. phg++,psWidths++,cGlyphs--;
  695. }
  696. }
  697. }
  698. // Retrieve widths from type 3 tables.
  699. else
  700. {
  701. TYPE3TABLE *p3t = (TYPE3TABLE *) pjTable;
  702. if (xScale == 16)
  703. {
  704. while (cGlyphs > 3)
  705. {
  706. cx = p3t[phg[0]].cx;
  707. psWidths[0] = (cx << 4) + cxExtra;
  708. cx = p3t[phg[1]].cx;
  709. psWidths[1] = (cx << 4) + cxExtra;
  710. cx = p3t[phg[2]].cx;
  711. psWidths[2] = (cx << 4) + cxExtra;
  712. cx = p3t[phg[3]].cx;
  713. psWidths[3] = (cx << 4) + cxExtra;
  714. phg += 4; psWidths += 4; cGlyphs -= 4;
  715. }
  716. while (cGlyphs)
  717. {
  718. cx = p3t[*phg].cx;
  719. *psWidths = (cx << 4) + cxExtra;
  720. phg++,psWidths++,cGlyphs--;
  721. }
  722. }
  723. else
  724. {
  725. while (cGlyphs)
  726. {
  727. cx = p3t[*phg].cx;
  728. *psWidths = (cx * xScale) + cxExtra;
  729. phg++,psWidths++,cGlyphs--;
  730. }
  731. }
  732. }
  733. return(TRUE);
  734. }
  735. /******************************Public*Routine******************************\
  736. * BmfdQueryFontFile
  737. *
  738. * A function to query per font file information.
  739. *
  740. * Parameters:
  741. *
  742. * hff Handle to a font file.
  743. *
  744. * ulMode This is a 32-bit number that must be one of the following
  745. * values:
  746. *
  747. * Allowed ulMode values:
  748. * ----------------------
  749. *
  750. * QFF_DESCRIPTION -- copies a UNICODE string in the buffer
  751. * that describes the contents of the font file.
  752. *
  753. * QFF_NUMFACES -- returns number of faces in the font file.
  754. *
  755. * cjBuf Maximum number of BYTEs to copy into the buffer. The
  756. * driver will not copy more than this many BYTEs.
  757. *
  758. * This should be zero if pulBuf is NULL.
  759. *
  760. * This parameter is not used in QFF_NUMFACES mode.
  761. *
  762. * pulBuf Pointer to the buffer to receive the data
  763. * If this is NULL, then the required buffer size
  764. * is returned as a count of BYTEs. Notice that this
  765. * is a PULONG, to enforce 32-bit data alignment.
  766. *
  767. * This parameter is not used in QFF_NUMFACES mode.
  768. *
  769. * Returns:
  770. *
  771. * If mode is QFF_DESCRIPTION, then the number of BYTEs copied into
  772. * the buffer is returned by the function. If pulBuf is NULL,
  773. * then the required buffer size (as a count of BYTEs) is returned.
  774. *
  775. * If mode is QFF_NUMFACES, then number of faces in font file is returned.
  776. *
  777. * FD_ERROR is returned if an error occurs.
  778. *
  779. * History:
  780. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  781. * Added QFF_NUMFACES mode (IFI/DDI merge).
  782. *
  783. * Fri 20-Mar-1992 -by- Bodin Dresevic [BodinD]
  784. * Wrote it.
  785. \**************************************************************************/
  786. LONG
  787. BmfdQueryFontFile (
  788. HFF hff, // handle to font file
  789. ULONG ulMode, // type of query
  790. ULONG cjBuf, // size of buffer (in BYTEs)
  791. PULONG pulBuf // return buffer (NULL if requesting size of data)
  792. )
  793. {
  794. // Verify the HFF.
  795. if (hff == HFF_INVALID)
  796. {
  797. WARNING("bmfd!BmfdQueryFontFile(): invalid HFF\n");
  798. return(FD_ERROR);
  799. }
  800. //
  801. // Which mode?.
  802. //
  803. switch(ulMode)
  804. {
  805. case QFF_DESCRIPTION:
  806. //
  807. // If present, return the description string.
  808. //
  809. if ( PFF(hff)->cjDescription != 0 )
  810. {
  811. //
  812. // If there is a buffer, copy the data.
  813. //
  814. if ( pulBuf != (PULONG) NULL )
  815. {
  816. //
  817. // Is buffer big enough?
  818. //
  819. if ( cjBuf < PFF(hff)->cjDescription )
  820. {
  821. WARNING("bmfd!BmfdQueryFontFile(): buffer too small for string\n");
  822. return (FD_ERROR);
  823. }
  824. else
  825. {
  826. RtlCopyMemory((PVOID) pulBuf,
  827. ((PBYTE) PFF(hff)) + PFF(hff)->dpwszDescription,
  828. PFF(hff)->cjDescription);
  829. }
  830. }
  831. return (LONG) PFF(hff)->cjDescription;
  832. }
  833. //
  834. // Otherwise, substitute the facename.
  835. //
  836. else
  837. {
  838. //
  839. // There is no description string associated with the font therefore we
  840. // substitue the facename of the first font in the font file.
  841. //
  842. IFIMETRICS *pifi = PFF(hff)->afai[0].pifi;
  843. PWSZ pwszFacename = (PWSZ)((PBYTE) pifi + pifi->dpwszFaceName);
  844. ULONG cjFacename = (wcslen(pwszFacename) + 1) * sizeof(WCHAR);
  845. //
  846. // If there is a buffer, copy to it.
  847. //
  848. if ( pulBuf != (PULONG) NULL )
  849. {
  850. //
  851. // Is buffer big enough?
  852. //
  853. if ( cjBuf < cjFacename )
  854. {
  855. WARNING("bmfd!BmfdQueryFontFile(): buffer too small for face\n");
  856. return (FD_ERROR);
  857. }
  858. else
  859. {
  860. RtlCopyMemory((PVOID) pulBuf,
  861. (PVOID) pwszFacename,
  862. cjFacename);
  863. }
  864. }
  865. return ((LONG) cjFacename);
  866. }
  867. case QFF_NUMFACES:
  868. return PFF(hff)->cFntRes;
  869. default:
  870. WARNING("gdisrv!BmfdQueryFontFile(): unknown mode\n");
  871. return FD_ERROR;
  872. }
  873. }
  874. /******************************Public*Routine******************************\
  875. * cjBmfdDeviceMetrics
  876. *
  877. *
  878. * Effects:
  879. *
  880. * Warnings:
  881. *
  882. * History:
  883. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  884. * Stole it from BodinD's FdQueryFaceAttr() implementation.
  885. \**************************************************************************/
  886. ULONG
  887. cjBmfdDeviceMetrics (
  888. PFONTCONTEXT pfc,
  889. FD_DEVICEMETRICS *pdevm
  890. )
  891. {
  892. PIFIMETRICS pifi;
  893. UINT xScale = pfc->ptlScale.x;
  894. UINT yScale = pfc->ptlScale.y;
  895. // compute the accelerator flags for this font
  896. // If this is a bitmap font where some of the glyphs have zero widths,
  897. // we need to turn off all the accelerator flags
  898. if (pfc->pfai->cvtfh.fsFlags & FS_ZERO_WIDTH_GLYPHS)
  899. {
  900. pdevm->flRealizedType = 0;
  901. }
  902. else
  903. {
  904. pdevm->flRealizedType =
  905. (
  906. FDM_TYPE_BM_SIDE_CONST | // all char bitmaps have the same cy
  907. FDM_TYPE_CONST_BEARINGS | // ac spaces for all chars the same, not 0 necessarilly
  908. FDM_TYPE_MAXEXT_EQUAL_BM_SIDE
  909. );
  910. // the above flags are set regardless of the possible simulation performed on the face
  911. // the remaining two are only set if italicizing has not been done
  912. if ( !(pfc->flFontType & FO_SIM_ITALIC) )
  913. {
  914. pdevm->flRealizedType |=
  915. (FDM_TYPE_ZERO_BEARINGS | FDM_TYPE_CHAR_INC_EQUAL_BM_BASE);
  916. }
  917. }
  918. pifi = pfc->pfai->pifi;
  919. #ifdef FE_SB // ROTATION:cjBmfdDeviceMetric(): set direction unit vectors
  920. /**********************************************************************
  921. Coordinate (0 degree) (90 degree) (180 degree) (270 degree)
  922. System
  923. |(-) A A
  924. | Side | | Base
  925. | | | Base Side
  926. -----+----->X +------> <------+ <------+ +------>
  927. (-) | (+) Base Side | |
  928. | Side| | Base
  929. |(+) V V
  930. Y
  931. ***********************************************************************/
  932. switch( pfc->ulRotate )
  933. {
  934. case 0L:
  935. // the direction unit vectors for all ANSI bitmap fonts are the
  936. // same. We do not even have to look to the font context:
  937. vLToE(&pdevm->pteBase.x, 1L);
  938. vLToE(&pdevm->pteBase.y, 0L);
  939. vLToE(&pdevm->pteSide.x, 0L);
  940. vLToE(&pdevm->pteSide.y, -1L); // y axis points down
  941. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  942. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  943. pdevm->ptlUnderline1.x = 0L;
  944. pdevm->ptlUnderline1.y = -(LONG)pifi->fwdUnderscorePosition * yScale;
  945. pdevm->ptlStrikeOut.x =
  946. (pfc->flFontType & FO_SIM_ITALIC) ? (LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  947. pdevm->ptlStrikeOut.y = -(LONG)pifi->fwdStrikeoutPosition * yScale;
  948. pdevm->ptlULThickness.x = 0;
  949. pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize * yScale;
  950. pdevm->ptlSOThickness.x = 0;
  951. pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize * yScale;
  952. break;
  953. case 900L:
  954. // the direction unit vectors for all ANSI bitmap fonts are the
  955. // same. We do not even have to look to the font context:
  956. vLToE(&pdevm->pteBase.x, 0L);
  957. vLToE(&pdevm->pteBase.y, -1L);
  958. vLToE(&pdevm->pteSide.x, -1L);
  959. vLToE(&pdevm->pteSide.y, 0L);
  960. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  961. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  962. pdevm->ptlUnderline1.x = -(LONG)pifi->fwdUnderscorePosition * yScale;
  963. pdevm->ptlUnderline1.y = 0;
  964. pdevm->ptlStrikeOut.x = -(LONG)pifi->fwdStrikeoutPosition * yScale;
  965. pdevm->ptlStrikeOut.y =
  966. (pfc->flFontType & FO_SIM_ITALIC) ? -(LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  967. pdevm->ptlULThickness.x = (LONG)pifi->fwdUnderscoreSize * yScale;
  968. pdevm->ptlULThickness.y = 0;
  969. pdevm->ptlSOThickness.x = (LONG)pifi->fwdStrikeoutSize * yScale;
  970. pdevm->ptlSOThickness.y = 0;
  971. break;
  972. case 1800L:
  973. // the direction unit vectors for all ANSI bitmap fonts are the
  974. // same. We do not even have to look to the font context:
  975. vLToE(&pdevm->pteBase.x, -1L);
  976. vLToE(&pdevm->pteBase.y, 0L);
  977. vLToE(&pdevm->pteSide.x, 0L);
  978. vLToE(&pdevm->pteSide.y, 1L);
  979. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  980. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  981. pdevm->ptlUnderline1.x = 0L;
  982. pdevm->ptlUnderline1.y = (LONG)pifi->fwdUnderscorePosition * yScale;
  983. pdevm->ptlStrikeOut.x =
  984. (pfc->flFontType & FO_SIM_ITALIC) ? -(LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  985. pdevm->ptlStrikeOut.y = pifi->fwdStrikeoutPosition * yScale;
  986. pdevm->ptlULThickness.x = 0;
  987. pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize * yScale;
  988. pdevm->ptlSOThickness.x = 0;
  989. pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize * yScale;
  990. break;
  991. case 2700L:
  992. // the direction unit vectors for all ANSI bitmap fonts are the
  993. // same. We do not even have to look to the font context:
  994. vLToE(&pdevm->pteBase.x, 0L);
  995. vLToE(&pdevm->pteBase.y, 1L);
  996. vLToE(&pdevm->pteSide.x, 1L);
  997. vLToE(&pdevm->pteSide.y, 0L);
  998. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  999. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  1000. pdevm->ptlUnderline1.x = (LONG)pifi->fwdUnderscorePosition * yScale;
  1001. pdevm->ptlUnderline1.y = 0L;
  1002. pdevm->ptlStrikeOut.x = (LONG)pifi->fwdStrikeoutPosition * yScale;
  1003. pdevm->ptlStrikeOut.y =
  1004. (pfc->flFontType & FO_SIM_ITALIC) ? (LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  1005. pdevm->ptlULThickness.x = (LONG)pifi->fwdUnderscoreSize * yScale;
  1006. pdevm->ptlULThickness.y = 0;
  1007. pdevm->ptlSOThickness.x = (LONG)pifi->fwdStrikeoutSize * yScale;
  1008. pdevm->ptlSOThickness.y = 0;
  1009. break;
  1010. default:
  1011. break;
  1012. }
  1013. #else
  1014. // the direction unit vectors for all ANSI bitmap fonts are the
  1015. // same. We do not even have to look to the font context:
  1016. vLToE(&pdevm->pteBase.x, 1L);
  1017. vLToE(&pdevm->pteBase.y, 0L);
  1018. vLToE(&pdevm->pteSide.x, 0L);
  1019. vLToE(&pdevm->pteSide.y, -1L); // y axis points down
  1020. #endif // FE_SB
  1021. // Set the constant increment for a fixed pitch font. Don't forget to
  1022. // take into account a bold simulation!
  1023. pdevm->lD = 0;
  1024. if ((pifi->flInfo & FM_INFO_CONSTANT_WIDTH) &&
  1025. !(pfc->pfai->cvtfh.fsFlags & FS_ZERO_WIDTH_GLYPHS))
  1026. {
  1027. pdevm->lD = (LONG) pifi->fwdMaxCharInc * xScale;
  1028. if (pfc->flFontType & FO_SIM_BOLD)
  1029. pdevm->lD++;
  1030. }
  1031. #ifndef FE_SB // cjBmfdDeviceMetric():
  1032. // for a bitmap font there is no difference between notional and device
  1033. // coords, so that the Ascender and Descender can be copied directly
  1034. // from PIFIMETRICS where these two numbers are in notional coords
  1035. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  1036. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  1037. pdevm->ptlUnderline1.x = 0L;
  1038. pdevm->ptlUnderline1.y = - pifi->fwdUnderscorePosition * yScale;
  1039. pdevm->ptlStrikeOut.y = - pifi->fwdStrikeoutPosition * yScale;
  1040. pdevm->ptlStrikeOut.x =
  1041. (pfc->flFontType & FO_SIM_ITALIC) ? (LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  1042. pdevm->ptlULThickness.x = 0;
  1043. pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize * yScale;
  1044. pdevm->ptlSOThickness.x = 0;
  1045. pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize * yScale;
  1046. // for a bitmap font there is no difference between notional and device
  1047. // coords, so that the Ascender and Descender can be copied directly
  1048. // from PIFIMETRICS where these two numbers are in notional coords
  1049. pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender * yScale);
  1050. pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender * yScale );
  1051. pdevm->ptlUnderline1.x = 0L;
  1052. pdevm->ptlUnderline1.y = - pifi->fwdUnderscorePosition * yScale;
  1053. pdevm->ptlStrikeOut.y = - pifi->fwdStrikeoutPosition * yScale;
  1054. pdevm->ptlStrikeOut.x =
  1055. (pfc->flFontType & FO_SIM_ITALIC) ? (LONG)pifi->fwdStrikeoutPosition / 2 : 0;
  1056. pdevm->ptlULThickness.x = 0;
  1057. pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize * yScale;
  1058. pdevm->ptlSOThickness.x = 0;
  1059. pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize * yScale;
  1060. #endif // FE_SB
  1061. // max glyph bitmap width in pixels in x direction
  1062. // does not need to be multiplied by xScale, this has already been taken into
  1063. // account, see the code in fdfc.c:
  1064. // cjGlyphMax =
  1065. // cjGlyphDataSimulated(
  1066. // pfo,
  1067. // (ULONG)pcvtfh->usMaxWidth * ptlScale.x,
  1068. // (ULONG)pcvtfh->cy * ptlScale.y,
  1069. // &cxMax);
  1070. // [bodind]
  1071. pdevm->cxMax = pfc->cxMax;
  1072. // new fields
  1073. pdevm->cyMax = pfc->cjGlyphMax / ((pfc->cxMax + 7) / 8);
  1074. pdevm->cjGlyphMax = pfc->cjGlyphMax;
  1075. return (sizeof(FD_DEVICEMETRICS));
  1076. }
  1077. #ifdef FE_SB // vFill_RotateGLYPHDATA()
  1078. #define CJ_DIB8_SCAN(cx) ((((cx) + 7) & ~7) >> 3)
  1079. /*
  1080. BIT macro returns non zero ( if bitmap[x,y] is on) or zero (bitmap[x,y] is off).
  1081. pb : bitmap
  1082. w : byte count per scan line
  1083. x : Xth bit in x direction
  1084. y : scan line
  1085. x
  1086. -------------------->
  1087. y | *******************************
  1088. | *******************************
  1089. | *******************************
  1090. V
  1091. */
  1092. BYTE BitON[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  1093. BYTE BitOFF[8] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
  1094. #define BIT(pb, w, x, y) (*((PBYTE)(pb) + (w) * (y) + ((x)/8)) & (BitON[(x) & 7]))
  1095. /******************************************************************************\
  1096. *
  1097. * VOID vFill_RotateGLYPHDATA()
  1098. *
  1099. *
  1100. * History :
  1101. *
  1102. * 11-Feb-1992 (Thu) -by- Hideyuki Nagase [hideyukn]
  1103. * Wrote it.
  1104. *
  1105. \******************************************************************************/
  1106. VOID
  1107. vFill_RotateGLYPHDATA (
  1108. GLYPHDATA *pDistGlyphData,
  1109. PVOID SrcGLYPHBITS,
  1110. PVOID DistGLYPHBITS,
  1111. UINT RotateDegree
  1112. )
  1113. {
  1114. GLYPHDATA SrcGlyphData;
  1115. ULONG ulSrcBitmapSizeX , ulDistBitmapSizeX;
  1116. ULONG ulSrcBitmapSizeY , ulDistBitmapSizeY;
  1117. GLYPHBITS *pSrcGlyphBits , *pDistGlyphBits;
  1118. PBYTE pbSrcBitmap , pbDistBitmap;
  1119. UINT x , y , k;
  1120. UINT cjScanSrc , cjScanDist;
  1121. PBYTE pb;
  1122. // Now , in this point *pDistGlyphData contain No rotated GLYPHDATA
  1123. // Copy No rotate GLYPHDATA to Source Area . later we write back changed data to
  1124. // distination area.
  1125. //
  1126. // these field are defined as:
  1127. //
  1128. // unit vector along the baseline - fxD, fxA, fxAB
  1129. // or
  1130. // unit vector in the ascent direction - fxInkTop, fxInkBottom
  1131. //
  1132. // Because baseline direction and ascent direction are rotated
  1133. // as ulRotate specifies, these fileds should be considered as
  1134. // rotation independent.
  1135. //
  1136. // Init Local value
  1137. // Set pointer to GLYPHBITS structure
  1138. pSrcGlyphBits = (GLYPHBITS *)SrcGLYPHBITS;
  1139. pDistGlyphBits = (GLYPHBITS *)DistGLYPHBITS;
  1140. if( pDistGlyphData != NULL )
  1141. {
  1142. // Init Source GlyphData
  1143. SrcGlyphData = *pDistGlyphData;
  1144. // Record the pointer to GLYPHBITS in GLYPHDATA structure
  1145. pDistGlyphData->gdf.pgb = pDistGlyphBits;
  1146. }
  1147. // Check Rotation
  1148. switch( RotateDegree )
  1149. {
  1150. case 0L :
  1151. WARNING("BMFD:vFill_RotateGLYPHDATA():Why come here?\n");
  1152. break;
  1153. case 900L :
  1154. if( pDistGlyphData != NULL )
  1155. {
  1156. // Setup GLYPHDATA structure
  1157. // x = y;
  1158. // y = -x; !!!! HighPart include plus or minus flag
  1159. pDistGlyphData->ptqD.x = SrcGlyphData.ptqD.y;
  1160. pDistGlyphData->ptqD.y.HighPart = -(SrcGlyphData.ptqD.x.HighPart);
  1161. pDistGlyphData->ptqD.y.LowPart = SrcGlyphData.ptqD.x.LowPart;
  1162. // top = -rihgt ; bottom = -left ; right = bottom ; left = top
  1163. pDistGlyphData->rclInk.top = -(SrcGlyphData.rclInk.right);
  1164. pDistGlyphData->rclInk.bottom = -(SrcGlyphData.rclInk.left);
  1165. pDistGlyphData->rclInk.right = SrcGlyphData.rclInk.bottom;
  1166. pDistGlyphData->rclInk.left = SrcGlyphData.rclInk.top;
  1167. }
  1168. if( pSrcGlyphBits != NULL && pDistGlyphBits != NULL )
  1169. {
  1170. // Get Bitmap size
  1171. ulSrcBitmapSizeX = pSrcGlyphBits->sizlBitmap.cx;
  1172. ulSrcBitmapSizeY = pSrcGlyphBits->sizlBitmap.cy;
  1173. // Get the pointer to Bitmap images
  1174. pbSrcBitmap = (PBYTE)pSrcGlyphBits->aj;
  1175. pbDistBitmap = (PBYTE)pDistGlyphBits->aj;
  1176. // Set Distination Bitmap Size
  1177. ulDistBitmapSizeX = ulSrcBitmapSizeY;
  1178. ulDistBitmapSizeY = ulSrcBitmapSizeX;
  1179. // Setup GLYPHBITS stuff
  1180. pDistGlyphBits->ptlOrigin.x = pSrcGlyphBits->ptlOrigin.y;
  1181. pDistGlyphBits->ptlOrigin.y = -(LONG)(ulSrcBitmapSizeX);
  1182. pDistGlyphBits->sizlBitmap.cx = pSrcGlyphBits->sizlBitmap.cy;
  1183. pDistGlyphBits->sizlBitmap.cy = pSrcGlyphBits->sizlBitmap.cx;
  1184. // Rotate bitmap inage
  1185. cjScanSrc = CJ_DIB8_SCAN( ulSrcBitmapSizeX );
  1186. cjScanDist = CJ_DIB8_SCAN( ulDistBitmapSizeX );
  1187. // we need to clear the dst buffer because the S3 driver expects
  1188. // extra stuff on the edges to be zeroed out
  1189. for ( y = 0; y < ulDistBitmapSizeY ; y++ )
  1190. {
  1191. for ( x= 0 , pb = pbDistBitmap + cjScanDist * y ;
  1192. x < ulDistBitmapSizeX ;
  1193. x++ )
  1194. {
  1195. k = x & 7; // k is from 0 to 7;
  1196. if ( BIT( pbSrcBitmap , cjScanSrc,
  1197. ulDistBitmapSizeY - y - 1 ,
  1198. x
  1199. )
  1200. )
  1201. *pb |= (BitON[ k ] );
  1202. else
  1203. *pb &= (BitOFF[ k ] );
  1204. if ( k == 7 )
  1205. pb++;
  1206. }
  1207. }
  1208. }
  1209. break;
  1210. case 1800L :
  1211. if( pDistGlyphData != NULL )
  1212. {
  1213. // Setup GLYPHDATA structure
  1214. // x = -x; !!!! HighPart include plus or minus flag
  1215. // y = -y; !!!! HighPart include plus or minus flag
  1216. pDistGlyphData->ptqD.x.HighPart = -(SrcGlyphData.ptqD.x.HighPart);
  1217. pDistGlyphData->ptqD.x.LowPart = SrcGlyphData.ptqD.x.LowPart;
  1218. pDistGlyphData->ptqD.y.HighPart = -(SrcGlyphData.ptqD.y.HighPart);
  1219. pDistGlyphData->ptqD.y.LowPart = SrcGlyphData.ptqD.y.LowPart;
  1220. // top = -bottom ; bottom = -top ; right = -left ; left = -right
  1221. pDistGlyphData->rclInk.top = -(SrcGlyphData.rclInk.bottom);
  1222. pDistGlyphData->rclInk.bottom = -(SrcGlyphData.rclInk.top);
  1223. pDistGlyphData->rclInk.right = -(SrcGlyphData.rclInk.left);
  1224. pDistGlyphData->rclInk.left = -(SrcGlyphData.rclInk.right);
  1225. }
  1226. if( pSrcGlyphBits != NULL && pDistGlyphBits != NULL )
  1227. {
  1228. // Get Bitmap size
  1229. ulSrcBitmapSizeX = pSrcGlyphBits->sizlBitmap.cx;
  1230. ulSrcBitmapSizeY = pSrcGlyphBits->sizlBitmap.cy;
  1231. // Get the pointer to Bitmap images
  1232. pbSrcBitmap = (PBYTE)pSrcGlyphBits->aj;
  1233. pbDistBitmap = (PBYTE)pDistGlyphBits->aj;
  1234. // Set Distination Bitmap Size
  1235. ulDistBitmapSizeX = ulSrcBitmapSizeX;
  1236. ulDistBitmapSizeY = ulSrcBitmapSizeY;
  1237. // Setup GLYPHBITS stuff
  1238. pDistGlyphBits->ptlOrigin.x = -(LONG)(ulSrcBitmapSizeX);
  1239. pDistGlyphBits->ptlOrigin.y = -(LONG)(ulSrcBitmapSizeY + pSrcGlyphBits->ptlOrigin.y);
  1240. pDistGlyphBits->sizlBitmap.cx = pSrcGlyphBits->sizlBitmap.cx;
  1241. pDistGlyphBits->sizlBitmap.cy = pSrcGlyphBits->sizlBitmap.cy;
  1242. // Rotate bitmap inage
  1243. cjScanSrc = CJ_DIB8_SCAN( ulSrcBitmapSizeX );
  1244. cjScanDist = CJ_DIB8_SCAN( ulDistBitmapSizeX );
  1245. for ( y = 0; y < ulDistBitmapSizeY ; y++ )
  1246. {
  1247. for ( x = 0 , pb = pbDistBitmap + cjScanDist * y ;
  1248. x < ulDistBitmapSizeX ;
  1249. x++ )
  1250. {
  1251. k = x & 7;
  1252. if ( BIT( pbSrcBitmap, cjScanSrc,
  1253. ulDistBitmapSizeX - x - 1,
  1254. ulDistBitmapSizeY - y - 1
  1255. )
  1256. )
  1257. *pb |= (BitON[ k ] );
  1258. else
  1259. *pb &= (BitOFF[ k ] );
  1260. if ( k == 7 )
  1261. pb++;
  1262. }
  1263. }
  1264. }
  1265. break;
  1266. case 2700L :
  1267. if( pDistGlyphData != NULL )
  1268. {
  1269. // Setup GLYPHDATA structure
  1270. // x = -y; !!!! HighPart include plus or minus flag
  1271. // y = x;
  1272. pDistGlyphData->ptqD.x.HighPart = -(SrcGlyphData.ptqD.y.HighPart);
  1273. pDistGlyphData->ptqD.x.LowPart = SrcGlyphData.ptqD.y.LowPart;
  1274. pDistGlyphData->ptqD.y = SrcGlyphData.ptqD.x;
  1275. // top = left ; bottom = right ; right = -bottom ; left = -top
  1276. pDistGlyphData->rclInk.top = SrcGlyphData.rclInk.left;
  1277. pDistGlyphData->rclInk.bottom = SrcGlyphData.rclInk.right;
  1278. pDistGlyphData->rclInk.right = -(SrcGlyphData.rclInk.bottom);
  1279. pDistGlyphData->rclInk.left = -(SrcGlyphData.rclInk.top);
  1280. }
  1281. if( pSrcGlyphBits != NULL && pDistGlyphBits != NULL )
  1282. {
  1283. // Get Bitmap size
  1284. ulSrcBitmapSizeX = pSrcGlyphBits->sizlBitmap.cx;
  1285. ulSrcBitmapSizeY = pSrcGlyphBits->sizlBitmap.cy;
  1286. // Get the pointer to Bitmap images
  1287. pbSrcBitmap = (PBYTE)pSrcGlyphBits->aj;
  1288. pbDistBitmap = (PBYTE)pDistGlyphBits->aj;
  1289. // Set Distination Bitmap Size
  1290. ulDistBitmapSizeX = ulSrcBitmapSizeY;
  1291. ulDistBitmapSizeY = ulSrcBitmapSizeX;
  1292. // Setup GLYPHBITS stuff
  1293. pDistGlyphBits->ptlOrigin.x = -(LONG)(ulSrcBitmapSizeY + pSrcGlyphBits->ptlOrigin.y);
  1294. pDistGlyphBits->ptlOrigin.y = pSrcGlyphBits->ptlOrigin.x;
  1295. pDistGlyphBits->sizlBitmap.cx = pSrcGlyphBits->sizlBitmap.cy;
  1296. pDistGlyphBits->sizlBitmap.cy = pSrcGlyphBits->sizlBitmap.cx;
  1297. // Rotate bitmap inage
  1298. cjScanSrc = CJ_DIB8_SCAN( ulSrcBitmapSizeX );
  1299. cjScanDist = CJ_DIB8_SCAN( ulDistBitmapSizeX );
  1300. for ( y = 0; y < ulDistBitmapSizeY ; y++ )
  1301. {
  1302. for ( x = 0 , pb = pbDistBitmap + cjScanDist * y ;
  1303. x < ulDistBitmapSizeX ;
  1304. x++ )
  1305. {
  1306. k = x & 7;
  1307. if ( BIT( pbSrcBitmap, cjScanSrc,
  1308. y ,
  1309. ulDistBitmapSizeX - x - 1
  1310. )
  1311. )
  1312. *pb |= (BitON[ k ] );
  1313. else
  1314. *pb &= (BitOFF[ k ] );
  1315. if ( k == 7 )
  1316. pb++;
  1317. }
  1318. }
  1319. }
  1320. break;
  1321. default :
  1322. WARNING("BMFD:vFill_RotateGLYPHDATA():ulRotate is invalid\n");
  1323. break;
  1324. } // end switch
  1325. }
  1326. #endif // FE_SB