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