VGA emulation now supports outw and outl.
[wine/multimedia.git] / graphics / mapping.c
blobe3d75f8609f36c08ce45172565ac535e180249a3
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "gdi.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
27 /***********************************************************************
28 * MAPPING_FixIsotropic
30 * Fix viewport extensions for isotropic mode.
32 void MAPPING_FixIsotropic( DC * dc )
34 double xdim = (double)dc->vportExtX * GetDeviceCaps( dc->hSelf, HORZSIZE ) /
35 (GetDeviceCaps( dc->hSelf, HORZRES ) * dc->wndExtX);
36 double ydim = (double)dc->vportExtY * GetDeviceCaps( dc->hSelf, VERTSIZE ) /
37 (GetDeviceCaps( dc->hSelf, VERTRES ) * dc->wndExtY);
38 if (xdim > ydim)
40 dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
41 if (!dc->vportExtX) dc->vportExtX = 1;
43 else
45 dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
46 if (!dc->vportExtY) dc->vportExtY = 1;
51 /***********************************************************************
52 * DPtoLP (GDI.67)
54 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
56 DC * dc = DC_GetDCPtr( hdc );
57 if (!dc) return FALSE;
59 while (count--)
61 points->x = MulDiv( points->x - dc->vportOrgX, dc->wndExtX, dc->vportExtX ) + dc->wndOrgX;
62 points->y = MulDiv( points->y - dc->vportOrgY, dc->wndExtY, dc->vportExtY ) + dc->wndOrgY;
63 points++;
65 GDI_ReleaseObj( hdc );
66 return TRUE;
70 /***********************************************************************
71 * DPtoLP (GDI32.@)
73 BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
75 DC * dc = DC_GetDCPtr( hdc );
76 if (!dc) return FALSE;
78 if (dc->vport2WorldValid)
80 while (count--)
82 FLOAT x = points->x;
83 FLOAT y = points->y;
84 points->x = floor( x * dc->xformVport2World.eM11 +
85 y * dc->xformVport2World.eM21 +
86 dc->xformVport2World.eDx + 0.5 );
87 points->y = floor( x * dc->xformVport2World.eM12 +
88 y * dc->xformVport2World.eM22 +
89 dc->xformVport2World.eDy + 0.5 );
90 points++;
93 GDI_ReleaseObj( hdc );
94 return (count < 0);
98 /***********************************************************************
99 * LPtoDP (GDI.99)
101 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
103 DC * dc = DC_GetDCPtr( hdc );
104 if (!dc) return FALSE;
106 while (count--)
108 points->x = MulDiv( points->x - dc->wndOrgX, dc->vportExtX, dc->wndExtX ) + dc->vportOrgX;
109 points->y = MulDiv( points->y - dc->wndOrgY, dc->vportExtY, dc->wndExtY ) + dc->vportOrgY;
110 points++;
112 GDI_ReleaseObj( hdc );
113 return TRUE;
117 /***********************************************************************
118 * LPtoDP (GDI32.@)
120 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
122 DC * dc = DC_GetDCPtr( hdc );
123 if (!dc) return FALSE;
125 while (count--)
127 FLOAT x = points->x;
128 FLOAT y = points->y;
129 points->x = floor( x * dc->xformWorld2Vport.eM11 +
130 y * dc->xformWorld2Vport.eM21 +
131 dc->xformWorld2Vport.eDx + 0.5 );
132 points->y = floor( x * dc->xformWorld2Vport.eM12 +
133 y * dc->xformWorld2Vport.eM22 +
134 dc->xformWorld2Vport.eDy + 0.5 );
135 points++;
137 GDI_ReleaseObj( hdc );
138 return TRUE;
142 /***********************************************************************
143 * SetMapMode (GDI.3)
145 INT16 WINAPI SetMapMode16( HDC16 hdc, INT16 mode )
147 return SetMapMode( hdc, mode );
151 /***********************************************************************
152 * SetMapMode (GDI32.@)
154 INT WINAPI SetMapMode( HDC hdc, INT mode )
156 INT prevMode;
157 INT horzSize, vertSize, horzRes, vertRes;
159 DC * dc = DC_GetDCPtr( hdc );
160 if (!dc) return 0;
161 if (dc->funcs->pSetMapMode)
163 prevMode = dc->funcs->pSetMapMode( dc->physDev, mode );
164 goto done;
167 TRACE("%04x %d\n", hdc, mode );
169 prevMode = dc->MapMode;
170 horzSize = GetDeviceCaps( hdc, HORZSIZE );
171 vertSize = GetDeviceCaps( hdc, VERTSIZE );
172 horzRes = GetDeviceCaps( hdc, HORZRES );
173 vertRes = GetDeviceCaps( hdc, VERTRES );
174 switch(mode)
176 case MM_TEXT:
177 dc->wndExtX = 1;
178 dc->wndExtY = 1;
179 dc->vportExtX = 1;
180 dc->vportExtY = 1;
181 break;
182 case MM_LOMETRIC:
183 case MM_ISOTROPIC:
184 dc->wndExtX = horzSize;
185 dc->wndExtY = vertSize;
186 dc->vportExtX = horzRes / 10;
187 dc->vportExtY = vertRes / -10;
188 break;
189 case MM_HIMETRIC:
190 dc->wndExtX = horzSize * 10;
191 dc->wndExtY = vertSize * 10;
192 dc->vportExtX = horzRes / 10;
193 dc->vportExtY = vertRes / -10;
194 break;
195 case MM_LOENGLISH:
196 dc->wndExtX = horzSize;
197 dc->wndExtY = vertSize;
198 dc->vportExtX = 254L * horzRes / 1000;
199 dc->vportExtY = -254L * vertRes / 1000;
200 break;
201 case MM_HIENGLISH:
202 dc->wndExtX = horzSize * 10;
203 dc->wndExtY = vertSize * 10;
204 dc->vportExtX = 254L * horzRes / 1000;
205 dc->vportExtY = -254L * vertRes / 1000;
206 break;
207 case MM_TWIPS:
208 dc->wndExtX = 144L * horzSize / 10;
209 dc->wndExtY = 144L * vertSize / 10;
210 dc->vportExtX = 254L * horzRes / 1000;
211 dc->vportExtY = -254L * vertRes / 1000;
212 break;
213 case MM_ANISOTROPIC:
214 break;
215 default:
216 goto done;
218 dc->MapMode = mode;
219 DC_UpdateXforms( dc );
220 done:
221 GDI_ReleaseObj( hdc );
222 return prevMode;
226 /***********************************************************************
227 * SetViewportExt (GDI.14)
229 DWORD WINAPI SetViewportExt16( HDC16 hdc, INT16 x, INT16 y )
231 SIZE size;
232 if (!SetViewportExtEx( hdc, x, y, &size )) return 0;
233 return MAKELONG( size.cx, size.cy );
237 /***********************************************************************
238 * SetViewportExtEx (GDI.479)
240 BOOL16 WINAPI SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
242 SIZE size32;
243 BOOL16 ret = SetViewportExtEx( hdc, x, y, &size32 );
244 if (size) { size->cx = size32.cx; size->cy = size32.cy; }
245 return ret;
249 /***********************************************************************
250 * SetViewportExtEx (GDI32.@)
252 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
254 BOOL ret = TRUE;
255 DC * dc = DC_GetDCPtr( hdc );
256 if (!dc) return FALSE;
257 if (dc->funcs->pSetViewportExt)
259 ret = dc->funcs->pSetViewportExt( dc->physDev, x, y );
260 goto done;
262 if (size)
264 size->cx = dc->vportExtX;
265 size->cy = dc->vportExtY;
267 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
268 goto done;
269 if (!x || !y)
271 ret = FALSE;
272 goto done;
274 dc->vportExtX = x;
275 dc->vportExtY = y;
276 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
277 DC_UpdateXforms( dc );
278 done:
279 GDI_ReleaseObj( hdc );
280 return ret;
284 /***********************************************************************
285 * SetViewportOrg (GDI.13)
287 DWORD WINAPI SetViewportOrg16( HDC16 hdc, INT16 x, INT16 y )
289 POINT pt;
290 if (!SetViewportOrgEx( hdc, x, y, &pt )) return 0;
291 return MAKELONG( pt.x, pt.y );
295 /***********************************************************************
296 * SetViewportOrgEx (GDI.480)
298 BOOL16 WINAPI SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
300 POINT pt32;
301 BOOL16 ret = SetViewportOrgEx( hdc, x, y, &pt32 );
302 if (pt) CONV_POINT32TO16( &pt32, pt );
303 return ret;
307 /***********************************************************************
308 * SetViewportOrgEx (GDI32.@)
310 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
312 BOOL ret = TRUE;
313 DC * dc = DC_GetDCPtr( hdc );
314 if (!dc) return FALSE;
315 if (dc->funcs->pSetViewportOrg)
316 ret = dc->funcs->pSetViewportOrg( dc->physDev, x, y );
317 else
319 if (pt)
321 pt->x = dc->vportOrgX;
322 pt->y = dc->vportOrgY;
324 dc->vportOrgX = x;
325 dc->vportOrgY = y;
326 DC_UpdateXforms( dc );
328 GDI_ReleaseObj( hdc );
329 return ret;
333 /***********************************************************************
334 * SetWindowExt (GDI.12)
336 DWORD WINAPI SetWindowExt16( HDC16 hdc, INT16 x, INT16 y )
338 SIZE size;
339 if (!SetWindowExtEx( hdc, x, y, &size )) return 0;
340 return MAKELONG( size.cx, size.cy );
344 /***********************************************************************
345 * SetWindowExtEx (GDI.481)
347 BOOL16 WINAPI SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
349 SIZE size32;
350 BOOL16 ret = SetWindowExtEx( hdc, x, y, &size32 );
351 if (size) { size->cx = size32.cx; size->cy = size32.cy; }
352 return ret;
356 /***********************************************************************
357 * SetWindowExtEx (GDI32.@)
359 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
361 BOOL ret = TRUE;
362 DC * dc = DC_GetDCPtr( hdc );
363 if (!dc) return FALSE;
364 if (dc->funcs->pSetWindowExt)
366 ret = dc->funcs->pSetWindowExt( dc->physDev, x, y );
367 goto done;
369 if (size)
371 size->cx = dc->wndExtX;
372 size->cy = dc->wndExtY;
374 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
375 goto done;
376 if (!x || !y)
378 ret = FALSE;
379 goto done;
381 dc->wndExtX = x;
382 dc->wndExtY = y;
383 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
384 DC_UpdateXforms( dc );
385 done:
386 GDI_ReleaseObj( hdc );
387 return ret;
391 /***********************************************************************
392 * SetWindowOrg (GDI.11)
394 DWORD WINAPI SetWindowOrg16( HDC16 hdc, INT16 x, INT16 y )
396 POINT pt;
397 if (!SetWindowOrgEx( hdc, x, y, &pt )) return 0;
398 return MAKELONG( pt.x, pt.y );
402 /***********************************************************************
403 * SetWindowOrgEx (GDI.482)
405 BOOL16 WINAPI SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
407 POINT pt32;
408 BOOL16 ret = SetWindowOrgEx( hdc, x, y, &pt32 );
409 if (pt) CONV_POINT32TO16( &pt32, pt );
410 return ret;
414 /***********************************************************************
415 * SetWindowOrgEx (GDI32.@)
417 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
419 BOOL ret = TRUE;
420 DC * dc = DC_GetDCPtr( hdc );
421 if (!dc) return FALSE;
422 if (dc->funcs->pSetWindowOrg) ret = dc->funcs->pSetWindowOrg( dc->physDev, x, y );
423 else
425 if (pt)
427 pt->x = dc->wndOrgX;
428 pt->y = dc->wndOrgY;
430 dc->wndOrgX = x;
431 dc->wndOrgY = y;
432 DC_UpdateXforms( dc );
434 GDI_ReleaseObj( hdc );
435 return ret;
439 /***********************************************************************
440 * OffsetViewportOrg (GDI.17)
442 DWORD WINAPI OffsetViewportOrg16( HDC16 hdc, INT16 x, INT16 y )
444 POINT pt;
445 if (!OffsetViewportOrgEx( hdc, x, y, &pt )) return 0;
446 return MAKELONG( pt.x, pt.y );
450 /***********************************************************************
451 * OffsetViewportOrgEx (GDI.476)
453 BOOL16 WINAPI OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt)
455 POINT pt32;
456 BOOL16 ret = OffsetViewportOrgEx( hdc, x, y, &pt32 );
457 if (pt) CONV_POINT32TO16( &pt32, pt );
458 return ret;
462 /***********************************************************************
463 * OffsetViewportOrgEx (GDI32.@)
465 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
467 BOOL ret = TRUE;
468 DC * dc = DC_GetDCPtr( hdc );
469 if (!dc) return FALSE;
470 if (dc->funcs->pOffsetViewportOrg)
471 ret = dc->funcs->pOffsetViewportOrg( dc->physDev, x, y );
472 else
474 if (pt)
476 pt->x = dc->vportOrgX;
477 pt->y = dc->vportOrgY;
479 dc->vportOrgX += x;
480 dc->vportOrgY += y;
481 DC_UpdateXforms( dc );
483 GDI_ReleaseObj( hdc );
484 return ret;
488 /***********************************************************************
489 * OffsetWindowOrg (GDI.15)
491 DWORD WINAPI OffsetWindowOrg16( HDC16 hdc, INT16 x, INT16 y )
493 POINT pt;
494 if (!OffsetWindowOrgEx( hdc, x, y, &pt )) return 0;
495 return MAKELONG( pt.x, pt.y );
499 /***********************************************************************
500 * OffsetWindowOrgEx (GDI.477)
502 BOOL16 WINAPI OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
504 POINT pt32;
505 BOOL16 ret = OffsetWindowOrgEx( hdc, x, y, &pt32 );
506 if (pt) CONV_POINT32TO16( &pt32, pt );
507 return ret;
511 /***********************************************************************
512 * OffsetWindowOrgEx (GDI32.@)
514 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
516 BOOL ret = TRUE;
517 DC * dc = DC_GetDCPtr( hdc );
518 if (!dc) return FALSE;
519 if (dc->funcs->pOffsetWindowOrg)
520 ret = dc->funcs->pOffsetWindowOrg( dc->physDev, x, y );
521 else
523 if (pt)
525 pt->x = dc->wndOrgX;
526 pt->y = dc->wndOrgY;
528 dc->wndOrgX += x;
529 dc->wndOrgY += y;
530 DC_UpdateXforms( dc );
532 GDI_ReleaseObj( hdc );
533 return ret;
537 /***********************************************************************
538 * ScaleViewportExt (GDI.18)
540 DWORD WINAPI ScaleViewportExt16( HDC16 hdc, INT16 xNum, INT16 xDenom,
541 INT16 yNum, INT16 yDenom )
543 SIZE size;
544 if (!ScaleViewportExtEx( hdc, xNum, xDenom, yNum, yDenom, &size ))
545 return FALSE;
546 return MAKELONG( size.cx, size.cy );
550 /***********************************************************************
551 * ScaleViewportExtEx (GDI.484)
553 BOOL16 WINAPI ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
554 INT16 yNum, INT16 yDenom, LPSIZE16 size )
556 SIZE size32;
557 BOOL16 ret = ScaleViewportExtEx( hdc, xNum, xDenom, yNum, yDenom,
558 &size32 );
559 if (size) { size->cx = size32.cx; size->cy = size32.cy; }
560 return ret;
564 /***********************************************************************
565 * ScaleViewportExtEx (GDI32.@)
567 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
568 INT yNum, INT yDenom, LPSIZE size )
570 BOOL ret = TRUE;
571 DC * dc = DC_GetDCPtr( hdc );
572 if (!dc) return FALSE;
573 if (dc->funcs->pScaleViewportExt)
575 ret = dc->funcs->pScaleViewportExt( dc->physDev, xNum, xDenom, yNum, yDenom );
576 goto done;
578 if (size)
580 size->cx = dc->vportExtX;
581 size->cy = dc->vportExtY;
583 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
584 goto done;
585 if (!xNum || !xDenom || !xNum || !yDenom)
587 ret = FALSE;
588 goto done;
590 dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
591 dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
592 if (dc->vportExtX == 0) dc->vportExtX = 1;
593 if (dc->vportExtY == 0) dc->vportExtY = 1;
594 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
595 DC_UpdateXforms( dc );
596 done:
597 GDI_ReleaseObj( hdc );
598 return ret;
602 /***********************************************************************
603 * ScaleWindowExt (GDI.16)
605 DWORD WINAPI ScaleWindowExt16( HDC16 hdc, INT16 xNum, INT16 xDenom,
606 INT16 yNum, INT16 yDenom )
608 SIZE size;
609 if (!ScaleWindowExtEx( hdc, xNum, xDenom, yNum, yDenom, &size ))
610 return FALSE;
611 return MAKELONG( size.cx, size.cy );
615 /***********************************************************************
616 * ScaleWindowExtEx (GDI.485)
618 BOOL16 WINAPI ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
619 INT16 yNum, INT16 yDenom, LPSIZE16 size )
621 SIZE size32;
622 BOOL16 ret = ScaleWindowExtEx( hdc, xNum, xDenom, yNum, yDenom,
623 &size32 );
624 if (size) { size->cx = size32.cx; size->cy = size32.cy; }
625 return ret;
629 /***********************************************************************
630 * ScaleWindowExtEx (GDI32.@)
632 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
633 INT yNum, INT yDenom, LPSIZE size )
635 BOOL ret = TRUE;
636 DC * dc = DC_GetDCPtr( hdc );
637 if (!dc) return FALSE;
638 if (dc->funcs->pScaleWindowExt)
640 ret = dc->funcs->pScaleWindowExt( dc->physDev, xNum, xDenom, yNum, yDenom );
641 goto done;
643 if (size)
645 size->cx = dc->wndExtX;
646 size->cy = dc->wndExtY;
648 if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
649 goto done;
650 if (!xNum || !xDenom || !xNum || !yDenom)
652 ret = FALSE;
653 goto done;
655 dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
656 dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
657 if (dc->wndExtX == 0) dc->wndExtX = 1;
658 if (dc->wndExtY == 0) dc->wndExtY = 1;
659 if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
660 DC_UpdateXforms( dc );
661 done:
662 GDI_ReleaseObj( hdc );
663 return ret;