[NtGdi]
[reactos.git] / reactos / win32ss / gdi / ntgdi / dcutil.c
1 #include <win32k.h>
2
3 #define NDEBUG
4 #include <debug.h>
5
6 BOOL FASTCALL
7 GreDPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
8 {
9 PDC dc;
10 if (!(dc = DC_LockDc(hdc)))
11 {
12 EngSetLastError(ERROR_INVALID_HANDLE);
13 return FALSE;
14 }
15 IntDPtoLP(dc, lpPoints, nCount);
16 DC_UnlockDc(dc);
17 return TRUE;
18 }
19
20 BOOL FASTCALL
21 GreLPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount)
22 {
23 PDC dc;
24 if (!(dc = DC_LockDc(hdc)))
25 {
26 EngSetLastError(ERROR_INVALID_HANDLE);
27 return FALSE;
28 }
29 IntLPtoDP(dc, lpPoints, nCount);
30 DC_UnlockDc(dc);
31 return TRUE;
32 }
33
34 int FASTCALL
35 GreGetBkMode(HDC hdc)
36 {
37 PDC dc;
38 LONG lBkMode;
39 if (!(dc = DC_LockDc(hdc)))
40 {
41 EngSetLastError(ERROR_INVALID_HANDLE);
42 return CLR_INVALID;
43 }
44 lBkMode = dc->pdcattr->lBkMode;
45 DC_UnlockDc(dc);
46 return lBkMode;
47 }
48
49 COLORREF FASTCALL
50 GreGetBkColor(HDC hdc)
51 {
52 PDC dc;
53 COLORREF crBk;
54 if (!(dc = DC_LockDc(hdc)))
55 {
56 EngSetLastError(ERROR_INVALID_HANDLE);
57 return CLR_INVALID;
58 }
59 crBk = dc->pdcattr->ulBackgroundClr;
60 DC_UnlockDc(dc);
61 return crBk;
62 }
63
64 int FASTCALL
65 GreGetMapMode(HDC hdc)
66 {
67 PDC dc;
68 INT iMapMode;
69 if (!(dc = DC_LockDc(hdc)))
70 {
71 EngSetLastError(ERROR_INVALID_HANDLE);
72 return CLR_INVALID;
73 }
74 iMapMode = dc->pdcattr->iMapMode;
75 DC_UnlockDc(dc);
76 return iMapMode;
77 }
78
79 COLORREF FASTCALL
80 GreGetTextColor(HDC hdc)
81 {
82 PDC dc;
83 ULONG ulForegroundClr;
84 if (!(dc = DC_LockDc(hdc)))
85 {
86 EngSetLastError(ERROR_INVALID_HANDLE);
87 return CLR_INVALID;
88 }
89 ulForegroundClr = dc->pdcattr->ulForegroundClr;
90 DC_UnlockDc(dc);
91 return ulForegroundClr;
92 }
93
94 COLORREF FASTCALL
95 IntGdiSetBkColor(HDC hDC, COLORREF color)
96 {
97 COLORREF oldColor;
98 PDC dc;
99 PDC_ATTR pdcattr;
100 HBRUSH hBrush;
101
102 if (!(dc = DC_LockDc(hDC)))
103 {
104 EngSetLastError(ERROR_INVALID_HANDLE);
105 return CLR_INVALID;
106 }
107 pdcattr = dc->pdcattr;
108
109 oldColor = pdcattr->ulBackgroundClr;
110 pdcattr->ulBackgroundClr = color;
111
112 if (pdcattr->crBackgroundClr != color)
113 {
114 pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
115 pdcattr->crBackgroundClr = color;
116 }
117 hBrush = pdcattr->hbrush;
118 DC_UnlockDc(dc);
119 NtGdiSelectBrush(hDC, hBrush);
120 return oldColor;
121 }
122
123 INT FASTCALL
124 IntGdiSetBkMode(HDC hDC, INT Mode)
125 {
126 COLORREF oldMode;
127 PDC dc;
128 PDC_ATTR pdcattr;
129
130 if (!(dc = DC_LockDc(hDC)))
131 {
132 EngSetLastError(ERROR_INVALID_HANDLE);
133 return CLR_INVALID;
134 }
135 pdcattr = dc->pdcattr;
136 oldMode = pdcattr->lBkMode;
137 pdcattr->jBkMode = Mode;
138 pdcattr->lBkMode = Mode;
139 DC_UnlockDc(dc);
140 return oldMode;
141 }
142
143 UINT
144 FASTCALL
145 IntGdiSetTextAlign(HDC hDC,
146 UINT Mode)
147 {
148 UINT prevAlign;
149 DC *dc;
150 PDC_ATTR pdcattr;
151
152 dc = DC_LockDc(hDC);
153 if (!dc)
154 {
155 EngSetLastError(ERROR_INVALID_HANDLE);
156 return GDI_ERROR;
157 }
158 pdcattr = dc->pdcattr;
159 prevAlign = pdcattr->lTextAlign;
160 pdcattr->lTextAlign = Mode;
161 DC_UnlockDc(dc);
162 return prevAlign;
163 }
164
165 COLORREF
166 FASTCALL
167 IntGdiSetTextColor(HDC hDC,
168 COLORREF color)
169 {
170 COLORREF crOldColor;
171 PDC pdc;
172 PDC_ATTR pdcattr;
173
174 pdc = DC_LockDc(hDC);
175 if (!pdc)
176 {
177 EngSetLastError(ERROR_INVALID_HANDLE);
178 return CLR_INVALID;
179 }
180 pdcattr = pdc->pdcattr;
181
182 crOldColor = (COLORREF) pdcattr->ulForegroundClr;
183 pdcattr->ulForegroundClr = (ULONG)color;
184
185 if (pdcattr->crForegroundClr != color)
186 {
187 pdcattr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
188 pdcattr->crForegroundClr = color;
189 }
190
191 DC_vUpdateTextBrush(pdc);
192 // DC_vUpdateLineBrush(pdc);
193 // DC_vUpdateFillBrush(pdc);
194
195 DC_UnlockDc(pdc);
196
197 return crOldColor;
198 }
199
200 COLORREF FASTCALL
201 IntSetDCBrushColor(HDC hdc, COLORREF crColor)
202 {
203 COLORREF OldColor = CLR_INVALID;
204 PDC dc;
205 if (!(dc = DC_LockDc(hdc)))
206 {
207 EngSetLastError(ERROR_INVALID_HANDLE);
208 return CLR_INVALID;
209 }
210 else
211 {
212 OldColor = (COLORREF) dc->pdcattr->ulBrushClr;
213 dc->pdcattr->ulBrushClr = (ULONG) crColor;
214
215 if ( dc->pdcattr->crBrushClr != crColor )
216 {
217 dc->pdcattr->ulDirty_ |= DIRTY_FILL;
218 dc->pdcattr->crBrushClr = crColor;
219 }
220 }
221 DC_UnlockDc(dc);
222 return OldColor;
223 }
224
225 COLORREF FASTCALL
226 IntSetDCPenColor(HDC hdc, COLORREF crColor)
227 {
228 COLORREF OldColor;
229 PDC dc;
230 if (!(dc = DC_LockDc(hdc)))
231 {
232 EngSetLastError(ERROR_INVALID_PARAMETER);
233 return CLR_INVALID;
234 }
235
236 OldColor = (COLORREF)dc->pdcattr->ulPenClr;
237 dc->pdcattr->ulPenClr = (ULONG)crColor;
238
239 if (dc->pdcattr->crPenClr != crColor)
240 {
241 dc->pdcattr->ulDirty_ |= DIRTY_LINE;
242 dc->pdcattr->crPenClr = crColor;
243 }
244 DC_UnlockDc(dc);
245 return OldColor;
246 }
247
248 int
249 FASTCALL
250 GreSetStretchBltMode(HDC hDC, int iStretchMode)
251 {
252 PDC pdc;
253 PDC_ATTR pdcattr;
254 INT oSMode = 0;
255
256 pdc = DC_LockDc(hDC);
257 if (pdc)
258 {
259 pdcattr = pdc->pdcattr;
260 oSMode = pdcattr->lStretchBltMode;
261 pdcattr->lStretchBltMode = iStretchMode;
262
263 // Wine returns an error here. We set the default.
264 if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
265
266 pdcattr->jStretchBltMode = iStretchMode;
267 DC_UnlockDc(pdc);
268 }
269 return oSMode;
270 }
271
272 int FASTCALL
273 GreGetGraphicsMode(HDC hdc)
274 {
275 PDC dc;
276 int GraphicsMode;
277 if (!(dc = DC_LockDc(hdc)))
278 {
279 EngSetLastError(ERROR_INVALID_HANDLE);
280 return CLR_INVALID;
281 }
282 GraphicsMode = dc->pdcattr->iGraphicsMode;
283 DC_UnlockDc(dc);
284 return GraphicsMode;
285 }
286
287 VOID
288 FASTCALL
289 DCU_SetDcUndeletable(HDC hDC)
290 {
291 PDC dc = DC_LockDc(hDC);
292 if (!dc)
293 {
294 EngSetLastError(ERROR_INVALID_HANDLE);
295 return;
296 }
297
298 dc->fs |= DC_FLAG_PERMANENT;
299 DC_UnlockDc(dc);
300 return;
301 }
302
303 #if 0
304 BOOL FASTCALL
305 IntIsPrimarySurface(SURFOBJ *SurfObj)
306 {
307 if (PrimarySurface.pSurface == NULL)
308 {
309 return FALSE;
310 }
311 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
312 }
313 #endif
314
315 BOOL
316 FASTCALL
317 IntSetDefaultRegion(PDC pdc)
318 {
319 PSURFACE pSurface;
320 PREGION prgn;
321 RECTL rclWnd, rclClip;
322
323 IntGdiReleaseRaoRgn(pdc);
324
325 rclWnd.left = 0;
326 rclWnd.top = 0;
327 rclWnd.right = pdc->dclevel.sizl.cx;
328 rclWnd.bottom = pdc->dclevel.sizl.cy;
329 rclClip = rclWnd;
330
331 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
332 if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
333 {
334 pSurface = pdc->dclevel.pSurface;
335 if (pSurface && pSurface->flags & PDEV_SURFACE)
336 {
337 rclClip.left += pdc->ppdev->ptlOrigion.x;
338 rclClip.top += pdc->ppdev->ptlOrigion.y;
339 rclClip.right += pdc->ppdev->ptlOrigion.x;
340 rclClip.bottom += pdc->ppdev->ptlOrigion.y;
341 }
342 }
343 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
344
345 prgn = pdc->prgnVis;
346
347 if (prgn && prgn != prgnDefault)
348 {
349 REGION_SetRectRgn( prgn,
350 rclClip.left,
351 rclClip.top,
352 rclClip.right ,
353 rclClip.bottom );
354 }
355 else
356 {
357 prgn = IntSysCreateRectpRgn( rclClip.left,
358 rclClip.top,
359 rclClip.right ,
360 rclClip.bottom );
361 pdc->prgnVis = prgn;
362 }
363
364 if (prgn)
365 {
366 pdc->ptlDCOrig.x = 0;
367 pdc->ptlDCOrig.y = 0;
368 pdc->erclWindow = rclWnd;
369 pdc->erclClip = rclClip;
370 /* Might be an InitDC or DCE... */
371 pdc->ptlFillOrigin.x = pdc->dcattr.VisRectRegion.Rect.right;
372 pdc->ptlFillOrigin.y = pdc->dcattr.VisRectRegion.Rect.bottom;
373 return TRUE;
374 }
375
376 pdc->prgnVis = prgnDefault;
377 return FALSE;
378 }
379
380
381 BOOL APIENTRY
382 NtGdiCancelDC(HDC hDC)
383 {
384 UNIMPLEMENTED;
385 return FALSE;
386 }
387
388
389 WORD APIENTRY
390 IntGdiSetHookFlags(HDC hDC, WORD Flags)
391 {
392 WORD wRet;
393 DC *dc = DC_LockDc(hDC);
394
395 if (NULL == dc)
396 {
397 EngSetLastError(ERROR_INVALID_HANDLE);
398 return 0;
399 }
400
401 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // FIXME: Wrong flag!
402
403 /* Info in "Undocumented Windows" is slightly confusing. */
404 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
405
406 if (Flags & DCHF_INVALIDATEVISRGN)
407 {
408 /* hVisRgn has to be updated */
409 dc->fs |= DC_FLAG_DIRTY_RAO;
410 }
411 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
412 {
413 //dc->fs &= ~DC_FLAG_DIRTY_RAO;
414 }
415
416 DC_UnlockDc(dc);
417
418 return wRet;
419 }
420
421
422 BOOL
423 APIENTRY
424 NtGdiGetDCDword(
425 HDC hDC,
426 UINT u,
427 DWORD *Result)
428 {
429 BOOL Ret = TRUE;
430 PDC pdc;
431 PDC_ATTR pdcattr;
432
433 DWORD SafeResult = 0;
434 NTSTATUS Status = STATUS_SUCCESS;
435
436 if (!Result)
437 {
438 EngSetLastError(ERROR_INVALID_PARAMETER);
439 return FALSE;
440 }
441
442 pdc = DC_LockDc(hDC);
443 if (!pdc)
444 {
445 EngSetLastError(ERROR_INVALID_HANDLE);
446 return FALSE;
447 }
448 pdcattr = pdc->pdcattr;
449
450 switch (u)
451 {
452 case GdiGetJournal:
453 break;
454
455 case GdiGetRelAbs:
456 SafeResult = pdcattr->lRelAbs;
457 break;
458
459 case GdiGetBreakExtra:
460 SafeResult = pdcattr->lBreakExtra;
461 break;
462
463 case GdiGerCharBreak:
464 SafeResult = pdcattr->cBreak;
465 break;
466
467 case GdiGetArcDirection:
468 if (pdcattr->dwLayout & LAYOUT_RTL)
469 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
470 else
471 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
472 break;
473
474 case GdiGetEMFRestorDc:
475 SafeResult = pdc->dclevel.lSaveDepth;
476 break;
477
478 case GdiGetFontLanguageInfo:
479 SafeResult = IntGetFontLanguageInfo(pdc);
480 break;
481
482 case GdiGetIsMemDc:
483 SafeResult = pdc->dctype;
484 break;
485
486 case GdiGetMapMode:
487 SafeResult = pdcattr->iMapMode;
488 break;
489
490 case GdiGetTextCharExtra:
491 SafeResult = pdcattr->lTextExtra;
492 break;
493
494 default:
495 EngSetLastError(ERROR_INVALID_PARAMETER);
496 Ret = FALSE;
497 break;
498 }
499
500 if (Ret)
501 {
502 _SEH2_TRY
503 {
504 ProbeForWrite(Result, sizeof(DWORD), 1);
505 *Result = SafeResult;
506 }
507 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
508 {
509 Status = _SEH2_GetExceptionCode();
510 }
511 _SEH2_END;
512
513 if (!NT_SUCCESS(Status))
514 {
515 SetLastNtError(Status);
516 Ret = FALSE;
517 }
518 }
519
520 DC_UnlockDc(pdc);
521 return Ret;
522 }
523
524 _Success_(return != FALSE)
525 BOOL
526 APIENTRY
527 NtGdiGetAndSetDCDword(
528 _In_ HDC hdc,
529 _In_ UINT u,
530 _In_ DWORD dwIn,
531 _Out_ DWORD *pdwResult)
532 {
533 BOOL Ret = TRUE;
534 PDC pdc;
535 PDC_ATTR pdcattr;
536
537 DWORD SafeResult = 0;
538 NTSTATUS Status = STATUS_SUCCESS;
539
540 if (!pdwResult)
541 {
542 EngSetLastError(ERROR_INVALID_PARAMETER);
543 return FALSE;
544 }
545
546 pdc = DC_LockDc(hdc);
547 if (!pdc)
548 {
549 EngSetLastError(ERROR_INVALID_HANDLE);
550 return FALSE;
551 }
552 pdcattr = pdc->pdcattr;
553
554 switch (u)
555 {
556 case GdiGetSetCopyCount:
557 SafeResult = pdc->ulCopyCount;
558 pdc->ulCopyCount = dwIn;
559 break;
560
561 case GdiGetSetTextAlign:
562 SafeResult = pdcattr->lTextAlign;
563 pdcattr->lTextAlign = dwIn;
564 // pdcattr->flTextAlign = dwIn; // Flags!
565 break;
566
567 case GdiGetSetRelAbs:
568 SafeResult = pdcattr->lRelAbs;
569 pdcattr->lRelAbs = dwIn;
570 break;
571
572 case GdiGetSetTextCharExtra:
573 SafeResult = pdcattr->lTextExtra;
574 pdcattr->lTextExtra = dwIn;
575 break;
576
577 case GdiGetSetSelectFont:
578 break;
579
580 case GdiGetSetMapperFlagsInternal:
581 if (dwIn & ~1)
582 {
583 EngSetLastError(ERROR_INVALID_PARAMETER);
584 Ret = FALSE;
585 break;
586 }
587 SafeResult = pdcattr->flFontMapper;
588 pdcattr->flFontMapper = dwIn;
589 break;
590
591 case GdiGetSetMapMode:
592 SafeResult = IntGdiSetMapMode(pdc, dwIn);
593 break;
594
595 case GdiGetSetArcDirection:
596 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
597 {
598 EngSetLastError(ERROR_INVALID_PARAMETER);
599 Ret = FALSE;
600 break;
601 }
602 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
603 {
604 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
605 if (dwIn == AD_CLOCKWISE)
606 {
607 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
608 break;
609 }
610 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
611 }
612 else // Left to Right
613 {
614 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
615 AD_COUNTERCLOCKWISE;
616 if (dwIn == AD_COUNTERCLOCKWISE)
617 {
618 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
619 break;
620 }
621 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
622 }
623 break;
624
625 default:
626 EngSetLastError(ERROR_INVALID_PARAMETER);
627 Ret = FALSE;
628 break;
629 }
630
631 if (Ret)
632 {
633 _SEH2_TRY
634 {
635 ProbeForWrite(pdwResult, sizeof(DWORD), 1);
636 *pdwResult = SafeResult;
637 }
638 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
639 {
640 Status = _SEH2_GetExceptionCode();
641 }
642 _SEH2_END;
643
644 if (!NT_SUCCESS(Status))
645 {
646 SetLastNtError(Status);
647 Ret = FALSE;
648 }
649 }
650
651 DC_UnlockDc(pdc);
652 return Ret;
653 }
654
655 DWORD
656 APIENTRY
657 NtGdiGetBoundsRect(
658 IN HDC hdc,
659 OUT LPRECT prc,
660 IN DWORD flags)
661 {
662 DWORD ret;
663 PDC pdc;
664
665 /* Lock the DC */
666 if (!(pdc = DC_LockDc(hdc))) return 0;
667
668 /* Get the return value */
669 ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE;
670 ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET;
671
672 /* Copy the rect to the caller */
673 _SEH2_TRY
674 {
675 ProbeForWrite(prc, sizeof(RECT), 1);
676 *prc = pdc->erclBoundsApp;
677 }
678 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
679 {
680 ret = 0;
681 }
682 _SEH2_END;
683
684 if (flags & DCB_RESET)
685 {
686 RECTL_vSetEmptyRect(&pdc->erclBoundsApp);
687 }
688
689 DC_UnlockDc(pdc);
690 return ret;
691 }
692
693
694 DWORD
695 APIENTRY
696 NtGdiSetBoundsRect(
697 IN HDC hdc,
698 IN LPRECT prc,
699 IN DWORD flags)
700 {
701 DWORD ret;
702 PDC pdc;
703 RECTL rcl;
704
705 /* Verify arguments */
706 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0;
707
708 /* Lock the DC */
709 if (!(pdc = DC_LockDc(hdc))) return 0;
710
711 /* Get the return value */
712 ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE;
713 ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET;
714
715 if (flags & DCB_RESET)
716 {
717 RECTL_vSetEmptyRect(&pdc->erclBoundsApp);
718 }
719
720 if (flags & DCB_ACCUMULATE && prc != NULL)
721 {
722 /* Capture the rect */
723 _SEH2_TRY
724 {
725 ProbeForRead(prc, sizeof(RECT), 1);
726 rcl = *prc;
727 }
728 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
729 {
730 DC_UnlockDc(pdc);
731 _SEH2_YIELD(return 0;)
732 }
733 _SEH2_END;
734
735 RECTL_vMakeWellOrdered(&rcl);
736 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
737 }
738
739 if (flags & DCB_ENABLE) pdc->fs |= DC_ACCUM_APP;
740 if (flags & DCB_DISABLE) pdc->fs &= ~DC_ACCUM_APP;
741 DC_UnlockDc(pdc);
742 return ret;
743 }
744
745 /* Translates a COLORREF to the right color in the specified DC color space */
746 ULONG
747 TranslateCOLORREF(PDC pdc, COLORREF crColor)
748 {
749 PSURFACE psurfDC;
750 PPALETTE ppalDC;
751 ULONG index, ulColor, iBitmapFormat;
752 EXLATEOBJ exlo;
753
754 /* Get the DC surface */
755 psurfDC = pdc->dclevel.pSurface;
756
757 /* If no surface is selected, use the default bitmap */
758 if (!psurfDC)
759 psurfDC = psurfDefaultBitmap;
760
761 /* Check what color type this is */
762 switch (crColor >> 24)
763 {
764 case 0x00: /* RGB color */
765 break;
766
767 case 0x01: /* PALETTEINDEX */
768 index = crColor & 0xFFFFFF;
769 ppalDC = pdc->dclevel.ppal;
770 if (index >= ppalDC->NumColors) index = 0;
771
772 /* Get the RGB value */
773 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
774 break;
775
776 case 0x02: /* PALETTERGB */
777
778 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
779 {
780 /* First find the nearest index in the dc palette */
781 ppalDC = pdc->dclevel.ppal;
782 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
783
784 /* Get the RGB value */
785 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
786 }
787 else
788 {
789 /* Use the pure color */
790 crColor = crColor & 0x00FFFFFF;
791 }
792 break;
793
794 case 0x10: /* DIBINDEX */
795 /* Mask the value to match the target bpp */
796 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat;
797 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
798 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
799 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
800 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
801 else index = crColor & 0xFFFFFF;
802 return index;
803
804 default:
805 DPRINT("Unsupported color type %u passed\n", crColor >> 24);
806 crColor &= 0xFFFFFF;
807 }
808
809 /* Initialize an XLATEOBJ from RGB to the target surface */
810 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0);
811
812 /* Translate the color to the target format */
813 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
814
815 /* Cleanup the XLATEOBJ */
816 EXLATEOBJ_vCleanup(&exlo);
817
818 return ulColor;
819 }
820
821