comparison src/shape_path.c @ 459:8b155b77fa14

Count positions an arc being for bounding box of the path. - An arc is part of a circle/ellipse. - We add positions of 4 corners into the list of points of the path. - The position of 4 corners will be included in the bounding box of the path.
author Thinker K.F. Li <thinker@branda.to>
date Thu, 10 Sep 2009 22:21:51 +0800
parents bb4f651090bf
children 115e7a936c94
comparison
equal deleted inserted replaced
458:bb4f651090bf 459:8b155b77fa14
175 angle = PI + angle; 175 angle = PI + angle;
176 176
177 return angle; 177 return angle;
178 } 178 }
179 179
180 static void _rotate(co_aix *x, co_aix *y, co_aix _sin, co_aix _cos) {
181 co_aix nx, ny;
182
183 nx = *x * _cos - *y * _sin;
184 ny = *x * _sin + *y * _cos;
185
186 *x = nx;
187 *y = ny;
188 }
189
180 #define TAKE_NUM(r) do { \ 190 #define TAKE_NUM(r) do { \
181 SKIP_SPACE(p); \ 191 SKIP_SPACE(p); \
182 old = p; \ 192 old = p; \
183 SKIP_NUM(p); \ 193 SKIP_NUM(p); \
184 if(p == old) \ 194 if(p == old) \
185 return ERR; \ 195 return ERR; \
186 r = atof(old); \ 196 r = atof(old); \
187 } while(0); 197 } while(0);
188 198
189 static int sh_path_arc_cmd_arg_fill(char cmd, char **cmds_p, 199 static int _sh_path_arc_cmd_arg_fill(char cmd, char **cmds_p,
190 const char **data_p, 200 const char **data_p,
191 co_aix **pnts_p, 201 co_aix **pnts_p,
192 co_aix **float_args_p) { 202 co_aix **float_args_p) {
193 co_aix rx, ry; 203 co_aix rx, ry;
194 co_aix x_rotate; 204 co_aix x_rotate;
195 int large, sweep; 205 int large, sweep;
196 co_aix x, y, x0, y0, cx, cy; 206 co_aix x, y, x0, y0, cx, cy;
207 co_aix corners[4][2];
197 co_aix angle_start, angle_stop; 208 co_aix angle_start, angle_stop;
198 co_aix *pnts = *pnts_p; 209 co_aix *pnts = *pnts_p;
199 const char *old; 210 const char *old;
200 const char *p; 211 const char *p;
201 char *cmds; 212 char *cmds;
202 co_aix *float_args; 213 co_aix *float_args;
214 co_aix _sin, _cos;
215 int i;
203 216
204 p = *data_p; 217 p = *data_p;
205 cmds = *cmds_p; 218 cmds = *cmds_p;
206 float_args = *float_args_p; 219 float_args = *float_args_p;
207 while(*p) { 220 while(*p) {
227 y += y0; 240 y += y0;
228 } 241 }
229 242
230 _calc_center(x0, y0, x, y, rx, ry, x_rotate, large, 243 _calc_center(x0, y0, x, y, rx, ry, x_rotate, large,
231 sweep, &cx, &cy); 244 sweep, &cx, &cy);
232 pnts += 8; /*!< \note Add corners here. */ 245
246 /* Compute positions for four corners.
247 * These four corners form a bounding box for the arc.
248 */
249 _sin = sinf(x_rotate);
250 _cos = cosf(x_rotate);
251 corners[0][0] = -rx;
252 corners[0][1] = -ry;
253 corners[1][0] = rx;
254 corners[1][1] = -ry;
255 corners[2][0] = rx;
256 corners[2][1] = ry;
257 corners[3][0] = -rx;
258 corners[3][1] = ry;
259 for(i = 0; i < 4; i++) {
260 _rotate(&corners[i][0], &corners[i][1], _sin, _cos);
261 *pnts++ = corners[i][0] + cx;
262 *pnts++ = corners[i][1] + cy;
263 }
264
233 *(pnts++) = x; 265 *(pnts++) = x;
234 *(pnts++) = y; 266 *(pnts++) = y;
235 267
236 angle_start = _angle_rotated_ellipse(x0 - cx, y0 - cy, 268 angle_start = _angle_rotated_ellipse(x0 - cx, y0 - cy,
237 rx, ry, x_rotate); 269 rx, ry, x_rotate);
386 418
387 udxx = (udra45x + udra45y) * _sqrt2; 419 udxx = (udra45x + udra45y) * _sqrt2;
388 udxy = (-udra45x + udra45y) * _sqrt2; 420 udxy = (-udra45x + udra45y) * _sqrt2;
389 421
390 /*! \note Why we calculate these numbers there? 422 /*! \note Why we calculate these numbers there?
391 * If we compute it when filling arguments, sh_path_arc_cmd_arg_fill(), 423 * If we compute it when filling arguments, _sh_path_arc_cmd_arg_fill(),
392 * we can avoid to recompute it for every drawing. But, transforming of 424 * we can avoid to recompute it for every drawing. But, transforming of
393 * coordinate can effect value of the numbers. 425 * coordinate can effect value of the numbers.
394 */ 426 */
395 rotate = acos(udxx); 427 rotate = acos(udxx);
396 if(udxy < 0) 428 if(udxy < 0)
762 /*! \todo implement h, H, v, V comamnds for path. */ 794 /*! \todo implement h, H, v, V comamnds for path. */
763 return ERR; 795 return ERR;
764 796
765 case 'A': 797 case 'A':
766 case 'a': 798 case 'a':
767 r = sh_path_arc_cmd_arg_fill(cmd, &cmds, 799 r = _sh_path_arc_cmd_arg_fill(cmd, &cmds,
768 (const char **)&p, &pnts, 800 (const char **)&p, &pnts,
769 &float_args); 801 &float_args);
770 if(r != OK) 802 if(r != OK)
771 return ERR; 803 return ERR;
772 break; 804 break;
773 805
774 case 'z': 806 case 'z':