cc28b06527a958d11c57a27a10e51dabdea3ae22
[reactos.git] / reactos / 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 XFORM *pxform,
29 PPOINT pptOut,
30 PPOINT pptIn,
31 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 MATRIX *pmx,
49 PPOINT pptOut,
50 PPOINT pptIn,
51 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 LPXFORM pxfResult,
66 const XFORM *pxf1,
67 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(HDC hdc)
115 {
116 PDC_ATTR pdcattr;
117
118 /* Get the DC attribute */
119 pdcattr = GdiGetDcAttr(hdc);
120 if (pdcattr == NULL)
121 {
122 SetLastError(ERROR_INVALID_PARAMETER);
123 return 0;
124 }
125
126 return pdcattr->iMapMode;
127 }
128
129 /*
130 * @implemented
131 */
132 INT
133 WINAPI
134 SetMapMode(
135 _In_ HDC hdc,
136 _In_ INT iMode)
137 {
138 PDC_ATTR pdcattr;
139
140 /* Get the DC attribute */
141 pdcattr = GdiGetDcAttr(hdc);
142 if (pdcattr == NULL)
143 {
144 SetLastError(ERROR_INVALID_PARAMETER);
145 return 0;
146 }
147
148 #if 0
149 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
150 {
151 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
152 return MFDRV_SetMapMode(hdc, iMode);
153 else
154 {
155 SetLastError(ERROR_INVALID_HANDLE);
156 return 0;
157 }
158 }
159 #endif
160 /* Force change if Isotropic is set for recompute. */
161 if ((iMode != pdcattr->iMapMode) || (iMode == MM_ISOTROPIC))
162 {
163 pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
164 return GetAndSetDCDWord( hdc, GdiGetSetMapMode, iMode, 0, 0, 0 );
165 }
166
167 return pdcattr->iMapMode;
168 }
169
170
171 BOOL
172 WINAPI
173 DPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
174 {
175 #if 0
176 INT i;
177 PDC_ATTR pdcattr;
178
179 pdcattr = GdiGetDcAttr(hdc);
180 if (!pdcattr)
181 {
182 SetLastError(ERROR_INVALID_HANDLE);
183 return FALSE;
184 }
185
186 if (pdcattr->flXform & ANY_XFORM_CHANGES)
187 {
188 GdiFixupTransforms(pdcattr);
189 }
190
191 // FIXME: can this fail on Windows?
192 GdiTransformPoints(&pdcattr->mxDeviceToWorld, lpPoints, lpPoints, nCount);
193
194 return TRUE;
195 #endif
196 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp);
197 }
198
199 BOOL
200 WINAPI
201 LPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount)
202 {
203 #if 0
204 INT i;
205 PDC_ATTR pdcattr;
206
207 pdcattr = GdiGetDcAttr(hdc);
208 if (!pdcattr)
209 {
210 SetLastError(ERROR_INVALID_HANDLE);
211 return FALSE;
212 }
213
214 if (pdcattr->flXform & ANY_XFORM_CHANGES)
215 {
216 GdiFixupTransforms(pdcattr);
217 }
218
219 // FIXME: can this fail on Windows?
220 GdiTransformPoints(&pdcattr->mxWorldToDevice, lpPoints, lpPoints, nCount);
221
222 return TRUE;
223 #endif
224 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp);
225 }
226
227 /*
228 * @implemented
229 *
230 */
231 BOOL
232 WINAPI
233 GetCurrentPositionEx(HDC hdc,
234 LPPOINT lpPoint)
235 {
236 PDC_ATTR Dc_Attr;
237
238 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
239
240 if ( lpPoint )
241 {
242 if ( Dc_Attr->ulDirty_ & DIRTY_PTLCURRENT ) // have a hit!
243 {
244 lpPoint->x = Dc_Attr->ptfxCurrent.x;
245 lpPoint->y = Dc_Attr->ptfxCurrent.y;
246 DPtoLP ( hdc, lpPoint, 1); // reconvert back.
247 Dc_Attr->ptlCurrent.x = lpPoint->x; // save it
248 Dc_Attr->ptlCurrent.y = lpPoint->y;
249 Dc_Attr->ulDirty_ &= ~DIRTY_PTLCURRENT; // clear bit
250 }
251 else
252 {
253 lpPoint->x = Dc_Attr->ptlCurrent.x;
254 lpPoint->y = Dc_Attr->ptlCurrent.y;
255 }
256 }
257 else
258 {
259 SetLastError(ERROR_INVALID_PARAMETER);
260 return FALSE;
261 }
262 return TRUE;
263 }
264
265 /*
266 * @implemented
267 */
268 BOOL
269 WINAPI
270 GetWorldTransform(HDC hDC, LPXFORM lpXform)
271 {
272 #if 0
273 PDC_ATTR pdcattr;
274
275 pdcattr = GdiGetDcAttr(hdc);
276 if (!pdcattr)
277 {
278 SetLastError(ERROR_INVALID_HANDLE);
279 return FALSE;
280 }
281
282 if (pdcattr->flXform & ANY_XFORM_INVALID)
283 {
284 GdiFixupTransforms(pdcattr);
285 }
286
287 MatrixToXForm(lpXform, &pdcattr->mxWorldToDevice);
288 #endif
289 return NtGdiGetTransform(hDC, GdiWorldSpaceToPageSpace, lpXform);
290 }
291
292
293 BOOL
294 WINAPI
295 SetWorldTransform( HDC hDC, CONST XFORM *Xform )
296 {
297 /* FIXME shall we add undoc #define MWT_SETXFORM 4 ?? */
298 return ModifyWorldTransform( hDC, Xform, MWT_MAX+1);
299 }
300
301
302 BOOL
303 WINAPI
304 ModifyWorldTransform(
305 HDC hDC,
306 CONST XFORM *Xform,
307 DWORD iMode
308 )
309 {
310 #if 0
311 // Handle something other than a normal dc object.
312 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
313 {
314 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
315 return FALSE;
316 else
317 {
318 PLDC pLDC = GdiGetLDC(hDC);
319 if ( !pLDC )
320 {
321 SetLastError(ERROR_INVALID_HANDLE);
322 return FALSE;
323 }
324 if (pLDC->iType == LDC_EMFLDC)
325 {
326 if (iMode == MWT_MAX+1)
327 if (!EMFDRV_SetWorldTransform( hDC, Xform) ) return FALSE;
328 return EMFDRV_ModifyWorldTransform( hDC, Xform, iMode); // Ported from wine.
329 }
330 return FALSE;
331 }
332 }
333 #endif
334 PDC_ATTR Dc_Attr;
335
336 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
337
338 /* Check that graphics mode is GM_ADVANCED */
339 if ( Dc_Attr->iGraphicsMode != GM_ADVANCED ) return FALSE;
340
341 return NtGdiModifyWorldTransform(hDC, (CONST LPXFORM) Xform, iMode);
342 }
343
344 BOOL
345 WINAPI
346 GetViewportExtEx(
347 HDC hdc,
348 LPSIZE lpSize
349 )
350 {
351 PDC_ATTR Dc_Attr;
352
353 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
354
355 if ((Dc_Attr->flXform & PAGE_EXTENTS_CHANGED) && (Dc_Attr->iMapMode == MM_ISOTROPIC))
356 // Something was updated, go to kernel.
357 return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (PPOINTL) lpSize );
358 else
359 {
360 lpSize->cx = Dc_Attr->szlViewportExt.cx;
361 lpSize->cy = Dc_Attr->szlViewportExt.cy;
362 }
363 return TRUE;
364 }
365
366
367 BOOL
368 WINAPI
369 GetViewportOrgEx(
370 HDC hdc,
371 LPPOINT lpPoint
372 )
373 {
374 PDC_ATTR Dc_Attr;
375
376 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
377 lpPoint->x = Dc_Attr->ptlViewportOrg.x;
378 lpPoint->y = Dc_Attr->ptlViewportOrg.y;
379 if (Dc_Attr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x;
380 return TRUE;
381 // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint );
382 }
383
384
385 BOOL
386 WINAPI
387 GetWindowExtEx(
388 HDC hdc,
389 LPSIZE lpSize
390 )
391 {
392 PDC_ATTR Dc_Attr;
393
394 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
395 lpSize->cx = Dc_Attr->szlWindowExt.cx;
396 lpSize->cy = Dc_Attr->szlWindowExt.cy;
397 if (Dc_Attr->dwLayout & LAYOUT_RTL) lpSize->cx = -lpSize->cx;
398 return TRUE;
399 // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize );
400 }
401
402
403 BOOL
404 WINAPI
405 GetWindowOrgEx(
406 HDC hdc,
407 LPPOINT lpPoint
408 )
409 {
410 PDC_ATTR Dc_Attr;
411
412 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
413 lpPoint->x = Dc_Attr->ptlWindowOrg.x;
414 lpPoint->y = Dc_Attr->ptlWindowOrg.y;
415 return TRUE;
416 //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint );
417 }
418
419 /*
420 * @unimplemented
421 */
422 BOOL
423 WINAPI
424 SetViewportExtEx(HDC hdc,
425 int nXExtent,
426 int nYExtent,
427 LPSIZE lpSize)
428 {
429 PDC_ATTR Dc_Attr;
430 #if 0
431 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
432 {
433 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
434 return MFDRV_SetViewportExtEx();
435 else
436 {
437 PLDC pLDC = GdiGetLDC(hdc);
438 if ( !pLDC )
439 {
440 SetLastError(ERROR_INVALID_HANDLE);
441 return FALSE;
442 }
443 if (pLDC->iType == LDC_EMFLDC)
444 {
445 return EMFDRV_SetViewportExtEx();
446 }
447 }
448 }
449 #endif
450 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
451 {
452 return FALSE;
453 }
454
455 if (lpSize)
456 {
457 lpSize->cx = Dc_Attr->szlViewportExt.cx;
458 lpSize->cy = Dc_Attr->szlViewportExt.cy;
459 }
460
461 if ((Dc_Attr->szlViewportExt.cx == nXExtent) && (Dc_Attr->szlViewportExt.cy == nYExtent))
462 return TRUE;
463
464 if ((Dc_Attr->iMapMode == MM_ISOTROPIC) || (Dc_Attr->iMapMode == MM_ANISOTROPIC))
465 {
466 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
467 {
468 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
469 {
470 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
471 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
472 }
473 }
474 Dc_Attr->szlViewportExt.cx = nXExtent;
475 Dc_Attr->szlViewportExt.cy = nYExtent;
476 if (Dc_Attr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc);
477 Dc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
478 }
479 return TRUE;
480 }
481
482 /*
483 * @unimplemented
484 */
485 BOOL
486 WINAPI
487 SetWindowOrgEx(HDC hdc,
488 int X,
489 int Y,
490 LPPOINT lpPoint)
491 {
492 #if 0
493 PDC_ATTR Dc_Attr;
494 #if 0
495 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
496 {
497 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
498 return MFDRV_SetWindowOrgEx();
499 else
500 {
501 PLDC pLDC = GdiGetLDC(hdc);
502 if ( !pLDC )
503 {
504 SetLastError(ERROR_INVALID_HANDLE);
505 return FALSE;
506 }
507 if (pLDC->iType == LDC_EMFLDC)
508 {
509 return EMFDRV_SetWindowOrgEx();
510 }
511 }
512 }
513 #endif
514 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
515
516 if (lpPoint)
517 {
518 lpPoint->x = Dc_Attr->ptlWindowOrg.x;
519 lpPoint->y = Dc_Attr->ptlWindowOrg.y;
520 }
521
522 if ((Dc_Attr->ptlWindowOrg.x == X) && (Dc_Attr->ptlWindowOrg.y == Y))
523 return TRUE;
524
525 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
526 {
527 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
528 {
529 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
530 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
531 }
532 }
533
534 Dc_Attr->ptlWindowOrg.x = X;
535 Dc_Attr->lWindowOrgx = X;
536 Dc_Attr->ptlWindowOrg.y = Y;
537 if (Dc_Attr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc);
538 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
539 return TRUE;
540 #endif
541 return NtGdiSetWindowOrgEx(hdc,X,Y,lpPoint);
542 }
543
544 /*
545 * @unimplemented
546 */
547 BOOL
548 WINAPI
549 SetWindowExtEx(
550 _In_ HDC hdc,
551 _In_ INT nXExtent,
552 _In_ INT nYExtent,
553 _Out_opt_ LPSIZE lpSize)
554 {
555 PDC_ATTR pdcattr;
556 ULONG ulType;
557
558 /* Check what type of DC that is */
559 ulType = GDI_HANDLE_GET_TYPE(hdc);
560 switch (ulType)
561 {
562 case GDILoObjType_LO_DC_TYPE:
563 /* Handle this in the path below */
564 break;
565 #if 0// FIXME: we don't support this
566 case GDILoObjType_LO_METADC16_TYPE:
567 return MFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
568
569 case GDILoObjType_LO_METAFILE_TYPE:
570 return EMFDRV_SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
571 #endif
572 default:
573 /* Other types are not allowed */
574 SetLastError(ERROR_INVALID_HANDLE);
575 return FALSE;
576 }
577
578 /* Get the DC attr */
579 pdcattr = GdiGetDcAttr(hdc);
580 if (!pdcattr)
581 {
582 /* Set the error value and return failure */
583 SetLastError(ERROR_INVALID_PARAMETER);
584 return FALSE;
585 }
586
587 if (lpSize)
588 {
589 lpSize->cx = pdcattr->szlWindowExt.cx;
590 lpSize->cy = pdcattr->szlWindowExt.cy;
591 if (pdcattr->dwLayout & LAYOUT_RTL) lpSize->cx = -lpSize->cx;
592 }
593
594 if (pdcattr->dwLayout & LAYOUT_RTL)
595 {
596 NtGdiMirrorWindowOrg(hdc);
597 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
598 }
599 else if ((pdcattr->iMapMode == MM_ISOTROPIC) || (pdcattr->iMapMode == MM_ANISOTROPIC))
600 {
601 if ((pdcattr->szlWindowExt.cx == nXExtent) && (pdcattr->szlWindowExt.cy == nYExtent))
602 return TRUE;
603
604 if ((!nXExtent) || (!nYExtent)) return FALSE;
605
606 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
607 {
608 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY)
609 {
610 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
611 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
612 }
613 }
614 pdcattr->szlWindowExt.cx = nXExtent;
615 pdcattr->szlWindowExt.cy = nYExtent;
616 if (pdcattr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc);
617 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
618 }
619
620 return TRUE;
621 }
622
623 /*
624 * @unimplemented
625 */
626 BOOL
627 WINAPI
628 SetViewportOrgEx(HDC hdc,
629 int X,
630 int Y,
631 LPPOINT lpPoint)
632 {
633 #if 0
634 PDC_ATTR Dc_Attr;
635 #if 0
636 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
637 {
638 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
639 return MFDRV_SetViewportOrgEx();
640 else
641 {
642 PLDC pLDC = GdiGetLDC(hdc);
643 if ( !pLDC )
644 {
645 SetLastError(ERROR_INVALID_HANDLE);
646 return FALSE;
647 }
648 if (pLDC->iType == LDC_EMFLDC)
649 {
650 return EMFDRV_SetViewportOrgEx();
651 }
652 }
653 }
654 #endif
655 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
656
657 if (lpPoint)
658 {
659 lpPoint->x = Dc_Attr->ptlViewportOrg.x;
660 lpPoint->y = Dc_Attr->ptlViewportOrg.y;
661 if (Dc_Attr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x;
662 }
663 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
664 if (Dc_Attr->dwLayout & LAYOUT_RTL) X = -X;
665 Dc_Attr->ptlViewportOrg.x = X;
666 Dc_Attr->ptlViewportOrg.y = Y;
667 return TRUE;
668 #endif
669 return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint);
670 }
671
672 /*
673 * @implemented
674 */
675 BOOL
676 WINAPI
677 ScaleViewportExtEx(
678 HDC a0,
679 int a1,
680 int a2,
681 int a3,
682 int a4,
683 LPSIZE a5
684 )
685 {
686 #if 0
687 if (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)
688 {
689 if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC)
690 return MFDRV_;
691 else
692 {
693 PLDC pLDC = GdiGetLDC(a0);
694 if ( !pLDC )
695 {
696 SetLastError(ERROR_INVALID_HANDLE);
697 return FALSE;
698 }
699 if (pLDC->iType == LDC_EMFLDC)
700 {
701 return EMFDRV_;
702 }
703 }
704 }
705 #endif
706 if (!GdiIsHandleValid((HGDIOBJ) a0) ||
707 (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)) return FALSE;
708
709 return NtGdiScaleViewportExtEx(a0, a1, a2, a3, a4, a5);
710 }
711
712 /*
713 * @implemented
714 */
715 BOOL
716 WINAPI
717 ScaleWindowExtEx(
718 HDC a0,
719 int a1,
720 int a2,
721 int a3,
722 int a4,
723 LPSIZE a5
724 )
725 {
726 #if 0
727 if (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)
728 {
729 if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC)
730 return MFDRV_;
731 else
732 {
733 PLDC pLDC = GdiGetLDC(a0);
734 if ( !pLDC )
735 {
736 SetLastError(ERROR_INVALID_HANDLE);
737 return FALSE;
738 }
739 if (pLDC->iType == LDC_EMFLDC)
740 {
741 return EMFDRV_;
742 }
743 }
744 }
745 #endif
746 if (!GdiIsHandleValid((HGDIOBJ) a0) ||
747 (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)) return FALSE;
748
749 return NtGdiScaleWindowExtEx(a0, a1, a2, a3, a4, a5);
750 }
751
752 /*
753 * @implemented
754 */
755 DWORD
756 WINAPI
757 GetLayout(HDC hdc
758 )
759 {
760 PDC_ATTR Dc_Attr;
761 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return GDI_ERROR;
762 return Dc_Attr->dwLayout;
763 }
764
765
766 /*
767 * @implemented
768 */
769 DWORD
770 WINAPI
771 SetLayout(HDC hdc,
772 DWORD dwLayout)
773 {
774 #if 0
775 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
776 {
777 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
778 return MFDRV_SetLayout( hdc, dwLayout);
779 else
780 {
781 PLDC pLDC = GdiGetLDC(hdc);
782 if ( !pLDC )
783 {
784 SetLastError(ERROR_INVALID_HANDLE);
785 return 0;
786 }
787 if (pLDC->iType == LDC_EMFLDC)
788 {
789 return EMFDRV_SetLayout( hdc, dwLayout);
790 }
791 }
792 }
793 #endif
794 if (!GdiIsHandleValid((HGDIOBJ) hdc) ||
795 (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)) return GDI_ERROR;
796 return NtGdiSetLayout( hdc, -1, dwLayout);
797 }
798
799 /*
800 * @implemented
801 */
802 DWORD
803 WINAPI
804 SetLayoutWidth(HDC hdc,LONG wox,DWORD dwLayout)
805 {
806 if (!GdiIsHandleValid((HGDIOBJ) hdc) ||
807 (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)) return GDI_ERROR;
808 return NtGdiSetLayout( hdc, wox, dwLayout);
809 }
810
811 /*
812 * @implemented
813 */
814 BOOL
815 WINAPI
816 GetDCOrgEx(
817 HDC hdc,
818 LPPOINT lpPoint)
819 {
820 return NtGdiGetDCPoint( hdc, GdiGetDCOrg, (PPOINTL)lpPoint );
821 }
822
823
824 /*
825 * @implemented
826 */
827 LONG
828 WINAPI
829 GetDCOrg(
830 HDC hdc)
831 {
832 // Officially obsolete by Microsoft
833 POINT Pt;
834 if (!GetDCOrgEx(hdc, &Pt))
835 return 0;
836 return(MAKELONG(Pt.x, Pt.y));
837 }
838
839
840 /*
841 * @implemented
842 *
843 */
844 BOOL
845 WINAPI
846 OffsetViewportOrgEx(HDC hdc,
847 int nXOffset,
848 int nYOffset,
849 LPPOINT lpPoint)
850 {
851 #if 0
852 PDC_ATTR Dc_Attr;
853 #if 0
854 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
855 {
856 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
857 return MFDRV_OffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint);
858 else
859 {
860 PLDC pLDC = GdiGetLDC(hdc);
861 if ( !pLDC )
862 {
863 SetLastError(ERROR_INVALID_HANDLE);
864 return FALSE;
865 }
866 if (pLDC->iType == LDC_EMFLDC)
867 {
868 return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
869 }
870 }
871 }
872 #endif
873 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
874
875 if ( lpPoint )
876 {
877 *lpPoint = (POINT)Dc_Attr->ptlViewportOrg;
878 if ( Dc_Attr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x;
879 }
880
881 if ( nXOffset || nYOffset != nXOffset )
882 {
883 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
884 {
885 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
886 {
887 NtGdiFlush();
888 Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY;
889 }
890 }
891 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
892 if ( Dc_Attr->dwLayout & LAYOUT_RTL) nXOffset = -nXOffset;
893 Dc_Attr->ptlViewportOrg.x += nXOffset;
894 Dc_Attr->ptlViewportOrg.y += nYOffset;
895 }
896 return TRUE;
897 #endif
898 return NtGdiOffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint);
899 }
900
901 /*
902 * @implemented
903 *
904 */
905 BOOL
906 WINAPI
907 OffsetWindowOrgEx(HDC hdc,
908 int nXOffset,
909 int nYOffset,
910 LPPOINT lpPoint)
911 {
912 #if 0
913 PDC_ATTR Dc_Attr;
914 #if 0
915 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
916 {
917 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
918 return MFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
919 else
920 {
921 PLDC pLDC = GdiGetLDC(hdc);
922 if ( !pLDC )
923 {
924 SetLastError(ERROR_INVALID_HANDLE);
925 return FALSE;
926 }
927 if (pLDC->iType == LDC_EMFLDC)
928 {
929 return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
930 }
931 }
932 }
933 #endif
934 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
935
936 if ( lpPoint )
937 {
938 *lpPoint = (POINT)Dc_Attr->ptlWindowOrg;
939 lpPoint->x = Dc_Attr->lWindowOrgx;
940 }
941
942 if ( nXOffset || nYOffset != nXOffset )
943 {
944 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
945 {
946 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
947 {
948 NtGdiFlush();
949 Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY;
950 }
951 }
952 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
953 Dc_Attr->ptlWindowOrg.x += nXOffset;
954 Dc_Attr->ptlWindowOrg.y += nYOffset;
955 Dc_Attr->lWindowOrgx += nXOffset;
956 }
957 return TRUE;
958 #endif
959 return NtGdiOffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint);
960 }
961