Authors: Paul Quinn <paulq@corel.ca>, Albert Den Haan <albertd@corel.ca>
[wine] / graphics / mapping.c
1 /*
2  * GDI mapping mode functions
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 #include <math.h>
8 #include "dc.h"
9 #include "debug.h"
10
11
12 /***********************************************************************
13  *           MAPPING_FixIsotropic
14  *
15  * Fix viewport extensions for isotropic mode.
16  */
17 void MAPPING_FixIsotropic( DC * dc )
18 {
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)
24     {
25         dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
26         if (!dc->vportExtX) dc->vportExtX = 1;
27     }
28     else
29     {
30         dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
31         if (!dc->vportExtY) dc->vportExtY = 1;
32     }   
33 }
34
35
36 /***********************************************************************
37  *           DPtoLP16    (GDI.67)
38  */
39 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
40 {
41     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
42     if (!dc) return FALSE;
43
44     while (count--)
45     {
46         points->x = XDPTOLP( dc, points->x );
47         points->y = YDPTOLP( dc, points->y );
48         points++;
49     }
50     return TRUE;
51 }
52
53
54 /***********************************************************************
55  *           DPtoLP32    (GDI32.65)
56  */
57 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
58 {
59     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
60     if (!dc) return FALSE;
61
62     while (count--)
63     {
64         if (!INTERNAL_DPTOLP( dc, points ))
65             return FALSE;
66         points++;
67     }
68     return TRUE;
69 }
70
71
72 /***********************************************************************
73  *           LPtoDP16    (GDI.99)
74  */
75 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
76 {
77     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
78     if (!dc) return FALSE;
79
80     while (count--)
81     {
82         points->x = XLPTODP( dc, points->x );
83         points->y = YLPTODP( dc, points->y );
84         points++;
85     }
86     return TRUE;
87 }
88
89
90 /***********************************************************************
91  *           LPtoDP32    (GDI32.247)
92  */
93 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
94 {
95     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
96     if (!dc) return FALSE;
97
98     while (count--)
99     {
100         INTERNAL_LPTODP( dc, points );
101         points++;
102     }
103     return TRUE;
104 }
105
106
107 /***********************************************************************
108  *           SetMapMode16    (GDI.3)
109  */
110 INT16 WINAPI SetMapMode16( HDC16 hdc, INT16 mode )
111 {
112     return SetMapMode32( hdc, mode );
113 }
114
115
116 /***********************************************************************
117  *           SetMapMode32    (GDI32.321)
118  */
119 INT32 WINAPI SetMapMode32( HDC32 hdc, INT32 mode )
120 {
121     INT32 prevMode;
122     DC * dc = DC_GetDCPtr( hdc );
123     if (!dc) return 0;
124     if (dc->funcs->pSetMapMode) return dc->funcs->pSetMapMode( dc, mode );
125
126     TRACE(gdi, "%04x %d\n", hdc, mode );
127     
128     prevMode = dc->w.MapMode;
129     switch(mode)
130     {
131       case MM_TEXT:
132           dc->wndOrgX   = dc->wndOrgY   = 0;
133           dc->vportOrgX = dc->vportOrgY = 0;
134           dc->wndExtX   = 1;
135           dc->wndExtY   = 1;
136           dc->vportExtX = 1;
137           dc->vportExtY = 1;
138           break;
139           
140       case MM_LOMETRIC:
141       case MM_ISOTROPIC:
142           dc->wndOrgX   = dc->wndOrgY   = 0;
143           dc->vportOrgX = dc->vportOrgY = 0;
144           dc->wndExtX   = dc->w.devCaps->horzSize;
145           dc->wndExtY   = dc->w.devCaps->vertSize;
146           dc->vportExtX = dc->w.devCaps->horzRes / 10;
147           dc->vportExtY = dc->w.devCaps->vertRes / -10;
148           break;
149           
150       case MM_HIMETRIC:
151           dc->wndOrgX   = dc->wndOrgY   = 0;
152           dc->vportOrgX = dc->vportOrgY = 0;
153           dc->wndExtX   = dc->w.devCaps->horzSize * 10;
154           dc->wndExtY   = dc->w.devCaps->vertSize * 10;
155           dc->vportExtX = dc->w.devCaps->horzRes / 10;
156           dc->vportExtY = dc->w.devCaps->vertRes / -10;
157           break;
158           
159       case MM_LOENGLISH:
160           dc->wndOrgX   = dc->wndOrgY   = 0;
161           dc->vportOrgX = dc->vportOrgY = 0;
162           dc->wndExtX   = dc->w.devCaps->horzSize;
163           dc->wndExtY   = dc->w.devCaps->vertSize;
164           dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
165           dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
166           break;          
167           
168       case MM_HIENGLISH:
169           dc->wndOrgX   = dc->wndOrgY   = 0;
170           dc->vportOrgX = dc->vportOrgY = 0;
171           dc->wndExtX   = dc->w.devCaps->horzSize * 10;
172           dc->wndExtY   = dc->w.devCaps->vertSize * 10;
173           dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
174           dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
175           break;
176           
177       case MM_TWIPS:
178           dc->wndOrgX   = dc->wndOrgY   = 0;
179           dc->vportOrgX = dc->vportOrgY = 0;
180           dc->wndExtX   = 144L * dc->w.devCaps->horzSize / 10;
181           dc->wndExtY   = 144L * dc->w.devCaps->vertSize / 10;
182           dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
183           dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
184           break;
185           
186       case MM_ANISOTROPIC:
187           break;
188
189       default:
190           return prevMode;
191     }
192     dc->w.MapMode = mode;
193     DC_UpdateXforms( dc );
194     return prevMode;
195 }
196
197
198 /***********************************************************************
199  *           SetViewportExt    (GDI.14)
200  */
201 DWORD WINAPI SetViewportExt( HDC16 hdc, INT16 x, INT16 y )
202 {
203     SIZE32 size;
204     if (!SetViewportExtEx32( hdc, x, y, &size )) return 0;
205     return MAKELONG( size.cx, size.cy );
206 }
207
208
209 /***********************************************************************
210  *           SetViewportExtEx16    (GDI.479)
211  */
212 BOOL16 WINAPI SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
213 {
214     SIZE32 size32;
215     BOOL16 ret = SetViewportExtEx32( hdc, x, y, &size32 );
216     if (size) CONV_SIZE32TO16( &size32, size );
217     return ret;
218 }
219
220
221 /***********************************************************************
222  *           SetViewportExtEx32    (GDI32.340)
223  */
224 BOOL32 WINAPI SetViewportExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
225 {
226     DC * dc = DC_GetDCPtr( hdc );
227     if (!dc) return FALSE;
228     if (dc->funcs->pSetViewportExt)
229         return dc->funcs->pSetViewportExt( dc, x, y );
230     if (size)
231     {
232         size->cx = dc->vportExtX;
233         size->cy = dc->vportExtY;
234     }
235     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
236         return TRUE;
237     if (!x || !y) return FALSE;
238     dc->vportExtX = x;
239     dc->vportExtY = y;
240     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
241     DC_UpdateXforms( dc );
242     return TRUE;
243 }
244
245
246 /***********************************************************************
247  *           SetViewportOrg    (GDI.13)
248  */
249 DWORD WINAPI SetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
250 {
251     POINT32 pt;
252     if (!SetViewportOrgEx32( hdc, x, y, &pt )) return 0;
253     return MAKELONG( pt.x, pt.y );
254 }
255
256
257 /***********************************************************************
258  *           SetViewportOrgEx16    (GDI.480)
259  */
260 BOOL16 WINAPI SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
261 {
262     POINT32 pt32;
263     BOOL16 ret = SetViewportOrgEx32( hdc, x, y, &pt32 );
264     if (pt) CONV_POINT32TO16( &pt32, pt );
265     return ret;
266 }
267
268
269 /***********************************************************************
270  *           SetViewportOrgEx32    (GDI32.341)
271  */
272 BOOL32 WINAPI SetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
273 {
274     DC * dc = DC_GetDCPtr( hdc );
275     if (!dc) return FALSE;
276     if (dc->funcs->pSetViewportOrg)
277         return dc->funcs->pSetViewportOrg( dc, x, y );
278     if (pt)
279     {
280         pt->x = dc->vportOrgX;
281         pt->y = dc->vportOrgY;
282     }
283     dc->vportOrgX = x;
284     dc->vportOrgY = y;
285     DC_UpdateXforms( dc );
286     return TRUE;
287 }
288
289
290 /***********************************************************************
291  *           SetWindowExt    (GDI.12)
292  */
293 DWORD WINAPI SetWindowExt( HDC16 hdc, INT16 x, INT16 y )
294 {
295     SIZE32 size;
296     if (!SetWindowExtEx32( hdc, x, y, &size )) return 0;
297     return MAKELONG( size.cx, size.cy );
298 }
299
300
301 /***********************************************************************
302  *           SetWindowExtEx16    (GDI.481)
303  */
304 BOOL16 WINAPI SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
305 {
306     SIZE32 size32;
307     BOOL16 ret = SetWindowExtEx32( hdc, x, y, &size32 );
308     if (size) CONV_SIZE32TO16( &size32, size );
309     return ret;
310 }
311
312
313 /***********************************************************************
314  *           SetWindowExtEx32    (GDI32.344)
315  */
316 BOOL32 WINAPI SetWindowExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
317 {
318     DC * dc = DC_GetDCPtr( hdc );
319     if (!dc) return FALSE;
320     if (dc->funcs->pSetWindowExt) return dc->funcs->pSetWindowExt( dc, x, y );
321     if (size)
322     {
323         size->cx = dc->wndExtX;
324         size->cy = dc->wndExtY;
325     }
326     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
327         return TRUE;
328     if (!x || !y) return FALSE;
329     dc->wndExtX = x;
330     dc->wndExtY = y;
331     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
332     DC_UpdateXforms( dc );
333     return TRUE;
334 }
335
336
337 /***********************************************************************
338  *           SetWindowOrg    (GDI.11)
339  */
340 DWORD WINAPI SetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
341 {
342     POINT32 pt;
343     if (!SetWindowOrgEx32( hdc, x, y, &pt )) return 0;
344     return MAKELONG( pt.x, pt.y );
345 }
346
347
348 /***********************************************************************
349  *           SetWindowOrgEx16    (GDI.482)
350  */
351 BOOL16 WINAPI SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
352 {
353     POINT32 pt32;
354     BOOL16 ret = SetWindowOrgEx32( hdc, x, y, &pt32 );
355     if (pt) CONV_POINT32TO16( &pt32, pt );
356     return ret;
357 }
358
359
360 /***********************************************************************
361  *           SetWindowOrgEx32    (GDI32.345)
362  */
363 BOOL32 WINAPI SetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
364 {
365     DC * dc = DC_GetDCPtr( hdc );
366     if (!dc) return FALSE;
367     if (dc->funcs->pSetWindowOrg) return dc->funcs->pSetWindowOrg( dc, x, y );
368     if (pt)
369     {
370         pt->x = dc->wndOrgX;
371         pt->y = dc->wndOrgY;
372     }
373     dc->wndOrgX = x;
374     dc->wndOrgY = y;
375     DC_UpdateXforms( dc );
376     return TRUE;
377 }
378
379
380 /***********************************************************************
381  *           OffsetViewportOrg    (GDI.17)
382  */
383 DWORD WINAPI OffsetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
384 {
385     POINT32 pt;
386     if (!OffsetViewportOrgEx32( hdc, x, y, &pt )) return 0;
387     return MAKELONG( pt.x, pt.y );
388 }
389
390
391 /***********************************************************************
392  *           OffsetViewportOrgEx16    (GDI.476)
393  */
394 BOOL16 WINAPI OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt)
395 {
396     POINT32 pt32;
397     BOOL16 ret = OffsetViewportOrgEx32( hdc, x, y, &pt32 );
398     if (pt) CONV_POINT32TO16( &pt32, pt );
399     return ret;
400 }
401
402
403 /***********************************************************************
404  *           OffsetViewportOrgEx32    (GDI32.257)
405  */
406 BOOL32 WINAPI OffsetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt)
407 {
408     DC * dc = DC_GetDCPtr( hdc );
409     if (!dc) return FALSE;
410     if (dc->funcs->pOffsetViewportOrg)
411         return dc->funcs->pOffsetViewportOrg( dc, x, y );
412     if (pt)
413     {
414         pt->x = dc->vportOrgX;
415         pt->y = dc->vportOrgY;
416     }
417     dc->vportOrgX += x;
418     dc->vportOrgY += y;
419     DC_UpdateXforms( dc );
420     return TRUE;
421 }
422
423
424 /***********************************************************************
425  *           OffsetWindowOrg    (GDI.15)
426  */
427 DWORD WINAPI OffsetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
428 {
429     POINT32 pt;
430     if (!OffsetWindowOrgEx32( hdc, x, y, &pt )) return 0;
431     return MAKELONG( pt.x, pt.y );
432 }
433
434
435 /***********************************************************************
436  *           OffsetWindowOrgEx16    (GDI.477)
437  */
438 BOOL16 WINAPI OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
439 {
440     POINT32 pt32;
441     BOOL16 ret = OffsetWindowOrgEx32( hdc, x, y, &pt32 );
442     if (pt) CONV_POINT32TO16( &pt32, pt );
443     return ret;
444 }
445
446
447 /***********************************************************************
448  *           OffsetWindowOrgEx32    (GDI32.258)
449  */
450 BOOL32 WINAPI OffsetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
451 {
452     DC * dc = DC_GetDCPtr( hdc );
453     if (!dc) return FALSE;
454     if (dc->funcs->pOffsetWindowOrg)
455         return dc->funcs->pOffsetWindowOrg( dc, x, y );
456     if (pt)
457     {
458         pt->x = dc->wndOrgX;
459         pt->y = dc->wndOrgY;
460     }
461     dc->wndOrgX += x;
462     dc->wndOrgY += y;
463     DC_UpdateXforms( dc );
464     return TRUE;
465 }
466
467
468 /***********************************************************************
469  *           ScaleViewportExt    (GDI.18)
470  */
471 DWORD WINAPI ScaleViewportExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
472                                INT16 yNum, INT16 yDenom )
473 {
474     SIZE32 size;
475     if (!ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
476         return FALSE;
477     return MAKELONG( size.cx,  size.cy );
478 }
479
480
481 /***********************************************************************
482  *           ScaleViewportExtEx16    (GDI.484)
483  */
484 BOOL16 WINAPI ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
485                                     INT16 yNum, INT16 yDenom, LPSIZE16 size )
486 {
487     SIZE32 size32;
488     BOOL16 ret = ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom,
489                                        &size32 );
490     if (size) CONV_SIZE32TO16( &size32, size );
491     return ret;
492 }
493
494
495 /***********************************************************************
496  *           ScaleViewportExtEx32    (GDI32.293)
497  */
498 BOOL32 WINAPI ScaleViewportExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
499                                     INT32 yNum, INT32 yDenom, LPSIZE32 size )
500 {
501     DC * dc = DC_GetDCPtr( hdc );
502     if (!dc) return FALSE;
503     if (dc->funcs->pScaleViewportExt)
504         return dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
505     if (size)
506     {
507         size->cx = dc->vportExtX;
508         size->cy = dc->vportExtY;
509     }
510     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
511         return TRUE;
512     if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
513     dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
514     dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
515     if (dc->vportExtX == 0) dc->vportExtX = 1;
516     if (dc->vportExtY == 0) dc->vportExtY = 1;
517     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
518     DC_UpdateXforms( dc );
519     return TRUE;
520 }
521
522
523 /***********************************************************************
524  *           ScaleWindowExt    (GDI.16)
525  */
526 DWORD WINAPI ScaleWindowExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
527                              INT16 yNum, INT16 yDenom )
528 {
529     SIZE32 size;
530     if (!ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
531         return FALSE;
532     return MAKELONG( size.cx,  size.cy );
533 }
534
535
536 /***********************************************************************
537  *           ScaleWindowExtEx16    (GDI.485)
538  */
539 BOOL16 WINAPI ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
540                                   INT16 yNum, INT16 yDenom, LPSIZE16 size )
541 {
542     SIZE32 size32;
543     BOOL16 ret = ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom,
544                                      &size32 );
545     if (size) CONV_SIZE32TO16( &size32, size );
546     return ret;
547 }
548
549
550 /***********************************************************************
551  *           ScaleWindowExtEx32    (GDI32.294)
552  */
553 BOOL32 WINAPI ScaleWindowExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
554                                   INT32 yNum, INT32 yDenom, LPSIZE32 size )
555 {
556     DC * dc = DC_GetDCPtr( hdc );
557     if (!dc) return FALSE;
558     if (dc->funcs->pScaleWindowExt)
559         return dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
560     if (size)
561     {
562         size->cx = dc->wndExtX;
563         size->cy = dc->wndExtY;
564     }
565     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
566         return TRUE;
567     if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
568     dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
569     dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
570     if (dc->wndExtX == 0) dc->wndExtX = 1;
571     if (dc->wndExtY == 0) dc->wndExtY = 1;
572     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
573     DC_UpdateXforms( dc );
574     return TRUE;
575 }