[WIN32SS][FONT] Fix the system logical stock font data (#709)
[reactos.git] / 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 BOOL FASTCALL
226 GreSetBrushOrg(
227 HDC hdc,
228 INT x,
229 INT y,
230 LPPOINT pptOut)
231 {
232 PDC pdc = DC_LockDc(hdc);
233 if (pdc == NULL)
234 {
235 EngSetLastError(ERROR_INVALID_HANDLE);
236 return FALSE;
237 }
238
239 if (pptOut != NULL)
240 {
241 *pptOut = pdc->pdcattr->ptlBrushOrigin;
242 }
243
244 pdc->pdcattr->ptlBrushOrigin.x = x;
245 pdc->pdcattr->ptlBrushOrigin.y = y;
246
247 DC_vSetBrushOrigin(pdc, x, y);
248
249 DC_UnlockDc(pdc);
250 return TRUE;
251 }
252
253 COLORREF FASTCALL
254 IntSetDCPenColor(HDC hdc, COLORREF crColor)
255 {
256 COLORREF OldColor;
257 PDC dc;
258 if (!(dc = DC_LockDc(hdc)))
259 {
260 EngSetLastError(ERROR_INVALID_PARAMETER);
261 return CLR_INVALID;
262 }
263
264 OldColor = (COLORREF)dc->pdcattr->ulPenClr;
265 dc->pdcattr->ulPenClr = (ULONG)crColor;
266
267 if (dc->pdcattr->crPenClr != crColor)
268 {
269 dc->pdcattr->ulDirty_ |= DIRTY_LINE;
270 dc->pdcattr->crPenClr = crColor;
271 }
272 DC_UnlockDc(dc);
273 return OldColor;
274 }
275
276 int
277 FASTCALL
278 GreSetStretchBltMode(HDC hDC, int iStretchMode)
279 {
280 PDC pdc;
281 PDC_ATTR pdcattr;
282 INT oSMode = 0;
283
284 pdc = DC_LockDc(hDC);
285 if (pdc)
286 {
287 pdcattr = pdc->pdcattr;
288 oSMode = pdcattr->lStretchBltMode;
289 pdcattr->lStretchBltMode = iStretchMode;
290
291 // Wine returns an error here. We set the default.
292 if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
293
294 pdcattr->jStretchBltMode = iStretchMode;
295 DC_UnlockDc(pdc);
296 }
297 return oSMode;
298 }
299
300 int FASTCALL
301 GreGetGraphicsMode(HDC hdc)
302 {
303 PDC dc;
304 int GraphicsMode;
305 if (!(dc = DC_LockDc(hdc)))
306 {
307 EngSetLastError(ERROR_INVALID_HANDLE);
308 return CLR_INVALID;
309 }
310 GraphicsMode = dc->pdcattr->iGraphicsMode;
311 DC_UnlockDc(dc);
312 return GraphicsMode;
313 }
314
315 VOID
316 FASTCALL
317 DCU_SetDcUndeletable(HDC hDC)
318 {
319 PDC dc = DC_LockDc(hDC);
320 if (!dc)
321 {
322 EngSetLastError(ERROR_INVALID_HANDLE);
323 return;
324 }
325
326 dc->fs |= DC_FLAG_PERMANENT;
327 DC_UnlockDc(dc);
328 return;
329 }
330
331 #if 0
332 BOOL FASTCALL
333 IntIsPrimarySurface(SURFOBJ *SurfObj)
334 {
335 if (PrimarySurface.pSurface == NULL)
336 {
337 return FALSE;
338 }
339 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
340 }
341 #endif
342
343 BOOL
344 FASTCALL
345 IntSetDefaultRegion(PDC pdc)
346 {
347 PSURFACE pSurface;
348 PREGION prgn;
349 RECTL rclWnd, rclClip;
350
351 IntGdiReleaseRaoRgn(pdc);
352
353 rclWnd.left = 0;
354 rclWnd.top = 0;
355 rclWnd.right = pdc->dclevel.sizl.cx;
356 rclWnd.bottom = pdc->dclevel.sizl.cy;
357 rclClip = rclWnd;
358
359 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
360 if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
361 {
362 pSurface = pdc->dclevel.pSurface;
363 if (pSurface && pSurface->flags & PDEV_SURFACE)
364 {
365 rclClip.left += pdc->ppdev->ptlOrigion.x;
366 rclClip.top += pdc->ppdev->ptlOrigion.y;
367 rclClip.right += pdc->ppdev->ptlOrigion.x;
368 rclClip.bottom += pdc->ppdev->ptlOrigion.y;
369 }
370 }
371 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
372
373 prgn = pdc->prgnVis;
374
375 if (prgn && prgn != prgnDefault)
376 {
377 REGION_SetRectRgn( prgn,
378 rclClip.left,
379 rclClip.top,
380 rclClip.right ,
381 rclClip.bottom );
382 }
383 else
384 {
385 prgn = IntSysCreateRectpRgn( rclClip.left,
386 rclClip.top,
387 rclClip.right ,
388 rclClip.bottom );
389 pdc->prgnVis = prgn;
390 }
391
392 if (prgn)
393 {
394 pdc->ptlDCOrig.x = 0;
395 pdc->ptlDCOrig.y = 0;
396 pdc->erclWindow = rclWnd;
397 pdc->erclClip = rclClip;
398 /* Might be an InitDC or DCE... */
399 pdc->ptlFillOrigin.x = pdc->dcattr.ptlBrushOrigin.x;
400 pdc->ptlFillOrigin.y = pdc->dcattr.ptlBrushOrigin.y;
401 return TRUE;
402 }
403
404 pdc->prgnVis = prgnDefault;
405 return FALSE;
406 }
407
408
409 BOOL APIENTRY
410 NtGdiCancelDC(HDC hDC)
411 {
412 UNIMPLEMENTED;
413 return FALSE;
414 }
415
416
417 WORD APIENTRY
418 IntGdiSetHookFlags(HDC hDC, WORD Flags)
419 {
420 WORD wRet;
421 DC *dc = DC_LockDc(hDC);
422
423 if (NULL == dc)
424 {
425 EngSetLastError(ERROR_INVALID_HANDLE);
426 return 0;
427 }
428
429 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // FIXME: Wrong flag!
430
431 /* Info in "Undocumented Windows" is slightly confusing. */
432 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
433
434 if (Flags & DCHF_INVALIDATEVISRGN)
435 {
436 /* hVisRgn has to be updated */
437 dc->fs |= DC_FLAG_DIRTY_RAO;
438 }
439 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
440 {
441 //dc->fs &= ~DC_FLAG_DIRTY_RAO;
442 }
443
444 DC_UnlockDc(dc);
445
446 return wRet;
447 }
448
449
450 BOOL
451 APIENTRY
452 NtGdiGetDCDword(
453 HDC hDC,
454 UINT u,
455 DWORD *Result)
456 {
457 BOOL Ret = TRUE;
458 PDC pdc;
459 PDC_ATTR pdcattr;
460
461 DWORD SafeResult = 0;
462 NTSTATUS Status = STATUS_SUCCESS;
463
464 if (!Result)
465 {
466 EngSetLastError(ERROR_INVALID_PARAMETER);
467 return FALSE;
468 }
469
470 pdc = DC_LockDc(hDC);
471 if (!pdc)
472 {
473 EngSetLastError(ERROR_INVALID_HANDLE);
474 return FALSE;
475 }
476 pdcattr = pdc->pdcattr;
477
478 switch (u)
479 {
480 case GdiGetJournal:
481 break;
482
483 case GdiGetRelAbs:
484 SafeResult = pdcattr->lRelAbs;
485 break;
486
487 case GdiGetBreakExtra:
488 SafeResult = pdcattr->lBreakExtra;
489 break;
490
491 case GdiGerCharBreak:
492 SafeResult = pdcattr->cBreak;
493 break;
494
495 case GdiGetArcDirection:
496 if (pdcattr->dwLayout & LAYOUT_RTL)
497 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
498 else
499 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
500 break;
501
502 case GdiGetEMFRestorDc:
503 SafeResult = pdc->dclevel.lSaveDepth;
504 break;
505
506 case GdiGetFontLanguageInfo:
507 SafeResult = IntGetFontLanguageInfo(pdc);
508 break;
509
510 case GdiGetIsMemDc:
511 SafeResult = pdc->dctype;
512 break;
513
514 case GdiGetMapMode:
515 SafeResult = pdcattr->iMapMode;
516 break;
517
518 case GdiGetTextCharExtra:
519 SafeResult = pdcattr->lTextExtra;
520 break;
521
522 default:
523 EngSetLastError(ERROR_INVALID_PARAMETER);
524 Ret = FALSE;
525 break;
526 }
527
528 if (Ret)
529 {
530 _SEH2_TRY
531 {
532 ProbeForWrite(Result, sizeof(DWORD), 1);
533 *Result = SafeResult;
534 }
535 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
536 {
537 Status = _SEH2_GetExceptionCode();
538 }
539 _SEH2_END;
540
541 if (!NT_SUCCESS(Status))
542 {
543 SetLastNtError(Status);
544 Ret = FALSE;
545 }
546 }
547
548 DC_UnlockDc(pdc);
549 return Ret;
550 }
551
552 _Success_(return != FALSE)
553 BOOL
554 APIENTRY
555 NtGdiGetAndSetDCDword(
556 _In_ HDC hdc,
557 _In_ UINT u,
558 _In_ DWORD dwIn,
559 _Out_ DWORD *pdwResult)
560 {
561 BOOL Ret = TRUE;
562 PDC pdc;
563 PDC_ATTR pdcattr;
564
565 DWORD SafeResult = 0;
566 NTSTATUS Status = STATUS_SUCCESS;
567
568 if (!pdwResult)
569 {
570 EngSetLastError(ERROR_INVALID_PARAMETER);
571 return FALSE;
572 }
573
574 pdc = DC_LockDc(hdc);
575 if (!pdc)
576 {
577 EngSetLastError(ERROR_INVALID_HANDLE);
578 return FALSE;
579 }
580 pdcattr = pdc->pdcattr;
581
582 switch (u)
583 {
584 case GdiGetSetCopyCount:
585 SafeResult = pdc->ulCopyCount;
586 pdc->ulCopyCount = dwIn;
587 break;
588
589 case GdiGetSetTextAlign:
590 SafeResult = pdcattr->lTextAlign;
591 pdcattr->lTextAlign = dwIn;
592 // pdcattr->flTextAlign = dwIn; // Flags!
593 break;
594
595 case GdiGetSetRelAbs:
596 SafeResult = pdcattr->lRelAbs;
597 pdcattr->lRelAbs = dwIn;
598 break;
599
600 case GdiGetSetTextCharExtra:
601 SafeResult = pdcattr->lTextExtra;
602 pdcattr->lTextExtra = dwIn;
603 break;
604
605 case GdiGetSetSelectFont:
606 break;
607
608 case GdiGetSetMapperFlagsInternal:
609 if (dwIn & ~1)
610 {
611 EngSetLastError(ERROR_INVALID_PARAMETER);
612 Ret = FALSE;
613 break;
614 }
615 SafeResult = pdcattr->flFontMapper;
616 pdcattr->flFontMapper = dwIn;
617 break;
618
619 case GdiGetSetMapMode:
620 SafeResult = IntGdiSetMapMode(pdc, dwIn);
621 break;
622
623 case GdiGetSetArcDirection:
624 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
625 {
626 EngSetLastError(ERROR_INVALID_PARAMETER);
627 Ret = FALSE;
628 break;
629 }
630 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
631 {
632 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
633 if (dwIn == AD_CLOCKWISE)
634 {
635 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
636 break;
637 }
638 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
639 }
640 else // Left to Right
641 {
642 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
643 AD_COUNTERCLOCKWISE;
644 if (dwIn == AD_COUNTERCLOCKWISE)
645 {
646 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
647 break;
648 }
649 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
650 }
651 break;
652
653 default:
654 EngSetLastError(ERROR_INVALID_PARAMETER);
655 Ret = FALSE;
656 break;
657 }
658
659 if (Ret)
660 {
661 _SEH2_TRY
662 {
663 ProbeForWrite(pdwResult, sizeof(DWORD), 1);
664 *pdwResult = SafeResult;
665 }
666 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
667 {
668 Status = _SEH2_GetExceptionCode();
669 }
670 _SEH2_END;
671
672 if (!NT_SUCCESS(Status))
673 {
674 SetLastNtError(Status);
675 Ret = FALSE;
676 }
677 }
678
679 DC_UnlockDc(pdc);
680 return Ret;
681 }
682
683 VOID
684 FASTCALL
685 IntUpdateBoundsRect(PDC pdc, PRECTL pRect)
686 {
687 if (pdc->fs & DC_ACCUM_APP)
688 {
689 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect);
690 }
691 if (pdc->fs & DC_ACCUM_WMGR)
692 {
693 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect);
694 }
695 }
696
697 DWORD
698 APIENTRY
699 NtGdiGetBoundsRect(
700 IN HDC hdc,
701 OUT LPRECT prc,
702 IN DWORD flags)
703 {
704 DWORD ret;
705 PDC pdc;
706 RECT rc;
707
708 /* Lock the DC */
709 if (!(pdc = DC_LockDc(hdc))) return 0;
710
711 if (!(flags & DCB_WINDOWMGR))
712 {
713 rc = pdc->erclBoundsApp;
714
715 if (RECTL_bIsEmptyRect(&rc))
716 {
717 rc.left = rc.top = rc.right = rc.bottom = 0;
718 ret = DCB_RESET;
719 }
720 else
721 {
722 RECTL rcRgn;
723 if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
724 if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
725 {
726 REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
727 }
728 rc.left = max( rc.left, 0 );
729 rc.top = max( rc.top, 0 );
730 rc.right = min( rc.right, rcRgn.right - rcRgn.left );
731 rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
732 DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
733 DPRINT("rc l %d t %d\n",rc.left,rc.top);
734 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
735 ret = DCB_SET;
736 }
737 IntDPtoLP( pdc, &rc, 2 );
738 DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
739 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
740 }
741 else
742 {
743 rc = pdc->erclBounds;
744 ret = DCB_SET;
745 }
746
747 /* Copy the rect to the caller */
748 _SEH2_TRY
749 {
750 ProbeForWrite(prc, sizeof(RECT), 1);
751 *prc = rc;
752 }
753 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
754 {
755 ret = 0;
756 }
757 _SEH2_END;
758
759 if (flags & DCB_RESET)
760 {
761 if (!(flags & DCB_WINDOWMGR))
762 {
763 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
764 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
765 }
766 else
767 {
768 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
769 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
770 }
771 }
772
773 DC_UnlockDc(pdc);
774 return ret;
775 }
776
777 DWORD
778 APIENTRY
779 NtGdiSetBoundsRect(
780 IN HDC hdc,
781 IN LPRECT prc,
782 IN DWORD flags)
783 {
784 DWORD ret;
785 PDC pdc;
786 RECTL rcl;
787
788 /* Verify arguments */
789 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0;
790
791 /* Lock the DC */
792 if (!(pdc = DC_LockDc(hdc))) return 0;
793
794 /* Get the return value */
795 ret = DCB_RESET; /* we don't have device-specific bounds */
796 ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) |
797 (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET );
798 ret |= (flags & DCB_WINDOWMGR);
799
800 if (flags & DCB_RESET)
801 {
802 if (!(flags & DCB_WINDOWMGR))
803 {
804 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
805 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
806 }
807 else
808 {
809 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
810 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
811 }
812 }
813
814 if (flags & DCB_ACCUMULATE && prc != NULL)
815 {
816 /* Capture the rect */
817 _SEH2_TRY
818 {
819 ProbeForRead(prc, sizeof(RECT), 1);
820 rcl = *prc;
821 }
822 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
823 {
824 DC_UnlockDc(pdc);
825 _SEH2_YIELD(return 0;)
826 }
827 _SEH2_END;
828
829 RECTL_vMakeWellOrdered(&rcl);
830
831 if (!(flags & DCB_WINDOWMGR))
832 {
833 IntLPtoDP( pdc, (POINT *)&rcl, 2 );
834 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
835 }
836 else
837 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl);
838 }
839
840 if (flags & DCB_ENABLE)
841 {
842 if (!(flags & DCB_WINDOWMGR))
843 pdc->fs |= DC_ACCUM_APP;
844 else
845 pdc->fs |= DC_ACCUM_WMGR;
846 }
847 if (flags & DCB_DISABLE)
848 {
849 if (!(flags & DCB_WINDOWMGR))
850 pdc->fs &= ~DC_ACCUM_APP;
851 else
852 pdc->fs &= ~DC_ACCUM_WMGR;
853 }
854 DC_UnlockDc(pdc);
855 return ret;
856 }
857
858 /* Translates a COLORREF to the right color in the specified DC color space */
859 ULONG
860 TranslateCOLORREF(PDC pdc, COLORREF crColor)
861 {
862 PSURFACE psurfDC;
863 PPALETTE ppalDC;
864 ULONG index, ulColor, iBitmapFormat;
865 EXLATEOBJ exlo;
866
867 /* Get the DC surface */
868 psurfDC = pdc->dclevel.pSurface;
869
870 /* If no surface is selected, use the default bitmap */
871 if (!psurfDC)
872 psurfDC = psurfDefaultBitmap;
873
874 /* Check what color type this is */
875 switch (crColor >> 24)
876 {
877 case 0x00: /* RGB color */
878 break;
879
880 case 0x01: /* PALETTEINDEX */
881 index = crColor & 0xFFFFFF;
882 ppalDC = pdc->dclevel.ppal;
883 if (index >= ppalDC->NumColors) index = 0;
884
885 /* Get the RGB value */
886 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
887 break;
888
889 case 0x02: /* PALETTERGB */
890
891 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
892 {
893 /* First find the nearest index in the dc palette */
894 ppalDC = pdc->dclevel.ppal;
895 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
896
897 /* Get the RGB value */
898 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
899 }
900 else
901 {
902 /* Use the pure color */
903 crColor = crColor & 0x00FFFFFF;
904 }
905 break;
906
907 case 0x10: /* DIBINDEX */
908 /* Mask the value to match the target bpp */
909 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat;
910 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
911 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
912 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
913 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
914 else index = crColor & 0xFFFFFF;
915 return index;
916
917 default:
918 DPRINT("Unsupported color type %u passed\n", crColor >> 24);
919 crColor &= 0xFFFFFF;
920 }
921
922 /* Initialize an XLATEOBJ from RGB to the target surface */
923 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0);
924
925 /* Translate the color to the target format */
926 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
927
928 /* Cleanup the XLATEOBJ */
929 EXLATEOBJ_vCleanup(&exlo);
930
931 return ulColor;
932 }
933
934