1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2000 Ales V. Hvezda
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
35 #include "../include/prototype.h"
37 #ifdef HAVE_LIBDMALLOC
41 /*! \brief Create and add line OBJECT to list.
42 * \par Function Description
43 * This function creates a new object representing a line.
44 * This object is added to the end of the list <B>object_list</B>
45 * pointed object belongs to.
46 * The line is described by its two ends - <B>x1</B>,<B>y1</B> and
47 * <B>x2</B>,<B>y2</B>.
48 * The <B>type</B> parameter must be equal to #OBJ_LINE.
49 * The <B>color</B> parameter corresponds to the color the box
52 * The #OBJECT structure is allocated with the
53 * #s_basic_init_object() function. The structure describing
54 * the line is allocated and initialized with the parameters given
57 * Both the line type and the filling type are set to default
58 * values : solid line type with a width of 0, and no filling.
59 * It can be changed after with the #o_set_line_options() and
60 * #o_set_fill_options().
62 * The object is added to the end of the list described by the
63 * <B>object_list</B> parameter by the #s_basic_link_object().
65 * \param [in] w_current The TOPLEVEL object.
66 * \param [in,out] object_list OBJECT list to add line to.
67 * \param [in] type Must be OBJ_LINE.
68 * \param [in] color Circle line color.
69 * \param [in] x1 Upper x coordinate.
70 * \param [in] y1 Upper y coordinate.
71 * \param [in] x2 Lower x coordinate.
72 * \param [in] y2 Lower y coordinate.
73 * \return A pointer to the new end of the object list.
75 OBJECT
*o_line_add(TOPLEVEL
*w_current
, OBJECT
*object_list
,
77 int x1
, int y1
, int x2
, int y2
)
81 /* create the object */
82 new_node
= s_basic_init_object("line");
83 new_node
->type
= type
;
84 new_node
->color
= color
;
86 new_node
->line
= (LINE
*) g_malloc(sizeof(LINE
));
88 /* describe the line with its two ends */
89 new_node
->line
->x
[0] = x1
;
90 new_node
->line
->y
[0] = y1
;
91 new_node
->line
->x
[1] = x2
;
92 new_node
->line
->y
[1] = y2
;
94 /* line type and filling initialized to default */
95 o_set_line_options(w_current
, new_node
,
96 END_NONE
, TYPE_SOLID
, 0, -1, -1);
97 o_set_fill_options(w_current
, new_node
,
98 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
100 new_node
->draw_func
= line_draw_func
;
101 new_node
->sel_func
= select_func
;
103 /* compute bounding box */
104 o_line_recalc(w_current
, new_node
);
106 object_list
= (OBJECT
*) s_basic_link_object(new_node
, object_list
);
111 /*! \brief Create a copy of a line.
112 * \par Function Description
113 * This function creates a verbatim copy of the
114 * object pointed by <B>o_current</B> describing a line. The new object
115 * is added at the end of the list following the <B>list_tail</B>
118 * \param [in] w_current The TOPLEVEL object.
119 * \param [out] list_tail OBJECT list to copy to.
120 * \param [in] o_current Line OBJECT to copy.
121 * \return A new pointer to the end of the object list.
123 OBJECT
*o_line_copy(TOPLEVEL
*w_current
, OBJECT
*list_tail
, OBJECT
*o_current
)
129 if (o_current
->saved_color
== -1) {
130 color
= o_current
->color
;
132 color
= o_current
->saved_color
;
136 * A new line object is added a the end of the object list with
137 * #o_line_add(). Values for its fields are default and need to
140 new_obj
= o_line_add(w_current
, list_tail
,
145 * The coordinates of the ends of the new line are set with the ones
146 * of the original line. The two lines have the sale line type and
149 * The bounding box are computed with
153 /* modify the line ends of the new line */
154 new_obj
->line
->x
[0] = o_current
->line
->x
[0];
155 new_obj
->line
->y
[0] = o_current
->line
->y
[0];
156 new_obj
->line
->x
[1] = o_current
->line
->x
[1];
157 new_obj
->line
->y
[1] = o_current
->line
->y
[1];
159 /* copy the line type and filling options */
160 o_set_line_options(w_current
, new_obj
, o_current
->line_end
,
161 o_current
->line_type
, o_current
->line_width
,
162 o_current
->line_length
, o_current
->line_space
);
163 o_set_fill_options(w_current
, new_obj
,
164 o_current
->fill_type
, o_current
->fill_width
,
165 o_current
->fill_pitch1
, o_current
->fill_angle1
,
166 o_current
->fill_pitch2
, o_current
->fill_angle2
);
168 /* calc the bounding box */
169 o_line_recalc(w_current
, o_current
);
171 /* new_obj->attribute = 0;*/
172 a_current
= o_current
->attribs
;
174 while ( a_current
) {
175 /* head attrib node has prev = NULL */
176 if (a_current
->prev
!= NULL
) {
177 a_current
->copied_to
= new_obj
;
179 a_current
= a_current
->next
;
183 /* return the new tail of the object list */
187 /*! \brief Modify the description of a line OBJECT.
188 * \par Function Description
189 * This function modifies the coordinates of one of the two ends of
190 * the line described by <B>*object</B>. The new coordinates of this end,
191 * identified by <B>whichone</B>, are given by <B>x</B> and <B>y</B>
194 * The coordinates of the end of line is modified in the world
195 * coordinate system. Screen coordinates and boundings are then updated.
197 * \param [in] w_current The TOPLEVEL object.
198 * \param [in,out] object Line OBJECT to modify.
199 * \param [in] x New x coordinate.
200 * \param [in] y New y coordinate.
201 * \param [in] whichone Which line parameter to modify.
203 * <B>whichone</B> can have the following values:
205 * <DT>*</DT><DD>LINE_END1
206 * <DT>*</DT><DD>LINE_END2
210 * pb20011009 - modified
212 void o_line_modify(TOPLEVEL
*w_current
, OBJECT
*object
,
213 int x
, int y
, int whichone
)
215 /* change one of the end of the line */
218 object
->line
->x
[0] = x
;
219 object
->line
->y
[0] = y
;
223 object
->line
->x
[1] = x
;
224 object
->line
->y
[1] = y
;
231 /* recalculate the bounding box */
232 o_line_recalc(w_current
, object
);
236 /*! \brief Create line OBJECT from character string.
237 * \par Function Description
238 * This function creates a line OBJECT from the character string
239 * <B>*buf</B> the description of a box. The new box is added to the
240 * list of objects of which <B>*object_list</B> is the last element
242 * The function returns a pointer on the new last element, that is
243 * the added line object.
245 * Depending on <B>*version</B>, the correct file format is considered.
246 * Currently two file format revisions are supported :
248 * <DT>*</DT><DD>the file format used until 20010704 release.
249 * <DT>*</DT><DD>the file format used for the releases after 20010704.
252 * \param [in] w_current The TOPLEVEL object.
253 * \param [out] object_list OBJECT list to create line in.
254 * \param [in] buf Character string with line description.
255 * \param [in] release_ver libgeda release version number.
256 * \param [in] fileformat_ver libgeda file format version number.
257 * \return A pointer to the new line object.
259 OBJECT
*o_line_read(TOPLEVEL
*w_current
, OBJECT
*object_list
, char buf
[],
260 unsigned int release_ver
, unsigned int fileformat_ver
)
267 int line_width
, line_space
, line_length
;
272 if(release_ver
<= VERSION_20000704
) {
274 * The old geda file format, i.e. releases 20000704 and older, does
275 * not handle the line type and the filling - here filling is irrelevant.
276 * They are set to default.
278 sscanf(buf
, "%c %d %d %d %d %d\n", &type
,
279 &x1
, &y1
, &x2
, &y2
, &color
);
283 line_type
= TYPE_SOLID
;
288 * The current line format to describe a line is a space separated
289 * list of characters and numbers in plain ASCII on a single line.
290 * The meaning of each item is described in the file format documentation.
292 sscanf(buf
, "%c %d %d %d %d %d %d %d %d %d %d\n", &type
,
293 &x1
, &y1
, &x2
, &y2
, &color
,
294 &line_width
, &line_end
, &line_type
, &line_length
, &line_space
);
297 d_x1
= x1
; /* \todo PB : Needed ? */
303 * Null length line are not allowed. If such a line is detected a
306 * It also checks is the required color is valid.
308 if (x1
== x2
&& y1
== y2
) {
309 fprintf(stderr
, "Found a zero length line [ %c %d %d %d %d %d ]\n",
310 type
, x1
, y1
, x2
, y2
, color
);
311 s_log_message("Found a zero length line [ %c %d %d %d %d %d ]\n",
312 type
, x1
, y1
, x2
, y2
, color
);
315 if (color
< 0 || color
> MAX_COLORS
) {
316 fprintf(stderr
, "Found an invalid color [ %s ]\n", buf
);
317 s_log_message("Found an invalid color [ %s ]\n", buf
);
318 s_log_message("Setting color to WHITE\n");
323 * A line is internally described by its two ends. A new object is
324 * allocated, initialized and added to the list of objects. Its line
325 * type is set according to the values of the fields on the line.
327 /* create and add the line to the list */
328 object_list
= o_line_add(w_current
, object_list
,
329 type
, color
, d_x1
, d_y1
, d_x2
, d_y2
);
330 /* set its line options */
331 o_set_line_options(w_current
, object_list
,
332 line_end
, line_type
, line_width
, line_length
,
334 /* filling is irrelevant for line, just set to default */
335 o_set_fill_options(w_current
, object_list
,
336 FILLING_HOLLOW
, -1, -1, -1, -1, -1);
341 /*! \brief Create a character string representation of a line OBJECT.
342 * \par Function Description
343 * The function formats a string in the buffer <B>*buff</B> to describe
344 * the box object <B>*object</B>.
345 * It follows the post-20000704 release file format that handle the
346 * line type and fill options - filling is irrelevant here.
348 * \param [in] object Line OBJECT to create string from.
349 * \return A pointer to the line OBJECT character string.
352 * Caller must free returned character string.
355 char *o_line_save(OBJECT
*object
)
359 int line_width
, line_space
, line_length
;
362 OBJECT_TYPE line_type
;
364 /* get the two ends */
365 x1
= object
->line
->x
[0];
366 y1
= object
->line
->y
[0];
367 x2
= object
->line
->x
[1];
368 y2
= object
->line
->y
[1];
370 /* description of the line type */
371 line_width
= object
->line_width
;
372 line_end
= object
->line_end
;
373 line_type
= object
->line_type
;
374 line_length
= object
->line_length
;
375 line_space
= object
->line_space
;
377 /* Use the right color */
378 if (object
->saved_color
== -1) {
379 color
= object
->color
;
381 color
= object
->saved_color
;
384 buf
= g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d", object
->type
,
385 x1
, y1
, x2
, y2
, color
,
386 line_width
, line_end
, line_type
,
387 line_length
, line_space
);
392 /*! \brief Translate a line position in WORLD coordinates by a delta.
393 * \par Function Description
394 * This function applies a translation of (<B>x1</B>,<B>y1</B>) to the line
395 * described by <B>*object</B>. <B>x1</B> and <B>y1</B> are in world unit.
397 * \param [in] w_current The TOPLEVEL object.
398 * \param [in] x1 x distance to move.
399 * \param [in] y1 y distance to move.
400 * \param [in,out] object Line OBJECT to translate.
402 void o_line_translate_world(TOPLEVEL
*w_current
,
403 int x1
, int y1
, OBJECT
*object
)
405 int left
, right
, top
, bottom
;
407 if (object
== NULL
) printf("ltw NO!\n");
409 /* Update world coords */
410 object
->line
->x
[0] = object
->line
->x
[0] + x1
;
411 object
->line
->y
[0] = object
->line
->y
[0] + y1
;
412 object
->line
->x
[1] = object
->line
->x
[1] + x1
;
413 object
->line
->y
[1] = object
->line
->y
[1] + y1
;
415 /* Update bounding box */
416 world_get_line_bounds(w_current
, object
, &left
, &top
, &right
, &bottom
);
418 object
->w_left
= left
;
420 object
->w_right
= right
;
421 object
->w_bottom
= bottom
;
425 /*! \brief Rotate Line OBJECT using WORLD coordinates.
426 * \par Function Description
427 * This function rotates the line described by
428 * <B>*object</B> around the (<B>world_centerx</B>,<B>world_centery</B>)
429 * point by <B>angle</B> degrees.
430 * The center of rotation is in world units.
432 * \param [in] w_current The TOPLEVEL object.
433 * \param [in] world_centerx Rotation center x coordinate in WORLD units.
434 * \param [in] world_centery Rotation center y coordinate in WORLD units.
435 * \param [in] angle Rotation angle in degrees (See note below).
436 * \param [in,out] object Line OBJECT to rotate.
438 void o_line_rotate_world(TOPLEVEL
*w_current
,
439 int world_centerx
, int world_centery
, int angle
,
447 /* angle must be positive */
448 if(angle
< 0) angle
= -angle
;
449 /* angle must be 90 multiple or no rotation performed */
450 if((angle
% 90) != 0) return;
453 * The center of rotation (<B>world_centerx</B>,<B>world_centery</B>)
454 * is translated to the origin. The rotation of the two ends of
455 * the line is performed. FInally, the rotated line is translated
456 * back to its previous location.
458 /* translate object to origin */
459 o_line_translate_world(w_current
, -world_centerx
, -world_centery
, object
);
461 /* rotate line end 1 */
462 rotate_point_90(object
->line
->x
[0], object
->line
->y
[0], angle
,
465 object
->line
->x
[0] = newx
;
466 object
->line
->y
[0] = newy
;
468 /* rotate line end 2 */
469 rotate_point_90(object
->line
->x
[1], object
->line
->y
[1], angle
,
472 object
->line
->x
[1] = newx
;
473 object
->line
->y
[1] = newy
;
475 /* translate object back to normal position */
476 o_line_translate_world(w_current
, world_centerx
, world_centery
, object
);
480 /*! \brief Mirror a line using WORLD coordinates.
481 * \par Function Description
482 * This function mirrors the line from the point
483 * (<B>world_centerx</B>,<B>world_centery</B>) in world unit.
485 * The line if first translated to the origin, then mirrored
486 * and finally translated back at its previous position.
488 * \param [in] w_current The TOPLEVEL object.
489 * \param [in] world_centerx Origin x coordinate in WORLD units.
490 * \param [in] world_centery Origin y coordinate in WORLD units.
491 * \param [in,out] object Line OBJECT to mirror.
493 void o_line_mirror_world(TOPLEVEL
*w_current
, int world_centerx
,
494 int world_centery
, OBJECT
*object
)
496 /* translate object to origin */
497 o_line_translate_world(w_current
, -world_centerx
, -world_centery
, object
);
499 /* mirror the line ends */
500 object
->line
->x
[0] = -object
->line
->x
[0];
501 object
->line
->x
[1] = -object
->line
->x
[1];
503 /* translate back in position */
504 o_line_translate_world(w_current
, world_centerx
, world_centery
, object
);
508 /*! \brief Recalculate line coordinates in SCREEN units.
509 * \par Function Description
510 * This function recalculate the bounding box of the <B>o_current</B>
512 * \param [in] w_current The TOPLEVEL object.
513 * \param [in,out] o_current Line OBJECT to be recalculated.
515 void o_line_recalc(TOPLEVEL
*w_current
, OBJECT
*o_current
)
517 int left
, right
, top
, bottom
;
519 if (o_current
->line
== NULL
) {
523 /* update the bounding box - screen unit */
524 world_get_line_bounds(w_current
, o_current
,
525 &left
, &top
, &right
, &bottom
);
526 o_current
->w_left
= left
;
527 o_current
->w_top
= top
;
528 o_current
->w_right
= right
;
529 o_current
->w_bottom
= bottom
;
533 /*! \brief Get line bounding rectangle in WORLD coordinates.
534 * \par Function Description
535 * This function sets the <B>left</B>, <B>top</B>, <B>right</B> and
536 * <B>bottom</B> parameters to the boundings of the line object described
537 * in <B>*line</B> in world units.
539 * \param [in] w_current The TOPLEVEL object.
540 * \param [in] OBJECT Line OBJECT to read coordinates from.
541 * \param [out] left Left line coordinate in WORLD units.
542 * \param [out] top Top line coordinate in WORLD units.
543 * \param [out] right Right line coordinate in WORLD units.
544 * \param [out] bottom Bottom line coordinate in WORLD units.
546 void world_get_line_bounds(TOPLEVEL
*w_current
, OBJECT
*object
,
547 int *left
, int *top
, int *right
, int *bottom
)
551 halfwidth
= object
->line_width
/ 2;
553 *left
= min( object
->line
->x
[0], object
->line
->x
[1] );
554 *top
= min( object
->line
->y
[0], object
->line
->y
[1] );
555 *right
= max( object
->line
->x
[0], object
->line
->x
[1] );
556 *bottom
= max( object
->line
->y
[0], object
->line
->y
[1] );
558 /* This isn't strictly correct, but a 1st order approximation */
562 *bottom
+= halfwidth
;
565 /*! \brief Print line to Postscript document.
566 * \par Function Description
567 * This function prints the line described by the <B>o_current</B>
568 * parameter to a Postscript document.
569 * The Postscript document is described by the <B>fp</B> file pointer.
571 * Parameters of the line are extracted from object pointed by
574 * \param [in] w_current The TOPLEVEL object.
575 * \param [in] fp FILE pointer to Postscript document.
576 * \param [in] o_current Line OBJECT to write to document.
577 * \param [in] origin_x Page x coordinate to place line OBJECT.
578 * \param [in] origin_y Page y coordinate to place line OBJECT.
580 void o_line_print(TOPLEVEL
*w_current
, FILE *fp
, OBJECT
*o_current
,
581 int origin_x
, int origin_y
)
585 int line_width
, length
, space
;
586 void (*outl_func
)() = NULL
;
588 if (o_current
== NULL
) {
589 printf("got null in o_line_print\n");
593 x1
= o_current
->line
->x
[0];
594 y1
= o_current
->line
->y
[0];
595 x2
= o_current
->line
->x
[1];
596 y2
= o_current
->line
->y
[1];
597 color
= o_current
->color
;
600 * Depending on the type of the line for this particular line, the
601 * appropriate function is chosen among
602 * #o_line_print_solid(), #o_line_print_dotted()#, #o_line_print_dashed(),
603 * #o_line_print_center() and #o_line_print_phantom().
605 * The needed parameters for each of these types are extracted from the
606 * <B>o_current</B> object. Depending on the type, unused parameters are
609 * In the eventuality of a length and/or space null, the line is printed
610 * solid to avoid and endless loop produced by other functions.
612 line_width
= o_current
->line_width
;
614 if(w_current
->line_style
== THICK
) {
615 line_width
=LINE_WIDTH
;
621 length
= o_current
->line_length
;
622 space
= o_current
->line_space
;
624 switch(o_current
->line_type
) {
626 length
= -1; space
= -1;
627 outl_func
= o_line_print_solid
;
632 outl_func
= o_line_print_dotted
;
636 outl_func
= o_line_print_dashed
;
640 outl_func
= o_line_print_center
;
644 outl_func
= o_line_print_phantom
;
648 /* Unused for now, print it solid */
649 length
= -1; space
= -1;
650 outl_func
= o_line_print_solid
;
654 if((length
== 0) || (space
== 0)) {
655 length
= -1; space
= -1;
656 outl_func
= o_line_print_solid
;
659 (*outl_func
)(w_current
, fp
,
660 x1
- origin_x
, y1
- origin_y
,
661 x2
- origin_x
, y2
- origin_y
,
663 line_width
, length
, space
,
667 /*! \brief Print a solid line to Postscript document.
668 * \par Function Description
669 * This function prints a line when a solid line type is required.
670 * The line is defined by the coordinates of its two ends in
671 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
672 * The Postscript document is defined by the file pointer <B>fp</B>.
673 * The parameters <B>length</B> and <B>space</B> are ignored whereas
674 * <B>line_width</B> specifies the width of the printed line.
676 * \param [in] w_current The TOPLEVEL object.
677 * \param [in] fp FILE pointer to Postscript document.
678 * \param [in] x1 Upper x coordinate.
679 * \param [in] y1 Upper y coordinate.
680 * \param [in] x2 Lower x coordinate.
681 * \param [in] y2 Lower y coordinate.
682 * \param [in] color Line color.
683 * \param [in] line_width Width of line.
684 * \param [in] length (unused).
685 * \param [in] space (unused).
686 * \param [in] origin_x Page x coordinate to place line OBJECT.
687 * \param [in] origin_y Page y coordinate to place line OBJECT.
689 void o_line_print_solid(TOPLEVEL
*w_current
, FILE *fp
,
690 int x1
, int y1
, int x2
, int y2
,
692 int line_width
, int length
, int space
,
693 int origin_x
, int origin_y
)
695 if (w_current
->print_color
) {
696 f_print_set_color(fp
, color
);
699 fprintf(fp
,"%d %d %d %d %d line\n",
700 x1
,y1
,x2
,y2
, line_width
);
703 /*! \brief Print a dotted line to Postscript document.
704 * \par Function Description
705 * This function prints a line when a dotted line type is required.
706 * The line is defined by the coordinates of its two ends in
707 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
708 * The Postscript document is defined by the file pointer <B>fp</B>.
709 * The parameter <B>length</B> is ignored whereas <B>line_width</B>
710 * specifies the diameter of the dots and <B>space</B> the distance
713 * A negative value for <B>space</B> leads to an endless loop.
715 * All dimensions are in mils.
717 * The function sets the color in which the line will be printed with.
719 * \param [in] w_current The TOPLEVEL object.
720 * \param [in] fp FILE pointer to Postscript document.
721 * \param [in] x1 Upper x coordinate.
722 * \param [in] y1 Upper y coordinate.
723 * \param [in] x2 Lower x coordinate.
724 * \param [in] y2 Lower y coordinate.
725 * \param [in] color Line color.
726 * \param [in] line_width Width of line.
727 * \param [in] length (unused).
728 * \param [in] space Space between dots.
729 * \param [in] origin_x Page x coordinate to place line OBJECT.
730 * \param [in] origin_y Page y coordinate to place line OBJECT.
732 void o_line_print_dotted(TOPLEVEL
*w_current
, FILE *fp
,
733 int x1
, int y1
, int x2
, int y2
,
735 int line_width
, int length
, int space
,
736 int origin_x
, int origin_y
)
742 if (w_current
->print_color
) {
743 f_print_set_color(fp
, color
);
746 /* The dotted line command takes an array of dots so print out the
747 * beginnings of the array
750 /* PB : is the width relevant for a dot (circle) ? */
751 /* f_print_set_line_width(fp, line_width); */
754 * Depending on the slope of the line the space parameter is
755 * projected on each of the two directions x and y resulting
756 * in <B>dx1</B> and <B>dy1</B>. Starting from one end by increments
757 * of space the dots are printed.
759 * A dot is represented by a filled circle. Position of the
760 * circle is (<B>xa</B>, <B>ya</B>) and its radius is the <B>line_width</B>
764 dx
= (double) (x2
- x1
);
765 dy
= (double) (y2
- y1
);
766 l
= sqrt((dx
* dx
) + (dy
* dy
));
768 dx1
= (dx
* space
) / l
;
769 dy1
= (dy
* space
) / l
;
775 fprintf(fp
,"[%d %d] ",
782 fprintf(fp
,"] %d dashed\n",line_width
);
787 /*! \brief Print a dashed line to Postscript document.
788 * \par Function Description
789 * This function prints a line when a dashed line type is required.
790 * The line is defined by the coordinates of its two ends in
791 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
792 * The postscript file is defined by the file pointer <B>fp</B>.
794 * A negative value for <B>space</B> or <B>length</B> leads to an
797 * All dimensions are in mils.
799 * The function sets the color in which the line will be printed and
800 * the width of the line - that is the width of the dashes.
802 * \param [in] w_current The TOPLEVEL object.
803 * \param [in] fp FILE pointer to Postscript document.
804 * \param [in] x1 Upper x coordinate.
805 * \param [in] y1 Upper y coordinate.
806 * \param [in] x2 Lower x coordinate.
807 * \param [in] y2 Lower y coordinate.
808 * \param [in] color Line color.
809 * \param [in] line_width Width of line.
810 * \param [in] length Length of a dash.
811 * \param [in] space Space between dashes.
812 * \param [in] origin_x Page x coordinate to place line OBJECT.
813 * \param [in] origin_y Page y coordinate to place line OBJECT.
815 void o_line_print_dashed(TOPLEVEL
*w_current
, FILE *fp
,
816 int x1
, int y1
, int x2
, int y2
,
818 int line_width
, int length
, int space
,
819 int origin_x
, int origin_y
)
822 double dx1
, dy1
, dx2
, dy2
;
823 double xa
, ya
, xb
, yb
;
825 if (w_current
->print_color
) {
826 f_print_set_color(fp
, color
);
829 /* the dashed line function takes an array of start-finish pairs
830 * output the beginnings of the array now
835 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
836 * parameter is projected on each of the two directions x and y
837 * resulting in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
838 * Starting from one end and incrementing alternatively by <B>space</B>
839 * and <B>length</B> the dashes are printed.
841 * It prints as many dashes of length <B>length</B> as possible.
843 dx
= (double) (x2
- x1
);
844 dy
= (double) (y2
- y1
);
845 l
= sqrt((dx
* dx
) + (dy
* dy
));
847 dx1
= (dx
* length
) / l
;
848 dy1
= (dy
* length
) / l
;
850 dx2
= (dx
* space
) / l
;
851 dy2
= (dy
* space
) / l
;
855 while((d
+ length
+ space
) < l
) {
860 fprintf(fp
, "[%d %d %d %d] ",
869 * When the above condition is no more satisfied, then it is not possible
870 * to print a dash of length <B>length</B>. However it may be possible to
871 * print the complete dash or a shorter one.
874 if((d
+ length
) < l
) {
883 fprintf(fp
, "[%d %d %d %d] ",
887 fprintf(fp
,"] %d dashed\n", line_width
);
891 /*! \brief Print a centered line type line to Postscript document.
892 * \par Function Description
893 * This function prints a line when a centered line type is required.
894 * The line is defined by the coordinates of its two ends in
895 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
896 * The Postscript document is defined by the file pointer <B>fp</B>.
898 * A negative value for <B>space</B> or <B>length</B> leads to an
901 * All dimensions are in mils.
903 * The function sets the color in which the line will be printed and the
904 * width of the line - that is the width of the dashes and the diameter
907 * \param [in] w_current The TOPLEVEL object.
908 * \param [in] fp FILE pointer to Postscript document.
909 * \param [in] x1 Upper x coordinate.
910 * \param [in] y1 Upper y coordinate.
911 * \param [in] x2 Lower x coordinate.
912 * \param [in] y2 Lower y coordinate.
913 * \param [in] color Line color.
914 * \param [in] line_width Width of line.
915 * \param [in] length Length of a dash.
916 * \param [in] space Space between dashes.
917 * \param [in] origin_x Page x coordinate to place line OBJECT.
918 * \param [in] origin_y Page y coordinate to place line OBJECT.
920 void o_line_print_center(TOPLEVEL
*w_current
, FILE *fp
,
921 int x1
, int y1
, int x2
, int y2
,
923 int line_width
, int length
, int space
,
924 int origin_x
, int origin_y
)
927 double dx1
, dy1
, dx2
, dy2
;
928 double xa
, ya
, xb
, yb
;
930 if (w_current
->print_color
) {
931 f_print_set_color(fp
, color
);
937 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
938 * parameter is projected on each of the two directions x and y resulting
939 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
940 * Starting from one end and incrementing alternatively by <B>space</B>
941 * and <B>length</B> the dashes and dots are printed.
943 * It prints as many sets of dash and dot as possible.
945 dx
= (double) (x2
- x1
);
946 dy
= (double) (y2
- y1
);
947 l
= sqrt((dx
* dx
) + (dy
* dy
));
949 dx1
= (dx
* length
) / l
;
950 dy1
= (dy
* length
) / l
;
952 dx2
= (dx
* space
) / l
;
953 dy2
= (dy
* space
) / l
;
957 while((d
+ length
+ 2 * space
) < l
) {
962 fprintf(fp
, "[%d %d %d %d] ",
970 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
977 * When the above condition is no more satisfied, then it is not possible
978 * to print a dash of length <B>length</B>.
979 * However two cases are possible :
981 * <DT>*</DT><DD>it is possible to print the dash and the dot.
982 * <DT>*</DT><DD>it is possible to print the dash or a part
983 * of the original dash.
987 if((d
+ length
+ space
) < l
) {
992 fprintf(fp
, "[%d %d %d %d] ",
1000 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1003 if(d
+ length
< l
) {
1011 fprintf(fp
, "[%d %d %d %d] ",
1013 (int) xb
, (int) yb
);
1017 fprintf(fp
,"] %d dashed\n", line_width
);
1020 * A dot is represented by a filled circle. Position of the circle is
1021 * (<B>xa</B>, <B>ya</B>) and its radius by the <B>line_width</B> parameter.
1025 /*! \brief Print a phantom line type line to Postscript document.
1026 * \par Function Description
1027 * This function prints a line when a phantom line type is required.
1028 * The line is defined by the coordinates of its two ends in
1029 * (<B>x1</B>,<B>y1</B>) and (<B>x2</B>,<B>y2</B>).
1030 * The Postscript document is defined by the file pointer <B>fp</B>.
1032 * A negative value for <B>space</B> or <B>length</B> leads to an
1035 * All dimensions are in mils.
1037 * The function sets the color in which the line will be printed and the
1038 * width of the line - that is the width of the dashes and the diameter
1041 * \param [in] w_current The TOPLEVEL object.
1042 * \param [in] fp FILE pointer to Postscript document.
1043 * \param [in] x1 Upper x coordinate.
1044 * \param [in] y1 Upper y coordinate.
1045 * \param [in] x2 Lower x coordinate.
1046 * \param [in] y2 Lower y coordinate.
1047 * \param [in] color Line color.
1048 * \param [in] line_width Width of line.
1049 * \param [in] length Length of a dash.
1050 * \param [in] space Space between dashes.
1051 * \param [in] origin_x Page x coordinate to place line OBJECT.
1052 * \param [in] origin_y Page y coordinate to place line OBJECT.
1054 void o_line_print_phantom(TOPLEVEL
*w_current
, FILE *fp
,
1055 int x1
, int y1
, int x2
, int y2
,
1057 int line_width
, int length
, int space
,
1058 int origin_x
, int origin_y
)
1060 double dx
, dy
, l
, d
;
1061 double dx1
, dy1
, dx2
, dy2
;
1062 double xa
, ya
, xb
, yb
;
1064 if (w_current
->print_color
) {
1065 f_print_set_color(fp
, color
);
1071 * Depending on the slope of the line the <B>length</B> (resp. <B>space</B>)
1072 * parameter is projected on each of the two directions x and y resulting
1073 * in <B>dx1</B> and <B>dy1</B> (resp. <B>dx2</B> and <B>dy2</B>).
1074 * Starting from one end and incrementing alternatively by <B>space</B>
1075 * and <B>length</B> the dashes and dots are printed.
1077 * It prints as many sets of dash-dot-dot as possible.
1079 dx
= (double) (x2
- x1
);
1080 dy
= (double) (y2
- y1
);
1081 l
= sqrt((dx
* dx
) + (dy
* dy
));
1083 dx1
= (dx
* length
) / l
;
1084 dy1
= (dy
* length
) / l
;
1086 dx2
= (dx
* space
) / l
;
1087 dy2
= (dy
* space
) / l
;
1091 while((d
+ length
+ 3 * space
) < l
) {
1096 fprintf(fp
,"[%d %d %d %d] ",
1104 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1110 fprintf(fp
,"[%d %d] ",(int) xa
, (int) ya
);
1117 * When the above condition is no more satisfied, then it is not possible
1118 * to print a complete set of dash-dot-dot.
1119 * However three cases are possible :
1121 * <DT>*</DT><DD>it is possible to print a dash and a dot and a dot.
1122 * <DT>*</DT><DD>it is possible to print a dash and a dot.
1123 * <DT>*</DT><DD>it is possible to print the dash or a part
1124 * of the original dash.
1128 if((d
+ length
+ 2 * space
) < l
) {
1133 fprintf(fp
,"[%d %d %d %d] ",
1141 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1147 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1150 if(d
+ length
+ space
< l
) {
1155 fprintf(fp
,"[%d %d %d %d] ",
1163 fprintf(fp
,"[%d %d] ",(int) xa
, (int)ya
);
1166 if(d
+ length
< l
) {
1174 fprintf(fp
,"[%d %d %d %d] ",
1181 fprintf(fp
,"] %d dashed\n", line_width
);
1186 * \par Function Description
1188 * \param [in] w_current The TOPLEVEL object.
1189 * \param [in] x_scale
1190 * \param [in] y_scale
1191 * \param [in] object
1193 void o_line_scale_world(TOPLEVEL
*w_current
, int x_scale
, int y_scale
,
1196 if (object
== NULL
) printf("lsw NO!\n");
1198 /* scale the line world coords */
1199 object
->line
->x
[0] = object
->line
->x
[0] * x_scale
;
1200 object
->line
->y
[0] = object
->line
->y
[0] * y_scale
;
1201 object
->line
->x
[1] = object
->line
->x
[1] * x_scale
;
1202 object
->line
->y
[1] = object
->line
->y
[1] * y_scale
;
1204 /* update boundingbox */
1205 o_line_recalc(w_current
, object
);
1210 * \par Function Description
1212 * \param [in] w_current The TOPLEVEL object.
1220 int o_line_visible(TOPLEVEL
*w_current
, LINE
*line
,
1221 int *x1
, int *y1
, int *x2
, int *y2
)
1226 /* don't do clipping if this is false */
1227 if (!w_current
->object_clipping
) {
1231 WORLDtoSCREEN( w_current
, line
->x
[0], line
->y
[0], x1
, y1
);
1232 WORLDtoSCREEN( w_current
, line
->x
[1], line
->y
[1], x2
, y2
);
1234 visible
= SCREENclip_change(w_current
, x1
, y1
, x2
, y2
);
1240 * \par Function Description
1242 * \param [in] object
1245 double o_line_length(OBJECT
*object
)
1250 if (!object
->line
) {
1254 dx
= object
->line
->x
[0]-object
->line
->x
[1];
1255 dy
= object
->line
->y
[0]-object
->line
->y
[1];
1257 length
= sqrt((dx
*dx
) + (dy
*dy
));