Release 1.3.7.
[wine/gsoc-2012-control.git] / dlls / gdi32 / mapping.c
blob667c83b8eccebb40f01c131eeed8026873bc0b8c
1 /*
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
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));
44 if (xdim > ydim)
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;
50 else
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 /***********************************************************************
60 * DPtoLP (GDI32.@)
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)
69 while (count--)
71 double x = points->x;
72 double y = points->y;
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 );
79 points++;
82 release_dc_ptr( dc );
83 return (count < 0);
87 /***********************************************************************
88 * LPtoDP (GDI32.@)
90 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
92 DC * dc = get_dc_ptr( hdc );
93 if (!dc) return FALSE;
95 while (count--)
97 double x = points->x;
98 double y = points->y;
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 );
105 points++;
107 release_dc_ptr( dc );
108 return TRUE;
112 /***********************************************************************
113 * SetMapMode (GDI32.@)
115 INT WINAPI SetMapMode( HDC hdc, INT mode )
117 INT ret;
118 INT horzSize, vertSize, horzRes, vertRes;
120 DC * dc = get_dc_ptr( hdc );
121 if (!dc) return 0;
122 if (dc->funcs->pSetMapMode)
124 if((ret = dc->funcs->pSetMapMode( dc->physDev, mode )) != TRUE)
126 if(ret == GDI_NO_MORE_WORK)
127 ret = TRUE;
128 goto done;
132 TRACE("%p %d\n", hdc, mode );
134 ret = dc->MapMode;
136 if (mode == dc->MapMode && (mode == MM_ISOTROPIC || mode == MM_ANISOTROPIC))
137 goto done;
139 horzSize = dc->virtual_size.cx;
140 vertSize = dc->virtual_size.cy;
141 horzRes = dc->virtual_res.cx;
142 vertRes = dc->virtual_res.cy;
143 switch(mode)
145 case MM_TEXT:
146 dc->wndExtX = 1;
147 dc->wndExtY = 1;
148 dc->vportExtX = 1;
149 dc->vportExtY = 1;
150 break;
151 case MM_LOMETRIC:
152 case MM_ISOTROPIC:
153 dc->wndExtX = horzSize * 10;
154 dc->wndExtY = vertSize * 10;
155 dc->vportExtX = horzRes;
156 dc->vportExtY = -vertRes;
157 break;
158 case MM_HIMETRIC:
159 dc->wndExtX = horzSize * 100;
160 dc->wndExtY = vertSize * 100;
161 dc->vportExtX = horzRes;
162 dc->vportExtY = -vertRes;
163 break;
164 case MM_LOENGLISH:
165 dc->wndExtX = MulDiv(1000, horzSize, 254);
166 dc->wndExtY = MulDiv(1000, vertSize, 254);
167 dc->vportExtX = horzRes;
168 dc->vportExtY = -vertRes;
169 break;
170 case MM_HIENGLISH:
171 dc->wndExtX = MulDiv(10000, horzSize, 254);
172 dc->wndExtY = MulDiv(10000, vertSize, 254);
173 dc->vportExtX = horzRes;
174 dc->vportExtY = -vertRes;
175 break;
176 case MM_TWIPS:
177 dc->wndExtX = MulDiv(14400, horzSize, 254);
178 dc->wndExtY = MulDiv(14400, vertSize, 254);
179 dc->vportExtX = horzRes;
180 dc->vportExtY = -vertRes;
181 break;
182 case MM_ANISOTROPIC:
183 break;
184 default:
185 goto done;
187 /* RTL layout is always MM_ANISOTROPIC */
188 if (!(dc->layout & LAYOUT_RTL)) dc->MapMode = mode;
189 DC_UpdateXforms( dc );
190 done:
191 release_dc_ptr( dc );
192 return ret;
196 /***********************************************************************
197 * SetViewportExtEx (GDI32.@)
199 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
201 INT ret = TRUE;
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)
209 ret = TRUE;
210 goto done;
213 if (size)
215 size->cx = dc->vportExtX;
216 size->cy = dc->vportExtY;
218 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
219 goto done;
220 if (!x || !y)
222 ret = FALSE;
223 goto done;
225 dc->vportExtX = x;
226 dc->vportExtY = y;
227 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
228 DC_UpdateXforms( dc );
229 done:
230 release_dc_ptr( dc );
231 return ret;
235 /***********************************************************************
236 * SetViewportOrgEx (GDI32.@)
238 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
240 INT ret = TRUE;
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)
248 ret = TRUE;
249 goto done;
252 if (pt)
254 pt->x = dc->vportOrgX;
255 pt->y = dc->vportOrgY;
257 dc->vportOrgX = x;
258 dc->vportOrgY = y;
259 DC_UpdateXforms( dc );
261 done:
262 release_dc_ptr( dc );
263 return ret;
267 /***********************************************************************
268 * SetWindowExtEx (GDI32.@)
270 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
272 INT ret = TRUE;
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)
280 ret = TRUE;
281 goto done;
284 if (size)
286 size->cx = dc->wndExtX;
287 size->cy = dc->wndExtY;
289 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
290 goto done;
291 if (!x || !y)
293 ret = FALSE;
294 goto done;
296 dc->wndExtX = x;
297 dc->wndExtY = y;
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 );
303 done:
304 release_dc_ptr( dc );
305 return ret;
309 /***********************************************************************
310 * SetWindowOrgEx (GDI32.@)
312 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
314 INT ret = TRUE;
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)
322 ret = TRUE;
323 goto done;
326 if (pt)
328 pt->x = dc->wndOrgX;
329 pt->y = dc->wndOrgY;
331 dc->wndOrgX = x;
332 dc->wndOrgY = y;
333 DC_UpdateXforms( dc );
334 done:
335 release_dc_ptr( dc );
336 return ret;
340 /***********************************************************************
341 * OffsetViewportOrgEx (GDI32.@)
343 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
345 INT ret = TRUE;
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)
353 ret = TRUE;
354 goto done;
357 if (pt)
359 pt->x = dc->vportOrgX;
360 pt->y = dc->vportOrgY;
362 dc->vportOrgX += x;
363 dc->vportOrgY += y;
364 DC_UpdateXforms( dc );
365 done:
366 release_dc_ptr( dc );
367 return ret;
371 /***********************************************************************
372 * OffsetWindowOrgEx (GDI32.@)
374 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
376 INT ret = TRUE;
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)
384 ret = TRUE;
385 goto done;
388 if (pt)
390 pt->x = dc->wndOrgX;
391 pt->y = dc->wndOrgY;
393 dc->wndOrgX += x;
394 dc->wndOrgY += y;
395 DC_UpdateXforms( dc );
396 done:
397 release_dc_ptr( dc );
398 return ret;
402 /***********************************************************************
403 * ScaleViewportExtEx (GDI32.@)
405 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
406 INT yNum, INT yDenom, LPSIZE size )
408 INT ret = TRUE;
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)
416 ret = TRUE;
417 goto done;
420 if (size)
422 size->cx = dc->vportExtX;
423 size->cy = dc->vportExtY;
425 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
426 goto done;
427 if (!xNum || !xDenom || !yNum || !yDenom)
429 ret = FALSE;
430 goto done;
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 );
438 done:
439 release_dc_ptr( dc );
440 return ret;
444 /***********************************************************************
445 * ScaleWindowExtEx (GDI32.@)
447 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
448 INT yNum, INT yDenom, LPSIZE size )
450 INT ret = TRUE;
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)
458 ret = TRUE;
459 goto done;
462 if (size)
464 size->cx = dc->wndExtX;
465 size->cy = dc->wndExtY;
467 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
468 goto done;
469 if (!xNum || !xDenom || !xNum || !yDenom)
471 ret = FALSE;
472 goto done;
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 );
480 done:
481 release_dc_ptr( dc );
482 return ret;
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.
493 * PARAMS
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).
500 * RETURNS
501 * TRUE if successful.
502 * FALSE if any (but not all) of the last four params are zero.
504 * NOTES
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)
514 DC * dc;
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)
525 return FALSE;
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 );
536 return TRUE;