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