[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 VOID
656 FASTCALL
657 IntUpdateBoundsRect(PDC pdc, PRECTL pRect)
658 {
659 if (pdc->fs & DC_ACCUM_APP)
660 {
661 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect);
662 }
663 if (pdc->fs & DC_ACCUM_WMGR)
664 {
665 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect);
666 }
667 }
668
669 DWORD
670 APIENTRY
671 NtGdiGetBoundsRect(
672 IN HDC hdc,
673 OUT LPRECT prc,
674 IN DWORD flags)
675 {
676 DWORD ret;
677 PDC pdc;
678 RECT rc;
679
680 /* Lock the DC */
681 if (!(pdc = DC_LockDc(hdc))) return 0;
682
683 if (!(flags & DCB_WINDOWMGR))
684 {
685 rc = pdc->erclBoundsApp;
686
687 if (RECTL_bIsEmptyRect(&rc))
688 {
689 rc.left = rc.top = rc.right = rc.bottom = 0;
690 ret = DCB_RESET;
691 }
692 else
693 {
694 RECTL rcRgn;
695 if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
696 if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
697 {
698 REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
699 }
700 rc.left = max( rc.left, 0 );
701 rc.top = max( rc.top, 0 );
702 rc.right = min( rc.right, rcRgn.right - rcRgn.left );
703 rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
704 DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
705 DPRINT("rc l %d t %d\n",rc.left,rc.top);
706 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
707 ret = DCB_SET;
708 }
709 IntDPtoLP( pdc, &rc, 2 );
710 DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
711 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
712 }
713 else
714 rc = pdc->erclBounds;
715
716 /* Copy the rect to the caller */
717 _SEH2_TRY
718 {
719 ProbeForWrite(prc, sizeof(RECT), 1);
720 *prc = rc;
721 }
722 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
723 {
724 ret = 0;
725 }
726 _SEH2_END;
727
728 if (flags & DCB_RESET)
729 {
730 if (!(flags & DCB_WINDOWMGR))
731 {
732 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
733 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
734 }
735 else
736 {
737 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
738 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
739 }
740 }
741
742 DC_UnlockDc(pdc);
743 return ret;
744 }
745
746 DWORD
747 APIENTRY
748 NtGdiSetBoundsRect(
749 IN HDC hdc,
750 IN LPRECT prc,
751 IN DWORD flags)
752 {
753 DWORD ret;
754 PDC pdc;
755 RECTL rcl;
756
757 /* Verify arguments */
758 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0;
759
760 /* Lock the DC */
761 if (!(pdc = DC_LockDc(hdc))) return 0;
762
763 /* Get the return value */
764 ret = DCB_RESET; /* we don't have device-specific bounds */
765 ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) |
766 (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET );
767 ret |= (flags & DCB_WINDOWMGR);
768
769 if (flags & DCB_RESET)
770 {
771 if (!(flags & DCB_WINDOWMGR))
772 {
773 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
774 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
775 }
776 else
777 {
778 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
779 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
780 }
781 }
782
783 if (flags & DCB_ACCUMULATE && prc != NULL)
784 {
785 /* Capture the rect */
786 _SEH2_TRY
787 {
788 ProbeForRead(prc, sizeof(RECT), 1);
789 rcl = *prc;
790 }
791 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
792 {
793 DC_UnlockDc(pdc);
794 _SEH2_YIELD(return 0;)
795 }
796 _SEH2_END;
797
798 RECTL_vMakeWellOrdered(&rcl);
799
800 if (!(flags & DCB_WINDOWMGR))
801 {
802 IntLPtoDP( pdc, (POINT *)&rcl, 2 );
803 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
804 }
805 else
806 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl);
807 }
808
809 if (flags & DCB_ENABLE)
810 {
811 if (!(flags & DCB_WINDOWMGR))
812 pdc->fs |= DC_ACCUM_APP;
813 else
814 pdc->fs |= DC_ACCUM_WMGR;
815 }
816 if (flags & DCB_DISABLE)
817 {
818 if (!(flags & DCB_WINDOWMGR))
819 pdc->fs &= ~DC_ACCUM_APP;
820 else
821 pdc->fs &= ~DC_ACCUM_WMGR;
822 }
823 DC_UnlockDc(pdc);
824 return ret;
825 }
826
827 /* Translates a COLORREF to the right color in the specified DC color space */
828 ULONG
829 TranslateCOLORREF(PDC pdc, COLORREF crColor)
830 {
831 PSURFACE psurfDC;
832 PPALETTE ppalDC;
833 ULONG index, ulColor, iBitmapFormat;
834 EXLATEOBJ exlo;
835
836 /* Get the DC surface */
837 psurfDC = pdc->dclevel.pSurface;
838
839 /* If no surface is selected, use the default bitmap */
840 if (!psurfDC)
841 psurfDC = psurfDefaultBitmap;
842
843 /* Check what color type this is */
844 switch (crColor >> 24)
845 {
846 case 0x00: /* RGB color */
847 break;
848
849 case 0x01: /* PALETTEINDEX */
850 index = crColor & 0xFFFFFF;
851 ppalDC = pdc->dclevel.ppal;
852 if (index >= ppalDC->NumColors) index = 0;
853
854 /* Get the RGB value */
855 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
856 break;
857
858 case 0x02: /* PALETTERGB */
859
860 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
861 {
862 /* First find the nearest index in the dc palette */
863 ppalDC = pdc->dclevel.ppal;
864 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
865
866 /* Get the RGB value */
867 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
868 }
869 else
870 {
871 /* Use the pure color */
872 crColor = crColor & 0x00FFFFFF;
873 }
874 break;
875
876 case 0x10: /* DIBINDEX */
877 /* Mask the value to match the target bpp */
878 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat;
879 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
880 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
881 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
882 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
883 else index = crColor & 0xFFFFFF;
884 return index;
885
886 default:
887 DPRINT("Unsupported color type %u passed\n", crColor >> 24);
888 crColor &= 0xFFFFFF;
889 }
890
891 /* Initialize an XLATEOBJ from RGB to the target surface */
892 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0);
893
894 /* Translate the color to the target format */
895 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
896
897 /* Cleanup the XLATEOBJ */
898 EXLATEOBJ_vCleanup(&exlo);
899
900 return ulColor;
901 }
902
903