2 * GDI mapping mode functions
4 * Copyright 1993 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "gdi_private.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(dc
);
32 /***********************************************************************
33 * MAPPING_FixIsotropic
35 * Fix viewport extensions for isotropic mode.
37 static void MAPPING_FixIsotropic( DC
* dc
)
39 double xdim
= fabs((double)dc
->vportExtX
* dc
->virtual_size
.cx
/
40 (dc
->virtual_res
.cx
* dc
->wndExtX
));
41 double ydim
= fabs((double)dc
->vportExtY
* dc
->virtual_size
.cy
/
42 (dc
->virtual_res
.cy
* dc
->wndExtY
));
46 INT mincx
= (dc
->vportExtX
>= 0) ? 1 : -1;
47 dc
->vportExtX
= floor(dc
->vportExtX
* ydim
/ xdim
+ 0.5);
48 if (!dc
->vportExtX
) dc
->vportExtX
= mincx
;
52 INT mincy
= (dc
->vportExtY
>= 0) ? 1 : -1;
53 dc
->vportExtY
= floor(dc
->vportExtY
* xdim
/ ydim
+ 0.5);
54 if (!dc
->vportExtY
) dc
->vportExtY
= mincy
;
59 /***********************************************************************
62 BOOL WINAPI
DPtoLP( HDC hdc
, LPPOINT points
, INT count
)
64 DC
* dc
= get_dc_ptr( hdc
);
65 if (!dc
) return FALSE
;
67 if (dc
->vport2WorldValid
)
73 points
->x
= floor( x
* dc
->xformVport2World
.eM11
+
74 y
* dc
->xformVport2World
.eM21
+
75 dc
->xformVport2World
.eDx
+ 0.5 );
76 points
->y
= floor( x
* dc
->xformVport2World
.eM12
+
77 y
* dc
->xformVport2World
.eM22
+
78 dc
->xformVport2World
.eDy
+ 0.5 );
87 /***********************************************************************
90 BOOL WINAPI
LPtoDP( HDC hdc
, LPPOINT points
, INT count
)
92 DC
* dc
= get_dc_ptr( hdc
);
93 if (!dc
) return FALSE
;
99 points
->x
= floor( x
* dc
->xformWorld2Vport
.eM11
+
100 y
* dc
->xformWorld2Vport
.eM21
+
101 dc
->xformWorld2Vport
.eDx
+ 0.5 );
102 points
->y
= floor( x
* dc
->xformWorld2Vport
.eM12
+
103 y
* dc
->xformWorld2Vport
.eM22
+
104 dc
->xformWorld2Vport
.eDy
+ 0.5 );
107 release_dc_ptr( dc
);
112 /***********************************************************************
113 * SetMapMode (GDI32.@)
115 INT WINAPI
SetMapMode( HDC hdc
, INT mode
)
118 INT horzSize
, vertSize
, horzRes
, vertRes
;
120 DC
* dc
= get_dc_ptr( hdc
);
122 if (dc
->funcs
->pSetMapMode
)
124 if((ret
= dc
->funcs
->pSetMapMode( dc
->physDev
, mode
)) != TRUE
)
126 if(ret
== GDI_NO_MORE_WORK
)
132 TRACE("%p %d\n", hdc
, mode
);
136 if (mode
== dc
->MapMode
&& (mode
== MM_ISOTROPIC
|| mode
== MM_ANISOTROPIC
))
139 horzSize
= dc
->virtual_size
.cx
;
140 vertSize
= dc
->virtual_size
.cy
;
141 horzRes
= dc
->virtual_res
.cx
;
142 vertRes
= dc
->virtual_res
.cy
;
153 dc
->wndExtX
= horzSize
* 10;
154 dc
->wndExtY
= vertSize
* 10;
155 dc
->vportExtX
= horzRes
;
156 dc
->vportExtY
= -vertRes
;
159 dc
->wndExtX
= horzSize
* 100;
160 dc
->wndExtY
= vertSize
* 100;
161 dc
->vportExtX
= horzRes
;
162 dc
->vportExtY
= -vertRes
;
165 dc
->wndExtX
= MulDiv(1000, horzSize
, 254);
166 dc
->wndExtY
= MulDiv(1000, vertSize
, 254);
167 dc
->vportExtX
= horzRes
;
168 dc
->vportExtY
= -vertRes
;
171 dc
->wndExtX
= MulDiv(10000, horzSize
, 254);
172 dc
->wndExtY
= MulDiv(10000, vertSize
, 254);
173 dc
->vportExtX
= horzRes
;
174 dc
->vportExtY
= -vertRes
;
177 dc
->wndExtX
= MulDiv(14400, horzSize
, 254);
178 dc
->wndExtY
= MulDiv(14400, vertSize
, 254);
179 dc
->vportExtX
= horzRes
;
180 dc
->vportExtY
= -vertRes
;
187 /* RTL layout is always MM_ANISOTROPIC */
188 if (!(dc
->layout
& LAYOUT_RTL
)) dc
->MapMode
= mode
;
189 DC_UpdateXforms( dc
);
191 release_dc_ptr( dc
);
196 /***********************************************************************
197 * SetViewportExtEx (GDI32.@)
199 BOOL WINAPI
SetViewportExtEx( HDC hdc
, INT x
, INT y
, LPSIZE size
)
202 DC
* dc
= get_dc_ptr( hdc
);
203 if (!dc
) return FALSE
;
204 if (dc
->funcs
->pSetViewportExt
)
206 if((ret
= dc
->funcs
->pSetViewportExt( dc
->physDev
, x
, y
)) != TRUE
)
208 if(ret
== GDI_NO_MORE_WORK
)
215 size
->cx
= dc
->vportExtX
;
216 size
->cy
= dc
->vportExtY
;
218 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
227 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
228 DC_UpdateXforms( dc
);
230 release_dc_ptr( dc
);
235 /***********************************************************************
236 * SetViewportOrgEx (GDI32.@)
238 BOOL WINAPI
SetViewportOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
241 DC
* dc
= get_dc_ptr( hdc
);
242 if (!dc
) return FALSE
;
243 if (dc
->funcs
->pSetViewportOrg
)
245 if((ret
= dc
->funcs
->pSetViewportOrg( dc
->physDev
, x
, y
)) != TRUE
)
247 if(ret
== GDI_NO_MORE_WORK
)
254 pt
->x
= dc
->vportOrgX
;
255 pt
->y
= dc
->vportOrgY
;
259 DC_UpdateXforms( dc
);
262 release_dc_ptr( dc
);
267 /***********************************************************************
268 * SetWindowExtEx (GDI32.@)
270 BOOL WINAPI
SetWindowExtEx( HDC hdc
, INT x
, INT y
, LPSIZE size
)
273 DC
* dc
= get_dc_ptr( hdc
);
274 if (!dc
) return FALSE
;
275 if (dc
->funcs
->pSetWindowExt
)
277 if((ret
= dc
->funcs
->pSetWindowExt( dc
->physDev
, x
, y
)) != TRUE
)
279 if(ret
== GDI_NO_MORE_WORK
)
286 size
->cx
= dc
->wndExtX
;
287 size
->cy
= dc
->wndExtY
;
289 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
298 /* The API docs say that you should call SetWindowExtEx before
299 SetViewportExtEx. This advice does not imply that Windows
300 doesn't ensure the isotropic mapping after SetWindowExtEx! */
301 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
302 DC_UpdateXforms( dc
);
304 release_dc_ptr( dc
);
309 /***********************************************************************
310 * SetWindowOrgEx (GDI32.@)
312 BOOL WINAPI
SetWindowOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
315 DC
* dc
= get_dc_ptr( hdc
);
316 if (!dc
) return FALSE
;
317 if (dc
->funcs
->pSetWindowOrg
)
319 if((ret
= dc
->funcs
->pSetWindowOrg( dc
->physDev
, x
, y
)) != TRUE
)
321 if(ret
== GDI_NO_MORE_WORK
)
333 DC_UpdateXforms( dc
);
335 release_dc_ptr( dc
);
340 /***********************************************************************
341 * OffsetViewportOrgEx (GDI32.@)
343 BOOL WINAPI
OffsetViewportOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
346 DC
* dc
= get_dc_ptr( hdc
);
347 if (!dc
) return FALSE
;
348 if (dc
->funcs
->pOffsetViewportOrg
)
350 if((ret
= dc
->funcs
->pOffsetViewportOrg( dc
->physDev
, x
, y
)) != TRUE
)
352 if(ret
== GDI_NO_MORE_WORK
)
359 pt
->x
= dc
->vportOrgX
;
360 pt
->y
= dc
->vportOrgY
;
364 DC_UpdateXforms( dc
);
366 release_dc_ptr( dc
);
371 /***********************************************************************
372 * OffsetWindowOrgEx (GDI32.@)
374 BOOL WINAPI
OffsetWindowOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
377 DC
* dc
= get_dc_ptr( hdc
);
378 if (!dc
) return FALSE
;
379 if (dc
->funcs
->pOffsetWindowOrg
)
381 if((ret
= dc
->funcs
->pOffsetWindowOrg( dc
->physDev
, x
, y
)) != TRUE
)
383 if(ret
== GDI_NO_MORE_WORK
)
395 DC_UpdateXforms( dc
);
397 release_dc_ptr( dc
);
402 /***********************************************************************
403 * ScaleViewportExtEx (GDI32.@)
405 BOOL WINAPI
ScaleViewportExtEx( HDC hdc
, INT xNum
, INT xDenom
,
406 INT yNum
, INT yDenom
, LPSIZE size
)
409 DC
* dc
= get_dc_ptr( hdc
);
410 if (!dc
) return FALSE
;
411 if (dc
->funcs
->pScaleViewportExt
)
413 if((ret
= dc
->funcs
->pScaleViewportExt( dc
->physDev
, xNum
, xDenom
, yNum
, yDenom
)) != TRUE
)
415 if(ret
== GDI_NO_MORE_WORK
)
422 size
->cx
= dc
->vportExtX
;
423 size
->cy
= dc
->vportExtY
;
425 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
427 if (!xNum
|| !xDenom
|| !yNum
|| !yDenom
)
432 dc
->vportExtX
= (dc
->vportExtX
* xNum
) / xDenom
;
433 dc
->vportExtY
= (dc
->vportExtY
* yNum
) / yDenom
;
434 if (dc
->vportExtX
== 0) dc
->vportExtX
= 1;
435 if (dc
->vportExtY
== 0) dc
->vportExtY
= 1;
436 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
437 DC_UpdateXforms( dc
);
439 release_dc_ptr( dc
);
444 /***********************************************************************
445 * ScaleWindowExtEx (GDI32.@)
447 BOOL WINAPI
ScaleWindowExtEx( HDC hdc
, INT xNum
, INT xDenom
,
448 INT yNum
, INT yDenom
, LPSIZE size
)
451 DC
* dc
= get_dc_ptr( hdc
);
452 if (!dc
) return FALSE
;
453 if (dc
->funcs
->pScaleWindowExt
)
455 if((ret
= dc
->funcs
->pScaleWindowExt( dc
->physDev
, xNum
, xDenom
, yNum
, yDenom
)) != TRUE
)
457 if(ret
== GDI_NO_MORE_WORK
)
464 size
->cx
= dc
->wndExtX
;
465 size
->cy
= dc
->wndExtY
;
467 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
469 if (!xNum
|| !xDenom
|| !xNum
|| !yDenom
)
474 dc
->wndExtX
= (dc
->wndExtX
* xNum
) / xDenom
;
475 dc
->wndExtY
= (dc
->wndExtY
* yNum
) / yDenom
;
476 if (dc
->wndExtX
== 0) dc
->wndExtX
= 1;
477 if (dc
->wndExtY
== 0) dc
->wndExtY
= 1;
478 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
479 DC_UpdateXforms( dc
);
481 release_dc_ptr( dc
);
485 /***********************************************************************
486 * SetVirtualResolution (GDI32.@)
488 * Undocumented on msdn.
490 * Changes the values of screen size in pixels and millimeters used by
491 * the mapping mode functions.
494 * hdc [I] Device context
495 * horz_res [I] Width in pixels (equivalent to HORZRES device cap).
496 * vert_res [I] Height in pixels (equivalent to VERTRES device cap).
497 * horz_size [I] Width in mm (equivalent to HORZSIZE device cap).
498 * vert_size [I] Height in mm (equivalent to VERTSIZE device cap).
501 * TRUE if successful.
502 * FALSE if any (but not all) of the last four params are zero.
505 * This doesn't change the values returned by GetDeviceCaps, just the
506 * scaling of the mapping modes.
508 * Calling with the last four params equal to zero sets the values
509 * back to their defaults obtained by calls to GetDeviceCaps.
511 BOOL WINAPI
SetVirtualResolution(HDC hdc
, DWORD horz_res
, DWORD vert_res
,
512 DWORD horz_size
, DWORD vert_size
)
515 TRACE("(%p %d %d %d %d)\n", hdc
, horz_res
, vert_res
, horz_size
, vert_size
);
517 if(horz_res
== 0 && vert_res
== 0 && horz_size
== 0 && vert_size
== 0)
519 horz_res
= GetDeviceCaps(hdc
, HORZRES
);
520 vert_res
= GetDeviceCaps(hdc
, VERTRES
);
521 horz_size
= GetDeviceCaps(hdc
, HORZSIZE
);
522 vert_size
= GetDeviceCaps(hdc
, VERTSIZE
);
524 else if(horz_res
== 0 || vert_res
== 0 || horz_size
== 0 || vert_size
== 0)
527 dc
= get_dc_ptr( hdc
);
528 if (!dc
) return FALSE
;
530 dc
->virtual_res
.cx
= horz_res
;
531 dc
->virtual_res
.cy
= vert_res
;
532 dc
->virtual_size
.cx
= horz_size
;
533 dc
->virtual_size
.cy
= vert_size
;
535 release_dc_ptr( dc
);