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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /*! \file o_line_basic.c
22 * \brief functions for the line object
30 #include "libgeda_priv.h"
32 #ifdef HAVE_LIBDMALLOC
36 /*! \brief Create and add line OBJECT to list.
37 * \par Function Description
38 * This function creates a new object representing a line.
40 * The line is described by its two ends - <B>x1</B>,<B>y1</B> and
41 * <B>x2</B>,<B>y2</B>.
42 * The <B>type</B> parameter must be equal to #OBJ_LINE.
43 * The <B>color</B> parameter corresponds to the color the box
46 * The #OBJECT structure is allocated with the #s_basic_new_object()
47 * function. The structure describing the line is allocated and
48 * initialized with the parameters given to the function.
50 * Both the line type and the filling type are set to default
51 * values : solid line type with a width of 0, and no filling.
52 * It can be changed after with the #o_set_line_options() and
53 * #o_set_fill_options().
55 * \param [in] toplevel The TOPLEVEL object.
56 * \param [in] type Must be OBJ_LINE.
57 * \param [in] color Circle line color.
58 * \param [in] x1 Upper x coordinate.
59 * \param [in] y1 Upper y coordinate.
60 * \param [in] x2 Lower x coordinate.
61 * \param [in] y2 Lower y coordinate.
62 * \return A pointer to the new end of the object list.
64 OBJECT
*o_line_new(TOPLEVEL
*toplevel
,
66 int x1
, int y1
, int x2
, int y2
)
70 /* create the object */
71 new_node
= s_basic_new_object(type
, "line");
72 new_node
->color
= color
;
74 new_node
->line
= (LINE
*) g_malloc(sizeof(LINE
));
76 /* describe the line with its two ends */
77 new_node
->line
->x
[0] = x1
;
78 new_node
->line
->y
[0] = y1
;
79 new_node
->line
->x
[1] = x2
;
80 new_node
->line
->y
[1] = y2
;
82 /* line type and filling initialized to default */
83 o_set_line_options(toplevel
, new_node
,
84 END_NONE
, TYPE_SOLID
, 0, -1, -1);
85 o_set_fill_options(toplevel
, new_node
,
86 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
88 /* compute bounding box */
89 o_line_recalc(toplevel
, new_node
);
94 /*! \brief Create a copy of a line.
95 * \par Function Description
96 * This function creates a verbatim copy of the
97 * object pointed by <B>o_current</B> describing a line.
99 * \param [in] toplevel The TOPLEVEL object.
100 * \param [in] o_current Line OBJECT to copy.
101 * \return The new OBJECT
103 OBJECT
*o_line_copy(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
107 /* A new line object is created with #o_line_new().
108 * Values for its fields are default and need to be modified. */
109 new_obj
= o_line_new (toplevel
, OBJ_LINE
, o_current
->color
,
110 o_current
->line
->x
[0], o_current
->line
->y
[0],
111 o_current
->line
->x
[1], o_current
->line
->y
[1]);
114 * The coordinates of the ends of the new line are set with the ones
115 * of the original line. The two lines have the sale line type and
118 * The bounding box are computed with
122 /* copy the line type and filling options */
123 o_set_line_options(toplevel
, new_obj
, o_current
->line_end
,
124 o_current
->line_type
, o_current
->line_width
,
125 o_current
->line_length
, o_current
->line_space
);
126 o_set_fill_options(toplevel
, new_obj
,
127 o_current
->fill_type
, o_current
->fill_width
,
128 o_current
->fill_pitch1
, o_current
->fill_angle1
,
129 o_current
->fill_pitch2
, o_current
->fill_angle2
);
131 /* calc the bounding box */
132 o_line_recalc(toplevel
, o_current
);
134 /* new_obj->attribute = 0;*/
136 /* return the new tail of the object list */
140 /*! \brief Modify the description of a line OBJECT.
141 * \par Function Description
142 * This function modifies the coordinates of one of the two ends of
143 * the line described by <B>*object</B>. The new coordinates of this end,
144 * identified by <B>whichone</B>, are given by <B>x</B> and <B>y</B>
147 * The coordinates of the end of line is modified in the world
148 * coordinate system. Screen coordinates and boundings are then updated.
150 * \param [in] toplevel The TOPLEVEL object.
151 * \param [in,out] object Line OBJECT to modify.
152 * \param [in] x New x coordinate.
153 * \param [in] y New y coordinate.
154 * \param [in] whichone Which line parameter to modify.
156 * <B>whichone</B> can have the following values:
158 * <DT>*</DT><DD>LINE_END1
159 * <DT>*</DT><DD>LINE_END2
162 void o_line_modify(TOPLEVEL
*toplevel
, OBJECT
*object
,
163 int x
, int y
, int whichone
)
165 o_emit_pre_change_notify (toplevel
, object
);
167 /* change one of the end of the line */
170 object
->line
->x
[0] = x
;
171 object
->line
->y
[0] = y
;
175 object
->line
->x
[1] = x
;
176 object
->line
->y
[1] = y
;
183 /* recalculate the bounding box */
184 o_line_recalc(toplevel
, object
);
185 o_emit_change_notify (toplevel
, object
);
188 /*! \brief Create line OBJECT from character string.
189 * \par Function Description
190 * This function creates a line OBJECT from the character string
191 * <B>*buf</B> the description of a box.
193 * The function returns a pointer on the new last element, that is
194 * the added line object.
196 * Depending on <B>*version</B>, the correct file format is considered.
197 * Currently two file format revisions are supported :
199 * <DT>*</DT><DD>the file format used until 20010704 release.
200 * <DT>*</DT><DD>the file format used for the releases after 20010704.
203 * \param [in] toplevel The TOPLEVEL object.
204 * \param [in] buf Character string with line description.
205 * \param [in] release_ver libgeda release version number.
206 * \param [in] fileformat_ver libgeda file format version number.
207 * \return A pointer to the new line object.
209 OBJECT
*o_line_read (TOPLEVEL
*toplevel
, char buf
[],
210 unsigned int release_ver
, unsigned int fileformat_ver
)
216 int line_width
, line_space
, line_length
;
221 if (release_ver
<= VERSION_20000704
) {
223 * The old geda file format, i.e. releases 20000704 and older, does
224 * not handle the line type and the filling - here filling is irrelevant.
225 * They are set to default.
227 sscanf (buf
, "%c %d %d %d %d %d\n", &type
,
228 &x1
, &y1
, &x2
, &y2
, &color
);
232 line_type
= TYPE_SOLID
;
237 * The current line format to describe a line is a space separated
238 * list of characters and numbers in plain ASCII on a single line.
239 * The meaning of each item is described in the file format documentation.
241 sscanf (buf
, "%c %d %d %d %d %d %d %d %d %d %d\n", &type
,
242 &x1
, &y1
, &x2
, &y2
, &color
,
243 &line_width
, &line_end
, &line_type
, &line_length
, &line_space
);
247 * Null length line are not allowed. If such a line is detected a
250 * It also checks is the required color is valid.
252 if (x1
== x2
&& y1
== y2
) {
253 s_log_message (_("Found a zero length line [ %c %d %d %d %d %d ]\n"),
254 type
, x1
, y1
, x2
, y2
, color
);
257 if (color
< 0 || color
> MAX_COLORS
) {
258 s_log_message (_("Found an invalid color [ %s ]\n"), buf
);
259 s_log_message (_("Setting color to default color\n"));
260 color
= DEFAULT_COLOR
;
264 * A line is internally described by its two ends. A new object is
265 * allocated, initialized and added to the list of objects. Its line
266 * type is set according to the values of the fields on the line.
268 /* create and add the line to the list */
269 new_obj
= o_line_new (toplevel
, type
, color
, x1
, y1
, x2
, y2
);
270 /* set its line options */
271 o_set_line_options (toplevel
, new_obj
,
272 line_end
, line_type
, line_width
, line_length
,
274 /* filling is irrelevant for line, just set to default */
275 o_set_fill_options (toplevel
, new_obj
,
276 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
281 /*! \brief Create a character string representation of a line OBJECT.
282 * \par Function Description
283 * The function formats a string in the buffer <B>*buff</B> to describe
284 * the box object <B>*object</B>.
285 * It follows the post-20000704 release file format that handle the
286 * line type and fill options - filling is irrelevant here.
288 * \param [in] toplevel a TOPLEVEL structure.
289 * \param [in] object Line OBJECT to create string from.
290 * \return A pointer to the line OBJECT character string.
293 * Caller must g_free returned character string.
296 char *o_line_save(TOPLEVEL
*toplevel
, OBJECT
*object
)
299 int line_width
, line_space
, line_length
;
302 OBJECT_TYPE line_type
;
304 /* get the two ends */
305 x1
= object
->line
->x
[0];
306 y1
= object
->line
->y
[0];
307 x2
= object
->line
->x
[1];
308 y2
= object
->line
->y
[1];
310 /* description of the line type */
311 line_width
= object
->line_width
;
312 line_end
= object
->line_end
;
313 line_type
= object
->line_type
;
314 line_length
= object
->line_length
;
315 line_space
= object
->line_space
;
317 buf
= g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d", object
->type
,
318 x1
, y1
, x2
, y2
, object
->color
,
319 line_width
, line_end
, line_type
,
320 line_length
, line_space
);
325 /*! \brief Translate a line position in WORLD coordinates by a delta.
326 * \par Function Description
327 * This function applies a translation of (<B>x1</B>,<B>y1</B>) to the line
328 * described by <B>*object</B>. <B>x1</B> and <B>y1</B> are in world unit.
330 * \param [in] toplevel The TOPLEVEL object.
331 * \param [in] dx x distance to move.
332 * \param [in] dy y distance to move.
333 * \param [in,out] object Line OBJECT to translate.
335 void o_line_translate_world(TOPLEVEL
*toplevel
,
336 int dx
, int dy
, OBJECT
*object
)
338 if (object
== NULL
) printf("ltw NO!\n");
340 /* Update world coords */
341 object
->line
->x
[0] = object
->line
->x
[0] + dx
;
342 object
->line
->y
[0] = object
->line
->y
[0] + dy
;
343 object
->line
->x
[1] = object
->line
->x
[1] + dx
;
344 object
->line
->y
[1] = object
->line
->y
[1] + dy
;
346 /* Update bounding box */
347 o_line_recalc (toplevel
, object
);
350 /*! \brief Rotate Line OBJECT using WORLD coordinates.
351 * \par Function Description
352 * This function rotates the line described by
353 * <B>*object</B> around the (<B>world_centerx</B>,<B>world_centery</B>)
354 * point by <B>angle</B> degrees.
355 * The center of rotation is in world units.
357 * \param [in] toplevel The TOPLEVEL object.
358 * \param [in] world_centerx Rotation center x coordinate in WORLD units.
359 * \param [in] world_centery Rotation center y coordinate in WORLD units.
360 * \param [in] angle Rotation angle in degrees (See note below).
361 * \param [in,out] object Line OBJECT to rotate.
363 void o_line_rotate_world(TOPLEVEL
*toplevel
,
364 int world_centerx
, int world_centery
, int angle
,
372 /* angle must be positive */
373 if(angle
< 0) angle
= -angle
;
374 /* angle must be 90 multiple or no rotation performed */
375 if((angle
% 90) != 0) return;
378 * The center of rotation (<B>world_centerx</B>,<B>world_centery</B>)
379 * is translated to the origin. The rotation of the two ends of
380 * the line is performed. FInally, the rotated line is translated
381 * back to its previous location.
383 /* translate object to origin */
384 o_line_translate_world(toplevel
, -world_centerx
, -world_centery
, object
);
386 /* rotate line end 1 */
387 rotate_point_90(object
->line
->x
[0], object
->line
->y
[0], angle
,
390 object
->line
->x
[0] = newx
;
391 object
->line
->y
[0] = newy
;
393 /* rotate line end 2 */
394 rotate_point_90(object
->line
->x
[1], object
->line
->y
[1], angle
,
397 object
->line
->x
[1] = newx
;
398 object
->line
->y
[1] = newy
;
400 /* translate object back to normal position */
401 o_line_translate_world(toplevel
, world_centerx
, world_centery
, object
);
405 /*! \brief Mirror a line using WORLD coordinates.
406 * \par Function Description
407 * This function mirrors the line from the point
408 * (<B>world_centerx</B>,<B>world_centery</B>) in world unit.
410 * The line if first translated to the origin, then mirrored
411 * and finally translated back at its previous position.
413 * \param [in] toplevel The TOPLEVEL object.
414 * \param [in] world_centerx Origin x coordinate in WORLD units.
415 * \param [in] world_centery Origin y coordinate in WORLD units.
416 * \param [in,out] object Line OBJECT to mirror.
418 void o_line_mirror_world(TOPLEVEL
*toplevel
, int world_centerx
,
419 int world_centery
, OBJECT
*object
)
421 /* translate object to origin */
422 o_line_translate_world(toplevel
, -world_centerx
, -world_centery
, object
);
424 /* mirror the line ends */
425 object
->line
->x
[0] = -object
->line
->x
[0];
426 object
->line
->x
[1] = -object
->line
->x
[1];
428 /* translate back in position */
429 o_line_translate_world(toplevel
, world_centerx
, world_centery
, object
);
433 /*! \brief Recalculate line coordinates in SCREEN units.
434 * \par Function Description
435 * This function recalculate the bounding box of the <B>o_current</B>
437 * \param [in] toplevel The TOPLEVEL object.
438 * \param [in,out] o_current Line OBJECT to be recalculated.
440 void o_line_recalc(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
442 int left
, right
, top
, bottom
;
444 if (o_current
->line
== NULL
) {
448 /* update the bounding box - screen unit */
449 world_get_line_bounds(toplevel
, o_current
,
450 &left
, &top
, &right
, &bottom
);
451 o_current
->w_left
= left
;
452 o_current
->w_top
= top
;
453 o_current
->w_right
= right
;
454 o_current
->w_bottom
= bottom
;
455 o_current
->w_bounds_valid
= TRUE
;
458 /*! \brief Get line bounding rectangle in WORLD coordinates.
459 * \par Function Description
460 * This function sets the <B>left</B>, <B>top</B>, <B>right</B> and
461 * <B>bottom</B> parameters to the boundings of the line object described
462 * in <B>*line</B> in world units.
464 * \param [in] toplevel The TOPLEVEL object.
465 * \param [in] object Line OBJECT to read coordinates from.
466 * \param [out] left Left line coordinate in WORLD units.
467 * \param [out] top Top line coordinate in WORLD units.
468 * \param [out] right Right line coordinate in WORLD units.
469 * \param [out] bottom Bottom line coordinate in WORLD units.
471 void world_get_line_bounds(TOPLEVEL
*toplevel
, OBJECT
*object
,
472 int *left
, int *top
, int *right
, int *bottom
)
476 halfwidth
= object
->line_width
/ 2;
478 *left
= min( object
->line
->x
[0], object
->line
->x
[1] );
479 *top
= min( object
->line
->y
[0], object
->line
->y
[1] );
480 *right
= max( object
->line
->x
[0], object
->line
->x
[1] );
481 *bottom
= max( object
->line
->y
[0], object
->line
->y
[1] );
483 /* This isn't strictly correct, but a 1st order approximation */
487 *bottom
+= halfwidth
;
490 /*! \brief get the position of the first line point
491 * \par Function Description
492 * This function gets the position of the first point of a line object.
494 * \param [in] toplevel The toplevel environment.
495 * \param [out] x pointer to the x-position
496 * \param [out] y pointer to the y-position
497 * \param [in] object The object to get the position.
498 * \return TRUE if successfully determined the position, FALSE otherwise
500 gboolean
o_line_get_position (TOPLEVEL
*toplevel
, gint
*x
, gint
*y
,
503 *x
= object
->line
->x
[0];
504 *y
= object
->line
->y
[0];
509 /*! \brief Print line to Postscript document.
510 * \par Function Description
511 * This function prints the line described by the <B>o_current</B>
512 * parameter to a Postscript document.
513 * The Postscript document is described by the <B>fp</B> file pointer.
515 * Parameters of the line are extracted from object pointed by
518 * \param [in] toplevel The TOPLEVEL object.
519 * \param [in] fp FILE pointer to Postscript document.
520 * \param [in] o_current Line OBJECT to write to document.
521 * \param [in] origin_x Page x coordinate to place line OBJECT.
522 * \param [in] origin_y Page y coordinate to place line OBJECT.
524 void o_line_print(TOPLEVEL
*toplevel
, FILE *fp
, OBJECT
*o_current
,
525 int origin_x
, int origin_y
)
529 int line_width
, length
, space
;
530 void (*outl_func
)() = NULL
;
532 if (o_current
== NULL
) {
533 printf("got null in o_line_print\n");
537 x1
= o_current
->line
->x
[0];
538 y1
= o_current
->line
->y
[0];
539 x2
= o_current
->line
->x
[1];
540 y2
= o_current
->line
->y
[1];
541 color
= o_current
->color
;
544 * Depending on the type of the line for this particular line, the
545 * appropriate function is chosen among
546 * #o_line_print_solid(), #o_line_print_dotted()#, #o_line_print_dashed(),
547 * #o_line_print_center() and #o_line_print_phantom().
549 * The needed parameters for each of these types are extracted from the
550 * <B>o_current</B> object. Depending on the type, unused parameters are
553 * In the eventuality of a length and/or space null, the line is printed
554 * solid to avoid and endless loop produced by other functions.
556 line_width
= o_current
->line_width
;
558 if(toplevel
->line_style
== THICK
) {
559 line_width
=LINE_WIDTH
;
565 length
= o_current
->line_length
;
566 space
= o_current
->line_space
;
568 switch(o_current
->line_type
) {
570 length
= -1; space
= -1;
571 outl_func
= o_line_print_solid
;
576 outl_func
= o_line_print_dotted
;
580 outl_func
= o_line_print_dashed
;
584 outl_func
= o_line_print_center
;
588 outl_func
= o_line_print_phantom
;
592 /* Unused for now, print it solid */
593 length
= -1; space
= -1;
594 outl_func
= o_line_print_solid
;
598 if((length
== 0) || (space
== 0)) {
599 length
= -1; space
= -1;
600 outl_func
= o_line_print_solid
;
603 (*outl_func
)(toplevel
, fp
,
604 x1
- origin_x
, y1
- origin_y
,
605 x2
- origin_x
, y2
- origin_y
,
607 line_width
, length
, space
,
611 /*! \brief Print a solid line to Postscript document.
612 * \par Function Description
613 * This function prints a line when a solid line type is required.
614 * The line is defined by the coordinates of its two ends in
615 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
616 * The Postscript document is defined by the file pointer <B>fp</B>.
617 * The parameters <B>length</B> and <B>space</B> are ignored whereas
618 * <B>line_width</B> specifies the width of the printed line.
620 * \param [in] toplevel The TOPLEVEL object.
621 * \param [in] fp FILE pointer to Postscript document.
622 * \param [in] x1 Upper x coordinate.
623 * \param [in] y1 Upper y coordinate.
624 * \param [in] x2 Lower x coordinate.
625 * \param [in] y2 Lower y coordinate.
626 * \param [in] color Line color.
627 * \param [in] line_width Width of line.
628 * \param [in] length (unused).
629 * \param [in] space (unused).
630 * \param [in] origin_x Page x coordinate to place line OBJECT.
631 * \param [in] origin_y Page y coordinate to place line OBJECT.
633 void o_line_print_solid(TOPLEVEL
*toplevel
, FILE *fp
,
634 int x1
, int y1
, int x2
, int y2
,
636 int line_width
, int length
, int space
,
637 int origin_x
, int origin_y
)
639 f_print_set_color(toplevel
, fp
, color
);
641 fprintf(fp
,"%d %d %d %d %d line\n",
642 x1
,y1
,x2
,y2
, line_width
);
645 /*! \brief Print a dotted line to Postscript document.
646 * \par Function Description
647 * This function prints a line when a dotted line type is required.
648 * The line is defined by the coordinates of its two ends in
649 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
650 * The Postscript document is defined by the file pointer <B>fp</B>.
651 * The parameter <B>length</B> is ignored whereas <B>line_width</B>
652 * specifies the diameter of the dots and <B>space</B> the distance
655 * A negative value for <B>space</B> leads to an endless loop.
657 * All dimensions are in mils.
659 * The function sets the color in which the line will be printed with.
661 * \param [in] toplevel The TOPLEVEL object.
662 * \param [in] fp FILE pointer to Postscript document.
663 * \param [in] x1 Upper x coordinate.
664 * \param [in] y1 Upper y coordinate.
665 * \param [in] x2 Lower x coordinate.
666 * \param [in] y2 Lower y coordinate.
667 * \param [in] color Line color.
668 * \param [in] line_width Width of line.
669 * \param [in] length (unused).
670 * \param [in] space Space between dots.
671 * \param [in] origin_x Page x coordinate to place line OBJECT.
672 * \param [in] origin_y Page y coordinate to place line OBJECT.
674 void o_line_print_dotted(TOPLEVEL
*toplevel
, FILE *fp
,
675 int x1
, int y1
, int x2
, int y2
,
677 int line_width
, int length
, int space
,
678 int origin_x
, int origin_y
)
684 f_print_set_color(toplevel
, fp
, color
);
686 /* The dotted line command takes an array of dots so print out the
687 * beginnings of the array
690 /* is the width relevant for a dot (circle) ? */
691 /* f_print_set_line_width(fp, line_width); */
694 * Depending on the slope of the line the space parameter is
695 * projected on each of the two directions x and y resulting
696 * in <B>dx1</B> and <B>dy1</B>. Starting from one end by increments
697 * of space the dots are printed.
699 * A dot is represented by a filled circle. Position of the
700 * circle is (<B>xa</B>, <B>ya</B>) and its radius is the <B>line_width</B>
704 dx
= (double) (x2
- x1
);
705 dy
= (double) (y2
- y1
);
706 l
= sqrt((dx
* dx
) + (dy
* dy
));
708 dx1
= (dx
* space
) / l
;
709 dy1
= (dy
* space
) / l
;
715 fprintf(fp
,"[%d %d] ",
722 fprintf(fp
,"] %d dashed\n",line_width
);
727 /*! \brief Print a dashed line to Postscript document.
728 * \par Function Description
729 * This function prints a line when a dashed line type is required.
730 * The line is defined by the coordinates of its two ends in
731 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
732 * The postscript file is defined by the file pointer <B>fp</B>.
734 * A negative value for <B>space</B> or <B>length</B> leads to an
737 * All dimensions are in mils.
739 * The function sets the color in which the line will be printed and
740 * the width of the line - that is the width of the dashes.
742 * \param [in] toplevel The TOPLEVEL object.
743 * \param [in] fp FILE pointer to Postscript document.
744 * \param [in] x1 Upper x coordinate.
745 * \param [in] y1 Upper y coordinate.
746 * \param [in] x2 Lower x coordinate.
747 * \param [in] y2 Lower y coordinate.
748 * \param [in] color Line color.
749 * \param [in] line_width Width of line.
750 * \param [in] length Length of a dash.
751 * \param [in] space Space between dashes.
752 * \param [in] origin_x Page x coordinate to place line OBJECT.
753 * \param [in] origin_y Page y coordinate to place line OBJECT.
755 void o_line_print_dashed(TOPLEVEL
*toplevel
, FILE *fp
,
756 int x1
, int y1
, int x2
, int y2
,
758 int line_width
, int length
, int space
,
759 int origin_x
, int origin_y
)
762 double dx1
, dy1
, dx2
, dy2
;
763 double xa
, ya
, xb
, yb
;
765 f_print_set_color(toplevel
, fp
, color
);
767 /* the dashed line function takes an array of start-finish pairs
768 * output the beginnings of the array now
773 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
774 * parameter is projected on each of the two directions x and y
775 * resulting in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
776 * Starting from one end and incrementing alternatively by <B>space</B>
777 * and <B>length</B> the dashes are printed.
779 * It prints as many dashes of length <B>length</B> as possible.
781 dx
= (double) (x2
- x1
);
782 dy
= (double) (y2
- y1
);
783 l
= sqrt((dx
* dx
) + (dy
* dy
));
785 dx1
= (dx
* length
) / l
;
786 dy1
= (dy
* length
) / l
;
788 dx2
= (dx
* space
) / l
;
789 dy2
= (dy
* space
) / l
;
793 while((d
+ length
+ space
) < l
) {
798 fprintf(fp
, "[%d %d %d %d] ",
807 * When the above condition is no more satisfied, then it is not possible
808 * to print a dash of length <B>length</B>. However it may be possible to
809 * print the complete dash or a shorter one.
812 if((d
+ length
) < l
) {
821 fprintf(fp
, "[%d %d %d %d] ",
825 fprintf(fp
,"] %d dashed\n", line_width
);
829 /*! \brief Print a centered line type line to Postscript document.
830 * \par Function Description
831 * This function prints a line when a centered line type is required.
832 * The line is defined by the coordinates of its two ends in
833 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
834 * The Postscript document is defined by the file pointer <B>fp</B>.
836 * A negative value for <B>space</B> or <B>length</B> leads to an
839 * All dimensions are in mils.
841 * The function sets the color in which the line will be printed and the
842 * width of the line - that is the width of the dashes and the diameter
845 * \param [in] toplevel The TOPLEVEL object.
846 * \param [in] fp FILE pointer to Postscript document.
847 * \param [in] x1 Upper x coordinate.
848 * \param [in] y1 Upper y coordinate.
849 * \param [in] x2 Lower x coordinate.
850 * \param [in] y2 Lower y coordinate.
851 * \param [in] color Line color.
852 * \param [in] line_width Width of line.
853 * \param [in] length Length of a dash.
854 * \param [in] space Space between dashes.
855 * \param [in] origin_x Page x coordinate to place line OBJECT.
856 * \param [in] origin_y Page y coordinate to place line OBJECT.
858 void o_line_print_center(TOPLEVEL
*toplevel
, FILE *fp
,
859 int x1
, int y1
, int x2
, int y2
,
861 int line_width
, int length
, int space
,
862 int origin_x
, int origin_y
)
865 double dx1
, dy1
, dx2
, dy2
;
866 double xa
, ya
, xb
, yb
;
868 f_print_set_color(toplevel
, fp
, color
);
873 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
874 * parameter is projected on each of the two directions x and y resulting
875 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
876 * Starting from one end and incrementing alternatively by <B>space</B>
877 * and <B>length</B> the dashes and dots are printed.
879 * It prints as many sets of dash and dot as possible.
881 dx
= (double) (x2
- x1
);
882 dy
= (double) (y2
- y1
);
883 l
= sqrt((dx
* dx
) + (dy
* dy
));
885 dx1
= (dx
* length
) / l
;
886 dy1
= (dy
* length
) / l
;
888 dx2
= (dx
* space
) / l
;
889 dy2
= (dy
* space
) / l
;
893 while((d
+ length
+ 2 * space
) < l
) {
898 fprintf(fp
, "[%d %d %d %d] ",
906 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
913 * When the above condition is no more satisfied, then it is not possible
914 * to print a dash of length <B>length</B>.
915 * However two cases are possible :
917 * <DT>*</DT><DD>it is possible to print the dash and the dot.
918 * <DT>*</DT><DD>it is possible to print the dash or a part
919 * of the original dash.
923 if((d
+ length
+ space
) < l
) {
928 fprintf(fp
, "[%d %d %d %d] ",
936 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
947 fprintf(fp
, "[%d %d %d %d] ",
953 fprintf(fp
,"] %d dashed\n", line_width
);
956 * A dot is represented by a filled circle. Position of the circle is
957 * (<B>xa</B>, <B>ya</B>) and its radius by the <B>line_width</B> parameter.
961 /*! \brief Print a phantom line type line to Postscript document.
962 * \par Function Description
963 * This function prints a line when a phantom line type is required.
964 * The line is defined by the coordinates of its two ends in
965 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
966 * The Postscript document is defined by the file pointer <B>fp</B>.
968 * A negative value for <B>space</B> or <B>length</B> leads to an
971 * All dimensions are in mils.
973 * The function sets the color in which the line will be printed and the
974 * width of the line - that is the width of the dashes and the diameter
977 * \param [in] toplevel The TOPLEVEL object.
978 * \param [in] fp FILE pointer to Postscript document.
979 * \param [in] x1 Upper x coordinate.
980 * \param [in] y1 Upper y coordinate.
981 * \param [in] x2 Lower x coordinate.
982 * \param [in] y2 Lower y coordinate.
983 * \param [in] color Line color.
984 * \param [in] line_width Width of line.
985 * \param [in] length Length of a dash.
986 * \param [in] space Space between dashes.
987 * \param [in] origin_x Page x coordinate to place line OBJECT.
988 * \param [in] origin_y Page y coordinate to place line OBJECT.
990 void o_line_print_phantom(TOPLEVEL
*toplevel
, FILE *fp
,
991 int x1
, int y1
, int x2
, int y2
,
993 int line_width
, int length
, int space
,
994 int origin_x
, int origin_y
)
997 double dx1
, dy1
, dx2
, dy2
;
998 double xa
, ya
, xb
, yb
;
1000 f_print_set_color(toplevel
, fp
, color
);
1005 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
1006 * parameter is projected on each of the two directions x and y resulting
1007 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
1008 * Starting from one end and incrementing alternatively by <B>space</B>
1009 * and <B>length</B> the dashes and dots are printed.
1011 * It prints as many sets of dash-dot-dot as possible.
1013 dx
= (double) (x2
- x1
);
1014 dy
= (double) (y2
- y1
);
1015 l
= sqrt((dx
* dx
) + (dy
* dy
));
1017 dx1
= (dx
* length
) / l
;
1018 dy1
= (dy
* length
) / l
;
1020 dx2
= (dx
* space
) / l
;
1021 dy2
= (dy
* space
) / l
;
1025 while((d
+ length
+ 3 * space
) < l
) {
1030 fprintf(fp
,"[%d %d %d %d] ",
1038 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1044 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1051 * When the above condition is no more satisfied, then it is not possible
1052 * to print a complete set of dash-dot-dot.
1053 * However three cases are possible :
1055 * <DT>*</DT><DD>it is possible to print a dash and a dot and a dot.
1056 * <DT>*</DT><DD>it is possible to print a dash and a dot.
1057 * <DT>*</DT><DD>it is possible to print the dash or a part
1058 * of the original dash.
1062 if((d
+ length
+ 2 * space
) < l
) {
1067 fprintf(fp
,"[%d %d %d %d] ",
1075 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1081 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1084 if(d
+ length
+ space
< l
) {
1089 fprintf(fp
,"[%d %d %d %d] ",
1097 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1100 if(d
+ length
< l
) {
1108 fprintf(fp
,"[%d %d %d %d] ",
1115 fprintf(fp
,"] %d dashed\n", line_width
);
1120 * \par Function Description
1122 * \param [in] toplevel The TOPLEVEL object.
1123 * \param [in] x_scale
1124 * \param [in] y_scale
1125 * \param [in] object
1127 void o_line_scale_world(TOPLEVEL
*toplevel
, int x_scale
, int y_scale
,
1130 if (object
== NULL
) printf("lsw NO!\n");
1132 /* scale the line world coords */
1133 object
->line
->x
[0] = object
->line
->x
[0] * x_scale
;
1134 object
->line
->y
[0] = object
->line
->y
[0] * y_scale
;
1135 object
->line
->x
[1] = object
->line
->x
[1] * x_scale
;
1136 object
->line
->y
[1] = object
->line
->y
[1] * y_scale
;
1138 /* update boundingbox */
1139 o_line_recalc(toplevel
, object
);
1144 /*! \brief calculate the lenght of a line object
1145 * \par Function Description
1146 * This function calculates the length of a line object
1148 * \param [in] object a line OBJECT
1149 * \return The length of the line
1151 double o_line_length(OBJECT
*object
)
1156 if (!object
->line
) {
1160 dx
= object
->line
->x
[0]-object
->line
->x
[1];
1161 dy
= object
->line
->y
[0]-object
->line
->y
[1];
1163 length
= sqrt((dx
*dx
) + (dy
*dy
));
1168 /*! \brief Calculates the distance between the given point and the closest
1169 * point on the given line segment.
1171 * If the closest point on the line resides beyond the line segment's
1172 * end point, this function returns the distance from the given point to the
1173 * closest end point.
1175 * If the line represents a single point (the endpoints are the same), this
1176 * function calcualtes the distance to that point.
1178 * \param [in] object The line OBJECT.
1179 * \param [in] x The x coordinate of the given point.
1180 * \param [in] y The y coordinate of the given point.
1181 * \param [in] force_solid If true, force treating the object as solid.
1182 * \return The shortest distance from the object to the point. With an
1183 * invalid parameter, this function returns G_MAXDOUBLE.
1185 double o_line_shortest_distance (OBJECT
*object
, int x
, int y
, int force_solid
)
1187 return m_line_shortest_distance (object
->line
, x
, y
);