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.

1090 lines
35 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: htblt.cxx
  3. *
  4. * Contains routine to halftone a bitmap. This path is used when a
  5. * StretchBlt or PlgBlt is called with StretchBltMode == HALFTONE.
  6. *
  7. * Created: 18-Nov-1991 16:06:47
  8. * Author: Wendy Wu [wendywu]
  9. *
  10. * Copyright (c) 1990-1999 Microsoft Corporation
  11. \**************************************************************************/
  12. #include "precomp.hxx"
  13. #if ((PRIMARY_ORDER_ABC != PRIMARY_ORDER_123) || \
  14. (PRIMARY_ORDER_ACB != PRIMARY_ORDER_132) || \
  15. (PRIMARY_ORDER_BAC != PRIMARY_ORDER_213) || \
  16. (PRIMARY_ORDER_BCA != PRIMARY_ORDER_231) || \
  17. (PRIMARY_ORDER_CAB != PRIMARY_ORDER_312) || \
  18. (PRIMARY_ORDER_CBA != PRIMARY_ORDER_321))
  19. #error * PRIMARY_ORDER different in winddi.h and ht.h *
  20. #endif
  21. /*****************************Private*Function*****************************\
  22. * bSetHTSrcSurfInfo
  23. *
  24. * Initialise the HTSURFACEINFO structure. The structure is alloacted
  25. * elsewhere, we simply fill it in given the nature of the surface
  26. * required for drawing. Used by source surface only.
  27. *
  28. * History:
  29. * 18-Nov-1991 -by- Wendy Wu [wendywu]
  30. * Stole from gdi\printers\rasdd\stretch.c.
  31. \**************************************************************************/
  32. BOOL bSetHTSrcSurfInfo(
  33. SURFOBJ *pSurfObj,
  34. XEPALOBJ palSrc,
  35. HTSURFACEINFO *pHTSurfInfo,
  36. XLATEOBJ *pxlo
  37. )
  38. {
  39. COUNT cMaxPalEntries;
  40. BYTE cBytesPerEntry;
  41. BOOL bBitFields;
  42. ASSERTGDI(palSrc.bValid(),"bhtBlt: invalid src pal\n");
  43. bBitFields = palSrc.bIsBitfields();
  44. switch (pSurfObj->iBitmapFormat)
  45. {
  46. case BMF_1BPP:
  47. cBytesPerEntry = sizeof(ULONG);
  48. cMaxPalEntries = 2;
  49. break;
  50. case BMF_4BPP:
  51. cBytesPerEntry = sizeof(ULONG);
  52. cMaxPalEntries = 16;
  53. break;
  54. case BMF_8BPP:
  55. cBytesPerEntry = sizeof(ULONG);
  56. cMaxPalEntries = 256;
  57. break;
  58. case BMF_16BPP:
  59. cBytesPerEntry = 2;
  60. cMaxPalEntries = 3;
  61. bBitFields = TRUE;
  62. break;
  63. case BMF_24BPP:
  64. cBytesPerEntry = 3;
  65. cMaxPalEntries = 0;
  66. break;
  67. case BMF_32BPP:
  68. cBytesPerEntry = 4;
  69. cMaxPalEntries = 3;
  70. bBitFields = TRUE;
  71. break;
  72. default:
  73. WARNING("This bitmap format is not implemented");
  74. return(FALSE);
  75. }
  76. //
  77. // The halftone now taking ScanLineDelta rather than compute the scanline
  78. // delta by itself, because many driver fake the pvBits, pvScan0 and
  79. // scanline delta for creating smaller surface and that sometime cause
  80. // halftone to break, to do this we passed to halftone ScanLineDelta and
  81. // (from lDelta in SURFOBJ) and pvScan0.
  82. //
  83. HTSURFACEINFO HTSurfInfo;
  84. HTSurfInfo.hSurface = (ULONG_PTR)pSurfObj;
  85. HTSurfInfo.SurfaceFormat = (BYTE)pSurfObj->iBitmapFormat;
  86. HTSurfInfo.ScanLineAlignBytes = BMF_ALIGN_DWORD;
  87. HTSurfInfo.Width = pSurfObj->sizlBitmap.cx;
  88. HTSurfInfo.Height = pSurfObj->sizlBitmap.cy;
  89. HTSurfInfo.ScanLineDelta = pSurfObj->lDelta;
  90. HTSurfInfo.pPlane = (LPBYTE)pSurfObj->pvScan0;
  91. HTSurfInfo.Flags = (USHORT)((pSurfObj->fjBitmap & BMF_TOPDOWN) ?
  92. HTSIF_SCANLINES_TOPDOWN : 0);
  93. COUNT cPalEntries = bBitFields ? 3 : palSrc.cEntries();
  94. if (cPalEntries > cMaxPalEntries)
  95. cPalEntries = cMaxPalEntries;
  96. if (HTSurfInfo.pColorTriad = (PCOLORTRIAD)PALLOCNOZ(
  97. cPalEntries * sizeof(ULONG) + sizeof(COLORTRIAD),'cthG'))
  98. {
  99. PCOLORTRIAD pColorTriad = HTSurfInfo.pColorTriad;
  100. pColorTriad->Type = COLOR_TYPE_RGB;
  101. pColorTriad->pColorTable = (LPBYTE)pColorTriad + sizeof(COLORTRIAD);
  102. pColorTriad->PrimaryOrder = PRIMARY_ORDER_RGB;
  103. // May not be needed by halftoning code, but just to be sure
  104. pColorTriad->PrimaryValueMax = 0;
  105. if (palSrc.bIsBGR())
  106. pColorTriad->PrimaryOrder = PRIMARY_ORDER_BGR;
  107. if (bBitFields)
  108. {
  109. // 16 or 32BPP.
  110. pColorTriad->BytesPerPrimary = 0;
  111. pColorTriad->BytesPerEntry = cBytesPerEntry;
  112. pColorTriad->ColorTableEntries = 3;
  113. ULONG *pulColors = (ULONG *)pColorTriad->pColorTable;
  114. if (palSrc.bIsBitfields())
  115. {
  116. pulColors[0] = palSrc.flRed();
  117. pulColors[1] = palSrc.flGre();
  118. pulColors[2] = palSrc.flBlu();
  119. }
  120. else
  121. {
  122. // BMF_32BPP, it's not BITFIELD so default to 888
  123. pulColors[1] = 0x00ff00;
  124. if (palSrc.bIsBGR())
  125. {
  126. pulColors[0] = 0xff0000;
  127. pulColors[2] = 0x0000ff;
  128. }
  129. else
  130. {
  131. pulColors[0] = 0x0000ff;
  132. pulColors[2] = 0xff0000;
  133. }
  134. }
  135. }
  136. else
  137. {
  138. pColorTriad->BytesPerPrimary = 1;
  139. pColorTriad->BytesPerEntry = cBytesPerEntry;
  140. pColorTriad->ColorTableEntries = cPalEntries;
  141. pColorTriad->PrimaryValueMax = 255;
  142. if (cPalEntries != 0)
  143. {
  144. // Not 24BPP or 32BPP
  145. // Bug #418345
  146. // If the source palette is monochrome, then we need to
  147. // use the foreground and background colors of the DC
  148. // which have been previously stored for us in the
  149. // translation object.
  150. XLATE* pxlate = (XLATE*) pxlo;
  151. if(palSrc.bIsMonochrome() &&
  152. (pxlate->flPrivate & XLATE_FROM_MONO))
  153. {
  154. ULONG *pulColors = (ULONG *)pColorTriad->pColorTable;
  155. // WINBUG #235687 bhouse 1-19-2000 DIBINDEX values not handled properly by halftone
  156. // When given a monochrome palette with a monochrome translate
  157. // we need to be sure to also translate DIBINDEX values appropriately
  158. pulColors[0] = ulColorRefToRGB(pxlate->ppalDst, pxlate->ppalDstDC, pxlate->iForeDst);
  159. pulColors[1] = ulColorRefToRGB(pxlate->ppalDst, pxlate->ppalDstDC, pxlate->iBackDst);
  160. }
  161. else
  162. {
  163. palSrc.ulGetEntries(0, cPalEntries,
  164. (PPALETTEENTRY)pColorTriad->pColorTable,FALSE);
  165. }
  166. }
  167. }
  168. }
  169. else
  170. {
  171. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  172. return(FALSE);
  173. }
  174. *pHTSurfInfo = HTSurfInfo;
  175. return(TRUE);
  176. }
  177. /*****************************Private*Function*****************************\
  178. * bSetHTSurfInfo
  179. *
  180. * Initialise the HTSURFACEINFO structure for destination and mask.
  181. *
  182. * History:
  183. * 14-Apr-1992 -by- Wendy Wu [wendywu]
  184. * Wrote it.
  185. \**************************************************************************/
  186. BOOL bSetHTSurfInfo(
  187. SURFOBJ *pSurfObj,
  188. HTSURFACEINFO *pHTSurfInfo, // Where data is placed
  189. LONG iFormatHT)
  190. {
  191. HTSURFACEINFO HTSurfInfo;
  192. //
  193. // The halftone now taking ScanLineDelta rather than compute the scanline
  194. // delta by itself, because many driver fake the pvBits, pvScan0 and
  195. // scanline delta for creating smaller surface and that sometime cause
  196. // halftone to break, to do this we passed to halftone ScanLineDelta and
  197. // (from lDelta in SURFOBJ) and pvScan0.
  198. //
  199. HTSurfInfo.hSurface = (ULONG_PTR)pSurfObj;
  200. HTSurfInfo.SurfaceFormat = (BYTE)iFormatHT;
  201. HTSurfInfo.ScanLineAlignBytes = BMF_ALIGN_DWORD;
  202. HTSurfInfo.Width = pSurfObj->sizlBitmap.cx;
  203. HTSurfInfo.Height = pSurfObj->sizlBitmap.cy;
  204. HTSurfInfo.ScanLineDelta = pSurfObj->lDelta;
  205. HTSurfInfo.pPlane = (LPBYTE)pSurfObj->pvScan0;
  206. HTSurfInfo.Flags = (USHORT)((pSurfObj->fjBitmap & BMF_TOPDOWN) ?
  207. HTSIF_SCANLINES_TOPDOWN : 0);
  208. HTSurfInfo.pColorTriad = NULL;
  209. *pHTSurfInfo = HTSurfInfo;
  210. return(TRUE);
  211. }
  212. /******************************Public*Routine******************************\
  213. * ppalGetFromXlate
  214. *
  215. * The halftoning algorithm needs to know the source palette. Unfortunately
  216. * the system wasn't designed to preserve that information, but with some
  217. * work we can do it. This routine starts the process of finding the source
  218. * palette in more of the cases. This routine will probably be modified
  219. * greatly to get 100% accuracy. We would need to construct a palette from
  220. * the table of indices given based on the DST palette or DST DC palette (if
  221. * pal managed) and return it. If this routine starts manufacturing palettes
  222. * it would need to inc the ref count on ones it doesn't create and then when
  223. * done dec the count and delete if 0. However this would require the rest
  224. * of palette world to use this convention and it all would take a week of
  225. * work.
  226. *
  227. * History:
  228. * 18-Feb-1994 -by- Patrick Haluptzok patrickh
  229. * Wrote it.
  230. \**************************************************************************/
  231. PPALETTE ppalGetFromXlate(SURFACE *pSurfSrc, SURFACE *pSurfDst,
  232. XLATE *pxlo, UINT iPal, BOOL bFirstTime)
  233. {
  234. ASSERTGDI((iPal == XO_SRCPALETTE) || (iPal == XO_DESTPALETTE), "ERROR invalid type requested");
  235. //
  236. // See if the source palette is lying in the source surface like
  237. // it usually is.
  238. //
  239. PPALETTE ppalReturn;
  240. if (iPal == XO_SRCPALETTE)
  241. {
  242. ppalReturn = pSurfSrc->ppal();
  243. }
  244. else
  245. {
  246. ppalReturn = pSurfDst->ppal();
  247. }
  248. if (ppalReturn == NULL)
  249. {
  250. //
  251. // Check xlate is passed in is not NULL and it's really valid.
  252. // Global ident xlate is not valid, it's just a shell with the
  253. // accelerators filled in.
  254. //
  255. if (pxlo != NULL)
  256. {
  257. if (iPal == XO_SRCPALETTE)
  258. {
  259. ppalReturn = pxlo->ppalSrc;
  260. }
  261. else
  262. {
  263. ppalReturn = pxlo->ppalDst;
  264. }
  265. }
  266. if (ppalReturn == NULL)
  267. {
  268. //
  269. // Let's try and grab it out of the PDEV now.
  270. //
  271. if (iPal == XO_SRCPALETTE)
  272. {
  273. PDEVOBJ po(pSurfSrc->hdev());
  274. if (po.bValid() && po.bIsPalManaged())
  275. {
  276. if (pSurfSrc->iFormat() == po.iDitherFormat())
  277. {
  278. ppalReturn = po.ppalSurf();
  279. }
  280. }
  281. }
  282. else
  283. {
  284. PDEVOBJ po(pSurfDst->hdev());
  285. if (po.bValid() && !po.bIsPalManaged())
  286. {
  287. if (pSurfDst->iFormat() == po.iDitherFormat())
  288. {
  289. ppalReturn = po.ppalSurf();
  290. }
  291. }
  292. }
  293. if (ppalReturn == NULL)
  294. {
  295. if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
  296. {
  297. //
  298. // Well if we can't figure it out from the source
  299. // and it's identity just get it from the destination
  300. //
  301. if (bFirstTime)
  302. ppalReturn = ppalGetFromXlate(pSurfSrc, pSurfDst, pxlo, iPal == XO_SRCPALETTE ? XO_DESTPALETTE : XO_SRCPALETTE, FALSE);
  303. }
  304. }
  305. }
  306. }
  307. return(ppalReturn);
  308. }
  309. /******************************Public*Function*****************************\
  310. * EngHTBlt
  311. *
  312. * Stretch/PlgBlt with halftone mode.
  313. *
  314. * History:
  315. * 19-Nov-1991 -by- Wendy Wu [wendywu]
  316. * Adapted from gdi\printers\rasdd\stretch.c.
  317. \**************************************************************************/
  318. int EngHTBlt
  319. (
  320. IN SURFOBJ *psoDst,
  321. IN SURFOBJ *psoSrc,
  322. IN SURFOBJ *psoMask,
  323. IN CLIPOBJ *pco,
  324. IN XLATEOBJ *pxlo,
  325. IN COLORADJUSTMENT *pca,
  326. IN PPOINTL pptlBrushOrg,
  327. IN PRECTL prclDest,
  328. IN PRECTL prclSrc,
  329. IN PPOINTL pptlMask,
  330. IN ULONG uFlags,
  331. IN BLENDOBJ *pBlendObj)
  332. {
  333. PSURFACE pSurfDst = SURFOBJ_TO_SURFACE(psoDst);
  334. PSURFACE pSurfSrc = SURFOBJ_TO_SURFACE(psoSrc);
  335. PSURFACE pSurfMask = SURFOBJ_TO_SURFACE(psoMask);
  336. HTSURFACEINFO HTDest;
  337. HTSURFACEINFO HTSrc;
  338. HTSURFACEINFO HTMask;
  339. COLORTRIAD clrtri;
  340. BYTE aclr[256];
  341. LONG cjDstWidth;
  342. PDEVOBJ poDst(pSurfDst->hdev());
  343. if (!poDst.bValid())
  344. return(HTBLT_NOTSUPPORTED);
  345. // Halftoning will relay on driver's halftone palette and output format,
  346. // even the target surface is not device surface. so that during halftoning,
  347. // we need to prevent happen dynamic mode chage, if the device is display.
  348. // thus we hold devlock here.
  349. DEVLOCKOBJ dlo;
  350. if (poDst.bDisplayPDEV())
  351. dlo.vLock(poDst);
  352. else
  353. dlo.vInit();
  354. // iFormatDst: The format of the destination bitmap. This is also used for
  355. // shadow bitmap creation if destination is not an engine bitmap.
  356. // iFormatHT: The halftone format that we'll pass to HT_HalftoneBitmap.
  357. // iFormatHTPal: The halftone format that we'll use to determine what kind
  358. // of halftone palette to create.
  359. ULONG iFormatDst, iFormatHT, iFormatHTPal;
  360. // Determine the halftone and destination bitmap formats.
  361. // If the destination is a DIB, we'll write directly to it unless the halftone
  362. // palette is different from the dest palette. So the halftone format has
  363. // to be the same as the destination format.
  364. // If the destination is not a DIB, we'll halftone to a shadow bitmap.
  365. // The format of this bitmap can be different from the device format and
  366. // is depending on the halftone format in GDIINFO.
  367. if (psoDst->iType == STYPE_BITMAP)
  368. {
  369. switch(pSurfDst->iFormat())
  370. {
  371. case BMF_1BPP:
  372. cjDstWidth = ((psoDst->sizlBitmap.cx + 31) & ~31) >> 3;
  373. iFormatHT = iFormatDst = BMF_1BPP;
  374. iFormatHTPal = HT_FORMAT_1BPP;
  375. break;
  376. case BMF_4BPP:
  377. cjDstWidth = ((psoDst->sizlBitmap.cx + 7) & ~7) >> 1;
  378. iFormatDst = BMF_4BPP;
  379. if (poDst.GdiInfo()->ulHTOutputFormat == HT_FORMAT_4BPP)
  380. {
  381. iFormatHT = BMF_4BPP;
  382. iFormatHTPal = HT_FORMAT_4BPP;
  383. }
  384. else
  385. {
  386. iFormatHT = BMF_4BPP_VGA16;
  387. iFormatHTPal = HT_FORMAT_4BPP_IRGB;
  388. }
  389. break;
  390. case BMF_8BPP:
  391. cjDstWidth = ((psoDst->sizlBitmap.cx + 3) & ~3);
  392. iFormatHT = BMF_8BPP_VGA256;
  393. iFormatDst = BMF_8BPP;
  394. iFormatHTPal = HT_FORMAT_8BPP;
  395. break;
  396. case BMF_16BPP:
  397. cjDstWidth = ((psoDst->sizlBitmap.cx + 1) & ~1) << 1;
  398. iFormatHT = BMF_16BPP_555;
  399. iFormatDst = BMF_16BPP;
  400. iFormatHTPal = HT_FORMAT_16BPP;
  401. break;
  402. case BMF_24BPP:
  403. cjDstWidth = (((psoDst->sizlBitmap.cx * 3) + 3) & ~3);
  404. iFormatHT = BMF_24BPP;
  405. iFormatDst = BMF_24BPP;
  406. iFormatHTPal = HT_FORMAT_24BPP;
  407. break;
  408. case BMF_32BPP:
  409. cjDstWidth = (((psoDst->sizlBitmap.cx << 2) + 3) & ~3);
  410. iFormatHT = BMF_32BPP;
  411. iFormatDst = BMF_32BPP;
  412. iFormatHTPal = HT_FORMAT_32BPP;
  413. break;
  414. default:
  415. return(HTBLT_NOTSUPPORTED);
  416. }
  417. }
  418. else
  419. {
  420. iFormatHTPal = poDst.GdiInfo()->ulHTOutputFormat;
  421. switch(iFormatHTPal)
  422. {
  423. case HT_FORMAT_1BPP:
  424. iFormatHT = iFormatDst = BMF_1BPP;
  425. break;
  426. case HT_FORMAT_4BPP:
  427. iFormatHT = iFormatDst = BMF_4BPP;
  428. break;
  429. case HT_FORMAT_4BPP_IRGB:
  430. iFormatHT = BMF_4BPP_VGA16;
  431. iFormatDst = BMF_4BPP;
  432. break;
  433. case HT_FORMAT_8BPP:
  434. iFormatHT = BMF_8BPP_VGA256;
  435. iFormatDst = BMF_8BPP;
  436. break;
  437. case HT_FORMAT_16BPP:
  438. iFormatHT = BMF_16BPP_555;
  439. iFormatDst = BMF_16BPP;
  440. break;
  441. case HT_FORMAT_24BPP:
  442. iFormatHT = BMF_24BPP;
  443. iFormatDst = BMF_24BPP;
  444. break;
  445. case HT_FORMAT_32BPP:
  446. iFormatHT = BMF_32BPP;
  447. iFormatDst = BMF_32BPP;
  448. break;
  449. default:
  450. return(HTBLT_NOTSUPPORTED);
  451. }
  452. }
  453. ERECTL erclTrim(0, 0, psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy);
  454. erclTrim *= *prclSrc;
  455. if (erclTrim.bEmpty())
  456. return(HTBLT_SUCCESS);
  457. //
  458. // Initialize halftone structure and get ready.
  459. //
  460. if ((poDst.pDevHTInfo() == NULL) && !poDst.bEnableHalftone(pca))
  461. return(HTBLT_ERROR);
  462. SURFACE *pSurfTempSrc;
  463. SURFMEM dimoSrc;
  464. //
  465. // Synchronize with the source device driver.
  466. //
  467. if ( pSurfSrc->flags() & HOOK_SYNCHRONIZE)
  468. {
  469. PDEVOBJ po( pSurfSrc->hdev());
  470. po.vSync(psoSrc,NULL,0);
  471. }
  472. if ((psoSrc->iType == STYPE_BITMAP) &&
  473. (psoSrc->iBitmapFormat != BMF_4RLE) &&
  474. (psoSrc->iBitmapFormat != BMF_8RLE))
  475. {
  476. pSurfTempSrc = pSurfSrc;
  477. }
  478. else
  479. {
  480. // Get the bits from the device.
  481. // Find out the format to use by looking at the preferred format in
  482. // the surface's pdev devinfo structure. We want to keep the original
  483. // color as much as possible since the halftone routine does a better
  484. // job in converting colors.
  485. DEVBITMAPINFO dbmiSrc;
  486. dbmiSrc.cxBitmap = psoSrc->sizlBitmap.cx;
  487. dbmiSrc.cyBitmap = psoSrc->sizlBitmap.cy;
  488. dbmiSrc.hpal = (HPALETTE) 0;
  489. dbmiSrc.fl = pSurfSrc->bUMPD() ? UMPD_SURFACE : 0;
  490. switch (psoSrc->iBitmapFormat)
  491. {
  492. case BMF_4RLE:
  493. dbmiSrc.iFormat = BMF_4BPP;
  494. break;
  495. case BMF_8RLE:
  496. dbmiSrc.iFormat = BMF_8BPP;
  497. break;
  498. default:
  499. dbmiSrc.iFormat = psoSrc->iBitmapFormat;
  500. break;
  501. }
  502. if (!dimoSrc.bCreateDIB(&dbmiSrc, (PVOID) NULL))
  503. {
  504. WARNING("dimoSrc.bCreateDIB failed in EngHTBlt\n");
  505. return(HTBLT_ERROR);
  506. }
  507. // Copy the bits, dispatch off dst's ldev which is the engine.
  508. if (!EngCopyBits(dimoSrc.pSurfobj(),
  509. psoSrc,
  510. (CLIPOBJ *) NULL,
  511. &xloIdent,
  512. &erclTrim,
  513. (POINTL *)&erclTrim))
  514. {
  515. WARNING("EngHTBlt:CopyBits failes\n");
  516. return(HTBLT_ERROR);
  517. }
  518. pSurfTempSrc = dimoSrc.ps;
  519. }
  520. //
  521. // Get the source palette.
  522. //
  523. PPALETTE ppalS = ppalGetFromXlate(pSurfSrc, pSurfDst, (XLATE *) pxlo, XO_SRCPALETTE, TRUE);
  524. if (ppalS == NULL)
  525. {
  526. WARNING("EngHTBlt could not find Source palette to use\n");
  527. return(HTBLT_NOTSUPPORTED);
  528. }
  529. XEPALOBJ palSrc(ppalS);
  530. //
  531. // Dest surface palette will be invalid only if it's a 256 color bitmap.
  532. //
  533. XEPALOBJ palDstSurf(ppalGetFromXlate( pSurfSrc, pSurfDst, (XLATE *) pxlo, XO_DESTPALETTE, TRUE));
  534. // Let's see if halftone palette is the same as the destination palette.
  535. BOOL bNoXlate;
  536. PALMEMOBJ palHTDst;
  537. XEPALOBJ *ppalHT = (XEPALOBJ *)NULL;
  538. if (iFormatHTPal != poDst.GdiInfo()->ulHTOutputFormat)
  539. {
  540. if (!palHTDst.bCreateHTPalette(iFormatHTPal, poDst.GdiInfo()))
  541. {
  542. return(HTBLT_ERROR);
  543. }
  544. ppalHT = (XEPALOBJ *)&palHTDst;
  545. bNoXlate = palHTDst.bEqualEntries(palDstSurf);
  546. }
  547. else
  548. {
  549. bNoXlate = poDst.bHTPalIsDevPal();
  550. }
  551. // Prepare for HT_HalftoneBitmap call.
  552. BITBLTPARAMS BitbltParams;
  553. ABINFO AbInfo;
  554. if(uFlags == BBPF_DO_ALPHA_BLEND)
  555. {
  556. BLENDFUNCTION BlendFunction = pBlendObj->BlendFunction;
  557. if(BlendFunction.BlendOp == AC_SRC_OVER)
  558. {
  559. AbInfo.Flags = 0;
  560. AbInfo.pDstPal = 0;
  561. AbInfo.cDstPal = 0;
  562. AbInfo.ConstAlphaValue = BlendFunction.SourceConstantAlpha;
  563. if(BlendFunction.AlphaFormat == AC_SRC_ALPHA &&
  564. BlendFunction.SourceConstantAlpha == 255)
  565. {
  566. // Per pixel Alpha : Need palette info.
  567. if(!bIsSourceBGRA(pSurfSrc))
  568. return HTBLT_ERROR;
  569. AbInfo.Flags |= ABIF_SRC_ALPHA_IS_PREMUL;
  570. //if(iFormatDst == BMF_32BPP)
  571. // AbInfo.Flags |= ABIF_BLEND_DEST_ALPHA;
  572. }
  573. else
  574. {
  575. AbInfo.Flags |= ABIF_USE_CONST_ALPHA_VALUE;
  576. }
  577. // Set Destination palette values for Halftone.
  578. if(palDstSurf.bValid())
  579. {
  580. AbInfo.pDstPal = (LPPALETTEENTRY)palDstSurf.apalColorGet();
  581. AbInfo.cDstPal = (WORD)palDstSurf.cEntries();
  582. if(palDstSurf.bIsBGR() ||
  583. ((palDstSurf.bIsBitfields()) &&
  584. (palDstSurf.flRed() == 0xff0000) &&
  585. (palDstSurf.flGre() == 0xff00) &&
  586. (palDstSurf.flBlu() == 0xff)))
  587. AbInfo.Flags |= ABIF_DSTPAL_IS_RGBQUAD;
  588. }
  589. BitbltParams.pABInfo = &AbInfo;
  590. }
  591. else
  592. uFlags = 0;
  593. }
  594. //
  595. // Remove pAbort, since it never used and delete by ht.h
  596. //
  597. BitbltParams.rclSrc = *prclSrc;
  598. BitbltParams.rclDest = *prclDest;
  599. BitbltParams.Flags = (USHORT)uFlags;
  600. BitbltParams.ptlBrushOrg = *pptlBrushOrg;
  601. BitbltParams.DestPrimaryOrder = (BYTE)poDst.GdiInfo()->ulPrimaryOrder;
  602. // Set ICM flags for halftoning
  603. ULONG lIcmMode = pxlo ? ((XLATE *) pxlo)->lIcmMode : DC_ICM_OFF;
  604. // 1) IF application ICM, BBPF_ICM_ON is ON.
  605. // 2) IF other ICM and not device caribrate, BBPF_ICM_ON is ON.
  606. if((IS_ICM_OUTSIDEDC(lIcmMode)) ||
  607. (!IS_ICM_DEVICE_CALIBRATE(lIcmMode) && (IS_ICM_HOST(lIcmMode) || (IS_ICM_DEVICE(lIcmMode)))))
  608. {
  609. ICMDUMP(("EngHTBlt(): ICM with Halftone (Dynamic Bit On)\n"));
  610. // Some kind of ICM (ICM on Application, Graphics Engine or Device)
  611. // is enabled, so tell halftoning code to disable thier color adjustment.
  612. BitbltParams.Flags |= BBPF_ICM_ON;
  613. }
  614. else
  615. {
  616. ICMDUMP(("EngHTBlt(): ICM with Halftone (Dynamic Bit Off)\n"));
  617. }
  618. // Get the relevant information about the destination bitmap.
  619. SURFACE *pSurfTempDst = pSurfDst;
  620. SURFMEM dimoDst;
  621. // Create a temporary bitmap if
  622. // 1) the destination bitmap is not an engine bitmap. or
  623. // 2) the bitmap width is not equal to the stride, because the halftone
  624. // code assumes they are equivalent, or
  625. // 3) the destination is not 8bpp (we have special case for this) and
  626. // the halftone palette is different from the destination palette, or
  627. // 4) the surfaces are overlapping
  628. BOOL bCreateShadowBitmap = FALSE;
  629. BYTE iDComplexity = (pco == (CLIPOBJ *) NULL) ? DC_TRIVIAL
  630. : pco->iDComplexity;
  631. // After the following "if" block, pcoNew should be used for clipping instead
  632. // of pco. We implement single rect clipping through banding in halftone.
  633. // if DC_COMPLEX, create a shadow bitmap to avoid calling HT_Bitmap many times
  634. CLIPOBJ *pcoNew = pco;
  635. if ((psoDst->iType != STYPE_BITMAP) ||
  636. (psoDst->lDelta != cjDstWidth) ||
  637. ((iFormatDst != BMF_8BPP) && !bNoXlate) ||
  638. (iDComplexity == DC_COMPLEX)||
  639. ((psoDst == psoSrc) && bIntersect(prclSrc, prclDest)))
  640. {
  641. bCreateShadowBitmap = TRUE;
  642. PRECTL prcl = prclDest;
  643. if (iDComplexity != DC_TRIVIAL)
  644. {
  645. // Clipping is not DC_TRIVIAL, use rclBounds as dest rect.
  646. prcl = &pco->rclBounds;
  647. // Clipping is done through banding if DC_RECT, do not clip
  648. // in CopyBits.
  649. if (iDComplexity == DC_RECT)
  650. pcoNew = NULL;
  651. // Do not enumerate clipping when calling halftone by marking
  652. // complexity to DC_TRIVIAL.
  653. iDComplexity = DC_TRIVIAL;
  654. }
  655. // Banding rect has to be well ordered and confined in the surface area.
  656. LONG lDxDst, lDyDst;
  657. SIZEL sizlDst = pSurfDst->sizl();
  658. LONG lLeft, lRight, lTop, lBottom;
  659. // Do the x part.
  660. if (prcl->right > prcl->left)
  661. {
  662. lLeft = prcl->left;
  663. lRight = prcl->right;
  664. }
  665. else
  666. {
  667. lLeft = prcl->right;
  668. lRight = prcl->left;
  669. }
  670. if (lLeft < 0L)
  671. lLeft = 0L;
  672. if (lRight > sizlDst.cx)
  673. lRight = sizlDst.cx;
  674. if ((lDxDst = (lRight - lLeft)) <= 0L)
  675. return(HTBLT_SUCCESS);
  676. BitbltParams.rclBand.left = lLeft;
  677. BitbltParams.rclBand.right = lRight;
  678. // Do the y part.
  679. if (prcl->bottom > prcl->top)
  680. {
  681. lTop = prcl->top;
  682. lBottom = prcl->bottom;
  683. }
  684. else
  685. {
  686. lTop = prcl->bottom;
  687. lBottom = prcl->top;
  688. }
  689. if (lTop < 0)
  690. lTop = 0;
  691. if (lBottom > sizlDst.cy)
  692. lBottom = sizlDst.cy;
  693. if ((lDyDst = (lBottom - lTop)) <= 0L)
  694. return(HTBLT_SUCCESS);
  695. BitbltParams.rclBand.top = lTop;
  696. BitbltParams.rclBand.bottom = lBottom;
  697. BitbltParams.Flags |= BBPF_HAS_BANDRECT;
  698. // Create the shadow bitmap.
  699. DEVBITMAPINFO dbmiDst;
  700. dbmiDst.cxBitmap = lDxDst;
  701. dbmiDst.cyBitmap = lDyDst;
  702. dbmiDst.hpal = 0;
  703. dbmiDst.fl = pSurfDst->bUMPD() ? UMPD_SURFACE : 0;
  704. dbmiDst.iFormat = iFormatDst;
  705. if (!dimoDst.bCreateDIB(&dbmiDst, (PVOID) NULL))
  706. {
  707. WARNING("dimoDst.bCreateDIB failed in EngHTBlt\n");
  708. return(HTBLT_ERROR);
  709. }
  710. pSurfTempDst = dimoDst.ps;
  711. }
  712. //
  713. // We need to xlate from halftone palette to dest surface palette if
  714. // the halftone palette is different from the destination palette.
  715. //
  716. EXLATEOBJ xloHTToDst, xloDstToHT;
  717. XLATEOBJ *pxloHTToDst = &xloIdent, *pxloDstToHT = &xloIdent;
  718. DEVICEHALFTONEINFO *pDevHTInfo = (DEVICEHALFTONEINFO *)poDst.pDevHTInfo();
  719. if (!bNoXlate)
  720. {
  721. XEPALOBJ palDstDC;
  722. EPALOBJ palHT((HPALETTE)pDevHTInfo->DeviceOwnData);
  723. ASSERTGDI(palHT.bValid(),"EngHTBlt: invalid HT pal\n");
  724. if (ppalHT == (XEPALOBJ *)NULL)
  725. {
  726. ppalHT = &palHT;
  727. }
  728. if ((pxlo == NULL) ||
  729. (((XLATE *) pxlo)->ppalDstDC == NULL))
  730. {
  731. palDstDC.ppalSet(ppalDefault);
  732. }
  733. else
  734. {
  735. palDstDC.ppalSet(((XLATE *) pxlo)->ppalDstDC);
  736. }
  737. if (!xloHTToDst.bInitXlateObj(
  738. NULL,
  739. DC_ICM_OFF,
  740. *ppalHT,
  741. palDstSurf,
  742. palDstDC,
  743. palDstDC,
  744. 0,
  745. 0x00FFFFFF,
  746. 0x00FFFFFF
  747. ))
  748. {
  749. WARNING("EngHTBlt: bInitXlateObj HT to Dst failed\n");
  750. return(HTBLT_ERROR);
  751. }
  752. pxloHTToDst = xloHTToDst.pxlo();
  753. // Init the Dst pal to HT pal xlateobj so we can do CopyBits from
  754. // the destination surface to the halftone buffer.
  755. if ((pSurfMask || uFlags == BBPF_DO_ALPHA_BLEND) && bCreateShadowBitmap)
  756. {
  757. if (!xloDstToHT.bInitXlateObj(
  758. NULL,
  759. DC_ICM_OFF,
  760. palDstSurf,
  761. *ppalHT,
  762. palDstDC,
  763. palDstDC,
  764. 0,
  765. 0x00FFFFFF,
  766. 0x00FFFFFF
  767. ))
  768. {
  769. WARNING("EngHTBlt: bInitXlateObj Dst to HT failed\n");
  770. return(HTBLT_ERROR);
  771. }
  772. pxloDstToHT = xloDstToHT.pxlo();
  773. }
  774. }
  775. // If there is a source mask, copy the destination bits to the buffer
  776. // so we can do CopyBits later on. This is fater than creating a
  777. // stretched mask and BitBlt with the created masks.
  778. // Synchronize with the destination device driver.
  779. poDst.vSync(psoDst,NULL,0);
  780. if ((pSurfMask || uFlags == BBPF_DO_ALPHA_BLEND) && bCreateShadowBitmap)
  781. {
  782. ERECTL ercl(0, 0, pSurfTempDst->sizl().cx, pSurfTempDst->sizl().cy);
  783. // Inc target surface uniqueness
  784. INC_SURF_UNIQ(pSurfTempDst);
  785. if (!(*PPFNGET(poDst,CopyBits, pSurfDst->flags()))
  786. (
  787. pSurfTempDst->pSurfobj(), // Target surf
  788. psoDst, // Source surf
  789. (CLIPOBJ *)NULL, // ClipObj
  790. pxloDstToHT, // XlateObj
  791. (RECTL *)&ercl, // Dest rect
  792. (POINTL *)&BitbltParams.rclBand // Src offset
  793. ))
  794. {
  795. // CopyBits failed. We'll paint the background white.
  796. if (!EngBitBlt(pSurfTempDst->pSurfobj(), // Target surf
  797. (SURFOBJ *)NULL, // Source surf
  798. (SURFOBJ *)NULL, // Mask surf
  799. (CLIPOBJ *)NULL, // ClipObj
  800. NULL, // XlateObj
  801. (RECTL *)&ercl, // Dest rect
  802. (POINTL *)NULL, // Src offset
  803. (POINTL *)NULL, // Mask offset
  804. (BRUSHOBJ *)NULL, // BrushObj
  805. (POINTL *)NULL, // Brush origin
  806. 0xFFFF)) // Rop
  807. {
  808. return(HTBLT_ERROR);
  809. }
  810. }
  811. }
  812. HTSrc.pColorTriad = (PCOLORTRIAD)NULL; // assume not allocate
  813. BOOL bRet = FALSE;
  814. if (bSetHTSrcSurfInfo(pSurfTempSrc->pSurfobj(), palSrc, &HTSrc, pxlo) &&
  815. bSetHTSurfInfo(pSurfTempDst->pSurfobj(), &HTDest, iFormatHT) &&
  816. (!pSurfMask || bSetHTSurfInfo(pSurfMask->pSurfobj(), &HTMask, psoMask->iBitmapFormat)))
  817. {
  818. PHTSURFACEINFO pMask = (PHTSURFACEINFO)NULL;
  819. if (pSurfMask)
  820. {
  821. BitbltParams.ptlSrcMask = *pptlMask;
  822. pMask = &HTMask;
  823. }
  824. if (!(poDst.GdiInfo()->flHTFlags & HT_FLAG_OUTPUT_CMY))
  825. BitbltParams.Flags |= BBPF_USE_ADDITIVE_PRIMS;
  826. // 8BPP halftone does color translations. So pass the xlate along.
  827. if (iFormatDst == BMF_8BPP)
  828. {
  829. HTDest.pColorTriad = &clrtri;
  830. clrtri.Type = COLOR_TYPE_RGB;
  831. clrtri.BytesPerPrimary = 1;
  832. clrtri.BytesPerEntry = 1;
  833. clrtri.PrimaryOrder = COLOR_TYPE_RGB;
  834. clrtri.PrimaryValueMax = 255;
  835. clrtri.ColorTableEntries = 256;;
  836. clrtri.pColorTable = aclr;
  837. COUNT iLimit = MIN(256,pxloHTToDst->cEntries);
  838. for(COUNT i = 0; i < iLimit; i++)
  839. {
  840. aclr[i] = (BYTE)(*(pxloHTToDst->pulXlate + i));
  841. }
  842. pxloHTToDst = &xloIdent;
  843. }
  844. // HT_HalftoneBitmap will return number of scans being drawn.
  845. switch (iDComplexity)
  846. {
  847. case DC_RECT:
  848. BitbltParams.Flags |= BBPF_HAS_DEST_CLIPRECT;
  849. BitbltParams.rclClip = pcoNew->rclBounds;
  850. case DC_TRIVIAL:
  851. bRet = (HT_HalftoneBitmap(pDevHTInfo,
  852. (PHTCOLORADJUSTMENT)pca,
  853. (PHTSURFACEINFO)&HTSrc,
  854. pMask,
  855. (PHTSURFACEINFO)&HTDest,
  856. (PBITBLTPARAMS)&BitbltParams) >= 0L);
  857. break;
  858. default: // DC_COMPLEX
  859. BitbltParams.Flags |= BBPF_HAS_DEST_CLIPRECT;
  860. ((ECLIPOBJ *) pcoNew)->cEnumStart(FALSE,CT_RECTANGLES,
  861. CD_ANY,CLIPOBJ_ENUM_LIMIT);
  862. bRet = TRUE;
  863. BOOL bMore;
  864. CLIPENUMRECT clenr;
  865. do {
  866. bMore = ((ECLIPOBJ *) pcoNew)->bEnum(sizeof(clenr),
  867. (PVOID) &clenr);
  868. for (ULONG iRT = 0; iRT < clenr.c; iRT++)
  869. {
  870. BitbltParams.rclClip = clenr.arcl[iRT];
  871. bRet &= (HT_HalftoneBitmap(pDevHTInfo,
  872. (PHTCOLORADJUSTMENT)pca,
  873. (PHTSURFACEINFO)&HTSrc,
  874. pMask,
  875. (PHTSURFACEINFO)&HTDest,
  876. (PBITBLTPARAMS)&BitbltParams) >= 0L);
  877. }
  878. } while (bMore && bRet);
  879. break;
  880. }
  881. if (bCreateShadowBitmap && bRet)
  882. {
  883. // Dispatch the call. Give it no mask.
  884. EPOINTL eptl(0,0);
  885. // Inc target surface uniqueness
  886. INC_SURF_UNIQ(pSurfDst);
  887. if (psoDst->iType != STYPE_BITMAP)
  888. {
  889. bRet = (*PPFNGET(poDst,CopyBits, pSurfDst->flags())) (
  890. psoDst,
  891. pSurfTempDst->pSurfobj(),
  892. pcoNew,
  893. pxloHTToDst,
  894. &BitbltParams.rclBand,
  895. (POINTL *)&eptl);
  896. }
  897. else
  898. {
  899. bRet = EngCopyBits(
  900. psoDst,
  901. pSurfTempDst->pSurfobj(),
  902. pcoNew,
  903. pxloHTToDst,
  904. &BitbltParams.rclBand,
  905. (POINTL *)&eptl);
  906. }
  907. }
  908. }
  909. if (HTSrc.pColorTriad)
  910. VFREEMEM((LPSTR)HTSrc.pColorTriad);
  911. return(bRet ? HTBLT_SUCCESS : HTBLT_ERROR);
  912. }