* Sync up to trunk head (r65095).
[reactos.git] / win32ss / gdi / gdi32 / objects / coord.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS System Libraries
4 * FILE: dll/gdi32/objects/coord.c
5 * PURPOSE: Functions for coordinate transformation
6 * PROGRAMMER:
7 */
8 #include <precomp.h>
9
10 /* Currently we use a MATRIX inside the DC_ATTR containing the
11 coordinate transformations, while we deal with XFORM structures
12 internally. If we move all coordinate transformation to gdi32,
13 we might as well have an XFORM structure in the DC_ATTR. */
14 void
15 MatrixToXForm(XFORM *pxform, const MATRIX *pmx)
16 {
17 XFORML *pxforml = (XFORML*)pxform;
18 pxforml->eM11 = FOtoF(&pmx->efM11);
19 pxforml->eM12 = FOtoF(&pmx->efM12);
20 pxforml->eM21 = FOtoF(&pmx->efM21);
21 pxforml->eM22 = FOtoF(&pmx->efM22);
22 pxforml->eDx = FOtoF(&pmx->efDx);
23 pxforml->eDy = FOtoF(&pmx->efDy);
24 }
25
26 void
27 GdiTransformPoints2(
28 _In_ XFORM *pxform,
29 _Out_writes_(nCount) PPOINT pptOut,
30 _In_reads_(nCount) PPOINT pptIn,
31 _In_ ULONG nCount)
32 {
33 ULONG i;
34 FLOAT x, y;
35
36 for (i = 0; i < nCount; i++)
37 {
38 x = pptIn[i].x * pxform->eM11 + pptIn[i].y * pxform->eM12 + pxform->eDx;
39 pptOut[i].x = _lrintf(x);
40 y = pptIn[i].x * pxform->eM21 + pptIn[i].y * pxform->eM22 + pxform->eDy;
41 pptOut[i].y = _lrintf(y);
42 }
43 }
44
45 FORCEINLINE
46 void
47 GdiTransformPoints(
48 _In_ MATRIX *pmx,
49 _Out_writes_(nCount) PPOINT pptOut,
50 _In_reads_(nCount) PPOINT pptIn,
51 _In_ ULONG nCount)
52 {
53 XFORM xform;
54
55 MatrixToXForm(&xform, pmx);
56 GdiTransformPoints2(&xform, pptOut, pptIn, nCount);
57 }
58
59 #define MAX_OFFSET 4294967041.0
60 #define _fmul(x,y) (((x) == 0) ? 0 : (x) * (y))
61
62 BOOL
63 WINAPI
64 CombineTransform(
65 _Out_ LPXFORM pxfResult,
66 _In_ const XFORM *pxf1,
67 _In_ const XFORM *pxf2)
68 {
69 XFORM xformTmp;
70
71 /* Check paramters */
72 if (!pxfResult || !pxf1 || !pxf2) return FALSE;
73
74 /* Do matrix multiplication, start with scaling elements */
75 xformTmp.eM11 = (pxf1->eM11 * pxf2->eM11) + (pxf1->eM12 * pxf2->eM21);
76 xformTmp.eM22 = (pxf1->eM21 * pxf2->eM12) + (pxf1->eM22 * pxf2->eM22);
77
78 /* Calculate shear/rotate elements only of they are present */
79 if ((pxf1->eM12 != 0.) || (pxf1->eM21 != 0.) ||
80 (pxf2->eM12 != 0.) || (pxf2->eM21 != 0.))
81 {
82 xformTmp.eM12 = (pxf1->eM11 * pxf2->eM12) + (pxf1->eM12 * pxf2->eM22);
83 xformTmp.eM21 = (pxf1->eM21 * pxf2->eM11) + (pxf1->eM22 * pxf2->eM21);
84 }
85 else
86 {
87 xformTmp.eM12 = 0.;
88 xformTmp.eM21 = 0.;
89 }
90
91 /* Calculate the offset */
92 xformTmp.eDx = _fmul(pxf1->eDx, pxf2->eM11) + _fmul(pxf1->eDy, pxf2->eM21) + pxf2->eDx;
93 xformTmp.eDy = _fmul(pxf1->eDx, pxf2->eM12) + _fmul(pxf1->eDy, pxf2->eM22) + pxf2->eDy;
94
95 /* Check for invalid offset ranges */
96 if ((xformTmp.eDx > MAX_OFFSET) || (xformTmp.eDx < -MAX_OFFSET) ||
97 (xformTmp.eDy > MAX_OFFSET) || (xformTmp.eDy < -MAX_OFFSET))
98 {
99 return FALSE;
100 }
101
102 /* All is ok, return the calculated values */
103 *pxfResult = xformTmp;
104 return TRUE;
105 }
106
107
108 /*
109 * @implemented
110 *
111 */
112 int
113 WINAPI
114 GetMapMode(
115 _In_ HDC hdc)
116 {
117 PDC_ATTR pdcattr;
118
119 /* Get the DC attribute */
120 pdcattr = GdiGetDcAttr(hdc);
121 if (pdcattr == NULL)
122 {
123 SetLastError(ERROR_INVALID_PARAMETER);
124 return 0;
125 }
126
127 /* Return the map mode */
128 return pdcattr->iMapMode;
129 }
130
131 /*
132 * @implemented
133 */
134 INT
135 WINAPI
136 SetMapMode(
137 _In_ HDC hdc,
138 _In_ INT iMode)
139 {
140 PDC_ATTR pdcattr;
141
142 /* Get the DC attribute */
143 pdcattr = GdiGetDcAttr(hdc);
144 if (pdcattr == NULL)
145 {
146 SetLastError(ERROR_INVALID_PARAMETER);
147 return 0;
148 }
149
150 #if 0
151 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
152 {
153 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
154 return MFDRV_SetMapMode(hdc, iMode);
155 else
156 {
157 SetLastError(ERROR_INVALID_HANDLE);
158 return 0;
159 }
160 }
161 #endif
162
163 /* Force change if Isotropic is set for recompute. */
164 if ((iMode != pdcattr->iMapMode) || (iMode == MM_ISOTROPIC))
165 {
166 pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
167 return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0);
168 }
169
170 /* Simply return the old mode, which equals the new mode */
171 return pdcattr->iMapMode;
172 }
173
174
175 BOOL
176 WINAPI
177 DPtoLP(
178 _In_ HDC hdc,
179 _Inout_updates_(nCount) LPPOINT lpPoints,
180 _In_ INT nCount)
181 {
182 #if 0
183 INT i;
184 PDC_ATTR pdcattr;
185
186 /* Get the DC attribute */
187 pdcattr = GdiGetDcAttr(hdc);
188 if (!pdcattr)
189 {
190 SetLastError(ERROR_INVALID_PARAMETER);
191 return FALSE;
192 }
193
194 if (pdcattr->flXform & ANY_XFORM_CHANGES)
195 {
196 GdiFixupTransforms(pdcattr);
197 }
198
199 // FIXME: can this fail on Windows?
200 GdiTransformPoints(&pdcattr->mxDeviceToWorld, lpPoints, lpPoints, nCount);
201
202 return TRUE;
203 #endif
204 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp);
205 }
206
207 BOOL
208 WINAPI
209 LPtoDP(
210 _In_ HDC hdc,
211 _Inout_updates_(nCount) LPPOINT lpPoints,
212 _In_ INT nCount)
213 {
214 #if 0
215 INT i;
216 PDC_ATTR pdcattr;
217
218 /* Get the DC attribute */
219 pdcattr = GdiGetDcAttr(hdc);
220 if (!pdcattr)
221 {
222 SetLastError(ERROR_INVALID_PARAMETER);
223 return FALSE;
224 }
225
226 if (pdcattr->flXform & ANY_XFORM_CHANGES)
227 {
228 GdiFixupTransforms(pdcattr);
229 }
230
231 // FIXME: can this fail on Windows?
232 GdiTransformPoints(&pdcattr->mxWorldToDevice, lpPoints, lpPoints, nCount);
233
234 return TRUE;
235 #endif
236 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp);
237 }
238
239 /*
240 * @implemented
241 *
242 */
243 BOOL
244 WINAPI
245 GetCurrentPositionEx(
246 _In_ HDC hdc,
247 _Out_ LPPOINT lpPoint)
248 {
249 PDC_ATTR pdcattr;
250
251 /* Get the DC attribute */
252 pdcattr = GdiGetDcAttr(hdc);
253 if ((pdcattr == NULL) || (lpPoint == NULL))
254 {
255 SetLastError(ERROR_INVALID_PARAMETER);
256 return FALSE;
257 }
258
259 if (pdcattr->ulDirty_ & DIRTY_PTLCURRENT) // have a hit!
260 {
261 lpPoint->x = pdcattr->ptfxCurrent.x;
262 lpPoint->y = pdcattr->ptfxCurrent.y;
263 DPtoLP(hdc, lpPoint, 1); // reconvert back.
264 pdcattr->ptlCurrent.x = lpPoint->x; // save it
265 pdcattr->ptlCurrent.y = lpPoint->y;
266 pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; // clear bit
267 }
268 else
269 {
270 lpPoint->x = pdcattr->ptlCurrent.x;
271 lpPoint->y = pdcattr->ptlCurrent.y;
272 }
273
274 return TRUE;
275 }
276
277 /*
278 * @implemented
279 */
280 BOOL
281 WINAPI
282 GetWorldTransform(
283 _In_ HDC hdc,
284 _Out_ LPXFORM pxform)
285 {
286 #if 0
287 PDC_ATTR pdcattr;
288
289 pdcattr = GdiGetDcAttr(hdc);
290 if (!pdcattr)
291 {
292 SetLastError(ERROR_INVALID_HANDLE);
293 return FALSE;
294 }
295
296 if (pdcattr->flXform & ANY_XFORM_INVALID)
297 {
298 GdiFixupTransforms(pdcattr);
299 }
300
301 MatrixToXForm(pxform, &pdcattr->mxWorldToDevice);
302 #endif
303 return NtGdiGetTransform(hdc, GdiWorldSpaceToPageSpace, pxform);
304 }
305
306
307 BOOL
308 WINAPI
309 SetWorldTransform(
310 _In_ HDC hdc,
311 _Out_ CONST XFORM *pxform)
312 {
313 /* FIXME shall we add undoc #define MWT_SETXFORM 4 ?? */
314 return ModifyWorldTransform(hdc, pxform, MWT_MAX+1);
315 }
316
317
318 BOOL
319 WINAPI
320 ModifyWorldTransform(
321 _In_ HDC hdc,
322 _In_opt_ CONST XFORM *pxform,
323 _In_ DWORD dwMode)
324 {
325 PDC_ATTR pdcattr;
326
327 #if 0
328 // Handle something other than a normal dc object.
329 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
330 {
331 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
332 return FALSE;
333 else
334 {
335 PLDC pLDC = GdiGetLDC(hdc);
336 if ( !pLDC )
337 {
338 SetLastError(ERROR_INVALID_HANDLE);
339 return FALSE;
340 }
341 if (pLDC->iType == LDC_EMFLDC)
342 {
343 if (dwMode == MWT_MAX+1)
344 if (!EMFDRV_SetWorldTransform(hdc, pxform) ) return FALSE;
345 return EMFDRV_ModifyWorldTransform(hdc, pxform, dwMode); // Ported from wine.
346 }
347 return FALSE;
348 }
349 }
350 #endif
351
352 /* Get the DC attribute */
353 pdcattr = GdiGetDcAttr(hdc);
354 if (pdcattr == NULL)
355 {
356 SetLastError(ERROR_INVALID_PARAMETER);
357 return FALSE;
358 }
359
360 /* Check that graphics mode is GM_ADVANCED */
361 if (pdcattr->iGraphicsMode != GM_ADVANCED)
362 return FALSE;
363
364 /* Call win32k to do the work */
365 return NtGdiModifyWorldTransform(hdc, (LPXFORM)pxform, dwMode);
366 }
367
368 BOOL
369 WINAPI
370 GetViewportExtEx(
371 _In_ HDC hdc,
372 _Out_ LPSIZE lpSize)
373 {
374 PDC_ATTR pdcattr;
375
376 /* Get the DC attribute */
377 pdcattr = GdiGetDcAttr(hdc);
378 if (pdcattr == NULL)
379 {
380 /* Do not set LastError here! */
381 return FALSE;
382 }
383
384 /* Check if we need to update values */
385 if ((pdcattr->flXform & PAGE_EXTENTS_CHANGED) &&
386 (pdcattr->iMapMode == MM_ISOTROPIC))
387 {
388 /* Call win32k to do the work */
389 return NtGdiGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)lpSize);
390 }
391
392 /* Nothing to calculate, return the current extension */
393 lpSize->cx = pdcattr->szlViewportExt.cx;
394 lpSize->cy = pdcattr->szlViewportExt.cy;
395
396 return TRUE;
397 }
398
399
400 BOOL
401 WINAPI
402 GetViewportOrgEx(
403 _In_ HDC hdc,
404 _Out_ LPPOINT lpPoint)
405 {
406 PDC_ATTR pdcattr;
407
408 /* Get the DC attribute */
409 pdcattr = GdiGetDcAttr(hdc);
410 if (pdcattr == NULL)
411 {
412 /* Do not set LastError here! */
413 return FALSE;
414 }
415
416 /* Get the current viewport org */
417 lpPoint->x = pdcattr->ptlViewportOrg.x;
418 lpPoint->y = pdcattr->ptlViewportOrg.y;
419
420 /* Handle right-to-left layout */
421 if (pdcattr->dwLayout & LAYOUT_RTL)
422 lpPoint->x = -lpPoint->x;
423
424 return TRUE;
425 }
426
427
428 BOOL
429 WINAPI
430 GetWindowExtEx(
431 _In_ HDC hdc,
432 _Out_ LPSIZE lpSize)
433 {
434 PDC_ATTR pdcattr;
435
436 /* Get the DC attribute */
437 pdcattr = GdiGetDcAttr(hdc);
438 if (pdcattr == NULL)
439 {
440 /* Do not set LastError here! */
441 return FALSE;
442 }
443
444 /* Get the current window extension */
445 lpSize->cx = pdcattr->szlWindowExt.cx;
446 lpSize->cy = pdcattr->szlWindowExt.cy;
447
448 /* Handle right-to-left layout */
449 if (pdcattr->dwLayout & LAYOUT_RTL)
450 lpSize->cx = -lpSize->cx;
451
452 return TRUE;
453 }
454
455
456 BOOL
457 WINAPI
458 GetWindowOrgEx(
459 _In_ HDC hdc,
460 _Out_ LPPOINT lpPoint)
461 {
462 PDC_ATTR pdcattr;
463
464 /* Get the DC attribute */
465 pdcattr = GdiGetDcAttr(hdc);
466 if (pdcattr == NULL)
467 {
468 /* Do not set LastError here! */
469 return FALSE;
470 }
471
472 /* Get the current window origin */
473 lpPoint->x = pdcattr->ptlWindowOrg.x;
474 lpPoint->y = pdcattr->ptlWindowOrg.y;
475
476 return TRUE;
477 }
478
479 /*
480 * @unimplemented
481 */
482 BOOL
483 WINAPI
484 SetViewportExtEx(
485 _In_ HDC hdc,
486 _In_ int nXExtent,
487 _In_ int nYExtent,
488 _Out_opt_ LPSIZE lpSize)
489 {
490 PDC_ATTR pdcattr;
491 #if 0
492 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
493 {
494 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
495 return MFDRV_SetViewportExtEx();
496 else
497 {
498 PLDC pLDC = GdiGetLDC(hdc);
499 if ( !pLDC )
500 {
501 SetLastError(ERROR_INVALID_HANDLE);
502 return FALSE;
503 }
504 if (pLDC->iType == LDC_EMFLDC)
505 {
506 return EMFDRV_SetViewportExtEx();
507 }
508 }
509 }
510 #endif
511
512 /* Get the DC attribute */
513 pdcattr = GdiGetDcAttr(hdc);
514 if (pdcattr == NULL)
515 {
516 SetLastError(ERROR_INVALID_PARAMETER);
517 return FALSE;
518 }
519
520 /* Check if the caller wants the old extension */
521 if (lpSize)
522 {
523 /* Return the current viewport extension */
524 lpSize->cx = pdcattr->szlViewportExt.cx;
525 lpSize->cy = pdcattr->szlViewportExt.cy;
526 }
527
528 /* Check for trivial case */
529 if ((pdcattr->szlViewportExt.cx == nXExtent) &&
530 (pdcattr->szlViewportExt.cy == nYExtent))
531 return TRUE;
532
533 /* Only change viewport extension if we are in iso or aniso mode */
534 if ((pdcattr->iMapMode == MM_ISOTROPIC) ||
535 (pdcattr->iMapMode == MM_ANISOTROPIC))
536 {
537 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
538 {
539 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
540 {
541 NtGdiFlush(); // Sync up pdcattr from Kernel space.
542 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
543 }
544 }
545
546 /* Set the new viewport extension */
547 pdcattr->szlViewportExt.cx = nXExtent;
548 pdcattr->szlViewportExt.cy = nYExtent;
549
550 /* Handle right-to-left layout */
551 if (pdcattr->dwLayout & LAYOUT_RTL)
552 NtGdiMirrorWindowOrg(hdc);
553
554 /* Update xform flags */
555 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
556 }
557
558 return TRUE;
559 }
560
561 /*
562 * @unimplemented
563 */
564 BOOL
565 WINAPI
566 SetWindowOrgEx(
567 _In_ HDC hdc,
568 _In_ int X,
569 _In_ int Y,
570 _Out_opt_ LPPOINT lpPoint)
571 {
572 #if 0
573 PDC_ATTR pdcattr;
574 #if 0
575 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
576 {
577 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
578 return MFDRV_SetWindowOrgEx();
579 else
580 {
581 PLDC pLDC = GdiGetLDC(hdc);
582 if ( !pLDC )
583 {
584 SetLastError(ERROR_INVALID_HANDLE);
585 return FALSE;
586 }
587 if (pLDC->iType == LDC_EMFLDC)
588 {
589 return EMFDRV_SetWindowOrgEx();
590 }
591 }
592 }
593 #endif
594 /* Get the DC attribute */
595 pdcattr = GdiGetDcAttr(hdc);
596 if (pdcattr == NULL)
597 {
598 /* Do not set LastError here! */
599 return FALSE;
600 }
601
602 if (lpPoint)
603 {
604 lpPoint->x = pdcattr->ptlWindowOrg.x;
605 lpPoint->y = pdcattr->ptlWindowOrg.y;
606 }
607
608 if ((pdcattr->ptlWindowOrg.x == X) && (pdcattr->ptlWindowOrg.y == Y))
609 return TRUE;
610
611 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
612 {
613 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
614 {
615 NtGdiFlush(); // Sync up pdcattr from Kernel space.
616 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
617 }
618 }
619
620 pdcattr->ptlWindowOrg.x = X;
621 pdcattr->lWindowOrgx = X;
622 pdcattr->ptlWindowOrg.y = Y;
623 if (pdcattr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc);
624 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
625 return TRUE;
626 #endif
627 return NtGdiSetWindowOrgEx(hdc,X,Y,lpPoint);
628 }
629
630 /*
631 * @unimplemented
632 */
633 BOOL
634 WINAPI
635 SetWindowExtEx(
636 _In_ HDC hdc,
637 _In_ INT nXExtent,
638 _In_ INT nYExtent,
639 _Out_opt_ LPSIZE lpSize)
640 {
641 PDC_ATTR pdcattr;
642 ULONG ulType;
643
644 /* Check what type of DC that is */
645 ulType = GDI_HANDLE_GET_TYPE(hdc);
646 switch (ulType)
647 {
648 case GDILoObjType_LO_ALTDC_TYPE:
649 case GDILoObjType_LO_DC_TYPE:
650 /* Handle this in the path below */
651 break;
652 #if 0// FIXME: we don't support this
653 case GDILoObjType_LO_METADC16_TYPE:
654 return MFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
655
656 case GDILoObjType_LO_METAFILE_TYPE:
657 return EMFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
658 #endif
659 default:
660 /* Other types are not allowed */
661 SetLastError(ERROR_INVALID_HANDLE);
662 return FALSE;
663 }
664
665 /* Get the DC attr */
666 pdcattr = GdiGetDcAttr(hdc);
667 if (!pdcattr)
668 {
669 /* Set the error value and return failure */
670 SetLastError(ERROR_INVALID_PARAMETER);
671 return FALSE;
672 }
673
674 /* Check if the caller wants the old extension */
675 if (lpSize)
676 {
677 /* Return the current window extension */
678 lpSize->cx = pdcattr->szlWindowExt.cx;
679 lpSize->cy = pdcattr->szlWindowExt.cy;
680
681 /* Handle right-to-left layout */
682 if (pdcattr->dwLayout & LAYOUT_RTL)
683 lpSize->cx = -lpSize->cx;
684 }
685
686 if (pdcattr->dwLayout & LAYOUT_RTL)
687 {
688 NtGdiMirrorWindowOrg(hdc);
689 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
690 }
691 else if ((pdcattr->iMapMode == MM_ISOTROPIC) ||
692 (pdcattr->iMapMode == MM_ANISOTROPIC))
693 {
694 if ((pdcattr->szlWindowExt.cx == nXExtent) &&
695 (pdcattr->szlWindowExt.cy == nYExtent))
696 return TRUE;
697
698 if ((!nXExtent) || (!nYExtent))
699 return FALSE;
700
701 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
702 {
703 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
704 {
705 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
706 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
707 }
708 }
709
710 pdcattr->szlWindowExt.cx = nXExtent;
711 pdcattr->szlWindowExt.cy = nYExtent;
712 if (pdcattr->dwLayout & LAYOUT_RTL)
713 NtGdiMirrorWindowOrg(hdc);
714
715 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
716 }
717
718 return TRUE;
719 }
720
721 /*
722 * @unimplemented
723 */
724 BOOL
725 WINAPI
726 SetViewportOrgEx(
727 _In_ HDC hdc,
728 _In_ int X,
729 _In_ int Y,
730 _Out_opt_ LPPOINT lpPoint)
731 {
732 #if 0
733 PDC_ATTR pdcattr;
734 #if 0
735 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
736 {
737 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
738 return MFDRV_SetViewportOrgEx();
739 else
740 {
741 PLDC pLDC = GdiGetLDC(hdc);
742 if ( !pLDC )
743 {
744 SetLastError(ERROR_INVALID_HANDLE);
745 return FALSE;
746 }
747 if (pLDC->iType == LDC_EMFLDC)
748 {
749 return EMFDRV_SetViewportOrgEx();
750 }
751 }
752 }
753 #endif
754
755 /* Get the DC attribute */
756 pdcattr = GdiGetDcAttr(hdc);
757 if (!pdcattr)
758 {
759 /* Do not set LastError here! */
760 return FALSE;
761 }
762
763 if (lpPoint)
764 {
765 lpPoint->x = pdcattr->ptlViewportOrg.x;
766 lpPoint->y = pdcattr->ptlViewportOrg.y;
767 if (pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x;
768 }
769 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
770 if (pdcattr->dwLayout & LAYOUT_RTL) X = -X;
771 pdcattr->ptlViewportOrg.x = X;
772 pdcattr->ptlViewportOrg.y = Y;
773 return TRUE;
774 #endif
775 return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint);
776 }
777
778 /*
779 * @implemented
780 */
781 BOOL
782 WINAPI
783 ScaleViewportExtEx(
784 _In_ HDC hdc,
785 _In_ INT xNum,
786 _In_ INT xDenom,
787 _In_ INT yNum,
788 _In_ INT yDenom,
789 _Out_ LPSIZE lpSize)
790 {
791 #if 0
792 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
793 {
794 if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC)
795 return MFDRV_;
796 else
797 {
798 PLDC pLDC = GdiGetLDC(hdc);
799 if ( !pLDC )
800 {
801 SetLastError(ERROR_INVALID_HANDLE);
802 return FALSE;
803 }
804 if (pLDC->iType == LDC_EMFLDC)
805 {
806 return EMFDRV_;
807 }
808 }
809 }
810 #endif
811 if (!GdiGetDcAttr(hdc))
812 {
813 SetLastError(ERROR_INVALID_PARAMETER);
814 return FALSE;
815 }
816
817 return NtGdiScaleViewportExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize);
818 }
819
820 /*
821 * @implemented
822 */
823 BOOL
824 WINAPI
825 ScaleWindowExtEx(
826 _In_ HDC hdc,
827 _In_ INT xNum,
828 _In_ INT xDenom,
829 _In_ INT yNum,
830 _In_ INT yDenom,
831 _Out_ LPSIZE lpSize)
832 {
833 #if 0
834 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
835 {
836 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
837 return MFDRV_;
838 else
839 {
840 PLDC pLDC = GdiGetLDC(hdc);
841 if ( !pLDC )
842 {
843 SetLastError(ERROR_INVALID_HANDLE);
844 return FALSE;
845 }
846 if (pLDC->iType == LDC_EMFLDC)
847 {
848 return EMFDRV_;
849 }
850 }
851 }
852 #endif
853
854 if (!GdiGetDcAttr(hdc))
855 {
856 SetLastError(ERROR_INVALID_PARAMETER);
857 return FALSE;
858 }
859
860 return NtGdiScaleWindowExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize);
861 }
862
863 /*
864 * @implemented
865 */
866 DWORD
867 WINAPI
868 GetLayout(
869 _In_ HDC hdc)
870 {
871 PDC_ATTR pdcattr;
872
873 /* METADC16 is not supported in this API */
874 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
875 {
876 return GDI_ERROR;
877 }
878
879 /* Get the DC attribute */
880 pdcattr = GdiGetDcAttr(hdc);
881 if (!pdcattr)
882 {
883 /* Set the error value and return failure */
884 SetLastError(ERROR_INVALID_PARAMETER);
885 return GDI_ERROR;
886 }
887
888 /* Return the layout */
889 return pdcattr->dwLayout;
890 }
891
892
893 /*
894 * @implemented
895 */
896 DWORD
897 WINAPI
898 SetLayout(
899 _In_ HDC hdc,
900 _In_ DWORD dwLayout)
901 {
902 #if 0
903 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
904 {
905 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
906 return MFDRV_SetLayout( hdc, dwLayout);
907 else
908 {
909 PLDC pLDC = GdiGetLDC(hdc);
910 if ( !pLDC )
911 {
912 SetLastError(ERROR_INVALID_HANDLE);
913 return 0;
914 }
915 if (pLDC->iType == LDC_EMFLDC)
916 {
917 return EMFDRV_SetLayout( hdc, dwLayout);
918 }
919 }
920 }
921 #endif
922 if (!GdiGetDcAttr(hdc))
923 {
924 SetLastError(ERROR_INVALID_PARAMETER);
925 return GDI_ERROR;
926 }
927
928 return NtGdiSetLayout(hdc, -1, dwLayout);
929 }
930
931 /*
932 * @implemented
933 */
934 DWORD
935 WINAPI
936 SetLayoutWidth(
937 _In_ HDC hdc,
938 _In_ LONG wox,
939 _In_ DWORD dwLayout)
940 {
941 /* Only normal DCs are handled here */
942 if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE)
943 {
944 return GDI_ERROR;
945 }
946
947 if (!GdiGetDcAttr(hdc))
948 {
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return GDI_ERROR;
951 }
952
953 return NtGdiSetLayout( hdc, wox, dwLayout);
954 }
955
956 /*
957 * @implemented
958 */
959 BOOL
960 WINAPI
961 GetDCOrgEx(
962 _In_ HDC hdc,
963 _Out_ LPPOINT lpPoint)
964 {
965 return NtGdiGetDCPoint(hdc, GdiGetDCOrg, (PPOINTL)lpPoint);
966 }
967
968
969 /*
970 * @implemented
971 */
972 LONG
973 WINAPI
974 GetDCOrg(
975 _In_ HDC hdc)
976 {
977 POINT pt;
978
979 /* Call the new API */
980 if (!GetDCOrgEx(hdc, &pt))
981 return 0;
982
983 /* Return the point in the old way */
984 return(MAKELONG(pt.x, pt.y));
985 }
986
987
988 /*
989 * @implemented
990 *
991 */
992 BOOL
993 WINAPI
994 OffsetViewportOrgEx(
995 _In_ HDC hdc,
996 _In_ int nXOffset,
997 _In_ int nYOffset,
998 _Out_opt_ LPPOINT lpPoint)
999 {
1000 #if 0
1001 PDC_ATTR pdcattr;
1002 #if 0
1003 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1004 {
1005 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1006 return MFDRV_OffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1007 else
1008 {
1009 PLDC pLDC = GdiGetLDC(hdc);
1010 if ( !pLDC )
1011 {
1012 SetLastError(ERROR_INVALID_HANDLE);
1013 return FALSE;
1014 }
1015 if (pLDC->iType == LDC_EMFLDC)
1016 {
1017 return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1018 }
1019 }
1020 }
1021 #endif
1022 /* Get the DC attribute */
1023 pdcattr = GdiGetDcAttr(hdc);
1024 if (!pdcattr)
1025 {
1026 /* Do not set LastError here! */
1027 return FALSE;
1028 }
1029
1030 if (lpPoint)
1031 {
1032 *lpPoint = (POINT)pdcattr->ptlViewportOrg;
1033 if ( pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x;
1034 }
1035
1036 if ( nXOffset || nYOffset != nXOffset )
1037 {
1038 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1039 {
1040 if (pdcattr->ulDirty_ & DC_MODE_DIRTY)
1041 {
1042 NtGdiFlush();
1043 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY;
1044 }
1045 }
1046
1047 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
1048 if (pdcattr->dwLayout & LAYOUT_RTL) nXOffset = -nXOffset;
1049 pdcattr->ptlViewportOrg.x += nXOffset;
1050 pdcattr->ptlViewportOrg.y += nYOffset;
1051 }
1052 return TRUE;
1053 #endif
1054 return NtGdiOffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1055 }
1056
1057 /*
1058 * @implemented
1059 *
1060 */
1061 BOOL
1062 WINAPI
1063 OffsetWindowOrgEx(
1064 _In_ HDC hdc,
1065 _In_ int nXOffset,
1066 _In_ int nYOffset,
1067 _Out_opt_ LPPOINT lpPoint)
1068 {
1069 #if 0
1070 PDC_ATTR pdcattr;
1071 #if 0
1072 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1073 {
1074 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1075 return MFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1076 else
1077 {
1078 PLDC pLDC = GdiGetLDC(hdc);
1079 if ( !pLDC )
1080 {
1081 SetLastError(ERROR_INVALID_HANDLE);
1082 return FALSE;
1083 }
1084 if (pLDC->iType == LDC_EMFLDC)
1085 {
1086 return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1087 }
1088 }
1089 }
1090 #endif
1091 /* Get the DC attribute */
1092 pdcattr = GdiGetDcAttr(hdc);
1093 if (!pdcattr)
1094 {
1095 /* Do not set LastError here! */
1096 return FALSE;
1097 }
1098
1099 if ( lpPoint )
1100 {
1101 *lpPoint = (POINT)pdcattr->ptlWindowOrg;
1102 lpPoint->x = pdcattr->lWindowOrgx;
1103 }
1104
1105 if ( nXOffset || nYOffset != nXOffset )
1106 {
1107 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1108 {
1109 if (pdcattr->ulDirty_ & DC_MODE_DIRTY)
1110 {
1111 NtGdiFlush();
1112 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY;
1113 }
1114 }
1115
1116 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
1117 pdcattr->ptlWindowOrg.x += nXOffset;
1118 pdcattr->ptlWindowOrg.y += nYOffset;
1119 pdcattr->lWindowOrgx += nXOffset;
1120 }
1121 return TRUE;
1122 #endif
1123 return NtGdiOffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
1124 }
1125