Move simple interrupt handlers to winedos.
[wine] / graphics / mapping.c
1 /*
2  * GDI mapping mode functions
3  *
4  * Copyright 1993 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "gdi.h"
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
25
26
27 /***********************************************************************
28  *           MAPPING_FixIsotropic
29  *
30  * Fix viewport extensions for isotropic mode.
31  */
32 void MAPPING_FixIsotropic( DC * dc )
33 {
34     double xdim = (double)dc->vportExtX * GetDeviceCaps( dc->hSelf, HORZSIZE ) /
35                   (GetDeviceCaps( dc->hSelf, HORZRES ) * dc->wndExtX);
36     double ydim = (double)dc->vportExtY * GetDeviceCaps( dc->hSelf, VERTSIZE ) /
37                   (GetDeviceCaps( dc->hSelf, VERTRES ) * dc->wndExtY);
38     if (xdim > ydim)
39     {
40         dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
41         if (!dc->vportExtX) dc->vportExtX = 1;
42     }
43     else
44     {
45         dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
46         if (!dc->vportExtY) dc->vportExtY = 1;
47     }
48 }
49
50
51 /***********************************************************************
52  *           DPtoLP    (GDI.67)
53  */
54 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
55 {
56     DC * dc = DC_GetDCPtr( hdc );
57     if (!dc) return FALSE;
58
59     while (count--)
60     {
61         points->x = MulDiv( points->x - dc->vportOrgX, dc->wndExtX, dc->vportExtX ) + dc->wndOrgX;
62         points->y = MulDiv( points->y - dc->vportOrgY, dc->wndExtY, dc->vportExtY ) + dc->wndOrgY;
63         points++;
64     }
65     GDI_ReleaseObj( hdc );
66     return TRUE;
67 }
68
69
70 /***********************************************************************
71  *           DPtoLP    (GDI32.@)
72  */
73 BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
74 {
75     DC * dc = DC_GetDCPtr( hdc );
76     if (!dc) return FALSE;
77
78     if (dc->vport2WorldValid)
79     {
80         while (count--)
81         {
82             FLOAT x = points->x;
83             FLOAT y = points->y;
84             points->x = floor( x * dc->xformVport2World.eM11 +
85                                y * dc->xformVport2World.eM21 +
86                                dc->xformVport2World.eDx + 0.5 );
87             points->y = floor( x * dc->xformVport2World.eM12 +
88                                y * dc->xformVport2World.eM22 +
89                                dc->xformVport2World.eDy + 0.5 );
90             points++;
91         }
92     }
93     GDI_ReleaseObj( hdc );
94     return (count < 0);
95 }
96
97
98 /***********************************************************************
99  *           LPtoDP    (GDI.99)
100  */
101 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
102 {
103     DC * dc = DC_GetDCPtr( hdc );
104     if (!dc) return FALSE;
105
106     while (count--)
107     {
108         points->x = MulDiv( points->x - dc->wndOrgX, dc->vportExtX, dc->wndExtX ) + dc->vportOrgX;
109         points->y = MulDiv( points->y - dc->wndOrgY, dc->vportExtY, dc->wndExtY ) + dc->vportOrgY;
110         points++;
111     }
112     GDI_ReleaseObj( hdc );
113     return TRUE;
114 }
115
116
117 /***********************************************************************
118  *           LPtoDP    (GDI32.@)
119  */
120 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
121 {
122     DC * dc = DC_GetDCPtr( hdc );
123     if (!dc) return FALSE;
124
125     while (count--)
126     {
127         FLOAT x = points->x;
128         FLOAT y = points->y;
129         points->x = floor( x * dc->xformWorld2Vport.eM11 +
130                            y * dc->xformWorld2Vport.eM21 +
131                            dc->xformWorld2Vport.eDx + 0.5 );
132         points->y = floor( x * dc->xformWorld2Vport.eM12 +
133                            y * dc->xformWorld2Vport.eM22 +
134                            dc->xformWorld2Vport.eDy + 0.5 );
135         points++;
136     }
137     GDI_ReleaseObj( hdc );
138     return TRUE;
139 }
140
141
142 /***********************************************************************
143  *           SetMapMode    (GDI32.@)
144  */
145 INT WINAPI SetMapMode( HDC hdc, INT mode )
146 {
147     INT ret;
148     INT horzSize, vertSize, horzRes, vertRes;
149
150     DC * dc = DC_GetDCPtr( hdc );
151     if (!dc) return 0;
152     if (dc->funcs->pSetMapMode)
153     {
154         if((ret = dc->funcs->pSetMapMode( dc->physDev, mode )) != TRUE)
155         {
156             if(ret == GDI_NO_MORE_WORK)
157                 ret = TRUE;
158             goto done;
159         }
160     }
161
162     TRACE("%04x %d\n", hdc, mode );
163
164     ret = dc->MapMode;
165     horzSize = GetDeviceCaps( hdc, HORZSIZE );
166     vertSize = GetDeviceCaps( hdc, VERTSIZE );
167     horzRes  = GetDeviceCaps( hdc, HORZRES );
168     vertRes  = GetDeviceCaps( hdc, VERTRES );
169     switch(mode)
170     {
171     case MM_TEXT:
172         dc->wndExtX   = 1;
173         dc->wndExtY   = 1;
174         dc->vportExtX = 1;
175         dc->vportExtY = 1;
176         break;
177     case MM_LOMETRIC:
178     case MM_ISOTROPIC:
179         dc->wndExtX   = horzSize;
180         dc->wndExtY   = vertSize;
181         dc->vportExtX = horzRes / 10;
182         dc->vportExtY = vertRes / -10;
183         break;
184     case MM_HIMETRIC:
185         dc->wndExtX   = horzSize * 10;
186         dc->wndExtY   = vertSize * 10;
187         dc->vportExtX = horzRes / 10;
188         dc->vportExtY = vertRes / -10;
189         break;
190     case MM_LOENGLISH:
191         dc->wndExtX   = horzSize;
192         dc->wndExtY   = vertSize;
193         dc->vportExtX = 254L * horzRes / 1000;
194         dc->vportExtY = -254L * vertRes / 1000;
195         break;
196     case MM_HIENGLISH:
197         dc->wndExtX   = horzSize * 10;
198         dc->wndExtY   = vertSize * 10;
199         dc->vportExtX = 254L * horzRes / 1000;
200         dc->vportExtY = -254L * vertRes / 1000;
201         break;
202     case MM_TWIPS:
203         dc->wndExtX   = 144L * horzSize / 10;
204         dc->wndExtY   = 144L * vertSize / 10;
205         dc->vportExtX = 254L * horzRes / 1000;
206         dc->vportExtY = -254L * vertRes / 1000;
207         break;
208     case MM_ANISOTROPIC:
209         break;
210     default:
211         goto done;
212     }
213     dc->MapMode = mode;
214     DC_UpdateXforms( dc );
215  done:
216     GDI_ReleaseObj( hdc );
217     return ret;
218 }
219
220
221 /***********************************************************************
222  *           SetViewportExtEx    (GDI32.@)
223  */
224 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
225 {
226     INT ret = TRUE;
227     DC * dc = DC_GetDCPtr( hdc );
228     if (!dc) return FALSE;
229     if (dc->funcs->pSetViewportExt)
230     {
231         if((ret = dc->funcs->pSetViewportExt( dc->physDev, x, y )) != TRUE)
232         {
233             if(ret == GDI_NO_MORE_WORK)
234                 ret = TRUE;
235             goto done;
236         }
237     }
238     if (size)
239     {
240         size->cx = dc->vportExtX;
241         size->cy = dc->vportExtY;
242     }
243     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
244         goto done;
245     if (!x || !y)
246     {
247         ret = FALSE;
248         goto done;
249     }
250     dc->vportExtX = x;
251     dc->vportExtY = y;
252     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
253     DC_UpdateXforms( dc );
254  done:
255     GDI_ReleaseObj( hdc );
256     return ret;
257 }
258
259
260 /***********************************************************************
261  *           SetViewportOrgEx    (GDI32.@)
262  */
263 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
264 {
265     INT ret = TRUE;
266     DC * dc = DC_GetDCPtr( hdc );
267     if (!dc) return FALSE;
268     if (dc->funcs->pSetViewportOrg)
269     {
270         if((ret = dc->funcs->pSetViewportOrg( dc->physDev, x, y )) != TRUE)
271         {
272             if(ret == GDI_NO_MORE_WORK)
273                 ret = TRUE;
274             goto done;
275         }
276     }
277     if (pt)
278     {
279         pt->x = dc->vportOrgX;
280         pt->y = dc->vportOrgY;
281     }
282     dc->vportOrgX = x;
283     dc->vportOrgY = y;
284     DC_UpdateXforms( dc );
285
286  done:
287     GDI_ReleaseObj( hdc );
288     return ret;
289 }
290
291
292 /***********************************************************************
293  *           SetWindowExtEx    (GDI32.@)
294  */
295 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
296 {
297     INT ret = TRUE;
298     DC * dc = DC_GetDCPtr( hdc );
299     if (!dc) return FALSE;
300     if (dc->funcs->pSetWindowExt)
301     {
302         if((ret = dc->funcs->pSetWindowExt( dc->physDev, x, y )) != TRUE)
303         {
304             if(ret == GDI_NO_MORE_WORK)
305                 ret = TRUE;
306             goto done;
307         }
308     }
309     if (size)
310     {
311         size->cx = dc->wndExtX;
312         size->cy = dc->wndExtY;
313     }
314     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
315         goto done;
316     if (!x || !y)
317     {
318         ret = FALSE;
319         goto done;
320     }
321     dc->wndExtX = x;
322     dc->wndExtY = y;
323     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
324     DC_UpdateXforms( dc );
325  done:
326     GDI_ReleaseObj( hdc );
327     return ret;
328 }
329
330
331 /***********************************************************************
332  *           SetWindowOrgEx    (GDI32.@)
333  */
334 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
335 {
336     INT ret = TRUE;
337     DC * dc = DC_GetDCPtr( hdc );
338     if (!dc) return FALSE;
339     if (dc->funcs->pSetWindowOrg)
340     {
341         if((ret = dc->funcs->pSetWindowOrg( dc->physDev, x, y )) != TRUE)
342         {
343             if(ret == GDI_NO_MORE_WORK)
344                 ret = TRUE;
345             goto done;
346         }
347     }
348     if (pt)
349     {
350         pt->x = dc->wndOrgX;
351         pt->y = dc->wndOrgY;
352     }
353     dc->wndOrgX = x;
354     dc->wndOrgY = y;
355     DC_UpdateXforms( dc );
356  done:
357     GDI_ReleaseObj( hdc );
358     return ret;
359 }
360
361
362 /***********************************************************************
363  *           OffsetViewportOrgEx    (GDI32.@)
364  */
365 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
366 {
367     INT ret = TRUE;
368     DC * dc = DC_GetDCPtr( hdc );
369     if (!dc) return FALSE;
370     if (dc->funcs->pOffsetViewportOrg)
371     {
372         if((ret = dc->funcs->pOffsetViewportOrg( dc->physDev, x, y )) != TRUE)
373         {
374             if(ret == GDI_NO_MORE_WORK)
375                 ret = TRUE;
376             goto done;
377         }
378     }
379     if (pt)
380     {
381         pt->x = dc->vportOrgX;
382         pt->y = dc->vportOrgY;
383     }
384     dc->vportOrgX += x;
385     dc->vportOrgY += y;
386     DC_UpdateXforms( dc );
387  done:
388     GDI_ReleaseObj( hdc );
389     return ret;
390 }
391
392
393 /***********************************************************************
394  *           OffsetWindowOrgEx    (GDI32.@)
395  */
396 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
397 {
398     INT ret = TRUE;
399     DC * dc = DC_GetDCPtr( hdc );
400     if (!dc) return FALSE;
401     if (dc->funcs->pOffsetWindowOrg)
402     {
403         if((ret = dc->funcs->pOffsetWindowOrg( dc->physDev, x, y )) != TRUE)
404         {
405             if(ret == GDI_NO_MORE_WORK)
406                 ret = TRUE;
407             goto done;
408         }
409     }
410     if (pt)
411     {
412         pt->x = dc->wndOrgX;
413         pt->y = dc->wndOrgY;
414     }
415     dc->wndOrgX += x;
416     dc->wndOrgY += y;
417     DC_UpdateXforms( dc );
418  done:
419     GDI_ReleaseObj( hdc );
420     return ret;
421 }
422
423
424 /***********************************************************************
425  *           ScaleViewportExtEx    (GDI32.@)
426  */
427 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
428                                     INT yNum, INT yDenom, LPSIZE size )
429 {
430     INT ret = TRUE;
431     DC * dc = DC_GetDCPtr( hdc );
432     if (!dc) return FALSE;
433     if (dc->funcs->pScaleViewportExt)
434     {
435         if((ret = dc->funcs->pScaleViewportExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
436         {
437             if(ret == GDI_NO_MORE_WORK)
438                 ret = TRUE;
439             goto done;
440         }
441     }
442     if (size)
443     {
444         size->cx = dc->vportExtX;
445         size->cy = dc->vportExtY;
446     }
447     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
448         goto done;
449     if (!xNum || !xDenom || !xNum || !yDenom)
450     {
451         ret = FALSE;
452         goto done;
453     }
454     dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
455     dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
456     if (dc->vportExtX == 0) dc->vportExtX = 1;
457     if (dc->vportExtY == 0) dc->vportExtY = 1;
458     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
459     DC_UpdateXforms( dc );
460  done:
461     GDI_ReleaseObj( hdc );
462     return ret;
463 }
464
465
466 /***********************************************************************
467  *           ScaleWindowExtEx    (GDI32.@)
468  */
469 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
470                                   INT yNum, INT yDenom, LPSIZE size )
471 {
472     INT ret = TRUE;
473     DC * dc = DC_GetDCPtr( hdc );
474     if (!dc) return FALSE;
475     if (dc->funcs->pScaleWindowExt)
476     {
477         if((ret = dc->funcs->pScaleWindowExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
478         {
479             if(ret == GDI_NO_MORE_WORK)
480                 ret = TRUE;
481             goto done;
482         }
483     }
484     if (size)
485     {
486         size->cx = dc->wndExtX;
487         size->cy = dc->wndExtY;
488     }
489     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
490         goto done;
491     if (!xNum || !xDenom || !xNum || !yDenom)
492     {
493         ret = FALSE;
494         goto done;
495     }
496     dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
497     dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
498     if (dc->wndExtX == 0) dc->wndExtX = 1;
499     if (dc->wndExtY == 0) dc->wndExtY = 1;
500     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
501     DC_UpdateXforms( dc );
502  done:
503     GDI_ReleaseObj( hdc );
504     return ret;
505 }