wer: Add new stubbed wer.dll.
[wine/hramrach.git] / dlls / gdi32 / mapping.c
blob8010b3d2c1202ca5051be925526442d67623d0fe
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 "wownt32.h"
27 #include "gdi_private.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dc);
33 /***********************************************************************
34 * MAPPING_FixIsotropic
36 * Fix viewport extensions for isotropic mode.
38 static void MAPPING_FixIsotropic( DC * dc )
40 double xdim = fabs((double)dc->vportExtX * dc->virtual_size.cx /
41 (dc->virtual_res.cx * dc->wndExtX));
42 double ydim = fabs((double)dc->vportExtY * dc->virtual_size.cy /
43 (dc->virtual_res.cy * dc->wndExtY));
45 if (xdim > ydim)
47 INT mincx = (dc->vportExtX >= 0) ? 1 : -1;
48 dc->vportExtX = floor(dc->vportExtX * ydim / xdim + 0.5);
49 if (!dc->vportExtX) dc->vportExtX = mincx;
51 else
53 INT mincy = (dc->vportExtY >= 0) ? 1 : -1;
54 dc->vportExtY = floor(dc->vportExtY * xdim / ydim + 0.5);
55 if (!dc->vportExtY) dc->vportExtY = mincy;
60 /***********************************************************************
61 * DPtoLP (GDI32.@)
63 BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
65 DC * dc = get_dc_ptr( hdc );
66 if (!dc) return FALSE;
68 if (dc->vport2WorldValid)
70 while (count--)
72 double x = points->x;
73 double y = points->y;
74 points->x = floor( x * dc->xformVport2World.eM11 +
75 y * dc->xformVport2World.eM21 +
76 dc->xformVport2World.eDx + 0.5 );
77 points->y = floor( x * dc->xformVport2World.eM12 +
78 y * dc->xformVport2World.eM22 +
79 dc->xformVport2World.eDy + 0.5 );
80 points++;
83 release_dc_ptr( dc );
84 return (count < 0);
88 /***********************************************************************
89 * LPtoDP (GDI32.@)
91 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
93 DC * dc = get_dc_ptr( hdc );
94 if (!dc) return FALSE;
96 while (count--)
98 double x = points->x;
99 double y = points->y;
100 points->x = floor( x * dc->xformWorld2Vport.eM11 +
101 y * dc->xformWorld2Vport.eM21 +
102 dc->xformWorld2Vport.eDx + 0.5 );
103 points->y = floor( x * dc->xformWorld2Vport.eM12 +
104 y * dc->xformWorld2Vport.eM22 +
105 dc->xformWorld2Vport.eDy + 0.5 );
106 points++;
108 release_dc_ptr( dc );
109 return TRUE;
113 /***********************************************************************
114 * SetMapMode (GDI32.@)
116 INT WINAPI SetMapMode( HDC hdc, INT mode )
118 INT ret;
119 INT horzSize, vertSize, horzRes, vertRes;
121 DC * dc = get_dc_ptr( hdc );
122 if (!dc) return 0;
123 if (dc->funcs->pSetMapMode)
125 if((ret = dc->funcs->pSetMapMode( dc->physDev, mode )) != TRUE)
127 if(ret == GDI_NO_MORE_WORK)
128 ret = TRUE;
129 goto done;
133 TRACE("%p %d\n", hdc, mode );
135 ret = dc->MapMode;
137 if (mode == dc->MapMode && (mode == MM_ISOTROPIC || mode == MM_ANISOTROPIC))
138 goto done;
140 horzSize = dc->virtual_size.cx;
141 vertSize = dc->virtual_size.cy;
142 horzRes = dc->virtual_res.cx;
143 vertRes = dc->virtual_res.cy;
144 switch(mode)
146 case MM_TEXT:
147 dc->wndExtX = 1;
148 dc->wndExtY = 1;
149 dc->vportExtX = 1;
150 dc->vportExtY = 1;
151 break;
152 case MM_LOMETRIC:
153 case MM_ISOTROPIC:
154 dc->wndExtX = horzSize * 10;
155 dc->wndExtY = vertSize * 10;
156 dc->vportExtX = horzRes;
157 dc->vportExtY = -vertRes;
158 break;
159 case MM_HIMETRIC:
160 dc->wndExtX = horzSize * 100;
161 dc->wndExtY = vertSize * 100;
162 dc->vportExtX = horzRes;
163 dc->vportExtY = -vertRes;
164 break;
165 case MM_LOENGLISH:
166 dc->wndExtX = MulDiv(1000, horzSize, 254);
167 dc->wndExtY = MulDiv(1000, vertSize, 254);
168 dc->vportExtX = horzRes;
169 dc->vportExtY = -vertRes;
170 break;
171 case MM_HIENGLISH:
172 dc->wndExtX = MulDiv(10000, horzSize, 254);
173 dc->wndExtY = MulDiv(10000, vertSize, 254);
174 dc->vportExtX = horzRes;
175 dc->vportExtY = -vertRes;
176 break;
177 case MM_TWIPS:
178 dc->wndExtX = MulDiv(14400, horzSize, 254);
179 dc->wndExtY = MulDiv(14400, vertSize, 254);
180 dc->vportExtX = horzRes;
181 dc->vportExtY = -vertRes;
182 break;
183 case MM_ANISOTROPIC:
184 break;
185 default:
186 goto done;
188 /* RTL layout is always MM_ANISOTROPIC */
189 if (!(dc->layout & LAYOUT_RTL)) dc->MapMode = mode;
190 DC_UpdateXforms( dc );
191 done:
192 release_dc_ptr( dc );
193 return ret;
197 /***********************************************************************
198 * SetViewportExtEx (GDI32.@)
200 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
202 INT ret = TRUE;
203 DC * dc = get_dc_ptr( hdc );
204 if (!dc) return FALSE;
205 if (dc->funcs->pSetViewportExt)
207 if((ret = dc->funcs->pSetViewportExt( dc->physDev, x, y )) != TRUE)
209 if(ret == GDI_NO_MORE_WORK)
210 ret = TRUE;
211 goto done;
214 if (size)
216 size->cx = dc->vportExtX;
217 size->cy = dc->vportExtY;
219 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
220 goto done;
221 if (!x || !y)
223 ret = FALSE;
224 goto done;
226 dc->vportExtX = x;
227 dc->vportExtY = y;
228 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
229 DC_UpdateXforms( dc );
230 done:
231 release_dc_ptr( dc );
232 return ret;
236 /***********************************************************************
237 * SetViewportOrgEx (GDI32.@)
239 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
241 INT ret = TRUE;
242 DC * dc = get_dc_ptr( hdc );
243 if (!dc) return FALSE;
244 if (dc->funcs->pSetViewportOrg)
246 if((ret = dc->funcs->pSetViewportOrg( dc->physDev, x, y )) != TRUE)
248 if(ret == GDI_NO_MORE_WORK)
249 ret = TRUE;
250 goto done;
253 if (pt)
255 pt->x = dc->vportOrgX;
256 pt->y = dc->vportOrgY;
258 dc->vportOrgX = x;
259 dc->vportOrgY = y;
260 DC_UpdateXforms( dc );
262 done:
263 release_dc_ptr( dc );
264 return ret;
268 /***********************************************************************
269 * SetWindowExtEx (GDI32.@)
271 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
273 INT ret = TRUE;
274 DC * dc = get_dc_ptr( hdc );
275 if (!dc) return FALSE;
276 if (dc->funcs->pSetWindowExt)
278 if((ret = dc->funcs->pSetWindowExt( dc->physDev, x, y )) != TRUE)
280 if(ret == GDI_NO_MORE_WORK)
281 ret = TRUE;
282 goto done;
285 if (size)
287 size->cx = dc->wndExtX;
288 size->cy = dc->wndExtY;
290 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
291 goto done;
292 if (!x || !y)
294 ret = FALSE;
295 goto done;
297 dc->wndExtX = x;
298 dc->wndExtY = y;
299 /* The API docs say that you should call SetWindowExtEx before
300 SetViewportExtEx. This advice does not imply that Windows
301 doesn't ensure the isotropic mapping after SetWindowExtEx! */
302 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
303 DC_UpdateXforms( dc );
304 done:
305 release_dc_ptr( dc );
306 return ret;
310 /***********************************************************************
311 * SetWindowOrgEx (GDI32.@)
313 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
315 INT ret = TRUE;
316 DC * dc = get_dc_ptr( hdc );
317 if (!dc) return FALSE;
318 if (dc->funcs->pSetWindowOrg)
320 if((ret = dc->funcs->pSetWindowOrg( dc->physDev, x, y )) != TRUE)
322 if(ret == GDI_NO_MORE_WORK)
323 ret = TRUE;
324 goto done;
327 if (pt)
329 pt->x = dc->wndOrgX;
330 pt->y = dc->wndOrgY;
332 dc->wndOrgX = x;
333 dc->wndOrgY = y;
334 DC_UpdateXforms( dc );
335 done:
336 release_dc_ptr( dc );
337 return ret;
341 /***********************************************************************
342 * OffsetViewportOrgEx (GDI32.@)
344 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
346 INT ret = TRUE;
347 DC * dc = get_dc_ptr( hdc );
348 if (!dc) return FALSE;
349 if (dc->funcs->pOffsetViewportOrg)
351 if((ret = dc->funcs->pOffsetViewportOrg( dc->physDev, x, y )) != TRUE)
353 if(ret == GDI_NO_MORE_WORK)
354 ret = TRUE;
355 goto done;
358 if (pt)
360 pt->x = dc->vportOrgX;
361 pt->y = dc->vportOrgY;
363 dc->vportOrgX += x;
364 dc->vportOrgY += y;
365 DC_UpdateXforms( dc );
366 done:
367 release_dc_ptr( dc );
368 return ret;
372 /***********************************************************************
373 * OffsetWindowOrgEx (GDI32.@)
375 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
377 INT ret = TRUE;
378 DC * dc = get_dc_ptr( hdc );
379 if (!dc) return FALSE;
380 if (dc->funcs->pOffsetWindowOrg)
382 if((ret = dc->funcs->pOffsetWindowOrg( dc->physDev, x, y )) != TRUE)
384 if(ret == GDI_NO_MORE_WORK)
385 ret = TRUE;
386 goto done;
389 if (pt)
391 pt->x = dc->wndOrgX;
392 pt->y = dc->wndOrgY;
394 dc->wndOrgX += x;
395 dc->wndOrgY += y;
396 DC_UpdateXforms( dc );
397 done:
398 release_dc_ptr( dc );
399 return ret;
403 /***********************************************************************
404 * ScaleViewportExtEx (GDI32.@)
406 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
407 INT yNum, INT yDenom, LPSIZE size )
409 INT ret = TRUE;
410 DC * dc = get_dc_ptr( hdc );
411 if (!dc) return FALSE;
412 if (dc->funcs->pScaleViewportExt)
414 if((ret = dc->funcs->pScaleViewportExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
416 if(ret == GDI_NO_MORE_WORK)
417 ret = TRUE;
418 goto done;
421 if (size)
423 size->cx = dc->vportExtX;
424 size->cy = dc->vportExtY;
426 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
427 goto done;
428 if (!xNum || !xDenom || !yNum || !yDenom)
430 ret = FALSE;
431 goto done;
433 dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
434 dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
435 if (dc->vportExtX == 0) dc->vportExtX = 1;
436 if (dc->vportExtY == 0) dc->vportExtY = 1;
437 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
438 DC_UpdateXforms( dc );
439 done:
440 release_dc_ptr( dc );
441 return ret;
445 /***********************************************************************
446 * ScaleWindowExtEx (GDI32.@)
448 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
449 INT yNum, INT yDenom, LPSIZE size )
451 INT ret = TRUE;
452 DC * dc = get_dc_ptr( hdc );
453 if (!dc) return FALSE;
454 if (dc->funcs->pScaleWindowExt)
456 if((ret = dc->funcs->pScaleWindowExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
458 if(ret == GDI_NO_MORE_WORK)
459 ret = TRUE;
460 goto done;
463 if (size)
465 size->cx = dc->wndExtX;
466 size->cy = dc->wndExtY;
468 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
469 goto done;
470 if (!xNum || !xDenom || !xNum || !yDenom)
472 ret = FALSE;
473 goto done;
475 dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
476 dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
477 if (dc->wndExtX == 0) dc->wndExtX = 1;
478 if (dc->wndExtY == 0) dc->wndExtY = 1;
479 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
480 DC_UpdateXforms( dc );
481 done:
482 release_dc_ptr( dc );
483 return ret;
486 /***********************************************************************
487 * SetVirtualResolution (GDI32.@)
489 * Undocumented on msdn.
491 * Changes the values of screen size in pixels and millimeters used by
492 * the mapping mode functions.
494 * PARAMS
495 * hdc [I] Device context
496 * horz_res [I] Width in pixels (equivalent to HORZRES device cap).
497 * vert_res [I] Height in pixels (equivalent to VERTRES device cap).
498 * horz_size [I] Width in mm (equivalent to HORZSIZE device cap).
499 * vert_size [I] Height in mm (equivalent to VERTSIZE device cap).
501 * RETURNS
502 * TRUE if successful.
503 * FALSE if any (but not all) of the last four params are zero.
505 * NOTES
506 * This doesn't change the values returned by GetDeviceCaps, just the
507 * scaling of the mapping modes.
509 * Calling with the last four params equal to zero sets the values
510 * back to their defaults obtained by calls to GetDeviceCaps.
512 BOOL WINAPI SetVirtualResolution(HDC hdc, DWORD horz_res, DWORD vert_res,
513 DWORD horz_size, DWORD vert_size)
515 DC * dc;
516 TRACE("(%p %d %d %d %d)\n", hdc, horz_res, vert_res, horz_size, vert_size);
518 if(horz_res == 0 && vert_res == 0 && horz_size == 0 && vert_size == 0)
520 horz_res = GetDeviceCaps(hdc, HORZRES);
521 vert_res = GetDeviceCaps(hdc, VERTRES);
522 horz_size = GetDeviceCaps(hdc, HORZSIZE);
523 vert_size = GetDeviceCaps(hdc, VERTSIZE);
525 else if(horz_res == 0 || vert_res == 0 || horz_size == 0 || vert_size == 0)
526 return FALSE;
528 dc = get_dc_ptr( hdc );
529 if (!dc) return FALSE;
531 dc->virtual_res.cx = horz_res;
532 dc->virtual_res.cy = vert_res;
533 dc->virtual_size.cx = horz_size;
534 dc->virtual_size.cy = vert_size;
536 release_dc_ptr( dc );
537 return TRUE;