Release 980301
[wine.git] / graphics / mapping.c
blob8ad198d9467871a90c35b89838f0187af99bec86
1 /*
2 * GDI mapping mode functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <math.h>
8 #include "dc.h"
9 #include "debug.h"
12 /***********************************************************************
13 * MAPPING_FixIsotropic
15 * Fix viewport extensions for isotropic mode.
17 void MAPPING_FixIsotropic( DC * dc )
19 double xdim = (double)dc->vportExtX * dc->w.devCaps->horzSize /
20 (dc->w.devCaps->horzRes * dc->wndExtX);
21 double ydim = (double)dc->vportExtY * dc->w.devCaps->vertSize /
22 (dc->w.devCaps->vertRes * dc->wndExtY);
23 if (xdim > ydim)
25 dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
26 if (!dc->vportExtX) dc->vportExtX = 1;
28 else
30 dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
31 if (!dc->vportExtY) dc->vportExtY = 1;
36 /***********************************************************************
37 * DPtoLP16 (GDI.67)
39 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
41 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
42 if (!dc) return FALSE;
44 while (count--)
46 points->x = XDPTOLP( dc, points->x );
47 points->y = YDPTOLP( dc, points->y );
48 points++;
50 return TRUE;
54 /***********************************************************************
55 * DPtoLP32 (GDI32.65)
57 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
59 FLOAT determinant=1.0, x, y;
61 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
62 if (!dc) return FALSE;
64 if (dc->w.UseWorldXform)
66 determinant = dc->w.WorldXform.eM11*dc->w.WorldXform.eM22 -
67 dc->w.WorldXform.eM12*dc->w.WorldXform.eM21;
68 if (determinant > -1e-12 && determinant < 1e-12)
69 return FALSE;
72 while (count--)
74 if (dc->w.UseWorldXform)
76 x = (FLOAT)XDPTOLP( dc, points->x ) - dc->w.WorldXform.eDx;
77 y = (FLOAT)YDPTOLP( dc, points->y ) - dc->w.WorldXform.eDy;
78 points->x = (INT32)( (x*dc->w.WorldXform.eM22 -
79 y*dc->w.WorldXform.eM21) / determinant );
80 points->y = (INT32)( (-x*dc->w.WorldXform.eM12 +
81 y*dc->w.WorldXform.eM11) / determinant );
83 else
85 points->x = XDPTOLP( dc, points->x );
86 points->y = YDPTOLP( dc, points->y );
88 points++;
90 return TRUE;
94 /***********************************************************************
95 * LPtoDP16 (GDI.99)
97 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
99 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
100 if (!dc) return FALSE;
102 while (count--)
104 points->x = XLPTODP( dc, points->x );
105 points->y = YLPTODP( dc, points->y );
106 points++;
108 return TRUE;
112 /***********************************************************************
113 * LPtoDP32 (GDI32.247)
115 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
117 FLOAT x, y;
119 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
120 if (!dc) return FALSE;
122 while (count--)
124 if (dc->w.UseWorldXform)
126 x = (FLOAT)points->x * dc->w.WorldXform.eM11 +
127 (FLOAT)points->y * dc->w.WorldXform.eM21 +
128 dc->w.WorldXform.eDx;
129 y = (FLOAT)points->x * dc->w.WorldXform.eM12 +
130 (FLOAT)points->y * dc->w.WorldXform.eM22 +
131 dc->w.WorldXform.eDy;
132 points->x = XLPTODP( dc, (INT32)x );
133 points->y = YLPTODP( dc, (INT32)y );
136 else
138 points->x = XLPTODP( dc, points->x );
139 points->y = YLPTODP( dc, points->y );
141 points++;
143 return TRUE;
147 /***********************************************************************
148 * SetMapMode16 (GDI.3)
150 INT16 WINAPI SetMapMode16( HDC16 hdc, INT16 mode )
152 return SetMapMode32( hdc, mode );
156 /***********************************************************************
157 * SetMapMode32 (GDI32.321)
159 INT32 WINAPI SetMapMode32( HDC32 hdc, INT32 mode )
161 INT32 prevMode;
162 DC * dc = DC_GetDCPtr( hdc );
163 if (!dc) return 0;
164 if (dc->funcs->pSetMapMode) return dc->funcs->pSetMapMode( dc, mode );
166 dprintf_info(gdi, "SetMapMode: %04x %d\n", hdc, mode );
168 prevMode = dc->w.MapMode;
169 switch(mode)
171 case MM_TEXT:
172 dc->wndOrgX = dc->wndOrgY = 0;
173 dc->vportOrgX = dc->vportOrgY = 0;
174 dc->wndExtX = 1;
175 dc->wndExtY = 1;
176 dc->vportExtX = 1;
177 dc->vportExtY = 1;
178 break;
180 case MM_LOMETRIC:
181 case MM_ISOTROPIC:
182 dc->wndOrgX = dc->wndOrgY = 0;
183 dc->vportOrgX = dc->vportOrgY = 0;
184 dc->wndExtX = dc->w.devCaps->horzSize;
185 dc->wndExtY = dc->w.devCaps->vertSize;
186 dc->vportExtX = dc->w.devCaps->horzRes / 10;
187 dc->vportExtY = dc->w.devCaps->vertRes / -10;
188 break;
190 case MM_HIMETRIC:
191 dc->wndOrgX = dc->wndOrgY = 0;
192 dc->vportOrgX = dc->vportOrgY = 0;
193 dc->wndExtX = dc->w.devCaps->horzSize * 10;
194 dc->wndExtY = dc->w.devCaps->vertSize * 10;
195 dc->vportExtX = dc->w.devCaps->horzRes / 10;
196 dc->vportExtY = dc->w.devCaps->vertRes / -10;
197 break;
199 case MM_LOENGLISH:
200 dc->wndOrgX = dc->wndOrgY = 0;
201 dc->vportOrgX = dc->vportOrgY = 0;
202 dc->wndExtX = dc->w.devCaps->horzSize;
203 dc->wndExtY = dc->w.devCaps->vertSize;
204 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
205 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
206 break;
208 case MM_HIENGLISH:
209 dc->wndOrgX = dc->wndOrgY = 0;
210 dc->vportOrgX = dc->vportOrgY = 0;
211 dc->wndExtX = dc->w.devCaps->horzSize * 10;
212 dc->wndExtY = dc->w.devCaps->vertSize * 10;
213 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
214 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
215 break;
217 case MM_TWIPS:
218 dc->wndOrgX = dc->wndOrgY = 0;
219 dc->vportOrgX = dc->vportOrgY = 0;
220 dc->wndExtX = 144L * dc->w.devCaps->horzSize / 10;
221 dc->wndExtY = 144L * dc->w.devCaps->vertSize / 10;
222 dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
223 dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
224 break;
226 case MM_ANISOTROPIC:
227 break;
229 default:
230 return prevMode;
232 dc->w.MapMode = mode;
233 return prevMode;
237 /***********************************************************************
238 * SetViewportExt (GDI.14)
240 DWORD WINAPI SetViewportExt( HDC16 hdc, INT16 x, INT16 y )
242 SIZE32 size;
243 if (!SetViewportExtEx32( hdc, x, y, &size )) return 0;
244 return MAKELONG( size.cx, size.cy );
248 /***********************************************************************
249 * SetViewportExtEx16 (GDI.479)
251 BOOL16 WINAPI SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
253 SIZE32 size32;
254 BOOL16 ret = SetViewportExtEx32( hdc, x, y, &size32 );
255 if (size) CONV_SIZE32TO16( &size32, size );
256 return ret;
260 /***********************************************************************
261 * SetViewportExtEx32 (GDI32.340)
263 BOOL32 WINAPI SetViewportExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
265 DC * dc = DC_GetDCPtr( hdc );
266 if (!dc) return FALSE;
267 if (dc->funcs->pSetViewportExt)
268 return dc->funcs->pSetViewportExt( dc, x, y );
269 if (size)
271 size->cx = dc->vportExtX;
272 size->cy = dc->vportExtY;
274 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
275 return TRUE;
276 if (!x || !y) return FALSE;
277 dc->vportExtX = x;
278 dc->vportExtY = y;
279 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
280 return TRUE;
284 /***********************************************************************
285 * SetViewportOrg (GDI.13)
287 DWORD WINAPI SetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
289 POINT32 pt;
290 if (!SetViewportOrgEx32( hdc, x, y, &pt )) return 0;
291 return MAKELONG( pt.x, pt.y );
295 /***********************************************************************
296 * SetViewportOrgEx16 (GDI.480)
298 BOOL16 WINAPI SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
300 POINT32 pt32;
301 BOOL16 ret = SetViewportOrgEx32( hdc, x, y, &pt32 );
302 if (pt) CONV_POINT32TO16( &pt32, pt );
303 return ret;
307 /***********************************************************************
308 * SetViewportOrgEx32 (GDI32.341)
310 BOOL32 WINAPI SetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
312 DC * dc = DC_GetDCPtr( hdc );
313 if (!dc) return FALSE;
314 if (dc->funcs->pSetViewportOrg)
315 return dc->funcs->pSetViewportOrg( dc, x, y );
316 if (pt)
318 pt->x = dc->vportOrgX;
319 pt->y = dc->vportOrgY;
321 dc->vportOrgX = x;
322 dc->vportOrgY = y;
323 return TRUE;
327 /***********************************************************************
328 * SetWindowExt (GDI.12)
330 DWORD WINAPI SetWindowExt( HDC16 hdc, INT16 x, INT16 y )
332 SIZE32 size;
333 if (!SetWindowExtEx32( hdc, x, y, &size )) return 0;
334 return MAKELONG( size.cx, size.cy );
338 /***********************************************************************
339 * SetWindowExtEx16 (GDI.481)
341 BOOL16 WINAPI SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
343 SIZE32 size32;
344 BOOL16 ret = SetWindowExtEx32( hdc, x, y, &size32 );
345 if (size) CONV_SIZE32TO16( &size32, size );
346 return ret;
350 /***********************************************************************
351 * SetWindowExtEx32 (GDI32.344)
353 BOOL32 WINAPI SetWindowExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
355 DC * dc = DC_GetDCPtr( hdc );
356 if (!dc) return FALSE;
357 if (dc->funcs->pSetWindowExt) return dc->funcs->pSetWindowExt( dc, x, y );
358 if (size)
360 size->cx = dc->wndExtX;
361 size->cy = dc->wndExtY;
363 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
364 return TRUE;
365 if (!x || !y) return FALSE;
366 dc->wndExtX = x;
367 dc->wndExtY = y;
368 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
369 return TRUE;
373 /***********************************************************************
374 * SetWindowOrg (GDI.11)
376 DWORD WINAPI SetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
378 POINT32 pt;
379 if (!SetWindowOrgEx32( hdc, x, y, &pt )) return 0;
380 return MAKELONG( pt.x, pt.y );
384 /***********************************************************************
385 * SetWindowOrgEx16 (GDI.482)
387 BOOL16 WINAPI SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
389 POINT32 pt32;
390 BOOL16 ret = SetWindowOrgEx32( hdc, x, y, &pt32 );
391 if (pt) CONV_POINT32TO16( &pt32, pt );
392 return ret;
396 /***********************************************************************
397 * SetWindowOrgEx32 (GDI32.345)
399 BOOL32 WINAPI SetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
401 DC * dc = DC_GetDCPtr( hdc );
402 if (!dc) return FALSE;
403 if (dc->funcs->pSetWindowOrg) return dc->funcs->pSetWindowOrg( dc, x, y );
404 if (pt)
406 pt->x = dc->wndOrgX;
407 pt->y = dc->wndOrgY;
409 dc->wndOrgX = x;
410 dc->wndOrgY = y;
411 return TRUE;
415 /***********************************************************************
416 * OffsetViewportOrg (GDI.17)
418 DWORD WINAPI OffsetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
420 POINT32 pt;
421 if (!OffsetViewportOrgEx32( hdc, x, y, &pt )) return 0;
422 return MAKELONG( pt.x, pt.y );
426 /***********************************************************************
427 * OffsetViewportOrgEx16 (GDI.476)
429 BOOL16 WINAPI OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt)
431 POINT32 pt32;
432 BOOL16 ret = OffsetViewportOrgEx32( hdc, x, y, &pt32 );
433 if (pt) CONV_POINT32TO16( &pt32, pt );
434 return ret;
438 /***********************************************************************
439 * OffsetViewportOrgEx32 (GDI32.257)
441 BOOL32 WINAPI OffsetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt)
443 DC * dc = DC_GetDCPtr( hdc );
444 if (!dc) return FALSE;
445 if (dc->funcs->pOffsetViewportOrg)
446 return dc->funcs->pOffsetViewportOrg( dc, x, y );
447 if (pt)
449 pt->x = dc->vportOrgX;
450 pt->y = dc->vportOrgY;
452 dc->vportOrgX += x;
453 dc->vportOrgY += y;
454 return TRUE;
458 /***********************************************************************
459 * OffsetWindowOrg (GDI.15)
461 DWORD WINAPI OffsetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
463 POINT32 pt;
464 if (!OffsetWindowOrgEx32( hdc, x, y, &pt )) return 0;
465 return MAKELONG( pt.x, pt.y );
469 /***********************************************************************
470 * OffsetWindowOrgEx16 (GDI.477)
472 BOOL16 WINAPI OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
474 POINT32 pt32;
475 BOOL16 ret = OffsetWindowOrgEx32( hdc, x, y, &pt32 );
476 if (pt) CONV_POINT32TO16( &pt32, pt );
477 return ret;
481 /***********************************************************************
482 * OffsetWindowOrgEx32 (GDI32.258)
484 BOOL32 WINAPI OffsetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
486 DC * dc = DC_GetDCPtr( hdc );
487 if (!dc) return FALSE;
488 if (dc->funcs->pOffsetWindowOrg)
489 return dc->funcs->pOffsetWindowOrg( dc, x, y );
490 if (pt)
492 pt->x = dc->wndOrgX;
493 pt->y = dc->wndOrgY;
495 dc->wndOrgX += x;
496 dc->wndOrgY += y;
497 return TRUE;
501 /***********************************************************************
502 * ScaleViewportExt (GDI.18)
504 DWORD WINAPI ScaleViewportExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
505 INT16 yNum, INT16 yDenom )
507 SIZE32 size;
508 if (!ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
509 return FALSE;
510 return MAKELONG( size.cx, size.cy );
514 /***********************************************************************
515 * ScaleViewportExtEx16 (GDI.484)
517 BOOL16 WINAPI ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
518 INT16 yNum, INT16 yDenom, LPSIZE16 size )
520 SIZE32 size32;
521 BOOL16 ret = ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom,
522 &size32 );
523 if (size) CONV_SIZE32TO16( &size32, size );
524 return ret;
528 /***********************************************************************
529 * ScaleViewportExtEx32 (GDI32.293)
531 BOOL32 WINAPI ScaleViewportExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
532 INT32 yNum, INT32 yDenom, LPSIZE32 size )
534 DC * dc = DC_GetDCPtr( hdc );
535 if (!dc) return FALSE;
536 if (dc->funcs->pScaleViewportExt)
537 return dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
538 if (size)
540 size->cx = dc->vportExtX;
541 size->cy = dc->vportExtY;
543 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
544 return TRUE;
545 if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
546 dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
547 dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
548 if (dc->vportExtX == 0) dc->vportExtX = 1;
549 if (dc->vportExtY == 0) dc->vportExtY = 1;
550 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
551 return TRUE;
555 /***********************************************************************
556 * ScaleWindowExt (GDI.16)
558 DWORD WINAPI ScaleWindowExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
559 INT16 yNum, INT16 yDenom )
561 SIZE32 size;
562 if (!ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
563 return FALSE;
564 return MAKELONG( size.cx, size.cy );
568 /***********************************************************************
569 * ScaleWindowExtEx16 (GDI.485)
571 BOOL16 WINAPI ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
572 INT16 yNum, INT16 yDenom, LPSIZE16 size )
574 SIZE32 size32;
575 BOOL16 ret = ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom,
576 &size32 );
577 if (size) CONV_SIZE32TO16( &size32, size );
578 return ret;
582 /***********************************************************************
583 * ScaleWindowExtEx32 (GDI32.294)
585 BOOL32 WINAPI ScaleWindowExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
586 INT32 yNum, INT32 yDenom, LPSIZE32 size )
588 DC * dc = DC_GetDCPtr( hdc );
589 if (!dc) return FALSE;
590 if (dc->funcs->pScaleWindowExt)
591 return dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
592 if (size)
594 size->cx = dc->wndExtX;
595 size->cy = dc->wndExtY;
597 if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
598 return TRUE;
599 if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
600 dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
601 dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
602 if (dc->wndExtX == 0) dc->wndExtX = 1;
603 if (dc->wndExtY == 0) dc->wndExtY = 1;
604 if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
605 return TRUE;