1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 /*! \file o_circle_basic.c
22 * \brief functions for the circle object
29 #include "libgeda_priv.h"
31 #ifdef HAVE_LIBDMALLOC
35 /*! Default setting for circle draw function. */
36 void (*circle_draw_func
)() = NULL
;
38 /*! \brief calculate the distance between two points
39 * \par Function Description
40 * This function calculates the distance between two points.
41 * The two points are defined by the (\a x1, \a y1) and (\a x2, \a y2)
43 * \param [in] x1 x-value of the first point
44 * \param [in] y1 y-value of the first point
45 * \param [in] x2 x-value of the second point
46 * \param [in] y2 y-value of the second point
47 * \return the distance
48 * \todo Move this function to a different place
50 int dist(int x1
, int y1
, int x2
, int y2
)
52 return sqrt(pow(x1
-x2
,2)+pow(y1
-y2
,2));
55 /*! \brief Create and add circle OBJECT to list.
56 * \par Function Description
57 * This function creates a new object representing a circle.
59 * The circle is described by its center (<B>x</B>,<B>y</B>) and its radius
61 * The <B>type</B> parameter must be equal to <B>OBJ_CIRCLE</B>. The <B>color</B>
62 * corresponds to the color the box will be drawn with.
64 * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object()
65 * function. The structure describing the circle is allocated and initialized
66 * with the parameters given to the function.
68 * Both the line type and the filling type are set to default values : solid
69 * line type with a width of 0, and no filling. It can be changed after
70 * with #o_set_line_options() and #o_set_fill_options().
72 * \param [in] toplevel The TOPLEVEL object.
73 * \param [in] type Must be OBJ_CIRCLE.
74 * \param [in] color Circle line color.
75 * \param [in] x Center x coordinate.
76 * \param [in] y Center y coordinate.
77 * \param [in] radius Radius of new circle.
78 * \return A pointer to the new end of the object list.
80 OBJECT
*o_circle_new(TOPLEVEL
*toplevel
,
82 int x
, int y
, int radius
)
86 /* create the object */
87 new_node
= s_basic_new_object(type
, "circle");
88 new_node
->color
= color
;
90 new_node
->circle
= (CIRCLE
*) g_malloc(sizeof(CIRCLE
));
92 /* describe the circle with its center and radius */
93 new_node
->circle
->center_x
= x
;
94 new_node
->circle
->center_y
= y
;
95 new_node
->circle
->radius
= radius
;
97 /* line type and filling initialized to default */
98 o_set_line_options(toplevel
, new_node
,
99 END_NONE
, TYPE_SOLID
, 0, -1, -1);
100 o_set_fill_options(toplevel
, new_node
,
101 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
103 new_node
->draw_func
= circle_draw_func
;
104 new_node
->sel_func
= select_func
;
106 /* compute the bounding box coords */
107 o_circle_recalc(toplevel
, new_node
);
112 /*! \brief Create a copy of a circle.
113 * \par Function Description
114 * The function #o_circle_copy() creates a verbatim copy of the object
115 * pointed by <B>o_current</B> describing a circle.
117 * \param [in] toplevel The TOPLEVEL object.
118 * \param [in] o_current Circle OBJECT to copy.
119 * \return The new OBJECT
121 OBJECT
*o_circle_copy(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
125 /* A new circle object is created with #o_circle_new().
126 * Values for its fields are default and need to be modified. */
127 new_obj
= o_circle_new (toplevel
, OBJ_CIRCLE
, o_current
->color
, 0, 0, 0);
130 * The parameters of the new circle are set with the ones of the original
131 * circle. The two circle have the same line type and the same filling
134 * The bounding box coordinates are computed with
135 * #o_circle_recalc().
138 new_obj
->circle
->center_x
= o_current
->circle
->center_x
;
139 new_obj
->circle
->center_y
= o_current
->circle
->center_y
;
140 new_obj
->circle
->radius
= o_current
->circle
->radius
;
142 o_set_line_options(toplevel
, new_obj
, o_current
->line_end
,
143 o_current
->line_type
, o_current
->line_width
,
144 o_current
->line_length
, o_current
->line_space
);
145 o_set_fill_options(toplevel
, new_obj
,
146 o_current
->fill_type
, o_current
->fill_width
,
147 o_current
->fill_pitch1
, o_current
->fill_angle1
,
148 o_current
->fill_pitch2
, o_current
->fill_angle2
);
150 o_circle_recalc(toplevel
, new_obj
);
152 /* new_obj->attribute = 0;*/
157 /*! \brief Modify the description of a circle OBJECT.
158 * \par Function Description
159 * This function modifies the description of the circle object <B>*object</B>
160 * depending on <B>whichone</B> that give the meaning of the <B>x</B> and <B>y</B>
163 * If <B>whichone</B> is equal to <B>CIRCLE_CENTER</B>, the new center of the
164 * circle is given by (<B>x</B>,<B>y</B>) where <B>x</B> and <B>y</B> are in world units.
166 * If <B>whichone</B> is equal to <B>CIRCLE_RADIUS</B>, the radius is given by
167 * <B>x</B> - in world units. <B>y</B> is ignored.
169 * The bounding box of the circle object is updated after the modification of its
172 * \param [in] toplevel The TOPLEVEL object.
173 * \param [in,out] object Circle OBJECT to modify.
174 * \param [in] x New center x coordinate, or radius value.
175 * \param [in] y New center y coordinate.
176 * Unused if radius is being modified.
177 * \param [in] whichone Which circle parameter to modify.
179 * <B>whichone</B> can have the following values:
181 * <DT>*</DT><DD>CIRCLE_CENTER
182 * <DT>*</DT><DD>CIRCLE_RADIUS
185 void o_circle_modify(TOPLEVEL
*toplevel
, OBJECT
*object
,
186 int x
, int y
, int whichone
)
190 /* modify the center of the circle */
191 object
->circle
->center_x
= x
;
192 object
->circle
->center_y
= y
;
195 /* modify the radius of the circle */
197 s_log_message(_("Null radius circles are not allowed\n"));
200 object
->circle
->radius
= x
;
206 /* recalculate the boundings */
207 o_circle_recalc(toplevel
, object
);
211 /*! \brief Create circle OBJECT from character string.
212 * \par Function Description
213 * The #o_circle_read() function gets from the character string <B>*buff</B> the
214 * description of a circle.
216 * Depending on <B>*version</B>, the right file format is considered.
217 * Currently two file format revisions are supported :
219 * <DT>*</DT><DD>the file format used until 2000704 release.
220 * <DT>*</DT><DD>the file format used for the releases after 20000704.
223 * \param [in] toplevel The TOPLEVEL object.
224 * \param [in] buf Character string with circle description.
225 * \param [in] release_ver libgeda release version number.
226 * \param [in] fileformat_ver libgeda file format version number.
227 * \return A pointer to the new circle object.
229 OBJECT
*o_circle_read (TOPLEVEL
*toplevel
, char buf
[],
230 unsigned int release_ver
, unsigned int fileformat_ver
)
237 int circle_width
, circle_space
, circle_length
;
238 int fill_width
, angle1
, pitch1
, angle2
, pitch2
;
243 if(release_ver
<= VERSION_20000704
) {
245 * The old geda file format, i.e. releases 20000704 and older, does not
246 * handle the line type and the filling of the box object. They are set
249 sscanf(buf
, "%c %d %d %d %d\n", &type
, &x1
, &y1
, &radius
, &color
);
252 circle_end
= END_NONE
;
253 circle_type
= TYPE_SOLID
;
257 circle_fill
= FILLING_HOLLOW
;
267 * The current line format to describe a circle is a space separated
268 * list of characters and numbers in plain ASCII on a single line. The
269 * meaning of each item is described in the file format documentation.
271 sscanf(buf
, "%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
272 &type
, &x1
, &y1
, &radius
, &color
,
273 &circle_width
, &circle_end
, &circle_type
,
274 &circle_length
, &circle_space
, &circle_fill
,
275 &fill_width
, &angle1
, &pitch1
, &angle2
, &pitch2
);
280 s_log_message(_("Found a zero radius circle [ %c %d %d %d %d ]\n"),
281 type
, x1
, y1
, radius
, color
);
285 if (color
< 0 || color
> MAX_COLORS
) {
286 s_log_message(_("Found an invalid color [ %s ]\n"), buf
);
287 s_log_message(_("Setting color to default color\n"));
288 color
= DEFAULT_COLOR
;
292 * A circle is internally described by its center and its radius.
294 * A new object is allocated, initialized and added to the object list.
295 * Its filling and line type are set according to the values of the field
298 new_obj
= o_circle_new(toplevel
, type
, color
, x1
, y1
, radius
);
299 o_set_line_options(toplevel
, new_obj
,
300 circle_end
, circle_type
, circle_width
,
301 circle_length
, circle_space
);
302 o_set_fill_options(toplevel
, new_obj
,
303 circle_fill
, fill_width
, pitch1
, angle1
, pitch2
, angle2
);
308 /*! \brief Create a character string representation of a circle OBJECT.
309 * \par Function Description
310 * This function formats a string in the buffer <B>*buff</B> to describe the
311 * circle object <B>*object</B>.
312 * It follows the post-20000704 release file format that handle the line
313 * type and fill options.
315 * \param [in] object Circle OBJECT to create string from.
316 * \return A pointer to the circle OBJECT character string.
319 * Caller must g_free returned character string.
322 char *o_circle_save(OBJECT
*object
)
326 int circle_width
, circle_space
, circle_length
;
327 int fill_width
, angle1
, pitch1
, angle2
, pitch2
;
329 OBJECT_END circle_end
;
330 OBJECT_TYPE circle_type
;
331 OBJECT_FILLING circle_fill
;
333 /* circle center and radius */
334 x
= object
->circle
->center_x
;
335 y
= object
->circle
->center_y
;
336 radius
= object
->circle
->radius
;
338 /* line type parameters */
339 circle_width
= object
->line_width
;
340 circle_end
= object
->line_end
;
341 circle_type
= object
->line_type
;
342 circle_length
= object
->line_length
;
343 circle_space
= object
->line_space
;
345 /* filling parameters */
346 circle_fill
= object
->fill_type
;
347 fill_width
= object
->fill_width
;
348 angle1
= object
->fill_angle1
;
349 pitch1
= object
->fill_pitch1
;
350 angle2
= object
->fill_angle2
;
351 pitch2
= object
->fill_pitch2
;
353 buf
= g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
354 object
->type
, x
, y
, radius
, object
->color
,
355 circle_width
, circle_end
, circle_type
, circle_length
,
356 circle_space
, circle_fill
,
357 fill_width
, angle1
, pitch1
, angle2
, pitch2
);
361 /*! \brief Translate a circle position in WORLD coordinates by a delta.
362 * \par Function Description
363 * This function applies a translation of (<B>x1</B>,<B>y1</B>) to the circle
364 * described by <B>*object</B>. <B>x1</B> and <B>y1</B> are in world unit.
366 * \param [in] toplevel The TOPLEVEL object.
367 * \param [in] dx x distance to move.
368 * \param [in] dy y distance to move.
369 * \param [in,out] object Circle OBJECT to translate.
371 void o_circle_translate_world(TOPLEVEL
*toplevel
,
372 int dx
, int dy
, OBJECT
*object
)
374 if (object
== NULL
) printf("ctw NO!\n");
376 /* Do world coords */
377 object
->circle
->center_x
= object
->circle
->center_x
+ dx
;
378 object
->circle
->center_y
= object
->circle
->center_y
+ dy
;
380 /* recalc the screen coords and the bounding box */
381 o_circle_recalc(toplevel
, object
);
385 /*! \brief Rotate Circle OBJECT using WORLD coordinates.
386 * \par Function Description
387 * The function #o_circle_rotate_world() rotate the circle described by
388 * <B>*object</B> around the (<B>world_centerx</B>,<B>world_centery</B>) point by
389 * angle <B>angle</B> degrees.
390 * The center of rotation is in world unit.
392 * \param [in] toplevel The TOPLEVEL object.
393 * \param [in] world_centerx Rotation center x coordinate in WORLD units.
394 * \param [in] world_centery Rotation center y coordinate in WORLD units.
395 * \param [in] angle Rotation angle in degrees (See note below).
396 * \param [in,out] object Circle OBJECT to rotate.
398 void o_circle_rotate_world(TOPLEVEL
*toplevel
,
399 int world_centerx
, int world_centery
, int angle
,
405 /* Only 90 degree multiple and positive angles are allowed. */
406 /* angle must be positive */
407 if(angle
< 0) angle
= -angle
;
408 /* angle must be a 90 multiple or no rotation performed */
409 if((angle
% 90) != 0) return;
412 * The center of rotation (<B>world_centerx</B>,<B>world_centery</B>) is
413 * translated to the origin. The rotation of the center around the origin
414 * is then performed. Finally, the rotated circle is translated back to
415 * its previous location.
418 /* translate object to origin */
419 object
->circle
->center_x
-= world_centerx
;
420 object
->circle
->center_y
-= world_centery
;
422 /* rotate the center of the circle around the origin */
423 x
= object
->circle
->center_x
;
424 y
= object
->circle
->center_y
;
425 rotate_point_90(x
, y
, angle
, &newx
, &newy
);
426 object
->circle
->center_x
= newx
;
427 object
->circle
->center_y
= newy
;
429 /* translate back in position */
430 object
->circle
->center_x
+= world_centerx
;
431 object
->circle
->center_y
+= world_centery
;
433 o_circle_recalc(toplevel
, object
);
437 /*! \brief Mirror circle using WORLD coordinates.
438 * \par Function Description
439 * This function recalculates the screen coords of the <B>o_current</B> pointed
440 * circle object from its world coords.
442 * The circle coordinates and its bounding are recalculated as well as the
443 * OBJECT specific (line width, filling ...).
445 * \param [in] toplevel The TOPLEVEL object.
446 * \param [in] world_centerx Origin x coordinate in WORLD units.
447 * \param [in] world_centery Origin y coordinate in WORLD units.
448 * \param [in,out] object Circle OBJECT to mirror.
450 void o_circle_mirror_world(TOPLEVEL
*toplevel
,
451 int world_centerx
, int world_centery
,
454 /* translate object to origin */
455 object
->circle
->center_x
-= world_centerx
;
456 object
->circle
->center_y
-= world_centery
;
458 /* mirror the center of the circle */
459 object
->circle
->center_x
= -object
->circle
->center_x
;
460 object
->circle
->center_y
= object
->circle
->center_y
;
462 /* translate back in position */
463 object
->circle
->center_x
+= world_centerx
;
464 object
->circle
->center_y
+= world_centery
;
466 /* recalc boundings and screen coords */
467 o_circle_recalc(toplevel
, object
);
471 /*! \brief Recalculate circle coordinates in SCREEN units.
472 * \par Function Description
473 * This function recalculates the screen coords of the <B>o_current</B> pointed
474 * circle object from its world coords.
476 * The circle coordinates and its bounding are recalculated as well as the
477 * OBJECT specific (line width, filling ...).
479 * \param [in] toplevel The TOPLEVEL object.
480 * \param [in,out] o_current Circle OBJECT to be recalculated.
482 void o_circle_recalc(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
484 int left
, right
, top
, bottom
;
486 if (o_current
->circle
== NULL
) {
490 /* update the bounding box - world unit */
491 world_get_circle_bounds(toplevel
, o_current
,
492 &left
, &top
, &right
, &bottom
);
493 o_current
->w_left
= left
;
494 o_current
->w_top
= top
;
495 o_current
->w_right
= right
;
496 o_current
->w_bottom
= bottom
;
497 o_current
->w_bounds_valid
= TRUE
;
500 /*! \brief Get circle bounding rectangle in WORLD coordinates.
501 * \par Function Description
502 * This function sets the <B>left</B>, <B>top</B>, <B>right</B> and <B>bottom</B>
503 * parameters to the boundings of the circle object described in <B>*circle</B>
506 * \param [in] toplevel The TOPLEVEL object.
507 * \param [in] object Circle OBJECT to read coordinates from.
508 * \param [out] left Left circle coordinate in WORLD units.
509 * \param [out] top Top circle coordinate in WORLD units.
510 * \param [out] right Right circle coordinate in WORLD units.
511 * \param [out] bottom Bottom circle coordinate in WORLD units.
513 void world_get_circle_bounds(TOPLEVEL
*toplevel
, OBJECT
*object
, int *left
,
514 int *top
, int *right
, int *bottom
)
518 halfwidth
= object
->line_width
/ 2;
520 *left
= object
->circle
->center_x
- object
->circle
->radius
;
521 *top
= object
->circle
->center_y
- object
->circle
->radius
;
522 *right
= object
->circle
->center_x
+ object
->circle
->radius
;
523 *bottom
= object
->circle
->center_y
+ object
->circle
->radius
;
525 /* This isn't strictly correct, but a 1st order approximation */
529 *bottom
+= halfwidth
;
533 /*! \brief get the position of the center point
534 * \par Function Description
535 * This function gets the position of the center point of a circle object.
537 * \param [in] toplevel The toplevel environment.
538 * \param [out] x pointer to the x-position
539 * \param [out] y pointer to the y-position
540 * \param [in] object The object to get the position.
541 * \return TRUE if successfully determined the position, FALSE otherwise
543 gboolean
o_circle_get_position (TOPLEVEL
*toplevel
, gint
*x
, gint
*y
,
546 *x
= object
->circle
->center_x
;
547 *y
= object
->circle
->center_y
;
551 /*! \brief Print circle to Postscript document.
552 * \par Function Description
553 * This function prints the circle described by the <B>o_current</B>
554 * parameter to a Postscript document. It takes into account its line type
556 * The Postscript document is descibed by the file pointer <B>fp</B>.
558 * The validity of the <B>o_current</B> pointer is checked :
559 * a null pointer causes an error message and a return.
561 * The description of the circle is extracted from the <B>o_current</B>
562 * parameter : the coordinates of the center of the circle, its radius,
563 * its line type, its fill type.
565 * The outline and the inside of the circle are successively handled by
566 * two differend sets of functions.
568 * \param [in] toplevel The TOPLEVEL object.
569 * \param [in] fp FILE pointer to Postscript document.
570 * \param [in] o_current Circle OBJECT to write to document.
571 * \param [in] origin_x Page x coordinate to place circle OBJECT.
572 * \param [in] origin_y Page y coordinate to place circle OBJECT.
574 void o_circle_print(TOPLEVEL
*toplevel
, FILE *fp
, OBJECT
*o_current
,
575 int origin_x
, int origin_y
)
579 int circle_width
, length
, space
;
580 int fill_width
, angle1
, pitch1
, angle2
, pitch2
;
581 void (*outl_func
)() = NULL
;
582 void (*fill_func
)() = NULL
;
584 if (o_current
== NULL
) {
585 printf("got null in o_circle_print\n");
589 x
= o_current
->circle
->center_x
;
590 y
= o_current
->circle
->center_y
;
591 radius
= o_current
->circle
->radius
;
593 color
= o_current
->color
;
596 * Depending on the type of the line for this particular circle, the
597 * appropriate function is chosen among #o_circle_print_solid(),
598 * #o_circle_print_dotted(), #o_circle_print_dashed(),
599 * #o_circle_print_center() and #o_circle_print_phantom().
601 * The needed parameters for each of these type is extracted from the
602 * <B>o_current</B> object. Depending on the type, unused parameters are
605 * In the eventuality of a length and/or space null, the line is
606 * printed solid to avoid and endless loop produced by other functions
609 circle_width
= o_current
->line_width
;
610 if(circle_width
<=2) {
611 if(toplevel
->line_style
== THICK
) {
612 circle_width
=LINE_WIDTH
;
617 length
= o_current
->line_length
;
618 space
= o_current
->line_space
;
620 switch(o_current
->line_type
) {
622 length
= -1; space
= -1;
623 outl_func
= o_circle_print_solid
;
628 outl_func
= o_circle_print_dotted
;
632 outl_func
= o_circle_print_dashed
;
636 outl_func
= o_circle_print_center
;
640 outl_func
= o_circle_print_phantom
;
644 /* Unused for now print it solid */
645 length
= -1; space
= -1;
646 outl_func
= o_circle_print_solid
;
650 if((length
== 0) || (space
== 0)) {
651 length
= -1; space
= -1;
652 outl_func
= o_circle_print_solid
;
655 (*outl_func
)(toplevel
, fp
,
656 x
- origin_x
, y
- origin_y
,
659 circle_width
, length
, space
,
663 * If the filling type of the circle is not <B>HOLLOW</B>, the appropriate
664 * function is chosen among #o_circle_print_filled(), #o_circle_print_mesh()
665 * and #o_circle_print_hatch(). The corresponding parameters are extracted
666 * from the <B>o_current</B> object and corrected afterward.
668 * The case where <B>pitch1</B> and <B>pitch2</B> are null or negative is
669 * avoided as it leads to an endless loop in most of the called functions.
670 * In such a case, the circle is printed filled. Unused parameters for
671 * each of these functions are set to -1 or any passive value.
673 if(o_current
->fill_type
!= FILLING_HOLLOW
) {
674 fill_width
= o_current
->fill_width
;
675 angle1
= o_current
->fill_angle1
;
676 pitch1
= o_current
->fill_pitch1
;
677 angle2
= o_current
->fill_angle2
;
678 pitch2
= o_current
->fill_pitch2
;
680 switch(o_current
->fill_type
) {
682 angle1
= -1; pitch1
= 1;
683 angle2
= -1; pitch2
= 1;
685 fill_func
= o_circle_print_filled
;
689 fill_func
= o_circle_print_mesh
;
693 angle2
= -1; pitch2
= 1;
694 fill_func
= o_circle_print_hatch
;
698 /* Unused for now, print it filled */
699 angle1
= -1; pitch1
= 1;
700 angle2
= -1; pitch2
= 1;
702 fill_func
= o_circle_print_filled
;
705 case(FILLING_HOLLOW
):
710 if((pitch1
<= 0) || (pitch2
<= 0)) {
711 angle1
= -1; pitch1
= 1;
712 angle2
= -1; pitch2
= 1;
713 fill_func
= o_circle_print_filled
;
716 (*fill_func
)(toplevel
, fp
,
720 angle1
, pitch1
, angle2
, pitch2
,
725 /*! \brief Print a solid circle to Postscript document.
726 * \par Function Description
727 * This function prints the outline of a circle when a solid line type
728 * is required. The circle is defined by its center in (<B>x</B>, <B>y</B>)
729 * and its radius in <B>radius</B>. It is printed with the color given
731 * The parameters <B>length</B> and <B>space</B> are ignored.
733 * It uses the function #o_arc_print_solid() to print the outline.
734 * Therefore it acts as an interface between the way a circle is defined
735 * and the way an arc is defined.
737 * All dimensions are in mils.
739 * \param [in] toplevel The TOPLEVEL object.
740 * \param [in] fp FILE pointer to Postscript document.
741 * \param [in] x Center x coordinate of circle.
742 * \param [in] y Center y coordinate of circle.
743 * \param [in] radius Circle radius.
744 * \param [in] color Circle color.
745 * \param [in] circle_width Width of circle.
746 * \param [in] length (unused).
747 * \param [in] space (unused).
748 * \param [in] origin_x Page x coordinate to place circle OBJECT.
749 * \param [in] origin_y Page y coordinate to place circle OBJECT.
751 void o_circle_print_solid(TOPLEVEL
*toplevel
, FILE *fp
,
752 int x
, int y
, int radius
,
754 int circle_width
, int length
, int space
,
755 int origin_x
, int origin_y
)
758 o_arc_print_solid(toplevel
, fp
,
762 circle_width
, -1, -1,
768 /*! \brief Print a dotted circle to Postscript document.
769 * \par Function Description
770 * This function prints the outline of a circle when a dotted line
771 * type is required. The circle is defined by its center
772 * in (<B>x</B>, <B>y</B>) and its radius in <B>radius</B>. It is printed
773 * with the color given in <B>color</B>.
774 * The parameter <B>length</B> is ignored.
776 * It uses the function #o_arc_print_dotted() to print the outline.
777 * Therefore it acts as an interface between the way a circle is
778 * defined and the way an arc is defined.
780 * All dimensions are in mils.
782 * \param [in] toplevel The TOPLEVEL object.
783 * \param [in] fp FILE pointer to Postscript document.
784 * \param [in] x Center x coordinate of circle.
785 * \param [in] y Center y coordinate of circle.
786 * \param [in] radius Circle radius.
787 * \param [in] color Circle color.
788 * \param [in] circle_width Width of circle.
789 * \param [in] length (unused).
790 * \param [in] space Space between dots.
791 * \param [in] origin_x Page x coordinate to place circle OBJECT.
792 * \param [in] origin_y Page y coordinate to place circle OBJECT.
794 void o_circle_print_dotted(TOPLEVEL
*toplevel
, FILE *fp
,
795 int x
, int y
, int radius
,
797 int circle_width
, int length
, int space
,
798 int origin_x
, int origin_y
)
801 o_arc_print_dotted(toplevel
, fp
,
805 circle_width
, -1, space
,
810 /*! \brief Print a dashed circle to Postscript document.
811 * \par Function Description
812 * This function prints the outline of a circle when a dashed line type
813 * is required. The circle is defined by its center in
814 * (<B>x</B>, <B>y</B>) and its radius in <B>radius</B>. It is printed with the
815 * color given in <B>color</B>.
817 * It uses the function #o_arc_print_dashed() to print the outline.
818 * Therefore it acts as an interface between the way a circle is
819 * defined and the way an arc is defined.
821 * All dimensions are in mils.
823 * \param [in] toplevel The TOPLEVEL object.
824 * \param [in] fp FILE pointer to Postscript document.
825 * \param [in] x Center x coordinate of circle.
826 * \param [in] y Center y coordinate of circle.
827 * \param [in] radius Circle radius.
828 * \param [in] color Circle color.
829 * \param [in] circle_width Width of circle.
830 * \param [in] length Length of dashed lines.
831 * \param [in] space Space between dashes.
832 * \param [in] origin_x Page x coordinate to place circle OBJECT.
833 * \param [in] origin_y Page y coordinate to place circle OBJECT.
835 void o_circle_print_dashed(TOPLEVEL
*toplevel
, FILE *fp
,
839 int circle_width
, int length
, int space
,
840 int origin_x
, int origin_y
)
843 o_arc_print_dashed(toplevel
, fp
,
847 circle_width
, length
, space
,
852 /*! \brief Print a centered line type circle to Postscript document.
853 * \par Function Description
854 * This function prints the outline of a circle when a centered line
855 * type is required. The circle is defined by its center in
856 * (<B>x</B>, <B>y</B>) and its radius in <B>radius</B>. It is printed with the
857 * color given in <B>color</B>.
859 * It uses the function #o_arc_print_center() to print the outline.
860 * Therefore it acts as an interface between the way a circle is
861 * defined and the way an arc is defined.
863 * All dimensions are in mils.
865 * \param [in] toplevel The TOPLEVEL object.
866 * \param [in] fp FILE pointer to Postscript document.
867 * \param [in] x Center x coordinate of circle.
868 * \param [in] y Center y coordinate of circle.
869 * \param [in] radius Circle radius.
870 * \param [in] color Circle color.
871 * \param [in] circle_width Width of circle.
872 * \param [in] length Length of dashed lines.
873 * \param [in] space Space between dashes.
874 * \param [in] origin_x Page x coordinate to place circle OBJECT.
875 * \param [in] origin_y Page y coordinate to place circle OBJECT.
877 void o_circle_print_center(TOPLEVEL
*toplevel
, FILE *fp
,
881 int circle_width
, int length
, int space
,
882 int origin_x
, int origin_y
)
885 o_arc_print_center(toplevel
, fp
,
889 circle_width
, length
, space
,
894 /*! \brief Print a phantom line type circle to Postscript document.
895 * \par Function Description
896 * This function prints the outline of a circle when a phantom line type
897 * is required. The circle is defined by its center in
898 * (<B>x</B>, <B>y</B>) and its radius in <B>radius</B>. It is printed with the
899 * color given in <B>color</B>.
901 * It uses the function #o_arc_print_phantom() to print the outline.
902 * Therefore it acts as an interface between the way a circle is defined
903 * and the way an arc is defined.
905 * All dimensions are in mils.
907 * \param [in] toplevel The TOPLEVEL object.
908 * \param [in] fp FILE pointer to Postscript document.
909 * \param [in] x Center x coordinate of circle.
910 * \param [in] y Center y coordinate of circle.
911 * \param [in] radius Circle radius.
912 * \param [in] color Circle color.
913 * \param [in] circle_width Width of circle.
914 * \param [in] length Length of dashed lines.
915 * \param [in] space Space between dashes.
916 * \param [in] origin_x Page x coordinate to place circle OBJECT.
917 * \param [in] origin_y Page y coordinate to place circle OBJECT.
919 void o_circle_print_phantom(TOPLEVEL
*toplevel
, FILE *fp
,
923 int circle_width
, int length
, int space
,
924 int origin_x
, int origin_y
)
927 o_arc_print_phantom(toplevel
, fp
,
931 circle_width
, length
, space
,
936 /*! \brief Print a solid pattern circle to Postscript document.
937 * \par Function Description
938 * The function prints a filled circle with a solid pattern.
939 * No outline is printed.
940 * The circle is defined by the coordinates of its center in
941 * (<B>x</B>,<B>y</B>) and its radius given by the <B>radius</B> parameter.
942 * The postscript file is defined by the file pointer <B>fp</B>.
943 * <B>fill_width</B>, <B>angle1</B> and <B>pitch1</B>, <B>angle2</B>
944 * and <B>pitch2</B> parameters are ignored in this functions but
945 * kept for compatibility with other fill functions.
947 * All dimensions are in mils (except <B>angle1</B> and <B>angle2</B> in degree).
949 * \param [in] toplevel The TOPLEVEL object.
950 * \param [in] fp FILE pointer to Postscript document.
951 * \param [in] x Center x coordinate of circle.
952 * \param [in] y Center y coordinate of circle.
953 * \param [in] radius Radius of circle.
954 * \param [in] color Circle color.
955 * \param [in] fill_width Circle fill width. (unused).
956 * \param [in] angle1 (unused).
957 * \param [in] pitch1 (unused).
958 * \param [in] angle2 (unused).
959 * \param [in] pitch2 (unused).
960 * \param [in] origin_x Page x coordinate to place circle OBJECT.
961 * \param [in] origin_y Page y coordinate to place circle OBJECT.
963 void o_circle_print_filled(TOPLEVEL
*toplevel
, FILE *fp
,
964 int x
, int y
, int radius
,
967 int angle1
, int pitch1
,
968 int angle2
, int pitch2
,
969 int origin_x
, int origin_y
)
971 f_print_set_color(toplevel
, fp
, color
);
973 fprintf(fp
, "%d %d %d dot\n",
974 x
-origin_x
, y
-origin_y
,
979 /*! \brief Print a mesh pattern circle to Postscript document.
980 * \par Function Description
981 * This function prints a meshed circle. No outline is printed.
982 * The circle is defined by the coordinates of its center in
983 * (<B>x</B>,<B>y</B>) and its radius by the <B>radius</B> parameter.
984 * The Postscript document is defined by the file pointer <B>fp</B>.
986 * The inside mesh is achieved by two successive call to the
987 * #o_circle_print_hatch() function, given <B>angle1</B> and <B>pitch1</B>
988 * the first time and <B>angle2</B> and <B>pitch2</B> the second time.
990 * Negative or null values for <B>pitch1</B> and/or <B>pitch2</B> are
991 * not allowed as it leads to an endless loop in #o_circle_print_hatch().
993 * All dimensions are in mils (except <B>angle1</B> and <B>angle2</B> in degree).
995 * \param [in] toplevel The TOPLEVEL object.
996 * \param [in] fp FILE pointer to Postscript document.
997 * \param [in] x Center x coordinate of circle.
998 * \param [in] y Center y coordinate of circle.
999 * \param [in] radius Radius of circle.
1000 * \param [in] color Circle color.
1001 * \param [in] fill_width Circle fill width.
1002 * \param [in] angle1 1st angle for mesh pattern.
1003 * \param [in] pitch1 1st pitch for mesh pattern.
1004 * \param [in] angle2 2nd angle for mesh pattern.
1005 * \param [in] pitch2 2nd pitch for mesh pattern.
1006 * \param [in] origin_x Page x coordinate to place circle OBJECT.
1007 * \param [in] origin_y Page y coordinate to place circle OBJECT.
1009 void o_circle_print_mesh(TOPLEVEL
*toplevel
, FILE *fp
,
1010 int x
, int y
, int radius
,
1013 int angle1
, int pitch1
,
1014 int angle2
, int pitch2
,
1015 int origin_x
, int origin_y
)
1017 o_circle_print_hatch(toplevel
, fp
,
1023 origin_x
, origin_y
);
1024 o_circle_print_hatch(toplevel
, fp
,
1030 origin_x
, origin_y
);
1034 /*! \brief Print a hatch pattern circle to Postscript document.
1035 * \par Function Description
1036 * The function prints a hatched circle. No outline is printed.
1037 * The circle is defined by the coordinates of its center in
1038 * (<B>x</B>,<B>y</B>) and its radius by the <B>radius</B> parameter.
1039 * The Postscript document is defined by the file pointer <B>fp</B>.
1040 * <B>angle2</B> and <B>pitch2</B> parameters are ignored in this
1041 * functions but kept for compatibility with other fill functions.
1043 * The only attribute of line here is its width from the parameter <B>width</B>.
1045 * Negative or null values for <B>pitch1</B> is not allowed as it
1046 * leads to an endless loop.
1048 * All dimensions are in mils (except <B>angle1</B> is in degrees).
1050 * \param [in] toplevel The TOPLEVEL object.
1051 * \param [in] fp FILE pointer to Postscript document.
1052 * \param [in] x Center x coordinate of circle.
1053 * \param [in] y Center y coordinate of circle.
1054 * \param [in] radius Radius of circle.
1055 * \param [in] color Circle color.
1056 * \param [in] fill_width Circle fill width.
1057 * \param [in] angle1 Angle for hatch pattern.
1058 * \param [in] pitch1 Pitch for hatch pattern.
1059 * \param [in] angle2 (unused).
1060 * \param [in] pitch2 (unused).
1061 * \param [in] origin_x Page x coordinate to place circle OBJECT.
1062 * \param [in] origin_y Page y coordinate to place circle OBJECT.
1064 void o_circle_print_hatch(TOPLEVEL
*toplevel
, FILE *fp
,
1065 int x
, int y
, int radius
,
1068 int angle1
, int pitch1
,
1069 int angle2
, int pitch2
,
1070 int origin_x
, int origin_y
)
1076 g_return_if_fail(toplevel
!= NULL
);
1077 g_return_if_fail(fp
!= NULL
);
1079 f_print_set_color(toplevel
, fp
, color
);
1081 /* Avoid printing line widths too small */
1082 if (fill_width
<= 1) fill_width
= 2;
1084 lines
= g_array_new(FALSE
, FALSE
, sizeof(LINE
));
1086 circle
.center_x
= x
;
1087 circle
.center_y
= y
;
1088 circle
.radius
= radius
;
1090 m_hatch_circle(&circle
, angle1
, pitch1
, lines
);
1092 for(index
=0; index
<lines
->len
; index
++) {
1093 LINE
*line
= &g_array_index(lines
, LINE
, index
);
1095 fprintf(fp
,"%d %d %d %d %d line\n",
1096 line
->x
[0], line
->y
[0],
1097 line
->x
[1], line
->y
[1],
1101 g_array_free(lines
, TRUE
);
1104 /*! \brief Calculates the distance between the given point and the closest
1105 * point on the perimeter of the circle.
1107 * \param [in] object The circle OBJECT.
1108 * \param [in] x The x coordinate of the given point.
1109 * \param [in] y The y coordinate of the given point.
1110 * \param [in] force_solid If true, force treating the object as solid.
1111 * \return The shortest distance from the object to the point. With an
1112 * invalid parameter, this function returns G_MAXDOUBLE.
1114 double o_circle_shortest_distance (OBJECT
*object
, int x
, int y
,
1119 g_return_val_if_fail (object
->circle
!= NULL
, G_MAXDOUBLE
);
1121 solid
= force_solid
|| object
->fill_type
!= FILLING_HOLLOW
;
1123 return m_circle_shortest_distance (object
->circle
, x
, y
, solid
);