ReactOS  0.4.15-dev-3272-g6e356a9
coord.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * PURPOSE: Coordinate systems
5  * FILE: win32ss/gdi/ntgdi/coord.c
6  * PROGRAMERS: Timo Kreuzer (timo.kreuzer@rectos.org)
7  * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8  */
9 
10 /* Coordinate translation overview
11  * -------------------------------
12  *
13  * Windows uses 3 different coordinate systems, referred to as world space,
14  * page space and device space.
15  *
16  * Device space:
17  * This is the coordinate system of the physical device that displays the
18  * graphics. One unit matches one pixel of the surface. The coordinate system
19  * is always orthogonal.
20  *
21  * Page space:
22  * This is the coordinate system on the screen or on the paper layout for
23  * printer devices. The coordinate system is also orthogonal but one unit
24  * does not necessarily match one pixel. Instead there are different mapping
25  * modes that can be set using SetMapMode() that specify how page space units
26  * are transformed into device space units. These mapping modes are:
27  * - MM_TEXT: One unit matches one unit in device space (one pixel)
28  * - MM_TWIPS One unit matches 1/20 point (1/1440 inch)
29  * - MM_LOMETRIC: One unit matches 0.1 millimeter
30  * - MM_HIMETRIC: One unit matches 0.01 millimeter
31  * - MM_LOENGLISH: One unit matches 0.01 inch
32  * - MM_HIENGLISH: One unit matches 0.001 inch
33  * - MM_ISOTROPIC:
34  * - MM_ANISOTROPIC:
35  * If the mapping mode is either MM_ISOTROPIC or MM_ANISOTROPIC, the actual
36  * transformation is calculated from the window and viewport extension.
37  * The window extension can be set using SetWindowExtEx() and describes the
38  * extents of an arbitrary window (not to confuse with the gui element!) in
39  * page space coordinates.
40  * The viewport extension can be set using SetViewportExtEx() and describes
41  * the extent of the same window in device space coordinates. If the mapping
42  * mode is MM_ISOTROPIC one of the viewport extensions can be adjusted by GDI
43  * to make sure the mapping stays isotropic, i.e. that it has the same x/y
44  * ratio as the window extension.
45  *
46  * World space:
47  * World space is the coordinate system that is used for all GDI drawing
48  * operations. The metrics of this coordinate system depend on the DCs
49  * graphics mode, which can be set using SetGraphicsMode().
50  * If the graphics mode is GM_COMPATIBLE, world space is identical to page
51  * space and no additional transformation is applied.
52  * If the graphics mode is GM_ADVANCED, an arbitrary coordinate transformation
53  * can be set using SetWorldTransform(), which is applied to transform world
54  * space coordinates into page space coordinates.
55  *
56  * User mode data:
57  * All coordinate translation data is stored in the DC attribute, so the values
58  * might be invalid. This has to be taken into account. Values might also be
59  * zero, so when a division is made, the value has to be read first and then
60  * checked! This is true for both integer and floating point values, even if
61  * we cannot get floating point exceptions on x86, we can get them on all other
62  * architectures that use the FPU directly instead of emulation.
63  * The result of all operations might be completely random and invalid, if it was
64  * messed with in an illegal way in user mode. This is not a problem, since the
65  * result of coordinate transformations are never expected to be "valid" values.
66  * In the worst case, the drawing operation draws rubbish into the DC.
67  */
68 
69 /* INCLUDES ******************************************************************/
70 
71 #include <win32k.h>
72 
73 #define NDEBUG
74 #include <debug.h>
75 C_ASSERT(sizeof(XFORML) == sizeof(XFORM));
76 
77 
78 /* GLOBALS *******************************************************************/
79 
81 {
86 };
87 
88 
89 /* FUNCTIONS *****************************************************************/
90 
91 VOID
94 {
95  PDC_ATTR pdcattr;
96  LONG64 fx, fy;
97  LONG s;
98  SIZEL szlWindowExt, szlViewportExt;
99  ASSERT(pdc->pdcattr->iMapMode == MM_ISOTROPIC);
100 
101  /* Get a pointer to the DC_ATTR */
102  pdcattr = pdc->pdcattr;
103 
104  /* Read the extents, we rely on non-null values */
105  szlWindowExt = pdcattr->szlWindowExt;
106  szlViewportExt = pdcattr->szlViewportExt;
107 
108  /* Check if all values are valid */
109  if ((szlWindowExt.cx == 0) || (szlWindowExt.cy == 0) ||
110  (szlViewportExt.cx == 0) || (szlViewportExt.cy == 0))
111  {
112  /* Someone put rubbish into the fields, just ignore it. */
113  return;
114  }
115 
116  fx = abs((LONG64)szlWindowExt.cx * szlViewportExt.cy);
117  fy = abs((LONG64)szlWindowExt.cy * szlViewportExt.cx);
118 
119  if (fx < fy)
120  {
121  s = (szlWindowExt.cy ^ szlViewportExt.cx) > 0 ? 1 : -1;
122  pdcattr->szlViewportExt.cx = (LONG)(fx * s / szlWindowExt.cy);
123  }
124  else if (fx > fy)
125  {
126  s = (szlWindowExt.cx ^ szlViewportExt.cy) > 0 ? 1 : -1;
127  pdcattr->szlViewportExt.cy = (LONG)(fy * s / szlWindowExt.cx);
128  }
129 
130  /* Reset the flag */
131  pdc->pdcattr->flXform &= ~PAGE_EXTENTS_CHANGED;
132 }
133 
134 VOID
135 FASTCALL
137 {
138  PDC_ATTR pdcattr = pdc->pdcattr;
139  PSIZEL pszlViewPortExt;
140  SIZEL szlWindowExt;
141 
142  /* Get the viewport extension */
143  pszlViewPortExt = DC_pszlViewportExt(pdc);
144 
145  /* Copy the window extension, so no one can mess with it */
146  szlWindowExt = pdcattr->szlWindowExt;
147 
148  /* No shearing / rotation */
149  FLOATOBJ_SetLong(&pmx->efM12, 0);
150  FLOATOBJ_SetLong(&pmx->efM21, 0);
151 
152  /* Calculate scaling */
153  if (szlWindowExt.cx != 0)
154  {
155  FLOATOBJ_SetLong(&pmx->efM11, pszlViewPortExt->cx);
156  FLOATOBJ_DivLong(&pmx->efM11, szlWindowExt.cx);
157  }
158  else
159  FLOATOBJ_SetLong(&pmx->efM11, 1);
160 
161  if (szlWindowExt.cy != 0)
162  {
163  FLOATOBJ_SetLong(&pmx->efM22, pszlViewPortExt->cy);
164  FLOATOBJ_DivLong(&pmx->efM22, szlWindowExt.cy);
165  }
166  else
167  FLOATOBJ_SetLong(&pmx->efM22, 1);
168 
169  /* Calculate x offset */
170  FLOATOBJ_SetLong(&pmx->efDx, -pdcattr->ptlWindowOrg.x);
171  FLOATOBJ_Mul(&pmx->efDx, &pmx->efM11);
172  FLOATOBJ_AddLong(&pmx->efDx, pdcattr->ptlViewportOrg.x);
173 
174  /* Calculate y offset */
175  FLOATOBJ_SetLong(&pmx->efDy, -pdcattr->ptlWindowOrg.y);
176  FLOATOBJ_Mul(&pmx->efDy, &pmx->efM22);
177  FLOATOBJ_AddLong(&pmx->efDy, pdcattr->ptlViewportOrg.y);
178 }
179 
180 VOID
181 FASTCALL
183 {
184  XFORMOBJ xoPageToDevice, xoWorldToPage, xoWorldToDevice;
185  MATRIX mxPageToDevice;
186 
187  // FIXME: make sure world-to-page is valid!
188 
189  /* Construct a transformation to do the page-to-device conversion */
190  DC_vGetPageToDevice(pdc, &mxPageToDevice);
191  XFORMOBJ_vInit(&xoPageToDevice, &mxPageToDevice);
192 
193  /* Recalculate the world-to-device xform */
194  XFORMOBJ_vInit(&xoWorldToPage, &pdc->pdcattr->mxWorldToPage);
195  XFORMOBJ_vInit(&xoWorldToDevice, &pdc->pdcattr->mxWorldToDevice);
196  XFORMOBJ_iCombine(&xoWorldToDevice, &xoWorldToPage, &xoPageToDevice);
197 
198  /* Reset the flags */
199  pdc->pdcattr->flXform &= ~WORLD_XFORM_CHANGED;
200 }
201 
202 VOID
203 FASTCALL
205 {
206  XFORMOBJ xoWorldToDevice, xoDeviceToWorld;
207  PMATRIX pmxWorldToDevice;
208 
209  /* Get the world-to-device translation */
210  pmxWorldToDevice = DC_pmxWorldToDevice(pdc);
211  XFORMOBJ_vInit(&xoWorldToDevice, pmxWorldToDevice);
212 
213  /* Create inverse of world-to-device transformation */
214  XFORMOBJ_vInit(&xoDeviceToWorld, &pdc->pdcattr->mxDeviceToWorld);
215  if (XFORMOBJ_iInverse(&xoDeviceToWorld, &xoWorldToDevice) == DDI_ERROR)
216  {
217  MX_Set0(&pdc->pdcattr->mxDeviceToWorld);
218  return;
219  }
220 
221  /* Reset the flag */
222  pdc->pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
223 }
224 
225 BOOL
226 NTAPI
228  XFORML *pxformDest,
229  XFORML *pxform1,
230  XFORML *pxform2)
231 {
232  MATRIX mxDest, mx1, mx2;
233  XFORMOBJ xoDest, xo1, xo2;
234 
235  /* Check for illegal parameters */
236  if (!pxformDest || !pxform1 || !pxform2) return FALSE;
237 
238  /* Initialize XFORMOBJs */
239  XFORMOBJ_vInit(&xoDest, &mxDest);
240  XFORMOBJ_vInit(&xo1, &mx1);
241  XFORMOBJ_vInit(&xo2, &mx2);
242 
243  /* Convert the XFORMLs into XFORMOBJs */
244  XFORMOBJ_iSetXform(&xo1, pxform1);
245  XFORMOBJ_iSetXform(&xo2, pxform2);
246 
247  /* Combine them */
248  XFORMOBJ_iCombine(&xoDest, &xo1, &xo2);
249 
250  /* Translate back into XFORML */
251  XFORMOBJ_iGetXform(&xoDest, pxformDest);
252 
253  return TRUE;
254 }
255 
256 BOOL
257 APIENTRY
259  LPXFORM UnsafeXFormResult,
260  LPXFORM Unsafexform1,
261  LPXFORM Unsafexform2)
262 {
263  BOOL Ret;
264 
265  _SEH2_TRY
266  {
267  ProbeForWrite(UnsafeXFormResult, sizeof(XFORM), 1);
268  ProbeForRead(Unsafexform1, sizeof(XFORM), 1);
269  ProbeForRead(Unsafexform2, sizeof(XFORM), 1);
270  Ret = GreCombineTransform((XFORML*)UnsafeXFormResult,
271  (XFORML*)Unsafexform1,
272  (XFORML*)Unsafexform2);
273  }
275  {
276  Ret = FALSE;
277  }
278  _SEH2_END;
279 
280  return Ret;
281 }
282 
283 // FIXME: Should be XFORML and use XFORMOBJ functions directly
284 BOOL
285 APIENTRY
287  HDC hdc,
288  DWORD iXform,
289  LPXFORM pXForm)
290 {
291  PDC pdc;
292  BOOL ret = TRUE;
293  MATRIX mxPageToDevice;
294  XFORMOBJ xo;
295  PMATRIX pmx;
296 
297  if (!pXForm)
298  {
300  return FALSE;
301  }
302 
303  pdc = DC_LockDc(hdc);
304  if (!pdc)
305  {
307  return FALSE;
308  }
309 
310  switch (iXform)
311  {
313  pmx = DC_pmxWorldToPage(pdc);
314  break;
315 
317  pmx = DC_pmxWorldToDevice(pdc);
318  break;
319 
321  pmx = DC_pmxDeviceToWorld(pdc);
322  break;
323 
325  DC_vGetPageToDevice(pdc, &mxPageToDevice);
326  pmx = &mxPageToDevice;
327  break;
328 
329  default:
330  DPRINT1("Unknown transform %lu\n", iXform);
331  ret = FALSE;
332  goto leave;
333  }
334 
335  /* Initialize an XFORMOBJ */
336  XFORMOBJ_vInit(&xo, pmx);
337 
338  _SEH2_TRY
339  {
340  ProbeForWrite(pXForm, sizeof(XFORML), 1);
341  XFORMOBJ_iGetXform(&xo, (XFORML*)pXForm);
342  }
344  {
345  ret = FALSE;
346  }
347  _SEH2_END;
348 
349 leave:
350  DC_UnlockDc(pdc);
351  return ret;
352 }
353 
354 
364 BOOL
365 APIENTRY
367  HDC hDC,
368  PPOINT UnsafePtsIn,
369  PPOINT UnsafePtOut,
370  INT Count,
371  INT iMode)
372 {
373  PDC pdc;
374  LPPOINT Points;
375  ULONG Size;
376  BOOL ret = TRUE;
377 
378  if (Count <= 0)
379  return TRUE;
380 
381  if (!UnsafePtsIn || !UnsafePtOut)
382  {
383  return FALSE;
384  }
385 
386  pdc = DC_LockDc(hDC);
387  if (!pdc)
388  {
389  return FALSE;
390  }
391 
392  Size = Count * sizeof(POINT);
393 
394  // FIXME: It would be wise to have a small stack buffer as optimization
396  if (!Points)
397  {
398  DC_UnlockDc(pdc);
400  return FALSE;
401  }
402 
403  _SEH2_TRY
404  {
405  ProbeForWrite(UnsafePtOut, Size, 1);
406  ProbeForRead(UnsafePtsIn, Size, 1);
407  RtlCopyMemory(Points, UnsafePtsIn, Size);
408  }
410  {
411  /* Do not set last error */
412  _SEH2_YIELD(goto leave;)
413  }
414  _SEH2_END;
415 
416  switch (iMode)
417  {
418  case GdiDpToLp:
420  break;
421 
422  case GdiLpToDp:
424  break;
425 
426  case 2: // Not supported yet. Need testing.
427  default:
428  {
430  ret = FALSE;
431  goto leave;
432  }
433  }
434 
435  if (ret)
436  {
437  _SEH2_TRY
438  {
439  /* Pointer was already probed! */
440  RtlCopyMemory(UnsafePtOut, Points, Size);
441  }
443  {
444  /* Do not set last error */
445  ret = FALSE;
446  }
447  _SEH2_END;
448  }
449 
450 //
451 // If we are getting called that means User XForms is a mess!
452 //
453 leave:
454  DC_UnlockDc(pdc);
456  return ret;
457 }
458 
459 BOOL
460 NTAPI
462  PDC pdc,
463  const XFORML *pxform,
464  DWORD dwMode)
465 {
466  MATRIX mxSrc;
467  XFORMOBJ xoSrc, xoDC;
468 
469  switch (dwMode)
470  {
471  case MWT_IDENTITY:
472  pdc->pdcattr->mxWorldToPage = gmxIdentity;
473  break;
474 
475  case MWT_LEFTMULTIPLY:
476  XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
477  XFORMOBJ_vInit(&xoSrc, &mxSrc);
478  if (XFORMOBJ_iSetXform(&xoSrc, pxform) == DDI_ERROR)
479  return FALSE;
480  XFORMOBJ_iCombine(&xoDC, &xoSrc, &xoDC);
481  break;
482 
483  case MWT_RIGHTMULTIPLY:
484  XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
485  XFORMOBJ_vInit(&xoSrc, &mxSrc);
486  if (XFORMOBJ_iSetXform(&xoSrc, pxform) == DDI_ERROR)
487  return FALSE;
488  XFORMOBJ_iCombine(&xoDC, &xoDC, &xoSrc);
489  break;
490 
491  case MWT_SET:
492  XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
493  if (XFORMOBJ_iSetXform(&xoDC, pxform) == DDI_ERROR)
494  return FALSE;
495  break;
496 
497  default:
498  return FALSE;
499  }
500 
501  /*Set invalidation flags */
502  pdc->pdcattr->flXform |= WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID;
503 
504  return TRUE;
505 }
506 
507 BOOL
508 APIENTRY
510  HDC hdc,
511  LPXFORM pxformUnsafe,
512  DWORD dwMode)
513 {
514  PDC pdc;
515  XFORML xformSafe;
516  BOOL Ret = TRUE;
517 
518  pdc = DC_LockDc(hdc);
519  if (!pdc)
520  {
522  return FALSE;
523  }
524 
525  /* The xform is permitted to be NULL for MWT_IDENTITY.
526  * However, if it is not NULL, then it must be valid even
527  * though it is not used. */
528  if ((dwMode != MWT_IDENTITY) && (pxformUnsafe == NULL))
529  {
530  DC_UnlockDc(pdc);
531  return FALSE;
532  }
533 
534  if (pxformUnsafe != NULL)
535  {
536  _SEH2_TRY
537  {
538  ProbeForRead(pxformUnsafe, sizeof(XFORML), 1);
539  RtlCopyMemory(&xformSafe, pxformUnsafe, sizeof(XFORML));
540  }
542  {
543  Ret = FALSE;
544  }
545  _SEH2_END;
546  }
547 
548  /* Safe to handle kernel mode data. */
549  if (Ret) Ret = GreModifyWorldTransform(pdc, &xformSafe, dwMode);
550  DC_UnlockDc(pdc);
551  return Ret;
552 }
553 
554 BOOL
555 APIENTRY
557  HDC hDC,
558  int XOffset,
559  int YOffset,
560  LPPOINT UnsafePoint)
561 {
562  PDC dc;
563  PDC_ATTR pdcattr;
565 
566  dc = DC_LockDc(hDC);
567  if (!dc)
568  {
570  return FALSE;
571  }
572  pdcattr = dc->pdcattr;
573 
574  if (UnsafePoint)
575  {
576  _SEH2_TRY
577  {
578  ProbeForWrite(UnsafePoint, sizeof(POINT), 1);
579  UnsafePoint->x = pdcattr->ptlViewportOrg.x;
580  UnsafePoint->y = pdcattr->ptlViewportOrg.y;
581  if (pdcattr->dwLayout & LAYOUT_RTL)
582  {
583  UnsafePoint->x = -UnsafePoint->x;
584  }
585  }
587  {
589  }
590  _SEH2_END;
591 
592  if (!NT_SUCCESS(Status))
593  {
595  DC_UnlockDc(dc);
596  return FALSE;
597  }
598  }
599 
600  if (pdcattr->dwLayout & LAYOUT_RTL)
601  {
602  XOffset = -XOffset;
603  }
604  pdcattr->ptlViewportOrg.x += XOffset;
605  pdcattr->ptlViewportOrg.y += YOffset;
607 
608  DC_UnlockDc(dc);
609 
610  return TRUE;
611 }
612 
613 BOOL
614 APIENTRY
616  HDC hDC,
617  int XOffset,
618  int YOffset,
619  LPPOINT Point)
620 {
621  PDC dc;
622  PDC_ATTR pdcattr;
623 
624  dc = DC_LockDc(hDC);
625  if (!dc)
626  {
628  return FALSE;
629  }
630  pdcattr = dc->pdcattr;
631 
632  if (Point)
633  {
635 
636  _SEH2_TRY
637  {
638  ProbeForWrite(Point, sizeof(POINT), 1);
639  Point->x = pdcattr->ptlWindowOrg.x;
640  Point->y = pdcattr->ptlWindowOrg.y;
641  }
643  {
645  }
646  _SEH2_END;
647 
648  if (!NT_SUCCESS(Status))
649  {
651  DC_UnlockDc(dc);
652  return FALSE;
653  }
654  }
655 
656  pdcattr->ptlWindowOrg.x += XOffset;
657  pdcattr->ptlWindowOrg.y += YOffset;
659 
660  DC_UnlockDc(dc);
661 
662  return TRUE;
663 }
664 
665 BOOL
666 APIENTRY
668  HDC hDC,
669  int Xnum,
670  int Xdenom,
671  int Ynum,
672  int Ydenom,
673  LPSIZE pSize)
674 {
675  PDC pDC;
676  PDC_ATTR pdcattr;
677  BOOL Ret = FALSE;
678  LONG X, Y;
679 
680  pDC = DC_LockDc(hDC);
681  if (!pDC)
682  {
684  return FALSE;
685  }
686  pdcattr = pDC->pdcattr;
687 
688  if (pdcattr->iMapMode > MM_TWIPS)
689  {
690  if (Xdenom && Ydenom)
691  {
692  DC_pszlViewportExt(pDC);
693  X = Xnum * pdcattr->szlViewportExt.cx / Xdenom;
694  if (X)
695  {
696  Y = Ynum * pdcattr->szlViewportExt.cy / Ydenom;
697  if (Y)
698  {
699  pdcattr->szlViewportExt.cx = X;
700  pdcattr->szlViewportExt.cy = Y;
701  pdcattr->flXform |= PAGE_XLATE_CHANGED;
702 
703  IntMirrorWindowOrg(pDC);
704 
705  pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
709 
710  if (pdcattr->iMapMode == MM_ISOTROPIC)
711  {
713  }
714 
715  Ret = TRUE;
716  }
717  }
718  }
719  }
720  else
721  Ret = TRUE;
722 
723  if (pSize)
724  {
725  _SEH2_TRY
726  {
727  ProbeForWrite(pSize, sizeof(SIZE), 1);
728 
729  pSize->cx = pdcattr->szlViewportExt.cx;
730  pSize->cy = pdcattr->szlViewportExt.cy;
731  }
733  {
735  Ret = FALSE;
736  }
737  _SEH2_END;
738  }
739 
740  DC_UnlockDc(pDC);
741  return Ret;
742 }
743 
744 BOOL
745 APIENTRY
747  HDC hDC,
748  int Xnum,
749  int Xdenom,
750  int Ynum,
751  int Ydenom,
752  LPSIZE pSize)
753 {
754  PDC pDC;
755  PDC_ATTR pdcattr;
756  BOOL Ret = FALSE;
757  LONG X, Y;
758 
759  pDC = DC_LockDc(hDC);
760  if (!pDC)
761  {
763  return FALSE;
764  }
765  pdcattr = pDC->pdcattr;
766 
767  if (pSize)
768  {
770 
771  _SEH2_TRY
772  {
773  ProbeForWrite(pSize, sizeof(SIZE), 1);
774 
775  X = pdcattr->szlWindowExt.cx;
776  if (pdcattr->dwLayout & LAYOUT_RTL) X = -X;
777  pSize->cx = X;
778  pSize->cy = pdcattr->szlWindowExt.cy;
779  }
781  {
783  }
784  _SEH2_END;
785 
786  if (!NT_SUCCESS(Status))
787  {
789  DC_UnlockDc(pDC);
790  return FALSE;
791  }
792  }
793 
794  if (pdcattr->iMapMode > MM_TWIPS)
795  {
796  if (Xdenom && Ydenom)
797  {
798  X = Xnum * pdcattr->szlWindowExt.cx / Xdenom;
799  if (X)
800  {
801  Y = Ynum * pdcattr->szlWindowExt.cy / Ydenom;
802  if (Y)
803  {
804  pdcattr->szlWindowExt.cx = X;
805  pdcattr->szlWindowExt.cy = Y;
806 
807  IntMirrorWindowOrg(pDC);
808 
809  pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
813 
814  Ret = TRUE;
815  }
816  }
817  }
818  }
819  else
820  Ret = TRUE;
821 
822  DC_UnlockDc(pDC);
823  return Ret;
824 }
825 
826 int
827 APIENTRY
829  PDC dc,
830  int MapMode)
831 {
832  INT iPrevMapMode;
833  FLONG flXform;
834  PDC_ATTR pdcattr = dc->pdcattr;
835 
836  if (MapMode == pdcattr->iMapMode)
837  return MapMode;
838 
839  flXform = pdcattr->flXform & ~(ISO_OR_ANISO_MAP_MODE|PTOD_EFM22_NEGATIVE|
842 
843  switch (MapMode)
844  {
845  case MM_TEXT:
846  pdcattr->szlWindowExt.cx = 1;
847  pdcattr->szlWindowExt.cy = 1;
848  pdcattr->szlViewportExt.cx = 1;
849  pdcattr->szlViewportExt.cy = 1;
851  break;
852 
853  case MM_ISOTROPIC:
854  flXform |= ISO_OR_ANISO_MAP_MODE;
855  /* Fall through */
856 
857  case MM_LOMETRIC:
858  pdcattr->szlWindowExt.cx = pdcattr->szlVirtualDeviceMm.cx * 10;
859  pdcattr->szlWindowExt.cy = pdcattr->szlVirtualDeviceMm.cy * 10;
860  pdcattr->szlViewportExt.cx = pdcattr->szlVirtualDevicePixel.cx;
861  pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
862  break;
863 
864  case MM_HIMETRIC:
865  pdcattr->szlWindowExt.cx = pdcattr->szlVirtualDeviceMm.cx * 100;
866  pdcattr->szlWindowExt.cy = pdcattr->szlVirtualDeviceMm.cy * 100;
867  pdcattr->szlViewportExt.cx = pdcattr->szlVirtualDevicePixel.cx;
868  pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
869  break;
870 
871  case MM_LOENGLISH:
872  pdcattr->szlWindowExt.cx = EngMulDiv(1000, pdcattr->szlVirtualDeviceMm.cx, 254);
873  pdcattr->szlWindowExt.cy = EngMulDiv(1000, pdcattr->szlVirtualDeviceMm.cy, 254);
874  pdcattr->szlViewportExt.cx = pdcattr->szlVirtualDevicePixel.cx;
875  pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
876  break;
877 
878  case MM_HIENGLISH:
879  pdcattr->szlWindowExt.cx = EngMulDiv(10000, pdcattr->szlVirtualDeviceMm.cx, 254);
880  pdcattr->szlWindowExt.cy = EngMulDiv(10000, pdcattr->szlVirtualDeviceMm.cy, 254);
881  pdcattr->szlViewportExt.cx = pdcattr->szlVirtualDevicePixel.cx;
882  pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
883  break;
884 
885  case MM_TWIPS:
886  pdcattr->szlWindowExt.cx = EngMulDiv(14400, pdcattr->szlVirtualDeviceMm.cx, 254);
887  pdcattr->szlWindowExt.cy = EngMulDiv(14400, pdcattr->szlVirtualDeviceMm.cy, 254);
888  pdcattr->szlViewportExt.cx = pdcattr->szlVirtualDevicePixel.cx;
889  pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
890  break;
891 
892  case MM_ANISOTROPIC:
894  flXform |= ISO_OR_ANISO_MAP_MODE;
895  break;
896 
897  default:
898  return 0;
899  }
900 
901  /* Save the old map mode and set the new one */
902  iPrevMapMode = pdcattr->iMapMode;
903  pdcattr->iMapMode = MapMode;
904 
905  /* Update xform flags */
906  pdcattr->flXform = flXform | (PAGE_XLATE_CHANGED | PAGE_EXTENTS_CHANGED |
909 
910  return iPrevMapMode;
911 }
912 
913 BOOL
914 FASTCALL
916  HDC hDC,
917  int X,
918  int Y,
919  LPPOINT Point)
920 {
921  PDC dc;
922  PDC_ATTR pdcattr;
923 
924  dc = DC_LockDc(hDC);
925  if (!dc)
926  {
928  return FALSE;
929  }
930  pdcattr = dc->pdcattr;
931 
932  if (Point)
933  {
934  Point->x = pdcattr->ptlViewportOrg.x;
935  Point->y = pdcattr->ptlViewportOrg.y;
936  }
937 
938  pdcattr->ptlViewportOrg.x = X;
939  pdcattr->ptlViewportOrg.y = Y;
941 
942  DC_UnlockDc(dc);
943  return TRUE;
944 }
945 
946 BOOL
947 APIENTRY
949  HDC hDC,
950  int X,
951  int Y,
952  LPPOINT Point)
953 {
954  PDC dc;
955  PDC_ATTR pdcattr;
956 
957  dc = DC_LockDc(hDC);
958  if (!dc)
959  {
961  return FALSE;
962  }
963  pdcattr = dc->pdcattr;
964 
965  if (Point)
966  {
968 
969  _SEH2_TRY
970  {
971  ProbeForWrite(Point, sizeof(POINT), 1);
972  Point->x = pdcattr->ptlViewportOrg.x;
973  Point->y = pdcattr->ptlViewportOrg.y;
974  }
976  {
978  }
979  _SEH2_END;
980 
981  if (!NT_SUCCESS(Status))
982  {
984  DC_UnlockDc(dc);
985  return FALSE;
986  }
987  }
988 
989  pdcattr->ptlViewportOrg.x = X;
990  pdcattr->ptlViewportOrg.y = Y;
992 
993  DC_UnlockDc(dc);
994 
995  return TRUE;
996 }
997 
998 BOOL
999 APIENTRY
1001  HDC hDC,
1002  int X,
1003  int Y,
1004  LPPOINT Point)
1005 {
1006  PDC dc;
1007  PDC_ATTR pdcattr;
1008 
1009  dc = DC_LockDc(hDC);
1010  if (!dc)
1011  {
1013  return FALSE;
1014  }
1015  pdcattr = dc->pdcattr;
1016 
1017  if (Point)
1018  {
1020 
1021  _SEH2_TRY
1022  {
1023  ProbeForWrite(Point, sizeof(POINT), 1);
1024  Point->x = pdcattr->ptlWindowOrg.x;
1025  Point->y = pdcattr->ptlWindowOrg.y;
1026  }
1028  {
1030  }
1031  _SEH2_END;
1032 
1033  if (!NT_SUCCESS(Status))
1034  {
1036  DC_UnlockDc(dc);
1037  return FALSE;
1038  }
1039  }
1040 
1041  pdcattr->ptlWindowOrg.x = X;
1042  pdcattr->ptlWindowOrg.y = Y;
1044 
1045  DC_UnlockDc(dc);
1046 
1047  return TRUE;
1048 }
1049 
1050 //
1051 // Mirror Window function.
1052 //
1053 VOID
1054 FASTCALL
1056 {
1057  PDC_ATTR pdcattr;
1058  LONG X, cx;
1059 
1060  pdcattr = dc->pdcattr;
1061 
1062  if (!(pdcattr->dwLayout & LAYOUT_RTL))
1063  {
1064  pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx; // Flip it back.
1065  return;
1066  }
1067 
1068  /* Copy the window extension, so no one can mess with it */
1069  cx = pdcattr->szlViewportExt.cx;
1070  if (cx == 0) return;
1071  //
1072  // WOrgx = wox - (Width - 1) * WExtx / VExtx
1073  //
1074  X = (dc->erclWindow.right - dc->erclWindow.left) - 1; // Get device width - 1
1075 
1076  X = (X * pdcattr->szlWindowExt.cx) / cx;
1077 
1078  pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx - X; // Now set the inverted win origion.
1080 
1081  return;
1082 }
1083 
1084 VOID
1085 NTAPI
1087  IN PDC pdc,
1088  IN LONG wox,
1089  IN DWORD dwLayout)
1090 {
1091  PDC_ATTR pdcattr = pdc->pdcattr;
1092 
1093  pdcattr->dwLayout = dwLayout;
1094 
1095  if (!(dwLayout & LAYOUT_ORIENTATIONMASK)) return;
1096 
1097  if (dwLayout & LAYOUT_RTL)
1098  {
1099  pdcattr->iMapMode = MM_ANISOTROPIC;
1100  }
1101 
1102  //pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy;
1103  //pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x;
1104 
1105  //if (wox == -1)
1106  // IntMirrorWindowOrg(pdc);
1107  //else
1108  // pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x;
1109 
1110  if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT;
1111 
1112  if (pdc->dclevel.flPath & DCPATH_CLOCKWISE)
1113  pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
1114  else
1115  pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
1116 
1117  pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
1121 }
1122 
1123 // NtGdiSetLayout
1124 //
1125 // The default is left to right. This function changes it to right to left, which
1126 // is the standard in Arabic and Hebrew cultures.
1127 //
1128 /*
1129  * @implemented
1130  */
1131 DWORD
1132 APIENTRY
1134  IN HDC hdc,
1135  IN LONG wox,
1136  IN DWORD dwLayout)
1137 {
1138  PDC pdc;
1139  DWORD dwOldLayout;
1140 
1141  pdc = DC_LockDc(hdc);
1142  if (!pdc)
1143  {
1145  return GDI_ERROR;
1146  }
1147 
1148  dwOldLayout = pdc->pdcattr->dwLayout;
1149  DC_vSetLayout(pdc, wox, dwLayout);
1150 
1151  DC_UnlockDc(pdc);
1152  return dwOldLayout;
1153 }
1154 
1155 /*
1156  * @implemented
1157  */
1158 LONG
1159 APIENTRY
1161  IN HDC hdc)
1162 {
1163  PDC dc;
1164  LONG Ret;
1165  dc = DC_LockDc(hdc);
1166  if (!dc)
1167  {
1169  return 0;
1170  }
1171  Ret = dc->erclWindow.right - dc->erclWindow.left;
1172  DC_UnlockDc(dc);
1173  return Ret;
1174 }
1175 
1176 /*
1177  * @implemented
1178  */
1179 BOOL
1180 APIENTRY
1182  IN HDC hdc)
1183 {
1184  PDC dc;
1185  dc = DC_LockDc(hdc);
1186  if (!dc)
1187  {
1189  return FALSE;
1190  }
1192  DC_UnlockDc(dc);
1193  return TRUE;
1194 }
1195 
1196 /*
1197  * @implemented
1198  */
1199 BOOL
1200 APIENTRY
1202  IN HDC hdc,
1203  IN INT cxVirtualDevice,
1204  IN INT cyVirtualDevice)
1205 {
1206  PDC dc;
1207  PDC_ATTR pdcattr;
1208 
1209  if (!cxVirtualDevice || !cyVirtualDevice)
1210  {
1211  return FALSE;
1212  }
1213 
1214  dc = DC_LockDc(hdc);
1215  if (!dc) return FALSE;
1216 
1217  pdcattr = dc->pdcattr;
1218 
1219  pdcattr->szlVirtualDeviceSize.cx = cxVirtualDevice;
1220  pdcattr->szlVirtualDeviceSize.cy = cyVirtualDevice;
1221 
1222  DC_UnlockDc(dc);
1223 
1224  return TRUE;
1225 }
1226 
1227 /*
1228  * @implemented
1229  */
1230 BOOL
1231 APIENTRY
1233  IN HDC hdc,
1234  IN INT cxVirtualDevicePixel,
1235  IN INT cyVirtualDevicePixel,
1236  IN INT cxVirtualDeviceMm,
1237  IN INT cyVirtualDeviceMm)
1238 {
1239  PDC dc;
1240  PDC_ATTR pdcattr;
1241 
1242  /* Check parameters (all zeroes resets to real resolution) */
1243  if (cxVirtualDevicePixel == 0 && cyVirtualDevicePixel == 0 &&
1244  cxVirtualDeviceMm == 0 && cyVirtualDeviceMm == 0)
1245  {
1246  cxVirtualDevicePixel = NtGdiGetDeviceCaps(hdc, HORZRES);
1247  cyVirtualDevicePixel = NtGdiGetDeviceCaps(hdc, VERTRES);
1248  cxVirtualDeviceMm = NtGdiGetDeviceCaps(hdc, HORZSIZE);
1249  cyVirtualDeviceMm = NtGdiGetDeviceCaps(hdc, VERTSIZE);
1250  }
1251  else if (cxVirtualDevicePixel == 0 || cyVirtualDevicePixel == 0 ||
1252  cxVirtualDeviceMm == 0 || cyVirtualDeviceMm == 0)
1253  {
1254  return FALSE;
1255  }
1256 
1257  dc = DC_LockDc(hdc);
1258  if (!dc) return FALSE;
1259 
1260  pdcattr = dc->pdcattr;
1261 
1262  pdcattr->szlVirtualDevicePixel.cx = cxVirtualDevicePixel;
1263  pdcattr->szlVirtualDevicePixel.cy = cyVirtualDevicePixel;
1264  pdcattr->szlVirtualDeviceMm.cx = cxVirtualDeviceMm;
1265  pdcattr->szlVirtualDeviceMm.cy = cyVirtualDeviceMm;
1266 
1267 // DC_vUpdateXforms(dc);
1268  DC_UnlockDc(dc);
1269  return TRUE;
1270 }
1271 
1272 static
1273 VOID FASTCALL
1275 {
1276  if (pDC->pdcattr->flFontMapper & 1) // TRUE assume 1.
1277  {
1278  // "This specifies that Windows should only match fonts that have the
1279  // same aspect ratio as the display.", Programming Windows, Fifth Ed.
1280  AspectRatio->cx = pDC->ppdev->gdiinfo.ulLogPixelsX;
1281  AspectRatio->cy = pDC->ppdev->gdiinfo.ulLogPixelsY;
1282  }
1283  else
1284  {
1285  AspectRatio->cx = 0;
1286  AspectRatio->cy = 0;
1287  }
1288 }
1289 
1290 BOOL APIENTRY
1292  HDC hDC,
1293  UINT iPoint,
1294  PPOINTL Point)
1295 {
1296  BOOL Ret = TRUE;
1297  DC *pdc;
1298  SIZE Size;
1299  PSIZEL pszlViewportExt;
1300 
1301  if (!Point)
1302  {
1304  return FALSE;
1305  }
1306 
1307  pdc = DC_LockDc(hDC);
1308  if (!pdc)
1309  {
1311  return FALSE;
1312  }
1313 
1314  switch (iPoint)
1315  {
1316  case GdiGetViewPortExt:
1317  pszlViewportExt = DC_pszlViewportExt(pdc);
1318  Point->x = pszlViewportExt->cx;
1319  Point->y = pszlViewportExt->cy;
1320  break;
1321 
1322  case GdiGetWindowExt:
1323  Point->x = pdc->pdcattr->szlWindowExt.cx;
1324  Point->y = pdc->pdcattr->szlWindowExt.cy;
1325  break;
1326 
1327  case GdiGetViewPortOrg:
1328  *Point = pdc->pdcattr->ptlViewportOrg;
1329  break;
1330 
1331  case GdiGetWindowOrg:
1332  *Point = pdc->pdcattr->ptlWindowOrg;
1333  break;
1334 
1335  case GdiGetDCOrg:
1336  *Point = pdc->ptlDCOrig;
1337  break;
1338 
1341  Point->x = Size.cx;
1342  Point->y = Size.cy;
1343  break;
1344 
1345  default:
1347  Ret = FALSE;
1348  break;
1349  }
1350 
1351  DC_UnlockDc(pdc);
1352  return Ret;
1353 }
1354 
1355 BOOL
1356 WINAPI
1358  _In_ HDC hdc,
1359  _In_ LONG x,
1360  _In_ LONG y,
1362 {
1363  PDC dc;
1364 
1365  dc = DC_LockDc(hdc);
1366  if (!dc) return FALSE;
1367 
1368  /* Set DC Origin */
1369  dc->ptlDCOrig.x = x;
1370  dc->ptlDCOrig.y = y;
1371 
1372  /* Recalculate Fill Origin */
1373  dc->ptlFillOrigin.x = dc->dclevel.ptlBrushOrigin.x + x;
1374  dc->ptlFillOrigin.y = dc->dclevel.ptlBrushOrigin.y + y;
1375 
1376  /* Set DC Window Rectangle */
1377  if (Rect)
1378  dc->erclWindow = *Rect;
1379 
1380  DC_UnlockDc(dc);
1381  return TRUE;
1382 }
1383 
1384 BOOL
1385 WINAPI
1387  _In_ HDC hdc,
1389  _Out_ PRECTL Rect)
1390 {
1391  PDC dc;
1392 
1393  dc = DC_LockDc(hdc);
1394  if (!dc) return FALSE;
1395 
1396  /* Retrieve DC Window Rectangle without a check */
1397  *Rect = dc->erclWindow;
1398 
1399  DC_UnlockDc(dc);
1400 
1401  /* Use default call for DC Origin and parameter checking */
1402  return GreGetDCPoint( hdc, GdiGetDCOrg, Point);
1403 }
1404 
1405 BOOL
1406 WINAPI
1408  _In_ HDC hdc,
1409  _Out_ LPSIZE lpSize)
1410 {
1411  return GreGetDCPoint(hdc, GdiGetWindowExt, (PPOINTL)lpSize);
1412 }
1413 
1414 BOOL
1415 WINAPI
1417  _In_ HDC hdc,
1418  _Out_ LPSIZE lpSize)
1419 {
1420  return GreGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)lpSize);
1421 }
1422 
1423 BOOL APIENTRY
1425  HDC hDC,
1426  UINT iPoint,
1427  PPOINTL Point)
1428 {
1429  BOOL Ret;
1430  POINTL SafePoint;
1431 
1432  if (!Point)
1433  {
1435  return FALSE;
1436  }
1437 
1438  Ret = GreGetDCPoint(hDC, iPoint, &SafePoint);
1439  if (Ret)
1440  {
1441  _SEH2_TRY
1442  {
1443  ProbeForWrite(Point, sizeof(POINT), 1);
1444  *Point = SafePoint;
1445  }
1447  {
1448  Ret = FALSE;
1449  }
1450  _SEH2_END;
1451  }
1452 
1453  return Ret;
1454 }
1455 
1456 /* EOF */
#define MM_ISOTROPIC
Definition: wingdi.h:870
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
LONG APIENTRY NtGdiGetDeviceWidth(IN HDC hdc)
Definition: coord.c:1160
#define abs(i)
Definition: fconv.c:206
BOOL FASTCALL GreSetViewportOrgEx(HDC hDC, int X, int Y, LPPOINT Point)
Definition: coord.c:915
#define IN
Definition: typedefs.h:39
BOOL NTAPI GreModifyWorldTransform(PDC pdc, const XFORML *pxform, DWORD dwMode)
Definition: coord.c:461
#define HORZRES
Definition: wingdi.h:716
int APIENTRY IntGdiSetMapMode(PDC dc, int MapMode)
Definition: coord.c:828
POINTL ptlViewportOrg
Definition: ntgdihdl.h:361
#define GDITAG_TEMP
Definition: tags.h:166
#define _In_opt_
Definition: ms_sal.h:309
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
long y
Definition: polytest.cpp:48
#define LAYOUT_RTL
Definition: wingdi.h:1371
#define Y(I)
#define MWT_SET
Definition: ntgdityp.h:180
_In_ ULONG iMode
Definition: winddi.h:3520
#define XFORMOBJ_iInverse
Definition: xformobj.h:17
long x
Definition: polytest.cpp:48
#define _Out_
Definition: ms_sal.h:345
BOOL APIENTRY NtGdiModifyWorldTransform(HDC hdc, LPXFORM pxformUnsafe, DWORD dwMode)
Definition: coord.c:509
#define TRUE
Definition: types.h:120
#define FLOATOBJ_DivLong(pf, l)
Definition: winddi.h:2829
#define PAGE_TO_DEVICE_IDENTITY
Definition: ntgdihdl.h:206
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define POSITIVE_Y_IS_UP
Definition: ntgdihdl.h:201
LONG NTSTATUS
Definition: precomp.h:26
INT iMapMode
Definition: ntgdihdl.h:356
#define GdiDeviceSpaceToWorldSpace
Definition: ntgdityp.h:185
static HDC
Definition: imagelist.c:92
#define MWT_LEFTMULTIPLY
Definition: wingdi.h:945
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
BOOL WINAPI GreGetViewportExtEx(_In_ HDC hdc, _Out_ LPSIZE lpSize)
Definition: coord.c:1416
BOOL APIENTRY NtGdiSetWindowOrgEx(HDC hDC, int X, int Y, LPPOINT Point)
Definition: coord.c:1000
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define XFORMOBJ_iSetXform
Definition: xformobj.h:14
BOOL APIENTRY NtGdiOffsetWindowOrgEx(HDC hDC, int XOffset, int YOffset, LPPOINT Point)
Definition: coord.c:615
FORCEINLINE VOID XFORMOBJ_vInit(OUT XFORMOBJ *pxo, IN MATRIX *pmx)
Definition: xformobj.h:21
BOOL APIENTRY NtGdiScaleWindowExtEx(HDC hDC, int Xnum, int Xdenom, int Ynum, int Ydenom, LPSIZE pSize)
Definition: coord.c:746
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:58
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
LONG y
Definition: windef.h:330
_SEH2_TRY
Definition: create.c:4226
#define LAYOUT_ORIENTATIONMASK
Definition: wingdi.h:1374
#define PAGE_XLATE_CHANGED
Definition: ntgdihdl.h:208
BOOL APIENTRY NtGdiOffsetViewportOrgEx(HDC hDC, int XOffset, int YOffset, LPPOINT UnsafePoint)
Definition: coord.c:556
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ISO_OR_ANISO_MAP_MODE
Definition: ntgdihdl.h:205
#define XFORMOBJ_iGetXform
Definition: xformobj.h:9
long LONG
Definition: pedump.c:60
BOOL APIENTRY NtGdiMirrorWindowOrg(IN HDC hdc)
Definition: coord.c:1181
BOOL APIENTRY NtGdiSetVirtualResolution(IN HDC hdc, IN INT cxVirtualDevicePixel, IN INT cyVirtualDevicePixel, IN INT cxVirtualDeviceMm, IN INT cyVirtualDeviceMm)
Definition: coord.c:1232
BOOL APIENTRY NtGdiGetTransform(HDC hdc, DWORD iXform, LPXFORM pXForm)
Definition: coord.c:286
VOID NTAPI DC_vSetLayout(IN PDC pdc, IN LONG wox, IN DWORD dwLayout)
Definition: coord.c:1086
#define FLOATOBJ_AddLong(pf, l)
Definition: winddi.h:2820
#define _In_
Definition: ms_sal.h:308
#define DDI_ERROR
Definition: winddi.h:154
BOOL APIENTRY NtGdiSetSizeDevice(IN HDC hdc, IN INT cxVirtualDevice, IN INT cyVirtualDevice)
Definition: coord.c:1201
LONG cx
Definition: windef.h:334
#define leave
Definition: seh.h:23
VOID FASTCALL DC_vUpdateDeviceToWorld(PDC pdc)
Definition: coord.c:204
VOID FASTCALL MX_Set0(OUT PMATRIX pmx)
Definition: xformobj.c:275
unsigned long FLONG
Definition: ntbasedef.h:366
VOID FASTCALL DC_vUpdateWorldToDevice(PDC pdc)
Definition: coord.c:182
BOOL NTAPI GreCombineTransform(XFORML *pxformDest, XFORML *pxform1, XFORML *pxform2)
Definition: coord.c:227
#define POINT
Definition: precomp.h:30
#define TA_RIGHT
Definition: wingdi.h:933
Status
Definition: gdiplustypes.h:24
int64_t LONG64
Definition: typedefs.h:68
#define FLOATOBJ_1
Definition: floatobj.h:109
int Count
Definition: noreturn.cpp:7
Definition: polytest.cpp:40
DWORD APIENTRY NtGdiSetLayout(IN HDC hdc, IN LONG wox, IN DWORD dwLayout)
Definition: coord.c:1133
#define ASSERT(a)
Definition: mode.c:44
#define GdiPageSpaceToDeviceSpace
Definition: ntgdityp.h:184
_In_ DWORD iXform
Definition: ntgdi.h:2251
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: matrix.h:43
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define GdiWorldSpaceToPageSpace
Definition: ntgdityp.h:182
#define WINAPI
Definition: msvc.h:6
#define PAGE_EXTENTS_CHANGED
Definition: ntgdihdl.h:209
#define MM_LOMETRIC
Definition: wingdi.h:872
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DEVICE_TO_PAGE_INVALID
Definition: ntgdihdl.h:198
LONG x
Definition: windef.h:329
BOOL WINAPI GreSetDCOrg(_In_ HDC hdc, _In_ LONG x, _In_ LONG y, _In_opt_ PRECTL Rect)
Definition: coord.c:1357
#define MM_LOENGLISH
Definition: wingdi.h:871
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static VOID FASTCALL DC_vGetAspectRatioFilter(PDC pDC, LPSIZE AspectRatio)
Definition: coord.c:1274
int ret
LONG lWindowOrgx
Definition: ntgdihdl.h:358
BOOL APIENTRY NtGdiScaleViewportExtEx(HDC hDC, int Xnum, int Xdenom, int Ynum, int Ydenom, LPSIZE pSize)
Definition: coord.c:667
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
HDC hdc
Definition: main.c:9
#define MM_ANISOTROPIC
Definition: wingdi.h:867
FLONG flXform
Definition: ntgdihdl.h:363
BOOL APIENTRY GreGetDCPoint(HDC hDC, UINT iPoint, PPOINTL Point)
Definition: coord.c:1291
#define MM_TWIPS
Definition: wingdi.h:874
SIZEL szlWindowExt
Definition: ntgdihdl.h:360
GLfixed fx
Definition: tritemp.h:482
GLdouble s
Definition: gl.h:2039
#define PTOD_EFM22_NEGATIVE
Definition: ntgdihdl.h:204
BOOL APIENTRY NtGdiGetDCPoint(HDC hDC, UINT iPoint, PPOINTL Point)
Definition: coord.c:1424
BOOL APIENTRY NtGdiTransformPoints(HDC hDC, PPOINT UnsafePtsIn, PPOINT UnsafePtOut, INT Count, INT iMode)
Definition: coord.c:366
_In_ UINT iPoint
Definition: ntgdi.h:2197
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
SIZEL szlVirtualDevicePixel
Definition: ntgdihdl.h:364
#define PAGE_TO_DEVICE_SCALE_IDENTITY
Definition: ntgdihdl.h:207
#define HORZSIZE
Definition: wingdi.h:714
#define GdiWorldSpaceToDeviceSpace
Definition: gdi_private.h:221
BOOL APIENTRY NtGdiCombineTransform(LPXFORM UnsafeXFormResult, LPXFORM Unsafexform1, LPXFORM Unsafexform2)
Definition: coord.c:258
VOID FASTCALL DC_vFixIsotropicMapping(PDC pdc)
Definition: coord.c:93
#define FLOATOBJ_SetLong(pf, l)
Definition: winddi.h:2815
static HDC hDC
Definition: 3dtext.c:33
VOID FASTCALL DC_vGetPageToDevice(PDC pdc, MATRIX *pmx)
Definition: coord.c:136
#define WORLD_XFORM_CHANGED
Definition: ntgdihdl.h:210
#define VERTSIZE
Definition: wingdi.h:715
_SEH2_END
Definition: create.c:4400
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
BOOL WINAPI GreGetWindowExtEx(_In_ HDC hdc, _Out_ LPSIZE lpSize)
Definition: coord.c:1407
unsigned int UINT
Definition: ndis.h:50
FORCEINLINE PSIZEL DC_pszlViewportExt(PDC pdc)
Definition: coord.h:111
#define NULL
Definition: types.h:112
#define VERTRES
Definition: wingdi.h:717
#define MM_HIMETRIC
Definition: wingdi.h:869
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
FLONG flTextAlign
Definition: ntgdihdl.h:342
#define DPRINT1
Definition: precomp.h:8
#define XFORMOBJ_iCombine
Definition: xformobj.h:15
#define DEVICE_TO_WORLD_INVALID
Definition: ntgdihdl.h:199
#define MWT_IDENTITY
Definition: wingdi.h:944
_Out_opt_ int * cx
Definition: commctrl.h:585
FORCEINLINE PMATRIX DC_pmxWorldToPage(PDC pdc)
Definition: coord.h:128
#define MM_TEXT
Definition: wingdi.h:873
#define FLOATOBJ_0
Definition: floatobj.h:108
SIZEL szlVirtualDeviceSize
Definition: ntgdihdl.h:366
SIZEL szlViewportExt
Definition: ntgdihdl.h:362
unsigned int ULONG
Definition: retypes.h:1
DWORD dwLayout
Definition: ntgdihdl.h:357
static const WCHAR dc[]
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE PMATRIX DC_pmxWorldToDevice(PDC pdc)
Definition: coord.h:135
BOOL WINAPI GreGetDCOrgEx(_In_ HDC hdc, _Out_ PPOINTL Point, _Out_ PRECTL Rect)
Definition: coord.c:1386
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define TA_CENTER
Definition: wingdi.h:931
GLfixed fy
Definition: tritemp.h:490
#define STATUS_SUCCESS
Definition: shellext.h:65
__kernel_entry W32KAPI INT APIENTRY NtGdiGetDeviceCaps(_In_ HDC hdc, _In_ INT i)
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define INVALIDATE_ATTRIBUTES
Definition: ntgdihdl.h:202
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
FORCEINLINE PMATRIX DC_pmxDeviceToWorld(PDC pdc)
Definition: coord.h:149
#define FLOATOBJ_Mul(pf, pf1)
Definition: winddi.h:2824
#define GDI_ERROR
Definition: wingdi.h:1309
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
BOOL APIENTRY NtGdiSetViewportOrgEx(HDC hDC, int X, int Y, LPPOINT Point)
Definition: coord.c:948
const MATRIX gmxIdentity
Definition: coord.c:80
LONG cy
Definition: windef.h:335
VOID FASTCALL IntMirrorWindowOrg(PDC dc)
Definition: coord.c:1055
#define MM_HIENGLISH
Definition: wingdi.h:868
C_ASSERT(sizeof(XFORML)==sizeof(XFORM))
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
static BOOLEAN INTERNAL_APPLY_MATRIX(PMATRIX matrix, LPPOINT points, UINT count)
Definition: coord.h:13
#define APIENTRY
Definition: api.h:79
struct Rect Rect
#define X(b, s)
POINTL ptlWindowOrg
Definition: ntgdihdl.h:359
SIZEL szlVirtualDeviceMm
Definition: ntgdihdl.h:365
#define PTOD_EFM11_NEGATIVE
Definition: ntgdihdl.h:203
#define MWT_RIGHTMULTIPLY
Definition: wingdi.h:946