Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / libgeda / src / o_circle_basic.c
blob9da6077ab2e73e9212f65f2e2e42573281a5f96a
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
25 #include <config.h>
26 #include <stdio.h>
27 #include <math.h>
29 #include "libgeda_priv.h"
31 #ifdef HAVE_LIBDMALLOC
32 #include <dmalloc.h>
33 #endif
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)
42 * parameters.
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
60 * <B>radius</B>.
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,
81 char type, int color,
82 int x, int y, int radius)
84 OBJECT *new_node;
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);
109 return 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)
123 OBJECT *new_obj;
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
132 * options.
134 * The bounding box coordinates are computed with
135 * #o_circle_recalc().
137 /* modify */
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;*/
154 return new_obj;
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>
161 * parameters.
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
170 * parameters.
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:
180 * <DL>
181 * <DT>*</DT><DD>CIRCLE_CENTER
182 * <DT>*</DT><DD>CIRCLE_RADIUS
183 * </DL>
185 void o_circle_modify(TOPLEVEL *toplevel, OBJECT *object,
186 int x, int y, int whichone)
188 switch(whichone) {
189 case CIRCLE_CENTER:
190 /* modify the center of the circle */
191 object->circle->center_x = x;
192 object->circle->center_y = y;
193 break;
194 case CIRCLE_RADIUS:
195 /* modify the radius of the circle */
196 if (x == 0) {
197 s_log_message(_("Null radius circles are not allowed\n"));
198 return;
200 object->circle->radius = x;
201 break;
202 default:
203 break;
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 :
218 * <DL>
219 * <DT>*</DT><DD>the file format used until 2000704 release.
220 * <DT>*</DT><DD>the file format used for the releases after 20000704.
221 * </DL>
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)
232 OBJECT *new_obj;
233 char type;
234 int x1, y1;
235 int radius;
236 int color;
237 int circle_width, circle_space, circle_length;
238 int fill_width, angle1, pitch1, angle2, pitch2;
239 int circle_end;
240 int circle_type;
241 int circle_fill;
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
247 * to default.
249 sscanf(buf, "%c %d %d %d %d\n", &type, &x1, &y1, &radius, &color);
251 circle_width = 0;
252 circle_end = END_NONE;
253 circle_type = TYPE_SOLID;
254 circle_length= -1;
255 circle_space = -1;
257 circle_fill = FILLING_HOLLOW;
258 fill_width = 0;
259 angle1 = -1;
260 pitch1 = -1;
261 angle2 = -1;
262 pitch2 = -1;
264 } else {
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);
279 if (radius == 0) {
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
296 * on the line.
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);
305 return new_obj;
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.
318 * \note
319 * Caller must g_free returned character string.
322 char *o_circle_save(OBJECT *object)
324 int x,y;
325 int radius;
326 int circle_width, circle_space, circle_length;
327 int fill_width, angle1, pitch1, angle2, pitch2;
328 char *buf;
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);
358 return(buf);
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,
400 OBJECT *object)
402 int newx, newy;
403 int x, y;
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,
452 OBJECT *object)
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) {
487 return;
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>
504 * in world units.
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)
516 int halfwidth;
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 */
526 *left -= halfwidth;
527 *top -= halfwidth;
528 *right += halfwidth;
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,
544 OBJECT *object)
546 *x = object->circle->center_x;
547 *y = object->circle->center_y;
548 return TRUE;
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
555 * and fill 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)
577 int x, y, radius;
578 int color;
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");
586 return;
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
603 * set to -1.
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
607 * in such a case.
609 circle_width = o_current->line_width;
610 if(circle_width <=2) {
611 if(toplevel->line_style == THICK) {
612 circle_width=LINE_WIDTH;
613 } else {
614 circle_width=2;
617 length = o_current->line_length;
618 space = o_current->line_space;
620 switch(o_current->line_type) {
621 case(TYPE_SOLID):
622 length = -1; space = -1;
623 outl_func = o_circle_print_solid;
624 break;
626 case(TYPE_DOTTED):
627 length = -1;
628 outl_func = o_circle_print_dotted;
629 break;
631 case(TYPE_DASHED):
632 outl_func = o_circle_print_dashed;
633 break;
635 case(TYPE_CENTER):
636 outl_func = o_circle_print_center;
637 break;
639 case(TYPE_PHANTOM):
640 outl_func = o_circle_print_phantom;
641 break;
643 case(TYPE_ERASE):
644 /* Unused for now print it solid */
645 length = -1; space = -1;
646 outl_func = o_circle_print_solid;
647 break;
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,
657 radius,
658 color,
659 circle_width, length, space,
660 origin_x, origin_y);
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) {
681 case(FILLING_FILL):
682 angle1 = -1; pitch1 = 1;
683 angle2 = -1; pitch2 = 1;
684 fill_width = -1;
685 fill_func = o_circle_print_filled;
686 break;
688 case(FILLING_MESH):
689 fill_func = o_circle_print_mesh;
690 break;
692 case(FILLING_HATCH):
693 angle2 = -1; pitch2 = 1;
694 fill_func = o_circle_print_hatch;
695 break;
697 case(FILLING_VOID):
698 /* Unused for now, print it filled */
699 angle1 = -1; pitch1 = 1;
700 angle2 = -1; pitch2 = 1;
701 fill_width = -1;
702 fill_func = o_circle_print_filled;
703 break;
705 case(FILLING_HOLLOW):
706 /* nop */
707 break;
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,
717 x, y, radius,
718 color,
719 fill_width,
720 angle1, pitch1, angle2, pitch2,
721 origin_x, origin_y);
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
730 * in <B>color</B>.
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,
753 int color,
754 int circle_width, int length, int space,
755 int origin_x, int origin_y)
758 o_arc_print_solid(toplevel, fp,
759 x, y, radius,
760 0, FULL_CIRCLE / 64,
761 color,
762 circle_width, -1, -1,
763 origin_x, origin_y);
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,
796 int color,
797 int circle_width, int length, int space,
798 int origin_x, int origin_y)
801 o_arc_print_dotted(toplevel, fp,
802 x, y, radius,
803 0, FULL_CIRCLE / 64,
804 color,
805 circle_width, -1, space,
806 origin_x, origin_y);
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,
836 int x, int y,
837 int radius,
838 int color,
839 int circle_width, int length, int space,
840 int origin_x, int origin_y)
843 o_arc_print_dashed(toplevel, fp,
844 x, y, radius,
845 0, FULL_CIRCLE / 64,
846 color,
847 circle_width, length, space,
848 origin_x, origin_y);
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,
878 int x, int y,
879 int radius,
880 int color,
881 int circle_width, int length, int space,
882 int origin_x, int origin_y)
885 o_arc_print_center(toplevel, fp,
886 x, y, radius,
887 0, FULL_CIRCLE / 64,
888 color,
889 circle_width, length, space,
890 origin_x, origin_y);
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,
920 int x, int y,
921 int radius,
922 int color,
923 int circle_width, int length, int space,
924 int origin_x, int origin_y)
927 o_arc_print_phantom(toplevel, fp,
928 x, y, radius,
929 0, FULL_CIRCLE / 64,
930 color,
931 circle_width, length, space,
932 origin_x, origin_y);
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,
965 int color,
966 int fill_width,
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,
975 radius);
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,
1011 int color,
1012 int fill_width,
1013 int angle1, int pitch1,
1014 int angle2, int pitch2,
1015 int origin_x, int origin_y)
1017 o_circle_print_hatch(toplevel, fp,
1018 x, y, radius,
1019 color,
1020 fill_width,
1021 angle1, pitch1,
1022 -1, -1,
1023 origin_x, origin_y);
1024 o_circle_print_hatch(toplevel, fp,
1025 x, y, radius,
1026 color,
1027 fill_width,
1028 angle2, pitch2,
1029 -1, -1,
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,
1066 int color,
1067 int fill_width,
1068 int angle1, int pitch1,
1069 int angle2, int pitch2,
1070 int origin_x, int origin_y)
1072 CIRCLE circle;
1073 gint index;
1074 GArray *lines;
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],
1098 fill_width);
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,
1115 int force_solid)
1117 int solid;
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);