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_line_basic.c
22 * \brief functions for the line object
30 #include "libgeda_priv.h"
32 #ifdef HAVE_LIBDMALLOC
36 /*! Default setting for line draw function. */
37 void (*line_draw_func
)() = NULL
;
39 /*! \brief Create and add line OBJECT to list.
40 * \par Function Description
41 * This function creates a new object representing a line.
43 * The line is described by its two ends - <B>x1</B>,<B>y1</B> and
44 * <B>x2</B>,<B>y2</B>.
45 * The <B>type</B> parameter must be equal to #OBJ_LINE.
46 * The <B>color</B> parameter corresponds to the color the box
49 * The #OBJECT structure is allocated with the #s_basic_new_object()
50 * function. The structure describing the line is allocated and
51 * initialized with the parameters given to the function.
53 * Both the line type and the filling type are set to default
54 * values : solid line type with a width of 0, and no filling.
55 * It can be changed after with the #o_set_line_options() and
56 * #o_set_fill_options().
58 * \param [in] toplevel The TOPLEVEL object.
59 * \param [in] type Must be OBJ_LINE.
60 * \param [in] color Circle line color.
61 * \param [in] x1 Upper x coordinate.
62 * \param [in] y1 Upper y coordinate.
63 * \param [in] x2 Lower x coordinate.
64 * \param [in] y2 Lower y coordinate.
65 * \return A pointer to the new end of the object list.
67 OBJECT
*o_line_new(TOPLEVEL
*toplevel
,
69 int x1
, int y1
, int x2
, int y2
)
73 /* create the object */
74 new_node
= s_basic_new_object(type
, "line");
75 new_node
->color
= color
;
77 new_node
->line
= (LINE
*) g_malloc(sizeof(LINE
));
79 /* describe the line with its two ends */
80 new_node
->line
->x
[0] = x1
;
81 new_node
->line
->y
[0] = y1
;
82 new_node
->line
->x
[1] = x2
;
83 new_node
->line
->y
[1] = y2
;
85 /* line type and filling initialized to default */
86 o_set_line_options(toplevel
, new_node
,
87 END_NONE
, TYPE_SOLID
, 0, -1, -1);
88 o_set_fill_options(toplevel
, new_node
,
89 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
91 new_node
->draw_func
= line_draw_func
;
92 new_node
->sel_func
= select_func
;
94 /* compute bounding box */
95 o_line_recalc(toplevel
, new_node
);
100 /*! \brief Create a copy of a line.
101 * \par Function Description
102 * This function creates a verbatim copy of the
103 * object pointed by <B>o_current</B> describing a line.
105 * \param [in] toplevel The TOPLEVEL object.
106 * \param [in] o_current Line OBJECT to copy.
107 * \return The new OBJECT
109 OBJECT
*o_line_copy(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
113 /* A new line object is created with #o_line_new().
114 * Values for its fields are default and need to be modified. */
115 new_obj
= o_line_new (toplevel
, OBJ_LINE
, o_current
->color
,
116 o_current
->line
->x
[0], o_current
->line
->y
[0],
117 o_current
->line
->x
[1], o_current
->line
->y
[1]);
120 * The coordinates of the ends of the new line are set with the ones
121 * of the original line. The two lines have the sale line type and
124 * The bounding box are computed with
128 /* copy the line type and filling options */
129 o_set_line_options(toplevel
, new_obj
, o_current
->line_end
,
130 o_current
->line_type
, o_current
->line_width
,
131 o_current
->line_length
, o_current
->line_space
);
132 o_set_fill_options(toplevel
, new_obj
,
133 o_current
->fill_type
, o_current
->fill_width
,
134 o_current
->fill_pitch1
, o_current
->fill_angle1
,
135 o_current
->fill_pitch2
, o_current
->fill_angle2
);
137 /* calc the bounding box */
138 o_line_recalc(toplevel
, o_current
);
140 /* new_obj->attribute = 0;*/
142 /* return the new tail of the object list */
146 /*! \brief Modify the description of a line OBJECT.
147 * \par Function Description
148 * This function modifies the coordinates of one of the two ends of
149 * the line described by <B>*object</B>. The new coordinates of this end,
150 * identified by <B>whichone</B>, are given by <B>x</B> and <B>y</B>
153 * The coordinates of the end of line is modified in the world
154 * coordinate system. Screen coordinates and boundings are then updated.
156 * \param [in] toplevel The TOPLEVEL object.
157 * \param [in,out] object Line OBJECT to modify.
158 * \param [in] x New x coordinate.
159 * \param [in] y New y coordinate.
160 * \param [in] whichone Which line parameter to modify.
162 * <B>whichone</B> can have the following values:
164 * <DT>*</DT><DD>LINE_END1
165 * <DT>*</DT><DD>LINE_END2
168 void o_line_modify(TOPLEVEL
*toplevel
, OBJECT
*object
,
169 int x
, int y
, int whichone
)
171 /* change one of the end of the line */
174 object
->line
->x
[0] = x
;
175 object
->line
->y
[0] = y
;
179 object
->line
->x
[1] = x
;
180 object
->line
->y
[1] = y
;
187 /* recalculate the bounding box */
188 o_line_recalc(toplevel
, object
);
192 /*! \brief Create line OBJECT from character string.
193 * \par Function Description
194 * This function creates a line OBJECT from the character string
195 * <B>*buf</B> the description of a box.
197 * The function returns a pointer on the new last element, that is
198 * the added line object.
200 * Depending on <B>*version</B>, the correct file format is considered.
201 * Currently two file format revisions are supported :
203 * <DT>*</DT><DD>the file format used until 20010704 release.
204 * <DT>*</DT><DD>the file format used for the releases after 20010704.
207 * \param [in] toplevel The TOPLEVEL object.
208 * \param [in] buf Character string with line description.
209 * \param [in] release_ver libgeda release version number.
210 * \param [in] fileformat_ver libgeda file format version number.
211 * \return A pointer to the new line object.
213 OBJECT
*o_line_read (TOPLEVEL
*toplevel
, char buf
[],
214 unsigned int release_ver
, unsigned int fileformat_ver
)
220 int line_width
, line_space
, line_length
;
225 if (release_ver
<= VERSION_20000704
) {
227 * The old geda file format, i.e. releases 20000704 and older, does
228 * not handle the line type and the filling - here filling is irrelevant.
229 * They are set to default.
231 sscanf (buf
, "%c %d %d %d %d %d\n", &type
,
232 &x1
, &y1
, &x2
, &y2
, &color
);
236 line_type
= TYPE_SOLID
;
241 * The current line format to describe a line is a space separated
242 * list of characters and numbers in plain ASCII on a single line.
243 * The meaning of each item is described in the file format documentation.
245 sscanf (buf
, "%c %d %d %d %d %d %d %d %d %d %d\n", &type
,
246 &x1
, &y1
, &x2
, &y2
, &color
,
247 &line_width
, &line_end
, &line_type
, &line_length
, &line_space
);
251 * Null length line are not allowed. If such a line is detected a
254 * It also checks is the required color is valid.
256 if (x1
== x2
&& y1
== y2
) {
257 s_log_message (_("Found a zero length line [ %c %d %d %d %d %d ]\n"),
258 type
, x1
, y1
, x2
, y2
, color
);
261 if (color
< 0 || color
> MAX_COLORS
) {
262 s_log_message (_("Found an invalid color [ %s ]\n"), buf
);
263 s_log_message (_("Setting color to default color\n"));
264 color
= DEFAULT_COLOR
;
268 * A line is internally described by its two ends. A new object is
269 * allocated, initialized and added to the list of objects. Its line
270 * type is set according to the values of the fields on the line.
272 /* create and add the line to the list */
273 new_obj
= o_line_new (toplevel
, type
, color
, x1
, y1
, x2
, y2
);
274 /* set its line options */
275 o_set_line_options (toplevel
, new_obj
,
276 line_end
, line_type
, line_width
, line_length
,
278 /* filling is irrelevant for line, just set to default */
279 o_set_fill_options (toplevel
, new_obj
,
280 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
285 /*! \brief Create a character string representation of a line OBJECT.
286 * \par Function Description
287 * The function formats a string in the buffer <B>*buff</B> to describe
288 * the box object <B>*object</B>.
289 * It follows the post-20000704 release file format that handle the
290 * line type and fill options - filling is irrelevant here.
292 * \param [in] object Line OBJECT to create string from.
293 * \return A pointer to the line OBJECT character string.
296 * Caller must g_free returned character string.
299 char *o_line_save(OBJECT
*object
)
302 int line_width
, line_space
, line_length
;
305 OBJECT_TYPE line_type
;
307 /* get the two ends */
308 x1
= object
->line
->x
[0];
309 y1
= object
->line
->y
[0];
310 x2
= object
->line
->x
[1];
311 y2
= object
->line
->y
[1];
313 /* description of the line type */
314 line_width
= object
->line_width
;
315 line_end
= object
->line_end
;
316 line_type
= object
->line_type
;
317 line_length
= object
->line_length
;
318 line_space
= object
->line_space
;
320 buf
= g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d", object
->type
,
321 x1
, y1
, x2
, y2
, object
->color
,
322 line_width
, line_end
, line_type
,
323 line_length
, line_space
);
328 /*! \brief Translate a line position in WORLD coordinates by a delta.
329 * \par Function Description
330 * This function applies a translation of (<B>x1</B>,<B>y1</B>) to the line
331 * described by <B>*object</B>. <B>x1</B> and <B>y1</B> are in world unit.
333 * \param [in] toplevel The TOPLEVEL object.
334 * \param [in] dx x distance to move.
335 * \param [in] dy y distance to move.
336 * \param [in,out] object Line OBJECT to translate.
338 void o_line_translate_world(TOPLEVEL
*toplevel
,
339 int dx
, int dy
, OBJECT
*object
)
341 if (object
== NULL
) printf("ltw NO!\n");
343 /* Update world coords */
344 object
->line
->x
[0] = object
->line
->x
[0] + dx
;
345 object
->line
->y
[0] = object
->line
->y
[0] + dy
;
346 object
->line
->x
[1] = object
->line
->x
[1] + dx
;
347 object
->line
->y
[1] = object
->line
->y
[1] + dy
;
349 /* Update bounding box */
350 o_line_recalc (toplevel
, object
);
353 /*! \brief Rotate Line OBJECT using WORLD coordinates.
354 * \par Function Description
355 * This function rotates the line described by
356 * <B>*object</B> around the (<B>world_centerx</B>,<B>world_centery</B>)
357 * point by <B>angle</B> degrees.
358 * The center of rotation is in world units.
360 * \param [in] toplevel The TOPLEVEL object.
361 * \param [in] world_centerx Rotation center x coordinate in WORLD units.
362 * \param [in] world_centery Rotation center y coordinate in WORLD units.
363 * \param [in] angle Rotation angle in degrees (See note below).
364 * \param [in,out] object Line OBJECT to rotate.
366 void o_line_rotate_world(TOPLEVEL
*toplevel
,
367 int world_centerx
, int world_centery
, int angle
,
375 /* angle must be positive */
376 if(angle
< 0) angle
= -angle
;
377 /* angle must be 90 multiple or no rotation performed */
378 if((angle
% 90) != 0) return;
381 * The center of rotation (<B>world_centerx</B>,<B>world_centery</B>)
382 * is translated to the origin. The rotation of the two ends of
383 * the line is performed. FInally, the rotated line is translated
384 * back to its previous location.
386 /* translate object to origin */
387 o_line_translate_world(toplevel
, -world_centerx
, -world_centery
, object
);
389 /* rotate line end 1 */
390 rotate_point_90(object
->line
->x
[0], object
->line
->y
[0], angle
,
393 object
->line
->x
[0] = newx
;
394 object
->line
->y
[0] = newy
;
396 /* rotate line end 2 */
397 rotate_point_90(object
->line
->x
[1], object
->line
->y
[1], angle
,
400 object
->line
->x
[1] = newx
;
401 object
->line
->y
[1] = newy
;
403 /* translate object back to normal position */
404 o_line_translate_world(toplevel
, world_centerx
, world_centery
, object
);
408 /*! \brief Mirror a line using WORLD coordinates.
409 * \par Function Description
410 * This function mirrors the line from the point
411 * (<B>world_centerx</B>,<B>world_centery</B>) in world unit.
413 * The line if first translated to the origin, then mirrored
414 * and finally translated back at its previous position.
416 * \param [in] toplevel The TOPLEVEL object.
417 * \param [in] world_centerx Origin x coordinate in WORLD units.
418 * \param [in] world_centery Origin y coordinate in WORLD units.
419 * \param [in,out] object Line OBJECT to mirror.
421 void o_line_mirror_world(TOPLEVEL
*toplevel
, int world_centerx
,
422 int world_centery
, OBJECT
*object
)
424 /* translate object to origin */
425 o_line_translate_world(toplevel
, -world_centerx
, -world_centery
, object
);
427 /* mirror the line ends */
428 object
->line
->x
[0] = -object
->line
->x
[0];
429 object
->line
->x
[1] = -object
->line
->x
[1];
431 /* translate back in position */
432 o_line_translate_world(toplevel
, world_centerx
, world_centery
, object
);
436 /*! \brief Recalculate line coordinates in SCREEN units.
437 * \par Function Description
438 * This function recalculate the bounding box of the <B>o_current</B>
440 * \param [in] toplevel The TOPLEVEL object.
441 * \param [in,out] o_current Line OBJECT to be recalculated.
443 void o_line_recalc(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
445 int left
, right
, top
, bottom
;
447 if (o_current
->line
== NULL
) {
451 /* update the bounding box - screen unit */
452 world_get_line_bounds(toplevel
, o_current
,
453 &left
, &top
, &right
, &bottom
);
454 o_current
->w_left
= left
;
455 o_current
->w_top
= top
;
456 o_current
->w_right
= right
;
457 o_current
->w_bottom
= bottom
;
458 o_current
->w_bounds_valid
= TRUE
;
461 /*! \brief Get line bounding rectangle in WORLD coordinates.
462 * \par Function Description
463 * This function sets the <B>left</B>, <B>top</B>, <B>right</B> and
464 * <B>bottom</B> parameters to the boundings of the line object described
465 * in <B>*line</B> in world units.
467 * \param [in] toplevel The TOPLEVEL object.
468 * \param [in] object Line OBJECT to read coordinates from.
469 * \param [out] left Left line coordinate in WORLD units.
470 * \param [out] top Top line coordinate in WORLD units.
471 * \param [out] right Right line coordinate in WORLD units.
472 * \param [out] bottom Bottom line coordinate in WORLD units.
474 void world_get_line_bounds(TOPLEVEL
*toplevel
, OBJECT
*object
,
475 int *left
, int *top
, int *right
, int *bottom
)
479 halfwidth
= object
->line_width
/ 2;
481 *left
= min( object
->line
->x
[0], object
->line
->x
[1] );
482 *top
= min( object
->line
->y
[0], object
->line
->y
[1] );
483 *right
= max( object
->line
->x
[0], object
->line
->x
[1] );
484 *bottom
= max( object
->line
->y
[0], object
->line
->y
[1] );
486 /* This isn't strictly correct, but a 1st order approximation */
490 *bottom
+= halfwidth
;
493 /*! \brief get the position of the first line point
494 * \par Function Description
495 * This function gets the position of the first point of a line object.
497 * \param [in] toplevel The toplevel environment.
498 * \param [out] x pointer to the x-position
499 * \param [out] y pointer to the y-position
500 * \param [in] object The object to get the position.
501 * \return TRUE if successfully determined the position, FALSE otherwise
503 gboolean
o_line_get_position (TOPLEVEL
*toplevel
, gint
*x
, gint
*y
,
506 *x
= object
->line
->x
[0];
507 *y
= object
->line
->y
[0];
512 /*! \brief Print line to Postscript document.
513 * \par Function Description
514 * This function prints the line described by the <B>o_current</B>
515 * parameter to a Postscript document.
516 * The Postscript document is described by the <B>fp</B> file pointer.
518 * Parameters of the line are extracted from object pointed by
521 * \param [in] toplevel The TOPLEVEL object.
522 * \param [in] fp FILE pointer to Postscript document.
523 * \param [in] o_current Line OBJECT to write to document.
524 * \param [in] origin_x Page x coordinate to place line OBJECT.
525 * \param [in] origin_y Page y coordinate to place line OBJECT.
527 void o_line_print(TOPLEVEL
*toplevel
, FILE *fp
, OBJECT
*o_current
,
528 int origin_x
, int origin_y
)
532 int line_width
, length
, space
;
533 void (*outl_func
)() = NULL
;
535 if (o_current
== NULL
) {
536 printf("got null in o_line_print\n");
540 x1
= o_current
->line
->x
[0];
541 y1
= o_current
->line
->y
[0];
542 x2
= o_current
->line
->x
[1];
543 y2
= o_current
->line
->y
[1];
544 color
= o_current
->color
;
547 * Depending on the type of the line for this particular line, the
548 * appropriate function is chosen among
549 * #o_line_print_solid(), #o_line_print_dotted()#, #o_line_print_dashed(),
550 * #o_line_print_center() and #o_line_print_phantom().
552 * The needed parameters for each of these types are extracted from the
553 * <B>o_current</B> object. Depending on the type, unused parameters are
556 * In the eventuality of a length and/or space null, the line is printed
557 * solid to avoid and endless loop produced by other functions.
559 line_width
= o_current
->line_width
;
561 if(toplevel
->line_style
== THICK
) {
562 line_width
=LINE_WIDTH
;
568 length
= o_current
->line_length
;
569 space
= o_current
->line_space
;
571 switch(o_current
->line_type
) {
573 length
= -1; space
= -1;
574 outl_func
= o_line_print_solid
;
579 outl_func
= o_line_print_dotted
;
583 outl_func
= o_line_print_dashed
;
587 outl_func
= o_line_print_center
;
591 outl_func
= o_line_print_phantom
;
595 /* Unused for now, print it solid */
596 length
= -1; space
= -1;
597 outl_func
= o_line_print_solid
;
601 if((length
== 0) || (space
== 0)) {
602 length
= -1; space
= -1;
603 outl_func
= o_line_print_solid
;
606 (*outl_func
)(toplevel
, fp
,
607 x1
- origin_x
, y1
- origin_y
,
608 x2
- origin_x
, y2
- origin_y
,
610 line_width
, length
, space
,
614 /*! \brief Print a solid line to Postscript document.
615 * \par Function Description
616 * This function prints a line when a solid line type is required.
617 * The line is defined by the coordinates of its two ends in
618 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
619 * The Postscript document is defined by the file pointer <B>fp</B>.
620 * The parameters <B>length</B> and <B>space</B> are ignored whereas
621 * <B>line_width</B> specifies the width of the printed line.
623 * \param [in] toplevel The TOPLEVEL object.
624 * \param [in] fp FILE pointer to Postscript document.
625 * \param [in] x1 Upper x coordinate.
626 * \param [in] y1 Upper y coordinate.
627 * \param [in] x2 Lower x coordinate.
628 * \param [in] y2 Lower y coordinate.
629 * \param [in] color Line color.
630 * \param [in] line_width Width of line.
631 * \param [in] length (unused).
632 * \param [in] space (unused).
633 * \param [in] origin_x Page x coordinate to place line OBJECT.
634 * \param [in] origin_y Page y coordinate to place line OBJECT.
636 void o_line_print_solid(TOPLEVEL
*toplevel
, FILE *fp
,
637 int x1
, int y1
, int x2
, int y2
,
639 int line_width
, int length
, int space
,
640 int origin_x
, int origin_y
)
642 f_print_set_color(toplevel
, fp
, color
);
644 fprintf(fp
,"%d %d %d %d %d line\n",
645 x1
,y1
,x2
,y2
, line_width
);
648 /*! \brief Print a dotted line to Postscript document.
649 * \par Function Description
650 * This function prints a line when a dotted line type is required.
651 * The line is defined by the coordinates of its two ends in
652 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
653 * The Postscript document is defined by the file pointer <B>fp</B>.
654 * The parameter <B>length</B> is ignored whereas <B>line_width</B>
655 * specifies the diameter of the dots and <B>space</B> the distance
658 * A negative value for <B>space</B> leads to an endless loop.
660 * All dimensions are in mils.
662 * The function sets the color in which the line will be printed with.
664 * \param [in] toplevel The TOPLEVEL object.
665 * \param [in] fp FILE pointer to Postscript document.
666 * \param [in] x1 Upper x coordinate.
667 * \param [in] y1 Upper y coordinate.
668 * \param [in] x2 Lower x coordinate.
669 * \param [in] y2 Lower y coordinate.
670 * \param [in] color Line color.
671 * \param [in] line_width Width of line.
672 * \param [in] length (unused).
673 * \param [in] space Space between dots.
674 * \param [in] origin_x Page x coordinate to place line OBJECT.
675 * \param [in] origin_y Page y coordinate to place line OBJECT.
677 void o_line_print_dotted(TOPLEVEL
*toplevel
, FILE *fp
,
678 int x1
, int y1
, int x2
, int y2
,
680 int line_width
, int length
, int space
,
681 int origin_x
, int origin_y
)
687 f_print_set_color(toplevel
, fp
, color
);
689 /* The dotted line command takes an array of dots so print out the
690 * beginnings of the array
693 /* is the width relevant for a dot (circle) ? */
694 /* f_print_set_line_width(fp, line_width); */
697 * Depending on the slope of the line the space parameter is
698 * projected on each of the two directions x and y resulting
699 * in <B>dx1</B> and <B>dy1</B>. Starting from one end by increments
700 * of space the dots are printed.
702 * A dot is represented by a filled circle. Position of the
703 * circle is (<B>xa</B>, <B>ya</B>) and its radius is the <B>line_width</B>
707 dx
= (double) (x2
- x1
);
708 dy
= (double) (y2
- y1
);
709 l
= sqrt((dx
* dx
) + (dy
* dy
));
711 dx1
= (dx
* space
) / l
;
712 dy1
= (dy
* space
) / l
;
718 fprintf(fp
,"[%d %d] ",
725 fprintf(fp
,"] %d dashed\n",line_width
);
730 /*! \brief Print a dashed line to Postscript document.
731 * \par Function Description
732 * This function prints a line when a dashed line type is required.
733 * The line is defined by the coordinates of its two ends in
734 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
735 * The postscript file is defined by the file pointer <B>fp</B>.
737 * A negative value for <B>space</B> or <B>length</B> leads to an
740 * All dimensions are in mils.
742 * The function sets the color in which the line will be printed and
743 * the width of the line - that is the width of the dashes.
745 * \param [in] toplevel The TOPLEVEL object.
746 * \param [in] fp FILE pointer to Postscript document.
747 * \param [in] x1 Upper x coordinate.
748 * \param [in] y1 Upper y coordinate.
749 * \param [in] x2 Lower x coordinate.
750 * \param [in] y2 Lower y coordinate.
751 * \param [in] color Line color.
752 * \param [in] line_width Width of line.
753 * \param [in] length Length of a dash.
754 * \param [in] space Space between dashes.
755 * \param [in] origin_x Page x coordinate to place line OBJECT.
756 * \param [in] origin_y Page y coordinate to place line OBJECT.
758 void o_line_print_dashed(TOPLEVEL
*toplevel
, FILE *fp
,
759 int x1
, int y1
, int x2
, int y2
,
761 int line_width
, int length
, int space
,
762 int origin_x
, int origin_y
)
765 double dx1
, dy1
, dx2
, dy2
;
766 double xa
, ya
, xb
, yb
;
768 f_print_set_color(toplevel
, fp
, color
);
770 /* the dashed line function takes an array of start-finish pairs
771 * output the beginnings of the array now
776 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
777 * parameter is projected on each of the two directions x and y
778 * resulting in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
779 * Starting from one end and incrementing alternatively by <B>space</B>
780 * and <B>length</B> the dashes are printed.
782 * It prints as many dashes of length <B>length</B> as possible.
784 dx
= (double) (x2
- x1
);
785 dy
= (double) (y2
- y1
);
786 l
= sqrt((dx
* dx
) + (dy
* dy
));
788 dx1
= (dx
* length
) / l
;
789 dy1
= (dy
* length
) / l
;
791 dx2
= (dx
* space
) / l
;
792 dy2
= (dy
* space
) / l
;
796 while((d
+ length
+ space
) < l
) {
801 fprintf(fp
, "[%d %d %d %d] ",
810 * When the above condition is no more satisfied, then it is not possible
811 * to print a dash of length <B>length</B>. However it may be possible to
812 * print the complete dash or a shorter one.
815 if((d
+ length
) < l
) {
824 fprintf(fp
, "[%d %d %d %d] ",
828 fprintf(fp
,"] %d dashed\n", line_width
);
832 /*! \brief Print a centered line type line to Postscript document.
833 * \par Function Description
834 * This function prints a line when a centered line type is required.
835 * The line is defined by the coordinates of its two ends in
836 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
837 * The Postscript document is defined by the file pointer <B>fp</B>.
839 * A negative value for <B>space</B> or <B>length</B> leads to an
842 * All dimensions are in mils.
844 * The function sets the color in which the line will be printed and the
845 * width of the line - that is the width of the dashes and the diameter
848 * \param [in] toplevel The TOPLEVEL object.
849 * \param [in] fp FILE pointer to Postscript document.
850 * \param [in] x1 Upper x coordinate.
851 * \param [in] y1 Upper y coordinate.
852 * \param [in] x2 Lower x coordinate.
853 * \param [in] y2 Lower y coordinate.
854 * \param [in] color Line color.
855 * \param [in] line_width Width of line.
856 * \param [in] length Length of a dash.
857 * \param [in] space Space between dashes.
858 * \param [in] origin_x Page x coordinate to place line OBJECT.
859 * \param [in] origin_y Page y coordinate to place line OBJECT.
861 void o_line_print_center(TOPLEVEL
*toplevel
, FILE *fp
,
862 int x1
, int y1
, int x2
, int y2
,
864 int line_width
, int length
, int space
,
865 int origin_x
, int origin_y
)
868 double dx1
, dy1
, dx2
, dy2
;
869 double xa
, ya
, xb
, yb
;
871 f_print_set_color(toplevel
, fp
, color
);
876 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
877 * parameter is projected on each of the two directions x and y resulting
878 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
879 * Starting from one end and incrementing alternatively by <B>space</B>
880 * and <B>length</B> the dashes and dots are printed.
882 * It prints as many sets of dash and dot as possible.
884 dx
= (double) (x2
- x1
);
885 dy
= (double) (y2
- y1
);
886 l
= sqrt((dx
* dx
) + (dy
* dy
));
888 dx1
= (dx
* length
) / l
;
889 dy1
= (dy
* length
) / l
;
891 dx2
= (dx
* space
) / l
;
892 dy2
= (dy
* space
) / l
;
896 while((d
+ length
+ 2 * space
) < l
) {
901 fprintf(fp
, "[%d %d %d %d] ",
909 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
916 * When the above condition is no more satisfied, then it is not possible
917 * to print a dash of length <B>length</B>.
918 * However two cases are possible :
920 * <DT>*</DT><DD>it is possible to print the dash and the dot.
921 * <DT>*</DT><DD>it is possible to print the dash or a part
922 * of the original dash.
926 if((d
+ length
+ space
) < l
) {
931 fprintf(fp
, "[%d %d %d %d] ",
939 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
950 fprintf(fp
, "[%d %d %d %d] ",
956 fprintf(fp
,"] %d dashed\n", line_width
);
959 * A dot is represented by a filled circle. Position of the circle is
960 * (<B>xa</B>, <B>ya</B>) and its radius by the <B>line_width</B> parameter.
964 /*! \brief Print a phantom line type line to Postscript document.
965 * \par Function Description
966 * This function prints a line when a phantom line type is required.
967 * The line is defined by the coordinates of its two ends in
968 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
969 * The Postscript document is defined by the file pointer <B>fp</B>.
971 * A negative value for <B>space</B> or <B>length</B> leads to an
974 * All dimensions are in mils.
976 * The function sets the color in which the line will be printed and the
977 * width of the line - that is the width of the dashes and the diameter
980 * \param [in] toplevel The TOPLEVEL object.
981 * \param [in] fp FILE pointer to Postscript document.
982 * \param [in] x1 Upper x coordinate.
983 * \param [in] y1 Upper y coordinate.
984 * \param [in] x2 Lower x coordinate.
985 * \param [in] y2 Lower y coordinate.
986 * \param [in] color Line color.
987 * \param [in] line_width Width of line.
988 * \param [in] length Length of a dash.
989 * \param [in] space Space between dashes.
990 * \param [in] origin_x Page x coordinate to place line OBJECT.
991 * \param [in] origin_y Page y coordinate to place line OBJECT.
993 void o_line_print_phantom(TOPLEVEL
*toplevel
, FILE *fp
,
994 int x1
, int y1
, int x2
, int y2
,
996 int line_width
, int length
, int space
,
997 int origin_x
, int origin_y
)
1000 double dx1
, dy1
, dx2
, dy2
;
1001 double xa
, ya
, xb
, yb
;
1003 f_print_set_color(toplevel
, fp
, color
);
1008 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
1009 * parameter is projected on each of the two directions x and y resulting
1010 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
1011 * Starting from one end and incrementing alternatively by <B>space</B>
1012 * and <B>length</B> the dashes and dots are printed.
1014 * It prints as many sets of dash-dot-dot as possible.
1016 dx
= (double) (x2
- x1
);
1017 dy
= (double) (y2
- y1
);
1018 l
= sqrt((dx
* dx
) + (dy
* dy
));
1020 dx1
= (dx
* length
) / l
;
1021 dy1
= (dy
* length
) / l
;
1023 dx2
= (dx
* space
) / l
;
1024 dy2
= (dy
* space
) / l
;
1028 while((d
+ length
+ 3 * space
) < l
) {
1033 fprintf(fp
,"[%d %d %d %d] ",
1041 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1047 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1054 * When the above condition is no more satisfied, then it is not possible
1055 * to print a complete set of dash-dot-dot.
1056 * However three cases are possible :
1058 * <DT>*</DT><DD>it is possible to print a dash and a dot and a dot.
1059 * <DT>*</DT><DD>it is possible to print a dash and a dot.
1060 * <DT>*</DT><DD>it is possible to print the dash or a part
1061 * of the original dash.
1065 if((d
+ length
+ 2 * space
) < l
) {
1070 fprintf(fp
,"[%d %d %d %d] ",
1078 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1084 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1087 if(d
+ length
+ space
< l
) {
1092 fprintf(fp
,"[%d %d %d %d] ",
1100 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1103 if(d
+ length
< l
) {
1111 fprintf(fp
,"[%d %d %d %d] ",
1118 fprintf(fp
,"] %d dashed\n", line_width
);
1123 * \par Function Description
1125 * \param [in] toplevel The TOPLEVEL object.
1126 * \param [in] x_scale
1127 * \param [in] y_scale
1128 * \param [in] object
1130 void o_line_scale_world(TOPLEVEL
*toplevel
, int x_scale
, int y_scale
,
1133 if (object
== NULL
) printf("lsw NO!\n");
1135 /* scale the line world coords */
1136 object
->line
->x
[0] = object
->line
->x
[0] * x_scale
;
1137 object
->line
->y
[0] = object
->line
->y
[0] * y_scale
;
1138 object
->line
->x
[1] = object
->line
->x
[1] * x_scale
;
1139 object
->line
->y
[1] = object
->line
->y
[1] * y_scale
;
1141 /* update boundingbox */
1142 o_line_recalc(toplevel
, object
);
1147 /*! \brief calculate the lenght of a line object
1148 * \par Function Description
1149 * This function calculates the length of a line object
1151 * \param [in] object a line OBJECT
1152 * \return The length of the line
1154 double o_line_length(OBJECT
*object
)
1159 if (!object
->line
) {
1163 dx
= object
->line
->x
[0]-object
->line
->x
[1];
1164 dy
= object
->line
->y
[0]-object
->line
->y
[1];
1166 length
= sqrt((dx
*dx
) + (dy
*dy
));
1171 /*! \brief Calculates the distance between the given point and the closest
1172 * point on the given line segment.
1174 * If the closest point on the line resides beyond the line segment's
1175 * end point, this function returns the distance from the given point to the
1176 * closest end point.
1178 * If the line represents a single point (the endpoints are the same), this
1179 * function calcualtes the distance to that point.
1181 * \param [in] object The line OBJECT.
1182 * \param [in] x The x coordinate of the given point.
1183 * \param [in] y The y coordinate of the given point.
1184 * \param [in] force_solid If true, force treating the object as solid.
1185 * \return The shortest distance from the object to the point. With an
1186 * invalid parameter, this function returns G_MAXDOUBLE.
1188 double o_line_shortest_distance (OBJECT
*object
, int x
, int y
, int force_solid
)
1190 return m_line_shortest_distance (object
->line
, x
, y
);