Release 950901
[wine] / windows / mapping.c
1 /*
2  * GDI mapping mode functions
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 #include <math.h>
8 #include "gdi.h"
9 #include "metafile.h"
10 #include "stddebug.h"
11 /* #define DEBUG_GDI */
12 #include "debug.h"
13
14
15 /***********************************************************************
16  *           MAPPING_FixIsotropic
17  *
18  * Fix viewport extensions for isotropic mode.
19  */
20 void MAPPING_FixIsotropic( DC * dc )
21 {
22     double xdim = (double)dc->w.VportExtX * dc->w.devCaps->horzSize /
23                   (dc->w.devCaps->horzRes * dc->w.WndExtX);
24     double ydim = (double)dc->w.VportExtY * dc->w.devCaps->vertSize /
25                   (dc->w.devCaps->vertRes * dc->w.WndExtY);
26     if (xdim > ydim)
27     {
28         dc->w.VportExtX = dc->w.VportExtX * fabs( ydim / xdim );
29         if (!dc->w.VportExtX) dc->w.VportExtX = 1;
30     }
31     else
32     {
33         dc->w.VportExtY = dc->w.VportExtY * fabs( xdim / ydim );
34         if (!dc->w.VportExtY) dc->w.VportExtY = 1;
35     }   
36 }
37
38 /***********************************************************************
39  *           DPtoLP    (GDI.67)
40  */
41 BOOL DPtoLP( HDC hdc, LPPOINT points, int count )
42 {
43     POINT * pt;
44     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
45     if (!dc) return FALSE;
46     
47     for (pt = points; count > 0; pt++, count--)
48     {
49         pt->x = XDPTOLP( dc, pt->x );
50         pt->y = YDPTOLP( dc, pt->y );
51     }
52     return TRUE;
53 }
54
55
56 /***********************************************************************
57  *           LPtoDP    (GDI.99)
58  */
59 BOOL LPtoDP( HDC hdc, LPPOINT points, int count )
60 {
61     POINT * pt;
62     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
63     if (!dc) return FALSE;
64     
65     for (pt = points; count > 0; pt++, count--)
66     {
67         pt->x = XLPTODP( dc, pt->x );
68         pt->y = YLPTODP( dc, pt->y );
69     }
70     return TRUE;
71 }
72
73
74 /***********************************************************************
75  *           SetMapMode    (GDI.3)
76  */
77 WORD SetMapMode( HDC hdc, WORD mode )
78 {
79     WORD prevMode;
80     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
81     if (!dc) 
82     {
83         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
84         if (!dc) return 0;
85         MF_MetaParam1(dc, META_SETMAPMODE, mode);
86         return 1;
87     }
88
89     dprintf_gdi(stddeb, "SetMapMode: %d %d\n", hdc, mode );
90     
91     prevMode = dc->w.MapMode;
92     switch(mode)
93     {
94       case MM_TEXT:
95           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
96           dc->w.VportOrgX = dc->w.VportOrgY = 0;
97           dc->w.WndExtX   = 1;
98           dc->w.WndExtY   = 1;
99           dc->w.VportExtX = 1;
100           dc->w.VportExtY = 1;
101           break;
102           
103       case MM_LOMETRIC:
104       case MM_ISOTROPIC:
105           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
106           dc->w.VportOrgX = dc->w.VportOrgY = 0;
107           dc->w.WndExtX   = dc->w.devCaps->horzSize;
108           dc->w.WndExtY   = dc->w.devCaps->vertSize;
109           dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
110           dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
111           break;
112           
113       case MM_HIMETRIC:
114           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
115           dc->w.VportOrgX = dc->w.VportOrgY = 0;
116           dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
117           dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
118           dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
119           dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
120           break;
121           
122       case MM_LOENGLISH:
123           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
124           dc->w.VportOrgX = dc->w.VportOrgY = 0;
125           dc->w.WndExtX   = dc->w.devCaps->horzSize;
126           dc->w.WndExtY   = dc->w.devCaps->vertSize;
127           dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
128           dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
129           break;          
130           
131       case MM_HIENGLISH:
132           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
133           dc->w.VportOrgX = dc->w.VportOrgY = 0;
134           dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
135           dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
136           dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
137           dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
138           break;
139           
140       case MM_TWIPS:
141           dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
142           dc->w.VportOrgX = dc->w.VportOrgY = 0;
143           dc->w.WndExtX   = (short)(144L * dc->w.devCaps->horzSize / 10);
144           dc->w.WndExtY   = (short)(144L * dc->w.devCaps->vertSize / 10);
145           dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
146           dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
147           break;
148           
149       case MM_ANISOTROPIC:
150           break;
151
152       default:
153           return prevMode;
154     }
155     dc->w.MapMode = mode;
156     return prevMode;
157 }
158
159
160 /***********************************************************************
161  *           SetViewportExt    (GDI.14)
162  */
163 DWORD SetViewportExt( HDC hdc, short x, short y )
164 {
165     SIZE size;
166     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
167     if (!dc) 
168     {
169         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
170         if (!dc) return FALSE;
171         MF_MetaParam2(dc, META_SETVIEWPORTEXT, x, y);
172         return 0;
173     }
174
175     size.cx = dc->w.VportExtX;
176     size.cy = dc->w.VportExtY;
177     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
178         return size.cx | (size.cy << 16);
179     if (!x || !y) return 0;
180     dc->w.VportExtX = x;
181     dc->w.VportExtY = y;
182     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
183     return size.cx | (size.cy << 16);
184 }
185
186
187 /***********************************************************************
188  *           SetViewportExtEx    (GDI.479)
189  */
190 BOOL SetViewportExtEx( HDC hdc, short x, short y, LPSIZE size )
191 {
192     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
193     if (!dc) return FALSE;
194     if (size)
195     {
196         size->cx = dc->w.VportExtX;
197         size->cy = dc->w.VportExtY;
198     }
199     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
200         return TRUE;
201     if (!x || !y) return FALSE;
202     dc->w.VportExtX = x;
203     dc->w.VportExtY = y;
204     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
205     return TRUE;
206 }
207
208
209 /***********************************************************************
210  *           SetViewportOrg    (GDI.13)
211  */
212 DWORD SetViewportOrg( HDC hdc, short x, short y )
213 {
214     POINT pt;
215     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
216     if (!dc) 
217     {
218         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
219         if (!dc) return FALSE;
220         MF_MetaParam2(dc, META_SETVIEWPORTORG, x, y);
221         return 0;
222     }
223
224     pt.x = dc->w.VportOrgX;
225     pt.y = dc->w.VportOrgY;
226     dc->w.VportOrgX = x;
227     dc->w.VportOrgY = y;
228     return pt.x | (pt.y << 16);
229 }
230
231
232 /***********************************************************************
233  *           SetViewportOrgEx    (GDI.480)
234  */
235 BOOL SetViewportOrgEx( HDC hdc, short x, short y, LPPOINT pt )
236 {
237     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
238     if (!dc) return FALSE;
239     if (pt)
240     {
241         pt->x = dc->w.VportOrgX;
242         pt->y = dc->w.VportOrgY;
243     }
244     dc->w.VportOrgX = x;
245     dc->w.VportOrgY = y;
246     return TRUE;
247 }
248
249
250 /***********************************************************************
251  *           SetWindowExt    (GDI.12)
252  */
253 DWORD SetWindowExt( HDC hdc, short x, short y )
254 {
255     SIZE size;
256     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
257     if (!dc) 
258     {
259         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
260         if (!dc) return FALSE;
261         MF_MetaParam2(dc, META_SETWINDOWEXT, x, y);
262         return 0;
263     }
264
265     size.cx = dc->w.WndExtX;
266     size.cy = dc->w.WndExtY;
267     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
268         return size.cx | (size.cy << 16);
269     if (!x || !y) return 0;
270     dc->w.WndExtX = x;
271     dc->w.WndExtY = y;
272     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
273     return size.cx | (size.cy << 16);
274 }
275
276
277 /***********************************************************************
278  *           SetWindowExtEx    (GDI.481)
279  */
280 BOOL SetWindowExtEx( HDC hdc, short x, short y, LPSIZE size )
281 {
282     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
283     if (!dc) return FALSE;
284     if (size)
285     {
286         size->cx = dc->w.WndExtX;
287         size->cy = dc->w.WndExtY;
288     }
289     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
290         return TRUE;
291     if (!x || !y) return FALSE;
292     dc->w.WndExtX = x;
293     dc->w.WndExtY = y;
294     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
295     return TRUE;
296 }
297
298
299 /***********************************************************************
300  *           SetWindowOrg    (GDI.11)
301  */
302 DWORD SetWindowOrg( HDC hdc, short x, short y )
303 {
304     POINT pt;
305     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
306     if (!dc) 
307     {
308         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
309         if (!dc) return FALSE;
310         MF_MetaParam2(dc, META_SETWINDOWORG, x, y);
311         return 0;
312     }
313
314     pt.x = dc->w.WndOrgX;
315     pt.y = dc->w.WndOrgY;
316     dc->w.WndOrgX = x;
317     dc->w.WndOrgY = y;
318     return pt.x | (pt.y << 16);
319 }
320
321
322 /***********************************************************************
323  *           SetWindowOrgEx    (GDI.482)
324  */
325 BOOL SetWindowOrgEx( HDC hdc, short x, short y, LPPOINT pt )
326 {
327     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
328     if (!dc) return FALSE;
329     if (pt)
330     {
331         pt->x = dc->w.WndOrgX;
332         pt->y = dc->w.WndOrgY;
333     }
334     dc->w.WndOrgX = x;
335     dc->w.WndOrgY = y;
336     return TRUE;
337 }
338
339
340 /***********************************************************************
341  *           OffsetViewportOrg    (GDI.17)
342  */
343 DWORD OffsetViewportOrg( HDC hdc, short x, short y )
344 {
345     POINT pt;
346     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
347     if (!dc) 
348     {
349         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
350         if (!dc) return FALSE;
351         MF_MetaParam2(dc, META_OFFSETVIEWPORTORG, x, y);
352         return 0;
353     }
354
355     pt.x = dc->w.VportOrgX;
356     pt.y = dc->w.VportOrgY;
357     dc->w.VportOrgX += x;
358     dc->w.VportOrgY += y;
359     return pt.x | (pt.y << 16);
360 }
361
362
363 /***********************************************************************
364  *           OffsetViewportOrgEx    (GDI.476)
365  */
366 BOOL OffsetViewportOrgEx( HDC hdc, short x, short y, LPPOINT pt )
367 {
368     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
369     if (!dc) return FALSE;
370     if (pt)
371     {
372         pt->x = dc->w.VportOrgX;
373         pt->y = dc->w.VportOrgY;
374     }
375     dc->w.VportOrgX += x;
376     dc->w.VportOrgY += y;
377     return TRUE;
378 }
379
380
381 /***********************************************************************
382  *           OffsetWindowOrg    (GDI.15)
383  */
384 DWORD OffsetWindowOrg( HDC hdc, short x, short y )
385 {
386     POINT pt;
387     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
388     if (!dc) 
389     {
390         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
391         if (!dc) return FALSE;
392         MF_MetaParam2(dc, META_OFFSETWINDOWORG, x, y);
393         return 0;
394     }
395
396     pt.x = dc->w.WndOrgX;
397     pt.y = dc->w.WndOrgY;
398     dc->w.WndOrgX += x;
399     dc->w.WndOrgY += y;
400     return pt.x | (pt.y << 16);
401 }
402
403
404 /***********************************************************************
405  *           OffsetWindowOrgEx    (GDI.477)
406  */
407 BOOL OffsetWindowOrgEx( HDC hdc, short x, short y, LPPOINT pt )
408 {
409     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
410     if (!dc) return FALSE;
411     if (pt)
412     {
413         pt->x = dc->w.WndOrgX;
414         pt->y = dc->w.WndOrgY;
415     }
416     dc->w.WndOrgX += x;
417     dc->w.WndOrgY += y;
418     return TRUE;
419 }
420
421
422 /***********************************************************************
423  *           ScaleViewportExt    (GDI.18)
424  */
425 DWORD ScaleViewportExt( HDC hdc, short xNum, short xDenom,
426                       short yNum, short yDenom )
427 {
428     SIZE size;
429     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
430     if (!dc) 
431     {
432         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
433         if (!dc) return FALSE;
434         MF_MetaParam4(dc, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom);
435         return 0;
436     }
437
438     size.cx = dc->w.VportExtX;
439     size.cy = dc->w.VportExtY;
440     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
441         return size.cx | (size.cy << 16);
442     if (!xNum || !xDenom || !xNum || !yDenom) return 0;
443     dc->w.VportExtX = (dc->w.VportExtX * xNum) / xDenom;
444     dc->w.VportExtY = (dc->w.VportExtY * yNum) / yDenom;
445     if (dc->w.VportExtX == 0) dc->w.VportExtX = 1;
446     if (dc->w.VportExtY == 0) dc->w.VportExtY = 1;
447     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
448     return size.cx | (size.cy << 16);
449 }
450
451
452 /***********************************************************************
453  *           ScaleViewportExtEx    (GDI.484)
454  */
455 BOOL ScaleViewportExtEx( HDC hdc, short xNum, short xDenom,
456                          short yNum, short yDenom, LPSIZE size )
457 {
458     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
459     if (!dc) return FALSE;
460     if (size)
461     {
462         size->cx = dc->w.VportExtX;
463         size->cy = dc->w.VportExtY;
464     }
465     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
466         return TRUE;
467     if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
468     dc->w.VportExtX = (dc->w.VportExtX * xNum) / xDenom;
469     dc->w.VportExtY = (dc->w.VportExtY * yNum) / yDenom;
470     if (dc->w.VportExtX == 0) dc->w.VportExtX = 1;
471     if (dc->w.VportExtY == 0) dc->w.VportExtY = 1;
472     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
473     return TRUE;
474 }
475
476
477 /***********************************************************************
478  *           ScaleWindowExt    (GDI.16)
479  */
480 DWORD ScaleWindowExt( HDC hdc, short xNum, short xDenom,
481                       short yNum, short yDenom )
482 {
483     SIZE size;
484     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
485     if (!dc) 
486     {
487         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
488         if (!dc) return FALSE;
489         MF_MetaParam4(dc, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom);
490         return 0;
491     }
492
493     size.cx = dc->w.WndExtX;
494     size.cy = dc->w.WndExtY;
495     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
496         return size.cx | (size.cy << 16);
497     if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
498     dc->w.WndExtX = (dc->w.WndExtX * xNum) / xDenom;
499     dc->w.WndExtY = (dc->w.WndExtY * yNum) / yDenom;
500     if (dc->w.WndExtX == 0) dc->w.WndExtX = 1;
501     if (dc->w.WndExtY == 0) dc->w.WndExtY = 1;
502     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
503     return size.cx | (size.cy << 16);
504 }
505
506
507 /***********************************************************************
508  *           ScaleWindowExtEx    (GDI.485)
509  */
510 BOOL ScaleWindowExtEx( HDC hdc, short xNum, short xDenom,
511                        short yNum, short yDenom, LPSIZE size )
512 {
513     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
514     if (!dc) return FALSE;
515     if (size)
516     {
517         size->cx = dc->w.WndExtX;
518         size->cy = dc->w.WndExtY;
519     }
520     if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
521         return TRUE;
522     if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
523     dc->w.WndExtX = (dc->w.WndExtX * xNum) / xDenom;
524     dc->w.WndExtY = (dc->w.WndExtY * yNum) / yDenom;
525     if (dc->w.WndExtX == 0) dc->w.WndExtX = 1;
526     if (dc->w.WndExtY == 0) dc->w.WndExtY = 1;
527     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
528     return TRUE;
529 }