Release 980215
[wine/multimedia.git] / graphics / mapping.c
blobb810a23c296053c043400c5018d0f822c9835ec5
1 /*
2 * GDI mapping mode functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <math.h>
8 #include "dc.h"
9 #include "stddebug.h"
10 #include "debug.h"
13 /***********************************************************************
14 * MAPPING_FixIsotropic
16 * Fix viewport extensions for isotropic mode.
18 void MAPPING_FixIsotropic( DC * dc )
20 double xdim = (double)dc->vportExtX * dc->w.devCaps->horzSize /
21 (dc->w.devCaps->horzRes * dc->wndExtX);
22 double ydim = (double)dc->vportExtY * dc->w.devCaps->vertSize /
23 (dc->w.devCaps->vertRes * dc->wndExtY);
24 if (xdim > ydim)
26 dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
27 if (!dc->vportExtX) dc->vportExtX = 1;
29 else
31 dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
32 if (!dc->vportExtY) dc->vportExtY = 1;
37 /***********************************************************************
38 * DPtoLP16 (GDI.67)
40 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
42 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
43 if (!dc) return FALSE;
45 while (count--)
47 points->x = XDPTOLP( dc, points->x );
48 points->y = YDPTOLP( dc, points->y );
49 points++;
51 return TRUE;
55 /***********************************************************************
56 * DPtoLP32 (GDI32.65)
58 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
60 FLOAT determinant=1.0, x, y;
62 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
63 if (!dc) return FALSE;
65 if (dc->w.UseWorldXform)
67 determinant = dc->w.WorldXform.eM11*dc->w.WorldXform.eM22 -
68 dc->w.WorldXform.eM12*dc->w.WorldXform.eM21;
69 if (determinant > -1e-12 && determinant < 1e-12)
70 return FALSE;
73 while (count--)
75 if (dc->w.UseWorldXform)
77 x = (FLOAT)XDPTOLP( dc, points->x ) - dc->w.WorldXform.eDx;
78 y = (FLOAT)YDPTOLP( dc, points->y ) - dc->w.WorldXform.eDy;
79 points->x = (INT32)( (x*dc->w.WorldXform.eM22 -
80 y*dc->w.WorldXform.eM21) / determinant );
81 points->y = (INT32)( (-x*dc->w.WorldXform.eM12 +
82 y*dc->w.WorldXform.eM11) / determinant );
84 else
86 points->x = XDPTOLP( dc, points->x );
87 points->y = YDPTOLP( dc, points->y );
89 points++;
91 return TRUE;
95 /***********************************************************************
96 * LPtoDP16 (GDI.99)
98 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
100 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
101 if (!dc) return FALSE;
103 while (count--)
105 points->x = XLPTODP( dc, points->x );
106 points->y = YLPTODP( dc, points->y );
107 points++;
109 return TRUE;
113 /***********************************************************************
114 * LPtoDP32 (GDI32.247)
116 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
118 FLOAT x, y;
120 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
121 if (!dc) return FALSE;
123 while (count--)
125 if (dc->w.UseWorldXform)
127 x = (FLOAT)points->x * dc->w.WorldXform.eM11 +
128 (FLOAT)points->y * dc->w.WorldXform.eM21 +
129 dc->w.WorldXform.eDx;
130 y = (FLOAT)points->x * dc->w.WorldXform.eM12 +
131 (FLOAT)points->y * dc->w.WorldXform.eM22 +
132 dc->w.WorldXform.eDy;
133 points->x = XLPTODP( dc, (INT32)x );
134 points->y = YLPTODP( dc, (INT32)y );
137 else
139 points->x = XLPTODP( dc, points->x );
140 points->y = YLPTODP( dc, points->y );
142 points++;
144 return TRUE;
148 /***********************************************************************
149 * SetMapMode16 (GDI.3)
151 INT16 WINAPI SetMapMode16( HDC16 hdc, INT16 mode )
153 return SetMapMode32( hdc, mode );
157 /***********************************************************************
158 * SetMapMode32 (GDI32.321)
160 INT32 WINAPI SetMapMode32( HDC32 hdc, INT32 mode )
162 INT32 prevMode;
163 DC * dc = DC_GetDCPtr( hdc );
164 if (!dc) return 0;
165 if (dc->funcs->pSetMapMode) return dc->funcs->pSetMapMode( dc, mode );
167 dprintf_gdi(stddeb, "SetMapMode: %04x %d\n", hdc, mode );
169 prevMode = dc->w.MapMode;
170 switch(mode)
172 case MM_TEXT:
173 dc->wndOrgX = dc->wndOrgY = 0;
174 dc->vportOrgX = dc->vportOrgY = 0;
175 dc->wndExtX = 1;
176 dc->wndExtY = 1;
177 dc->vportExtX = 1;
178 dc->vportExtY = 1;
179 break;
181 case MM_LOMETRIC:
182 case MM_ISOTROPIC:
183 dc->wndOrgX = dc->wndOrgY = 0;
184 dc->vportOrgX = dc->vportOrgY = 0;
185 dc->wndExtX = dc->w.devCaps->horzSize;
186 dc->wndExtY = dc->w.devCaps->vertSize;
187 dc->vportExtX = dc->w.devCaps->horzRes / 10;
188 dc->vportExtY = dc->w.devCaps->vertRes / -10;
189 break;
191 case MM_HIMETRIC:
192 dc->wndOrgX = dc->wndOrgY = 0;
193 dc->vportOrgX = dc->vportOrgY = 0;
194 dc->wndExtX = dc->w.devCaps->horzSize * 10;
195 dc->wndExtY = dc->w.devCaps->vertSize * 10;
196 dc->vportExtX = dc->w.devCaps->horzRes / 10;
197 dc->vportExtY = dc->w.devCaps->vertRes / -10;
198 break;
200 case MM_LOENGLISH:
201 dc->wndOrgX = dc->wndOrgY = 0;
202 dc->vportOrgX = dc->vportOrgY = 0;
203 dc->wndExtX = dc->w.devCaps->horzSize;
204 dc->wndExtY = dc->w.devCaps->vertSize;
205 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
206 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
207 break;
209 case MM_HIENGLISH:
210 dc->wndOrgX = dc->wndOrgY = 0;
211 dc->vportOrgX = dc->vportOrgY = 0;
212 dc->wndExtX = dc->w.devCaps->horzSize * 10;
213 dc->wndExtY = dc->w.devCaps->vertSize * 10;
214 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
215 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
216 break;
218 case MM_TWIPS:
219 dc->wndOrgX = dc->wndOrgY = 0;
220 dc->vportOrgX = dc->vportOrgY = 0;
221 dc->wndExtX = 144L * dc->w.devCaps->horzSize / 10;
222 dc->wndExtY = 144L * dc->w.devCaps->vertSize / 10;
223 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
224 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
225 break;
227 case MM_ANISOTROPIC:
228 break;
230 default:
231 return prevMode;
233 dc->w.MapMode = mode;
234 return prevMode;
238 /***********************************************************************
239 * SetViewportExt (GDI.14)
241 DWORD WINAPI SetViewportExt( HDC16 hdc, INT16 x, INT16 y )
243 SIZE32 size;
244 if (!SetViewportExtEx32( hdc, x, y, &size )) return 0;
245 return MAKELONG( size.cx, size.cy );
249 /***********************************************************************
250 * SetViewportExtEx16 (GDI.479)
252 BOOL16 WINAPI SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
254 SIZE32 size32;
255 BOOL16 ret = SetViewportExtEx32( hdc, x, y, &size32 );
256 if (size) CONV_SIZE32TO16( &size32, size );
257 return ret;
261 /***********************************************************************
262 * SetViewportExtEx32 (GDI32.340)
264 BOOL32 WINAPI SetViewportExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
266 DC * dc = DC_GetDCPtr( hdc );
267 if (!dc) return FALSE;
268 if (dc->funcs->pSetViewportExt)
269 return dc->funcs->pSetViewportExt( dc, x, y );
270 if (size)
272 size->cx = dc->vportExtX;
273 size->cy = dc->vportExtY;
275 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
276 return TRUE;
277 if (!x || !y) return FALSE;
278 dc->vportExtX = x;
279 dc->vportExtY = y;
280 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
281 return TRUE;
285 /***********************************************************************
286 * SetViewportOrg (GDI.13)
288 DWORD WINAPI SetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
290 POINT32 pt;
291 if (!SetViewportOrgEx32( hdc, x, y, &pt )) return 0;
292 return MAKELONG( pt.x, pt.y );
296 /***********************************************************************
297 * SetViewportOrgEx16 (GDI.480)
299 BOOL16 WINAPI SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
301 POINT32 pt32;
302 BOOL16 ret = SetViewportOrgEx32( hdc, x, y, &pt32 );
303 if (pt) CONV_POINT32TO16( &pt32, pt );
304 return ret;
308 /***********************************************************************
309 * SetViewportOrgEx32 (GDI32.341)
311 BOOL32 WINAPI SetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
313 DC * dc = DC_GetDCPtr( hdc );
314 if (!dc) return FALSE;
315 if (dc->funcs->pSetViewportOrg)
316 return dc->funcs->pSetViewportOrg( dc, x, y );
317 if (pt)
319 pt->x = dc->vportOrgX;
320 pt->y = dc->vportOrgY;
322 dc->vportOrgX = x;
323 dc->vportOrgY = y;
324 return TRUE;
328 /***********************************************************************
329 * SetWindowExt (GDI.12)
331 DWORD WINAPI SetWindowExt( HDC16 hdc, INT16 x, INT16 y )
333 SIZE32 size;
334 if (!SetWindowExtEx32( hdc, x, y, &size )) return 0;
335 return MAKELONG( size.cx, size.cy );
339 /***********************************************************************
340 * SetWindowExtEx16 (GDI.481)
342 BOOL16 WINAPI SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
344 SIZE32 size32;
345 BOOL16 ret = SetWindowExtEx32( hdc, x, y, &size32 );
346 if (size) CONV_SIZE32TO16( &size32, size );
347 return ret;
351 /***********************************************************************
352 * SetWindowExtEx32 (GDI32.344)
354 BOOL32 WINAPI SetWindowExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
356 DC * dc = DC_GetDCPtr( hdc );
357 if (!dc) return FALSE;
358 if (dc->funcs->pSetWindowExt) return dc->funcs->pSetWindowExt( dc, x, y );
359 if (size)
361 size->cx = dc->wndExtX;
362 size->cy = dc->wndExtY;
364 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
365 return TRUE;
366 if (!x || !y) return FALSE;
367 dc->wndExtX = x;
368 dc->wndExtY = y;
369 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
370 return TRUE;
374 /***********************************************************************
375 * SetWindowOrg (GDI.11)
377 DWORD WINAPI SetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
379 POINT32 pt;
380 if (!SetWindowOrgEx32( hdc, x, y, &pt )) return 0;
381 return MAKELONG( pt.x, pt.y );
385 /***********************************************************************
386 * SetWindowOrgEx16 (GDI.482)
388 BOOL16 WINAPI SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
390 POINT32 pt32;
391 BOOL16 ret = SetWindowOrgEx32( hdc, x, y, &pt32 );
392 if (pt) CONV_POINT32TO16( &pt32, pt );
393 return ret;
397 /***********************************************************************
398 * SetWindowOrgEx32 (GDI32.345)
400 BOOL32 WINAPI SetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
402 DC * dc = DC_GetDCPtr( hdc );
403 if (!dc) return FALSE;
404 if (dc->funcs->pSetWindowOrg) return dc->funcs->pSetWindowOrg( dc, x, y );
405 if (pt)
407 pt->x = dc->wndOrgX;
408 pt->y = dc->wndOrgY;
410 dc->wndOrgX = x;
411 dc->wndOrgY = y;
412 return TRUE;
416 /***********************************************************************
417 * OffsetViewportOrg (GDI.17)
419 DWORD WINAPI OffsetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
421 POINT32 pt;
422 if (!OffsetViewportOrgEx32( hdc, x, y, &pt )) return 0;
423 return MAKELONG( pt.x, pt.y );
427 /***********************************************************************
428 * OffsetViewportOrgEx16 (GDI.476)
430 BOOL16 WINAPI OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt)
432 POINT32 pt32;
433 BOOL16 ret = OffsetViewportOrgEx32( hdc, x, y, &pt32 );
434 if (pt) CONV_POINT32TO16( &pt32, pt );
435 return ret;
439 /***********************************************************************
440 * OffsetViewportOrgEx32 (GDI32.257)
442 BOOL32 WINAPI OffsetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt)
444 DC * dc = DC_GetDCPtr( hdc );
445 if (!dc) return FALSE;
446 if (dc->funcs->pOffsetViewportOrg)
447 return dc->funcs->pOffsetViewportOrg( dc, x, y );
448 if (pt)
450 pt->x = dc->vportOrgX;
451 pt->y = dc->vportOrgY;
453 dc->vportOrgX += x;
454 dc->vportOrgY += y;
455 return TRUE;
459 /***********************************************************************
460 * OffsetWindowOrg (GDI.15)
462 DWORD WINAPI OffsetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
464 POINT32 pt;
465 if (!OffsetWindowOrgEx32( hdc, x, y, &pt )) return 0;
466 return MAKELONG( pt.x, pt.y );
470 /***********************************************************************
471 * OffsetWindowOrgEx16 (GDI.477)
473 BOOL16 WINAPI OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
475 POINT32 pt32;
476 BOOL16 ret = OffsetWindowOrgEx32( hdc, x, y, &pt32 );
477 if (pt) CONV_POINT32TO16( &pt32, pt );
478 return ret;
482 /***********************************************************************
483 * OffsetWindowOrgEx32 (GDI32.258)
485 BOOL32 WINAPI OffsetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
487 DC * dc = DC_GetDCPtr( hdc );
488 if (!dc) return FALSE;
489 if (dc->funcs->pOffsetWindowOrg)
490 return dc->funcs->pOffsetWindowOrg( dc, x, y );
491 if (pt)
493 pt->x = dc->wndOrgX;
494 pt->y = dc->wndOrgY;
496 dc->wndOrgX += x;
497 dc->wndOrgY += y;
498 return TRUE;
502 /***********************************************************************
503 * ScaleViewportExt (GDI.18)
505 DWORD WINAPI ScaleViewportExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
506 INT16 yNum, INT16 yDenom )
508 SIZE32 size;
509 if (!ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
510 return FALSE;
511 return MAKELONG( size.cx, size.cy );
515 /***********************************************************************
516 * ScaleViewportExtEx16 (GDI.484)
518 BOOL16 WINAPI ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
519 INT16 yNum, INT16 yDenom, LPSIZE16 size )
521 SIZE32 size32;
522 BOOL16 ret = ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom,
523 &size32 );
524 if (size) CONV_SIZE32TO16( &size32, size );
525 return ret;
529 /***********************************************************************
530 * ScaleViewportExtEx32 (GDI32.293)
532 BOOL32 WINAPI ScaleViewportExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
533 INT32 yNum, INT32 yDenom, LPSIZE32 size )
535 DC * dc = DC_GetDCPtr( hdc );
536 if (!dc) return FALSE;
537 if (dc->funcs->pScaleViewportExt)
538 return dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
539 if (size)
541 size->cx = dc->vportExtX;
542 size->cy = dc->vportExtY;
544 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
545 return TRUE;
546 if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
547 dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
548 dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
549 if (dc->vportExtX == 0) dc->vportExtX = 1;
550 if (dc->vportExtY == 0) dc->vportExtY = 1;
551 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
552 return TRUE;
556 /***********************************************************************
557 * ScaleWindowExt (GDI.16)
559 DWORD WINAPI ScaleWindowExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
560 INT16 yNum, INT16 yDenom )
562 SIZE32 size;
563 if (!ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
564 return FALSE;
565 return MAKELONG( size.cx, size.cy );
569 /***********************************************************************
570 * ScaleWindowExtEx16 (GDI.485)
572 BOOL16 WINAPI ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
573 INT16 yNum, INT16 yDenom, LPSIZE16 size )
575 SIZE32 size32;
576 BOOL16 ret = ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom,
577 &size32 );
578 if (size) CONV_SIZE32TO16( &size32, size );
579 return ret;
583 /***********************************************************************
584 * ScaleWindowExtEx32 (GDI32.294)
586 BOOL32 WINAPI ScaleWindowExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
587 INT32 yNum, INT32 yDenom, LPSIZE32 size )
589 DC * dc = DC_GetDCPtr( hdc );
590 if (!dc) return FALSE;
591 if (dc->funcs->pScaleWindowExt)
592 return dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
593 if (size)
595 size->cx = dc->wndExtX;
596 size->cy = dc->wndExtY;
598 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
599 return TRUE;
600 if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
601 dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
602 dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
603 if (dc->wndExtX == 0) dc->wndExtX = 1;
604 if (dc->wndExtY == 0) dc->wndExtY = 1;
605 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
606 return TRUE;