1 /* libwmf ("player/coord.h"): library for wmf conversion
2    Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
3 
4    The libwmf Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8 
9    The libwmf Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public
15    License along with the libwmf Library; see the file COPYING.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18 
19 
20 /* File to be included from player/player.c
21  */
22 
23 #ifndef WMFPLAYER_COORD_H
24 #define WMFPLAYER_COORD_H
25 
26 /**
27  * Set the device origin coordinate.
28  *
29  * @param API  the API handle
30  * @param d_pt origin in device coordinates
31  *
32  * Not really recommended.
33  */
wmf_set_viewport_origin(wmfAPI * API,wmfD_Coord d_pt)34 void wmf_set_viewport_origin (wmfAPI* API,wmfD_Coord d_pt)
35 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
36 
37 	P->Viewport_Origin = d_pt;
38 }
39 
L_Coord(U16 u16_x,U16 u16_y)40 static wmfL_Coord L_Coord (U16 u16_x,U16 u16_y)
41 {	wmfL_Coord l_pt;
42 
43 	l_pt.x = U16_2_S32 (u16_x);
44 	l_pt.y = U16_2_S32 (u16_y);
45 
46 	return (l_pt);
47 }
48 
D_Rect(wmfAPI * API,wmfD_Rect * d_r,U16 u16_x1,U16 u16_y1,U16 u16_x2,U16 u16_y2)49 static void D_Rect (wmfAPI* API,wmfD_Rect* d_r,U16 u16_x1,U16 u16_y1,U16 u16_x2,U16 u16_y2)
50 {	wmfL_Coord l_pt_1;
51 	wmfL_Coord l_pt_2;
52 
53 	wmfD_Coord d_pt_1;
54 	wmfD_Coord d_pt_2;
55 
56 	l_pt_1.x = U16_2_S32 (u16_x1);
57 	l_pt_1.y = U16_2_S32 (u16_y1);
58 	l_pt_2.x = U16_2_S32 (u16_x2);
59 	l_pt_2.y = U16_2_S32 (u16_y2);
60 
61 	d_pt_1 = wmf_D_Coord_translate (API,l_pt_1);
62 	d_pt_2 = wmf_D_Coord_translate (API,l_pt_2);
63 
64 	if (d_pt_1.x <= d_pt_2.x)
65 	{	d_r->TL.x = d_pt_1.x;
66 		d_r->BR.x = d_pt_2.x;
67 	}
68 	else
69 	{	d_r->TL.x = d_pt_2.x;
70 		d_r->BR.x = d_pt_1.x;
71 	}
72 
73 	if (d_pt_1.y <= d_pt_2.y)
74 	{	d_r->TL.y = d_pt_1.y;
75 		d_r->BR.y = d_pt_2.y;
76 	}
77 	else
78 	{	d_r->TL.y = d_pt_2.y;
79 		d_r->BR.y = d_pt_1.y;
80 	}
81 }
82 
D_Coord_Register(wmfAPI * API,wmfD_Coord d_pt,float scope)83 static void D_Coord_Register (wmfAPI* API,wmfD_Coord d_pt,float scope)
84 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
85 
86 	if ((P->flags & PLAYER_TLBR_D_SET) == 0)
87 	{	P->D_TL = d_pt;
88 		P->D_BR = d_pt;
89 
90 		P->flags |= PLAYER_TLBR_D_SET;
91 	}
92 
93 	scope = ABS (scope);
94 
95 	if (P->D_TL.x > (d_pt.x - scope)) P->D_TL.x = d_pt.x - scope;
96 	if (P->D_TL.y > (d_pt.y - scope)) P->D_TL.y = d_pt.y - scope;
97 	if (P->D_BR.x < (d_pt.x + scope)) P->D_BR.x = d_pt.x + scope;
98 	if (P->D_BR.y < (d_pt.y + scope)) P->D_BR.y = d_pt.y + scope;
99 }
100 
wmf_L_Coord_translate(wmfAPI * API,wmfD_Coord d_pt)101 static wmfL_Coord wmf_L_Coord_translate (wmfAPI* API,wmfD_Coord d_pt)
102 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
103 
104 	wmfL_Coord l_pt;
105 
106 	d_pt.x += P->Viewport_Origin.x;
107 	d_pt.y += P->Viewport_Origin.y;
108 
109 	l_pt.x = (float) ((double) d_pt.x / PixelWidth (API));
110 	l_pt.y = (float) ((double) d_pt.y / PixelHeight (API));
111 
112 	l_pt.x += P->dc->Window.Ox;
113 	l_pt.y += P->dc->Window.Oy;
114 
115 	return (l_pt);
116 }
117 
wmf_D_Coord_translate(wmfAPI * API,wmfL_Coord l_pt)118 static wmfD_Coord wmf_D_Coord_translate (wmfAPI* API,wmfL_Coord l_pt)
119 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
120 
121 	wmfD_Coord d_pt;
122 
123 	l_pt.x -= P->dc->Window.Ox;
124 	l_pt.y -= P->dc->Window.Oy;
125 
126 	d_pt.x = (float) ((double) l_pt.x * PixelWidth (API));
127 	d_pt.y = (float) ((double) l_pt.y * PixelHeight (API));
128 
129 	d_pt.x -= P->Viewport_Origin.x;
130 	d_pt.y -= P->Viewport_Origin.y;
131 
132 	return (d_pt);
133 }
134 
WmfSetMapMode(wmfAPI * API,U16 map_mode)135 static void WmfSetMapMode (wmfAPI* API,U16 map_mode)
136 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
137 
138 	switch (map_mode)
139 	{
140 	case (MM_TEXT): /* each unit is 1pt */ WMF_DEBUG (API,"map_mode: MM_TEXT");
141 		P->dc->pixel_width  = 1;
142 		P->dc->pixel_height = 1;
143 	break;
144 
145 	case (MM_LOMETRIC): /* each unit is 0.1mm */ WMF_DEBUG (API,"map_mode: MM_LOMETRIC");
146 		P->dc->pixel_width  = INCH_TO_POINT (MM_TO_INCH (0.1));
147 		P->dc->pixel_height = INCH_TO_POINT (MM_TO_INCH (0.1));
148 	break;
149 
150 	case (MM_HIMETRIC): /* each unit is 0.01mm */ WMF_DEBUG (API,"map_mode: MM_HIMETRIC");
151 		P->dc->pixel_width  = INCH_TO_POINT (MM_TO_INCH (0.01));
152 		P->dc->pixel_height = INCH_TO_POINT (MM_TO_INCH (0.01));
153 	break;
154 
155 	case (MM_LOENGLISH): /* each unit is 0.01 inch */ WMF_DEBUG (API,"map_mode: MM_LOENGLISH");
156 		P->dc->pixel_width  = INCH_TO_POINT (0.01);
157 		P->dc->pixel_height = INCH_TO_POINT (0.01);
158 	break;
159 
160 	case (MM_HIENGLISH): /* each unit is 0.001 inch */ WMF_DEBUG (API,"map_mode: MM_HIENGLISH");
161 		P->dc->pixel_width  = INCH_TO_POINT (0.001);
162 		P->dc->pixel_height = INCH_TO_POINT (0.001);
163 	break;
164 
165 	case (MM_TWIPS): /* each unit is 1/1440 inch */ WMF_DEBUG (API,"map_mode: MM_TWIPS");
166 		P->dc->pixel_width  = 0.05;
167 		P->dc->pixel_height = 0.05;
168 	break;
169 
170 	case (MM_ISOTROPIC):
171 	case (MM_ANISOTROPIC): WMF_DEBUG (API,"map_mode: MM_[AN]ISOTROPIC");
172 		/* scale here depends on window & viewport extents */
173 		PixelWidth (API);
174 		PixelHeight (API);
175 	break;
176 
177 	default:
178 		if (PLACEABLE (API))
179 		{	WMF_DEBUG (API,"map_mode: MM_DPI (placeable)");
180 
181 			P->dc->pixel_width  = INCH_TO_POINT ((double) 1 / (double) DPI (API));
182 			P->dc->pixel_height = INCH_TO_POINT ((double) 1 / (double) DPI (API));
183 
184 			map_mode = MM_DPI; /* [fjf] added this - uncertainly */
185 		}
186 		else
187 		{	WMF_ERROR (API,"unexpected mapping mode!");
188 			API->err = wmf_E_BadFormat;
189 		}
190 	break;
191 	}
192 
193 	P->dc->map_mode = map_mode;
194 }
195 
PixelWidth(wmfAPI * API)196 static double PixelWidth (wmfAPI* API)
197 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
198 
199 	switch (P->dc->map_mode)
200 	{
201 	case (MM_ISOTROPIC):	/* scale here depends on window & viewport extents */
202 	case (MM_ANISOTROPIC):
203 
204 		if (P->dc->Window.width == 0)
205 		{	WMF_ERROR (API,"PixelWidth: window has bad size!");
206 			API->err = wmf_E_BadFormat;
207 			break;
208 		}
209 		if (P->Viewport_Width == 0)
210 		{	WMF_ERROR (API,"PixelWidth: viewport has bad size!");
211 			API->err = wmf_E_BadFormat;
212 			break;
213 		}
214 		P->dc->pixel_width  = (double) P->Viewport_Width  / (double) P->dc->Window.width;
215 
216 	break;
217 
218 	case (MM_TEXT):      /* each unit is 1pt */
219 	case (MM_LOMETRIC):  /* each unit is 0.1mm */
220 	case (MM_HIMETRIC):  /* each unit is 0.01mm */
221 	case (MM_LOENGLISH): /* each unit is 0.01 inch */
222 	case (MM_HIENGLISH): /* each unit is 0.001 inch */
223 	case (MM_TWIPS):     /* each unit is 1/1440 inch */
224 	case (MM_DPI):       /* isotropic; placeable meta file */
225 		if (P->dc->Window.width < 0)
226 			return -P->dc->pixel_width;
227 	break;
228 
229 	default:
230 		if (!ERR (API))
231 		{	WMF_ERROR (API,"unexpected mapping mode!");
232 			API->err = wmf_E_Glitch;
233 		}
234 	break;
235 	}
236 
237 	if (ERR (API)) return (1);
238 
239 	return (P->dc->pixel_width);
240 }
241 
PixelHeight(wmfAPI * API)242 static double PixelHeight (wmfAPI* API)
243 {	wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
244 
245 	switch (P->dc->map_mode)
246 	{
247 	case (MM_ISOTROPIC):	/* scale here depends on window & viewport extents */
248 	case (MM_ANISOTROPIC):
249 
250 		if (P->dc->Window.height == 0)
251 		{	WMF_ERROR (API,"PixelHeight: window has bad size!");
252 			API->err = wmf_E_BadFormat;
253 			break;
254 		}
255 		if (P->Viewport_Height == 0)
256 		{	WMF_ERROR (API,"PixelHeight: viewport has bad size!");
257 			API->err = wmf_E_BadFormat;
258 			break;
259 		}
260 		P->dc->pixel_height  = (double) P->Viewport_Height / (double) P->dc->Window.height;
261 
262 	break;
263 
264 	case (MM_TEXT):      /* each unit is 1pt */
265 	case (MM_LOMETRIC):  /* each unit is 0.1mm */
266 	case (MM_HIMETRIC):  /* each unit is 0.01mm */
267 	case (MM_LOENGLISH): /* each unit is 0.01 inch */
268 	case (MM_HIENGLISH): /* each unit is 0.001 inch */
269 	case (MM_TWIPS):     /* each unit is 1/1440 inch */
270 	case (MM_DPI):       /* isotropic; placeable meta file */
271 		if (P->dc->Window.height < 0)
272 			return -P->dc->pixel_height;
273 	break;
274 
275 	default:
276 		if (!ERR (API))
277 		{	WMF_ERROR (API,"unexpected mapping mode!");
278 			API->err = wmf_E_Glitch;
279 		}
280 	break;
281 	}
282 
283 	if (ERR (API)) return (1);
284 
285 	return (P->dc->pixel_height);
286 }
287 
288 #endif /* ! WMFPLAYER_COORD_H */
289