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