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