2 * GDI mapping mode functions
4 * Copyright 1993 Alexandre Julliard
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "gdi_private.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
33 /***********************************************************************
34 * MAPPING_FixIsotropic
36 * Fix viewport extensions for isotropic mode.
38 static void MAPPING_FixIsotropic( DC
* dc
)
40 double xdim
= fabs((double)dc
->vportExtX
* GetDeviceCaps( dc
->hSelf
, HORZSIZE
) /
41 (GetDeviceCaps( dc
->hSelf
, HORZRES
) * dc
->wndExtX
));
42 double ydim
= fabs((double)dc
->vportExtY
* GetDeviceCaps( dc
->hSelf
, VERTSIZE
) /
43 (GetDeviceCaps( dc
->hSelf
, VERTRES
) * dc
->wndExtY
));
47 INT mincx
= (dc
->vportExtX
>= 0) ? 1 : -1;
48 dc
->vportExtX
= floor(dc
->vportExtX
* ydim
/ xdim
+ 0.5);
49 if (!dc
->vportExtX
) dc
->vportExtX
= mincx
;
53 INT mincy
= (dc
->vportExtY
>= 0) ? 1 : -1;
54 dc
->vportExtY
= floor(dc
->vportExtY
* xdim
/ ydim
+ 0.5);
55 if (!dc
->vportExtY
) dc
->vportExtY
= mincy
;
60 /***********************************************************************
63 BOOL16 WINAPI
DPtoLP16( HDC16 hdc
, LPPOINT16 points
, INT16 count
)
65 DC
* dc
= get_dc_ptr( HDC_32(hdc
) );
66 if (!dc
) return FALSE
;
70 points
->x
= MulDiv( points
->x
- dc
->vportOrgX
, dc
->wndExtX
, dc
->vportExtX
) + dc
->wndOrgX
;
71 points
->y
= MulDiv( points
->y
- dc
->vportOrgY
, dc
->wndExtY
, dc
->vportExtY
) + dc
->wndOrgY
;
79 /***********************************************************************
82 BOOL WINAPI
DPtoLP( HDC hdc
, LPPOINT points
, INT count
)
84 DC
* dc
= get_dc_ptr( hdc
);
85 if (!dc
) return FALSE
;
87 if (dc
->vport2WorldValid
)
93 points
->x
= floor( x
* dc
->xformVport2World
.eM11
+
94 y
* dc
->xformVport2World
.eM21
+
95 dc
->xformVport2World
.eDx
+ 0.5 );
96 points
->y
= floor( x
* dc
->xformVport2World
.eM12
+
97 y
* dc
->xformVport2World
.eM22
+
98 dc
->xformVport2World
.eDy
+ 0.5 );
102 release_dc_ptr( dc
);
107 /***********************************************************************
110 BOOL16 WINAPI
LPtoDP16( HDC16 hdc
, LPPOINT16 points
, INT16 count
)
112 DC
* dc
= get_dc_ptr( HDC_32(hdc
) );
113 if (!dc
) return FALSE
;
117 points
->x
= MulDiv( points
->x
- dc
->wndOrgX
, dc
->vportExtX
, dc
->wndExtX
) + dc
->vportOrgX
;
118 points
->y
= MulDiv( points
->y
- dc
->wndOrgY
, dc
->vportExtY
, dc
->wndExtY
) + dc
->vportOrgY
;
121 release_dc_ptr( dc
);
126 /***********************************************************************
129 BOOL WINAPI
LPtoDP( HDC hdc
, LPPOINT points
, INT count
)
131 DC
* dc
= get_dc_ptr( hdc
);
132 if (!dc
) return FALSE
;
136 double x
= points
->x
;
137 double y
= points
->y
;
138 points
->x
= floor( x
* dc
->xformWorld2Vport
.eM11
+
139 y
* dc
->xformWorld2Vport
.eM21
+
140 dc
->xformWorld2Vport
.eDx
+ 0.5 );
141 points
->y
= floor( x
* dc
->xformWorld2Vport
.eM12
+
142 y
* dc
->xformWorld2Vport
.eM22
+
143 dc
->xformWorld2Vport
.eDy
+ 0.5 );
146 release_dc_ptr( dc
);
151 /***********************************************************************
152 * SetMapMode (GDI32.@)
154 INT WINAPI
SetMapMode( HDC hdc
, INT mode
)
157 INT horzSize
, vertSize
, horzRes
, vertRes
;
159 DC
* dc
= get_dc_ptr( hdc
);
161 if (dc
->funcs
->pSetMapMode
)
163 if((ret
= dc
->funcs
->pSetMapMode( dc
->physDev
, mode
)) != TRUE
)
165 if(ret
== GDI_NO_MORE_WORK
)
171 TRACE("%p %d\n", hdc
, mode
);
175 if (mode
== dc
->MapMode
&& (mode
== MM_ISOTROPIC
|| mode
== MM_ANISOTROPIC
))
178 horzSize
= GetDeviceCaps( hdc
, HORZSIZE
);
179 vertSize
= GetDeviceCaps( hdc
, VERTSIZE
);
180 horzRes
= GetDeviceCaps( hdc
, HORZRES
);
181 vertRes
= GetDeviceCaps( hdc
, VERTRES
);
192 dc
->wndExtX
= horzSize
* 10;
193 dc
->wndExtY
= vertSize
* 10;
194 dc
->vportExtX
= horzRes
;
195 dc
->vportExtY
= -vertRes
;
198 dc
->wndExtX
= horzSize
* 100;
199 dc
->wndExtY
= vertSize
* 100;
200 dc
->vportExtX
= horzRes
;
201 dc
->vportExtY
= -vertRes
;
204 dc
->wndExtX
= MulDiv(1000, horzSize
, 254);
205 dc
->wndExtY
= MulDiv(1000, vertSize
, 254);
206 dc
->vportExtX
= horzRes
;
207 dc
->vportExtY
= -vertRes
;
210 dc
->wndExtX
= MulDiv(10000, horzSize
, 254);
211 dc
->wndExtY
= MulDiv(10000, vertSize
, 254);
212 dc
->vportExtX
= horzRes
;
213 dc
->vportExtY
= -vertRes
;
216 dc
->wndExtX
= MulDiv(14400, horzSize
, 254);
217 dc
->wndExtY
= MulDiv(14400, vertSize
, 254);
218 dc
->vportExtX
= horzRes
;
219 dc
->vportExtY
= -vertRes
;
227 DC_UpdateXforms( dc
);
229 release_dc_ptr( dc
);
234 /***********************************************************************
235 * SetViewportExtEx (GDI32.@)
237 BOOL WINAPI
SetViewportExtEx( HDC hdc
, INT x
, INT y
, LPSIZE size
)
240 DC
* dc
= get_dc_ptr( hdc
);
241 if (!dc
) return FALSE
;
242 if (dc
->funcs
->pSetViewportExt
)
244 if((ret
= dc
->funcs
->pSetViewportExt( dc
->physDev
, x
, y
)) != TRUE
)
246 if(ret
== GDI_NO_MORE_WORK
)
253 size
->cx
= dc
->vportExtX
;
254 size
->cy
= dc
->vportExtY
;
256 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
265 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
266 DC_UpdateXforms( dc
);
268 release_dc_ptr( dc
);
273 /***********************************************************************
274 * SetViewportOrgEx (GDI32.@)
276 BOOL WINAPI
SetViewportOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
279 DC
* dc
= get_dc_ptr( hdc
);
280 if (!dc
) return FALSE
;
281 if (dc
->funcs
->pSetViewportOrg
)
283 if((ret
= dc
->funcs
->pSetViewportOrg( dc
->physDev
, x
, y
)) != TRUE
)
285 if(ret
== GDI_NO_MORE_WORK
)
292 pt
->x
= dc
->vportOrgX
;
293 pt
->y
= dc
->vportOrgY
;
297 DC_UpdateXforms( dc
);
300 release_dc_ptr( dc
);
305 /***********************************************************************
306 * SetWindowExtEx (GDI32.@)
308 BOOL WINAPI
SetWindowExtEx( HDC hdc
, INT x
, INT y
, LPSIZE size
)
311 DC
* dc
= get_dc_ptr( hdc
);
312 if (!dc
) return FALSE
;
313 if (dc
->funcs
->pSetWindowExt
)
315 if((ret
= dc
->funcs
->pSetWindowExt( dc
->physDev
, x
, y
)) != TRUE
)
317 if(ret
== GDI_NO_MORE_WORK
)
324 size
->cx
= dc
->wndExtX
;
325 size
->cy
= dc
->wndExtY
;
327 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
336 /* The API docs say that you should call SetWindowExtEx before
337 SetViewportExtEx. This advice does not imply that Windows
338 doesn't ensure the isotropic mapping after SetWindowExtEx! */
339 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
340 DC_UpdateXforms( dc
);
342 release_dc_ptr( dc
);
347 /***********************************************************************
348 * SetWindowOrgEx (GDI32.@)
350 BOOL WINAPI
SetWindowOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
353 DC
* dc
= get_dc_ptr( hdc
);
354 if (!dc
) return FALSE
;
355 if (dc
->funcs
->pSetWindowOrg
)
357 if((ret
= dc
->funcs
->pSetWindowOrg( dc
->physDev
, x
, y
)) != TRUE
)
359 if(ret
== GDI_NO_MORE_WORK
)
371 DC_UpdateXforms( dc
);
373 release_dc_ptr( dc
);
378 /***********************************************************************
379 * OffsetViewportOrgEx (GDI32.@)
381 BOOL WINAPI
OffsetViewportOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
384 DC
* dc
= get_dc_ptr( hdc
);
385 if (!dc
) return FALSE
;
386 if (dc
->funcs
->pOffsetViewportOrg
)
388 if((ret
= dc
->funcs
->pOffsetViewportOrg( dc
->physDev
, x
, y
)) != TRUE
)
390 if(ret
== GDI_NO_MORE_WORK
)
397 pt
->x
= dc
->vportOrgX
;
398 pt
->y
= dc
->vportOrgY
;
402 DC_UpdateXforms( dc
);
404 release_dc_ptr( dc
);
409 /***********************************************************************
410 * OffsetWindowOrgEx (GDI32.@)
412 BOOL WINAPI
OffsetWindowOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT pt
)
415 DC
* dc
= get_dc_ptr( hdc
);
416 if (!dc
) return FALSE
;
417 if (dc
->funcs
->pOffsetWindowOrg
)
419 if((ret
= dc
->funcs
->pOffsetWindowOrg( dc
->physDev
, x
, y
)) != TRUE
)
421 if(ret
== GDI_NO_MORE_WORK
)
433 DC_UpdateXforms( dc
);
435 release_dc_ptr( dc
);
440 /***********************************************************************
441 * ScaleViewportExtEx (GDI32.@)
443 BOOL WINAPI
ScaleViewportExtEx( HDC hdc
, INT xNum
, INT xDenom
,
444 INT yNum
, INT yDenom
, LPSIZE size
)
447 DC
* dc
= get_dc_ptr( hdc
);
448 if (!dc
) return FALSE
;
449 if (dc
->funcs
->pScaleViewportExt
)
451 if((ret
= dc
->funcs
->pScaleViewportExt( dc
->physDev
, xNum
, xDenom
, yNum
, yDenom
)) != TRUE
)
453 if(ret
== GDI_NO_MORE_WORK
)
460 size
->cx
= dc
->vportExtX
;
461 size
->cy
= dc
->vportExtY
;
463 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
465 if (!xNum
|| !xDenom
|| !xNum
|| !yDenom
)
470 dc
->vportExtX
= (dc
->vportExtX
* xNum
) / xDenom
;
471 dc
->vportExtY
= (dc
->vportExtY
* yNum
) / yDenom
;
472 if (dc
->vportExtX
== 0) dc
->vportExtX
= 1;
473 if (dc
->vportExtY
== 0) dc
->vportExtY
= 1;
474 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
475 DC_UpdateXforms( dc
);
477 release_dc_ptr( dc
);
482 /***********************************************************************
483 * ScaleWindowExtEx (GDI32.@)
485 BOOL WINAPI
ScaleWindowExtEx( HDC hdc
, INT xNum
, INT xDenom
,
486 INT yNum
, INT yDenom
, LPSIZE size
)
489 DC
* dc
= get_dc_ptr( hdc
);
490 if (!dc
) return FALSE
;
491 if (dc
->funcs
->pScaleWindowExt
)
493 if((ret
= dc
->funcs
->pScaleWindowExt( dc
->physDev
, xNum
, xDenom
, yNum
, yDenom
)) != TRUE
)
495 if(ret
== GDI_NO_MORE_WORK
)
502 size
->cx
= dc
->wndExtX
;
503 size
->cy
= dc
->wndExtY
;
505 if ((dc
->MapMode
!= MM_ISOTROPIC
) && (dc
->MapMode
!= MM_ANISOTROPIC
))
507 if (!xNum
|| !xDenom
|| !xNum
|| !yDenom
)
512 dc
->wndExtX
= (dc
->wndExtX
* xNum
) / xDenom
;
513 dc
->wndExtY
= (dc
->wndExtY
* yNum
) / yDenom
;
514 if (dc
->wndExtX
== 0) dc
->wndExtX
= 1;
515 if (dc
->wndExtY
== 0) dc
->wndExtY
= 1;
516 if (dc
->MapMode
== MM_ISOTROPIC
) MAPPING_FixIsotropic( dc
);
517 DC_UpdateXforms( dc
);
519 release_dc_ptr( dc
);