b636bef965ffc91d5060c2ce2294cbe7fb87386b
[reactos.git] / reactos / subsystems / win32 / win32k / eng / xlate.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Color Translation Functions
5 * FILE: subsystems/win32/win32k/eng/xlate.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 #include <w32k.h>
10
11 #include <intrin.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /** Globals *******************************************************************/
18
19 ULONG giUniqueXlate = 0;
20 EXLATEOBJ gexloTrivial;
21 XLATEOBJ* gpxloTrivial = &gexloTrivial.xlo;
22
23 const BYTE gajXlate5to8[32] =
24 { 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99,107,115,123,
25 132,140,148,156,165,173,181,189,197,206,214,222,231,239,247,255};
26
27 const BYTE gajXlate6to8[64] =
28 { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 52, 57, 61,
29 65, 69, 73, 77, 81, 85, 89, 93, 97,101,105,109,113,117,121,125,
30 130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,
31 194,198,202,207,210,215,219,223,227,231,235,239,243,247,251,255};
32
33
34 /** iXlate functions **********************************************************/
35
36 ULONG
37 FASTCALL
38 EXLATEOBJ_iXlateTrivial(PEXLATEOBJ pexlo, ULONG iColor)
39 {
40 return iColor;
41 }
42
43 ULONG
44 FASTCALL
45 EXLATEOBJ_iXlateToMono(PEXLATEOBJ pexlo, ULONG iColor)
46 {
47 return (iColor == pexlo->xlo.pulXlate[0]);
48 }
49
50 ULONG
51 FASTCALL
52 EXLATEOBJ_iXlateTable(PEXLATEOBJ pexlo, ULONG iColor)
53 {
54 if (iColor >= pexlo->xlo.cEntries)
55 {
56 iColor %= pexlo->xlo.cEntries;
57 }
58 return pexlo->xlo.pulXlate[iColor];
59 }
60
61 ULONG
62 FASTCALL
63 EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor)
64 {
65 ULONG iNewColor;
66
67 /* Copy green */
68 iNewColor = iColor & 0x00ff00;
69
70 /* Mask red and blue */
71 iColor &= 0xff00ff;
72
73 /* Shift and copy red and blue */
74 iNewColor |= iColor >> 16;
75 iNewColor |= iColor << 16;
76
77 return iNewColor;
78 }
79
80 ULONG
81 FASTCALL
82 EXLATEOBJ_iXlateRGBto555(PEXLATEOBJ pxlo, ULONG iColor)
83 {
84 ULONG iNewColor;
85
86 /* Copy red */
87 iColor <<= 7;
88 iNewColor = iColor & 0x7C00;
89
90 /* Copy green */
91 iColor >>= 13;
92 iNewColor |= iColor & 0x3E0;
93
94 /* Copy green */
95 iColor >>= 13;
96 iNewColor |= iColor & 0x1F;
97
98 return iNewColor;
99 }
100
101 ULONG
102 FASTCALL
103 EXLATEOBJ_iXlateBGRto555(PEXLATEOBJ pxlo, ULONG iColor)
104 {
105 ULONG iNewColor;
106
107 /* Copy blue */
108 iColor >>= 3;
109 iNewColor = iColor & 0x1f;
110
111 /* Copy green */
112 iColor >>= 3;
113 iNewColor |= (iColor & 0x3E0);
114
115 /* Copy red */
116 iColor >>= 3;
117 iNewColor |= (iColor & 0x7C00);
118
119 return iNewColor;
120 }
121
122 ULONG
123 FASTCALL
124 EXLATEOBJ_iXlateRGBto565(PEXLATEOBJ pxlo, ULONG iColor)
125 {
126 ULONG iNewColor;
127
128 /* Copy red */
129 iColor <<= 8;
130 iNewColor = iColor & 0xF800;
131
132 /* Copy green */
133 iColor >>= 13;
134 iNewColor |= iColor & 0x7E0;
135
136 /* Copy green */
137 iColor >>= 14;
138 iNewColor |= iColor & 0x1F;
139
140 return iNewColor;
141 }
142
143 ULONG
144 FASTCALL
145 EXLATEOBJ_iXlateBGRto565(PEXLATEOBJ pxlo, ULONG iColor)
146 {
147 ULONG iNewColor;
148
149 /* Copy blue */
150 iColor >>= 3;
151 iNewColor = iColor & 0x1f;
152
153 /* Copy green */
154 iColor >>= 2;
155 iNewColor |= (iColor & 0x7E0);
156
157 /* Copy red */
158 iColor >>= 3;
159 iNewColor |= (iColor & 0xF800);
160
161 return iNewColor;
162 }
163
164 ULONG
165 FASTCALL
166 EXLATEOBJ_iXlateRGBtoPal(PEXLATEOBJ pexlo, ULONG iColor)
167 {
168 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
169 }
170
171 ULONG
172 FASTCALL
173 EXLATEOBJ_iXlate555toRGB(PEXLATEOBJ pxlo, ULONG iColor)
174 {
175 ULONG iNewColor;
176
177 /* Copy blue */
178 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
179
180 /* Copy green */
181 iColor >>= 5;
182 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
183
184 /* Copy red */
185 iColor >>= 5;
186 iNewColor |= gajXlate5to8[iColor & 0x1F];
187
188 return iNewColor;
189 }
190
191 ULONG
192 FASTCALL
193 EXLATEOBJ_iXlate555toBGR(PEXLATEOBJ pxlo, ULONG iColor)
194 {
195 ULONG iNewColor;
196
197 /* Copy blue */
198 iNewColor = gajXlate5to8[iColor & 0x1F];
199
200 /* Copy green */
201 iColor >>= 5;
202 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
203
204 /* Copy red */
205 iColor >>= 5;
206 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
207
208 return iNewColor;
209 }
210
211 ULONG
212 FASTCALL
213 EXLATEOBJ_iXlate555to565(PEXLATEOBJ pxlo, ULONG iColor)
214 {
215 ULONG iNewColor;
216
217 /* Copy blue */
218 iNewColor = iColor & 0x1f;
219
220 /* Copy red and green */
221 iColor <<= 1;
222 iNewColor |= iColor & 0xFFC0;
223
224 /* Duplicate highest green bit */
225 iColor >>= 5;
226 iNewColor |= (iColor & 0x20);
227
228 return iNewColor;
229 }
230
231 ULONG
232 FASTCALL
233 EXLATEOBJ_iXlate555toPal(PEXLATEOBJ pexlo, ULONG iColor)
234 {
235 iColor = EXLATEOBJ_iXlate555toRGB(pexlo, iColor);
236
237 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
238 }
239
240 ULONG
241 FASTCALL
242 EXLATEOBJ_iXlate565to555(PEXLATEOBJ pxlo, ULONG iColor)
243 {
244 ULONG iNewColor;
245
246 /* Copy blue */
247 iNewColor = iColor & 0x1f;
248
249 /* Copy red and green */
250 iColor >>= 1;
251 iNewColor |= iColor & 0x7FE0;
252
253 return iNewColor;
254 }
255
256 ULONG
257 FASTCALL
258 EXLATEOBJ_iXlate565toRGB(PEXLATEOBJ pexlo, ULONG iColor)
259 {
260 ULONG iNewColor;
261
262 /* Copy blue */
263 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
264
265 /* Copy green */
266 iColor >>= 5;
267 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
268
269 /* Copy red */
270 iColor >>= 6;
271 iNewColor |= gajXlate5to8[iColor & 0x1F];
272
273 return iNewColor;
274 }
275
276 ULONG
277 FASTCALL
278 EXLATEOBJ_iXlate565toBGR(PEXLATEOBJ pexlo, ULONG iColor)
279 {
280 ULONG iNewColor;
281
282 /* Copy blue */
283 iNewColor = gajXlate5to8[iColor & 0x1F];
284
285 /* Copy green */
286 iColor >>= 5;
287 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
288
289 /* Copy blue */
290 iColor >>= 6;
291 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
292
293 return iNewColor;
294 }
295
296 ULONG
297 FASTCALL
298 EXLATEOBJ_iXlate565toPal(EXLATEOBJ *pexlo, ULONG iColor)
299 {
300 iColor = EXLATEOBJ_iXlate565toRGB(pexlo, iColor);
301
302 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
303 }
304
305 ULONG
306 FASTCALL
307 EXLATEOBJ_iXlateShiftAndMask(PEXLATEOBJ pexlo, ULONG iColor)
308 {
309 ULONG iNewColor;
310
311 iNewColor = _rotl(iColor, pexlo->ulRedShift) & pexlo->ulRedMask;
312 iNewColor |= _rotl(iColor, pexlo->ulGreenShift) & pexlo->ulGreenMask;
313 iNewColor |= _rotl(iColor, pexlo->ulBlueShift) & pexlo->ulBlueMask;
314
315 return iNewColor;
316 }
317
318 ULONG
319 FASTCALL
320 EXLATEOBJ_iXlateBitfieldsToPal(PEXLATEOBJ pexlo, ULONG iColor)
321 {
322 /* Convert bitfields to RGB */
323 iColor = EXLATEOBJ_iXlateShiftAndMask(pexlo, iColor);
324
325 /* Return nearest index */
326 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
327 }
328
329
330 /** Private Functions *********************************************************/
331
332 VOID
333 NTAPI
334 EXLATEOBJ_vInitTrivial(PEXLATEOBJ pexlo)
335 {
336 pexlo->xlo.iUniq = InterlockedIncrement((LONG*)&giUniqueXlate);
337 pexlo->xlo.flXlate = XO_TRIVIAL;
338 pexlo->xlo.iSrcType = PAL_RGB;
339 pexlo->xlo.iDstType = PAL_RGB;
340 pexlo->xlo.cEntries = 0;
341 pexlo->xlo.pulXlate = pexlo->aulXlate;
342 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
343 pexlo->ppalSrc = &gpalRGB;
344 pexlo->ppalDst = &gpalRGB;
345 pexlo->ppalDstDc = &gpalRGB;
346 pexlo->hColorTransform = NULL;
347 }
348
349 VOID
350 NTAPI
351 EXLATEOBJ_vInitialize(
352 PEXLATEOBJ pexlo,
353 PALETTE *ppalSrc,
354 PALETTE *ppalDst,
355 COLORREF crSrcBackColor,
356 COLORREF crDstBackColor,
357 COLORREF crDstForeColor)
358 {
359 ULONG cEntries;
360 ULONG i, ulColor;
361
362 EXLATEOBJ_vInitTrivial(pexlo);
363
364 if (ppalDst == ppalSrc || !ppalSrc || !ppalDst ||
365 ((ppalDst->Mode == PAL_RGB || ppalDst->Mode == PAL_BGR) &&
366 ppalDst->Mode == ppalSrc->Mode))
367 {
368 return;
369 }
370
371 pexlo->ppalSrc = ppalSrc;
372 pexlo->ppalDst = ppalDst;
373 pexlo->xlo.iSrcType = ppalSrc->Mode;
374 pexlo->xlo.iDstType = ppalDst->Mode;
375
376 /* Chack if both of the pallettes are indexed */
377 if (!(ppalSrc->Mode & PAL_INDEXED) || !(ppalDst->Mode & PAL_INDEXED))
378 {
379 /* At least one palette is not indexed, calculate shifts/masks */
380 ULONG aulMasksSrc[3], aulMasksDst[3];
381
382 PALETTE_vGetBitMasks(ppalSrc, aulMasksSrc);
383 PALETTE_vGetBitMasks(ppalDst, aulMasksDst);
384
385 pexlo->ulRedMask = aulMasksDst[0];
386 pexlo->ulGreenMask = aulMasksDst[1];
387 pexlo->ulBlueMask = aulMasksDst[2];
388
389 pexlo->ulRedShift = CalculateShift(aulMasksSrc[0], aulMasksDst[0]);
390 pexlo->ulGreenShift = CalculateShift(aulMasksSrc[1], aulMasksDst[1]);
391 pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
392 }
393
394 if (ppalSrc->Mode & PAL_MONOCHROME)
395 {
396 /* This is a monochrome palette */
397 if (!(ppalDst->Mode & PAL_MONOCHROME))
398 {
399 /* Mono to color, use the dest DC's fore and back color */
400 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
401 pexlo->xlo.flXlate |= XO_TABLE;
402 pexlo->xlo.cEntries = 2;
403 pexlo->xlo.pulXlate[0] =
404 PALETTE_ulGetNearestIndex(ppalDst, crDstForeColor);
405 pexlo->xlo.pulXlate[1] =
406 PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
407 }
408 }
409 else if (ppalDst->Mode & PAL_MONOCHROME)
410 {
411 pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
412 pexlo->xlo.flXlate |= XO_TO_MONO;
413 pexlo->xlo.cEntries = 1;
414
415 if (ppalSrc->Mode & PAL_INDEXED)
416 {
417 pexlo->aulXlate[0] =
418 PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
419 }
420 else if (ppalSrc->Mode & PAL_BGR)
421 {
422 pexlo->aulXlate[0] = crSrcBackColor;
423 }
424 else if (ppalSrc->Mode & PAL_RGB)
425 {
426 pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
427 GetGValue(crSrcBackColor),
428 GetRValue(crSrcBackColor));
429 }
430 else if (ppalSrc->Mode & PAL_BITFIELDS)
431 {
432 PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
433 pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask);
434 pexlo->ulGreenShift = CalculateShift(0xFF00, pexlo->ulGreenMask);
435 pexlo->ulBlueShift = CalculateShift(0xFF0000, pexlo->ulBlueMask);
436
437 pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
438 }
439 }
440 else if (ppalSrc->Mode & PAL_INDEXED)
441 {
442 cEntries = ppalSrc->NumColors;
443
444 /* Allocate buffer if needed */
445 if (cEntries > 6)
446 {
447 pexlo->xlo.pulXlate = EngAllocMem(0,
448 cEntries * sizeof(ULONG),
449 TAG_XLATEOBJ);
450 if (!pexlo->xlo.pulXlate)
451 {
452 DPRINT1("Could not allocate pulXlate buffer.\n");
453 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
454 pexlo->xlo.flXlate = XO_TRIVIAL;
455 return;
456 }
457 }
458 pexlo->xlo.cEntries = cEntries;
459
460 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
461 if (ppalDst->Mode & PAL_INDEXED)
462 {
463 pexlo->xlo.flXlate |= XO_TABLE;
464
465 for (i = 0; i < cEntries; i++)
466 {
467 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
468 ppalSrc->IndexedColors[i].peGreen,
469 ppalSrc->IndexedColors[i].peBlue);
470
471 pexlo->xlo.pulXlate[i] =
472 PALETTE_ulGetNearestPaletteIndex(ppalDst, ulColor);
473
474 if (pexlo->xlo.pulXlate[i] != i)
475 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
476 }
477
478 if (pexlo->xlo.flXlate & XO_TRIVIAL)
479 {
480 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
481 {
482 EngFreeMem(pexlo->xlo.pulXlate);
483 pexlo->xlo.pulXlate = pexlo->aulXlate;
484 }
485 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
486 pexlo->xlo.flXlate = XO_TRIVIAL;
487 return;
488 }
489 }
490 else
491 {
492 // FIXME: use PALETTE_ulGetNearest
493 EXLATEOBJ exloTmp = *pexlo;
494 exloTmp.xlo.pulXlate = exloTmp.aulXlate;
495
496 pexlo->xlo.flXlate |= XO_TABLE;
497 for (i = 0; i < pexlo->xlo.cEntries; i++)
498 {
499 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
500 ppalSrc->IndexedColors[i].peGreen,
501 ppalSrc->IndexedColors[i].peBlue);
502 pexlo->xlo.pulXlate[i] =
503 EXLATEOBJ_iXlateShiftAndMask(&exloTmp, ulColor);
504 }
505 }
506 }
507 else if (ppalSrc->Mode & PAL_RGB)
508 {
509 if (ppalDst->Mode & PAL_INDEXED)
510 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
511
512 else if (ppalDst->Mode & PAL_BGR)
513 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
514
515 else if (ppalDst->Mode & PAL_RGB16_555)
516 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
517
518 else if (ppalDst->Mode & PAL_RGB16_565)
519 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
520
521 else if (ppalDst->Mode & PAL_BITFIELDS)
522 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
523 }
524 else if (ppalSrc->Mode & PAL_BGR)
525 {
526 if (ppalDst->Mode & PAL_INDEXED)
527 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
528
529 else if (ppalDst->Mode & PAL_RGB)
530 /* The inverse function works the same */
531 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
532
533 else if (ppalDst->Mode & PAL_RGB16_555)
534 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
535
536 else if (ppalDst->Mode & PAL_RGB16_565)
537 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
538
539 else if (ppalDst->Mode & PAL_BITFIELDS)
540 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
541 }
542 else if (ppalSrc->Mode & PAL_RGB16_555)
543 {
544 if (ppalDst->Mode & PAL_INDEXED)
545 pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
546
547 else if (ppalDst->Mode & PAL_RGB)
548 pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
549
550 else if (ppalDst->Mode & PAL_BGR)
551 pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
552
553 else if (ppalDst->Mode & PAL_RGB16_565)
554 pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
555
556 else if (ppalDst->Mode & PAL_BITFIELDS)
557 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
558 }
559 else if (ppalSrc->Mode & PAL_RGB16_565)
560 {
561 if (ppalDst->Mode & PAL_INDEXED)
562 pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
563
564 else if (ppalDst->Mode & PAL_RGB)
565 pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
566
567 else if (ppalDst->Mode & PAL_BGR)
568 pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
569
570 else if (ppalDst->Mode & PAL_RGB16_555)
571 pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
572
573 else if (ppalDst->Mode & PAL_BITFIELDS)
574 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
575 }
576 else if (ppalSrc->Mode & PAL_BITFIELDS)
577 {
578 if (ppalDst->Mode & PAL_INDEXED)
579 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
580 else
581 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
582 }
583
584 /* Check for a trivial shift and mask operation */
585 if (pexlo->pfnXlate == EXLATEOBJ_iXlateShiftAndMask &&
586 !pexlo->ulRedShift && !pexlo->ulGreenShift && !pexlo->ulBlueShift)
587 {
588 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
589 }
590
591 /* Check for trivial xlate */
592 if (pexlo->pfnXlate == EXLATEOBJ_iXlateTrivial)
593 pexlo->xlo.flXlate = XO_TRIVIAL;
594 else
595 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
596 }
597
598 VOID
599 NTAPI
600 EXLATEOBJ_vInitXlateFromDCs(
601 EXLATEOBJ* pexlo,
602 PDC pdcSrc,
603 PDC pdcDst)
604 {
605 PSURFACE psurfDst, psurfSrc;
606 HPALETTE hpalSrc, hpalDst;
607 PPALETTE ppalSrc, ppalDst, ppalDstDc;
608
609 DPRINT("Enter EXLATEOBJ_vInitXlateFromDCs\n");
610
611 /* Do basic init */
612 EXLATEOBJ_vInitTrivial(pexlo);
613
614 psurfDst = pdcDst->dclevel.pSurface;
615 psurfSrc = pdcSrc->dclevel.pSurface;
616
617 if (psurfDst == psurfSrc)
618 {
619 return;
620 }
621
622 hpalSrc = psurfSrc->hDIBPalette;
623 if (!hpalSrc)
624 hpalSrc = pPrimarySurface->DevInfo.hpalDefault;
625
626 ppalSrc = PALETTE_ShareLockPalette(hpalSrc);
627 if (!ppalSrc)
628 return;
629
630 hpalDst = psurfDst->hDIBPalette;
631 if (!hpalDst) hpalDst = pPrimarySurface->DevInfo.hpalDefault;
632
633 ppalDst = PALETTE_ShareLockPalette(hpalDst);
634 if (!ppalDst)
635 {
636 PALETTE_ShareUnlockPalette(ppalSrc);
637 return;
638 }
639
640 ppalDstDc = pdcDst->dclevel.ppal;
641 ASSERT(ppalDstDc);
642
643 /* KB41464 details how to convert between mono and color */
644 if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
645 {
646 if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
647 {
648 // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
649 EXLATEOBJ_vInitialize(pexlo,
650 ppalSrc,
651 &gpalMono,
652 pdcSrc->pdcattr->crBackgroundClr,
653 pdcDst->pdcattr->crBackgroundClr,
654 pdcDst->pdcattr->crForegroundClr);
655 }
656 }
657 else if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP && !psurfSrc->hSecure)
658 {
659 // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
660 EXLATEOBJ_vInitialize(pexlo,
661 &gpalMono,
662 ppalDst,
663 0,
664 pdcDst->pdcattr->crBackgroundClr,
665 pdcDst->pdcattr->crForegroundClr);
666 }
667 else
668 {
669 EXLATEOBJ_vInitialize(pexlo, ppalSrc, ppalDst, 0, 0, 0);
670 }
671
672 PALETTE_ShareUnlockPalette(ppalDst);
673 PALETTE_ShareUnlockPalette(ppalSrc);
674 }
675
676
677 VOID
678 NTAPI
679 EXLATEOBJ_vInitBrushXlate(
680 PEXLATEOBJ pexlo,
681 BRUSH *pbrush,
682 SURFACE *psurfDst,
683 COLORREF crForegroundClr,
684 COLORREF crBackgroundClr)
685 {
686 HPALETTE hpalDst = NULL;
687 PPALETTE ppalDst, ppalPattern;
688 SURFACE *psurfPattern;
689
690 ASSERT(pexlo);
691 ASSERT(pbrush);
692 ASSERT(psurfDst);
693 ASSERT(!(pbrush->flAttrs & (GDIBRUSH_IS_SOLID | GDIBRUSH_IS_NULL)));
694
695 EXLATEOBJ_vInitTrivial(pexlo);
696
697 hpalDst = psurfDst->hDIBPalette;
698 if (!hpalDst) hpalDst = pPrimarySurface->DevInfo.hpalDefault;
699 ppalDst = PALETTE_ShareLockPalette(hpalDst);
700 if (!ppalDst)
701 {
702 DPRINT1("No ppalDst!\n");
703 return;
704 }
705
706 psurfPattern = SURFACE_ShareLockSurface(pbrush->hbmPattern);
707 if (!psurfPattern)
708 {
709 PALETTE_ShareUnlockPalette(ppalDst);
710 return;
711 }
712
713 #if 0
714 if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
715 {
716 if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
717 {
718 // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
719 EXLATEOBJ_vInitialize(pexlo,
720 ppalSrc,
721 &gpalMono,
722 0,
723 crBackgroundClr,
724 crForegroundClr);
725 }
726 }
727 else
728 #endif
729 if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP &&
730 !(pbrush->flAttrs & GDIBRUSH_IS_DIB))
731 {
732 /* Special case: 1 bpp pattern, not a DIB brush. */
733 if (psurfDst->SurfObj.iBitmapFormat != BMF_1BPP)
734 {
735 // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
736 EXLATEOBJ_vInitialize(pexlo,
737 &gpalMono,
738 ppalDst,
739 0,
740 crBackgroundClr,
741 crForegroundClr);
742 }
743 }
744 else
745 {
746 /* Default: use the patterns' palette */
747 ppalPattern = PALETTE_LockPalette(psurfPattern->hDIBPalette);
748 if (ppalPattern)
749 {
750 EXLATEOBJ_vInitialize(pexlo, &gpalRGB, ppalDst, 0, 0, 0);
751 PALETTE_UnlockPalette(ppalPattern);
752 }
753 }
754
755 PALETTE_ShareUnlockPalette(ppalDst);
756 SURFACE_ShareUnlockSurface(psurfPattern);
757 }
758
759 VOID
760 NTAPI
761 EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)
762 {
763 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
764 {
765 EngFreeMem(pexlo->xlo.pulXlate);
766 }
767 pexlo->xlo.pulXlate = pexlo->aulXlate;
768 }
769
770 VOID
771 InitXlateImpl(VOID)
772 {
773
774 EXLATEOBJ_vInitTrivial(&gexloTrivial);
775 }
776
777
778 /** Public DDI Functions ******************************************************/
779
780 #undef XLATEOBJ_iXlate
781 ULONG
782 NTAPI
783 XLATEOBJ_iXlate(XLATEOBJ *pxlo, ULONG iColor)
784 {
785 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
786
787 if (!pxlo)
788 return iColor;
789
790 /* Call the iXlate function */
791 return pexlo->pfnXlate(pexlo, iColor);
792 }
793
794 ULONG
795 NTAPI
796 XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
797 {
798 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
799 PPALETTE ppal;
800 INT i;
801
802 if (!pxlo)
803 {
804 return 0;
805 }
806
807 if (iPal > 5)
808 {
809 DPRINT1("XLATEOBJ_cGetPalette called with wrong iPal: %d\n", iPal);
810 return 0;
811 }
812
813 /* Get the requested palette */
814 if (iPal == XO_DESTDCPALETTE)
815 {
816 ppal = pexlo->ppalDstDc;
817 }
818 else if (iPal == XO_SRCPALETTE || iPal == XO_SRCBITFIELDS)
819 {
820 ppal = pexlo->ppalSrc;
821 }
822 else
823 {
824 ppal = pexlo->ppalDst;
825 }
826
827 /* Verify palette type match */
828 if (!ppal ||
829 ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
830 && !(ppal->Mode & PAL_INDEXED)) ||
831 ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
832 && !(ppal->Mode & PAL_BITFIELDS)))
833 {
834 return 0;
835 }
836
837 if(!pPalOut)
838 {
839 return ppal->NumColors;
840 }
841
842 /* Copy the values into the buffer */
843 if (ppal->Mode & PAL_INDEXED)
844 {
845 cPal = min(cPal, ppal->NumColors);
846 for (i = 0; i < cPal; i++)
847 {
848 pPalOut[i] = RGB(ppal->IndexedColors[i].peRed,
849 ppal->IndexedColors[i].peGreen,
850 ppal->IndexedColors[i].peBlue);
851 }
852 }
853 else
854 {
855 // FIXME: should use the above code
856 pPalOut[0] = ppal->RedMask;
857 pPalOut[1] = ppal->GreenMask;
858 pPalOut[2] = ppal->BlueMask;
859 }
860
861 return cPal;
862 }
863
864 HANDLE
865 NTAPI
866 XLATEOBJ_hGetColorTransform(XLATEOBJ *pxlo)
867 {
868 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
869 return pexlo->hColorTransform;
870 }
871
872 PULONG
873 NTAPI
874 XLATEOBJ_piVector(XLATEOBJ *pxlo)
875 {
876 if (pxlo->iSrcType == PAL_INDEXED)
877 {
878 return pxlo->pulXlate;
879 }
880
881 return NULL;
882 }
883
884 /* EOF */