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)
5 *
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.
10 *
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.
15 *
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
19 */
20
21 /*! \file o_box_basic.c
22 * \brief functions for the box object
23 */
24
25 #include <config.h>
26 #include <math.h>
27 #include <stdio.h>
28
29 #include "libgeda_priv.h"
30
31 #ifdef HAVE_LIBDMALLOC
32 #include <dmalloc.h>
33 #endif
34
35 /*! \brief Create a BOX OBJECT
36 * \par Function Description
37 * This function creates a new object representing a box.
38 *
39 * The box is described by its upper left corner - <B>x1</B>, <B>y1</B> - and
40 * its lower right corner - <B>x2</B>, <B>y2</B>.
41 * The <B>type</B> parameter must be equal to <B>OBJ_BOX</B>. The <B>color</B>
42 * corresponds to the color the box will be drawn with.
43 * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object()
44 * function. The structure describing the box is allocated and initialized
45 * with the parameters given to the function.
46 *
47 * Both the line type and the filling type are set to default values : solid
48 * line type with a width of 0, and no filling. It can be changed after
49 * with the #o_set_line_options() and #o_set_fill_options().
50 *
51 * \param [in] toplevel The TOPLEVEL object.
52 * \param [in] type Box type.
53 * \param [in] color Box border color.
54 * \param [in] x1 Upper x coordinate.
55 * \param [in] y1 Upper y coordinate.
56 * \param [in] x2 Lower x coordinate.
57 * \param [in] y2 Lower y coordinate.
58 * \return The new OBJECT
59 */
o_box_new(TOPLEVEL * toplevel,char type,int color,int x1,int y1,int x2,int y2)60 OBJECT *o_box_new(TOPLEVEL *toplevel,
61 char type, int color,
62 int x1, int y1, int x2, int y2)
63 {
64 OBJECT *new_node;
65 BOX *box;
66
67 /* create the object */
68 new_node = s_basic_new_object(type, "box");
69 new_node->color = color;
70
71 box = (BOX *) g_malloc(sizeof(BOX));
72 new_node->box = box;
73
74 /* describe the box with its upper left and lower right corner */
75 box->upper_x = x1;
76 box->upper_y = y1;
77 box->lower_x = x2;
78 box->lower_y = y2;
79
80 /* line type and filling initialized to default */
81 o_set_line_options(toplevel, new_node,
82 END_NONE, TYPE_SOLID, 0, -1, -1);
83 o_set_fill_options(toplevel, new_node,
84 FILLING_HOLLOW, -1, -1, -1, -1, -1);
85
86 /* compute the bounding box */
87 o_box_recalc(toplevel, new_node);
88
89 return new_node;
90 }
91
92 /*! \brief Copy a box to a list.
93 * \par Function Description
94 * The function #o_box_copy() creates a verbatim copy of the object
95 * pointed by <B>o_current</B> describing a box.
96 *
97 * \param [in] toplevel The TOPLEVEL object.
98 * \param [in] o_current BOX OBJECT to copy.
99 * \return The new OBJECT
100 */
o_box_copy(TOPLEVEL * toplevel,OBJECT * o_current)101 OBJECT *o_box_copy(TOPLEVEL *toplevel, OBJECT *o_current)
102 {
103 OBJECT *new_obj;
104
105 /* A new box object is created with #o_box_new().
106 * Values for its fields are default and need to be modified. */
107 new_obj = o_box_new (toplevel, OBJ_BOX, o_current->color, 0, 0, 0, 0);
108
109 /*
110 * The dimensions of the new box are set with the ones of the original box.
111 * The two boxes have the same line type and the same filling options.
112 *
113 * The coordinates and the values in world unit are computed with
114 * #o_box_recalc().
115 */
116
117 new_obj->box->upper_x = o_current->box->upper_x;
118 new_obj->box->upper_y = o_current->box->upper_y;
119 new_obj->box->lower_x = o_current->box->lower_x;
120 new_obj->box->lower_y = o_current->box->lower_y;
121
122 o_set_line_options(toplevel, new_obj, o_current->line_end,
123 o_current->line_type, o_current->line_width,
124 o_current->line_length, o_current->line_space);
125 o_set_fill_options(toplevel, new_obj,
126 o_current->fill_type, o_current->fill_width,
127 o_current->fill_pitch1, o_current->fill_angle1,
128 o_current->fill_pitch2, o_current->fill_angle2);
129
130 o_box_recalc(toplevel, new_obj);
131
132 /* new_obj->attribute = 0;*/
133
134 return new_obj;
135 }
136
137 /*! \brief Modify a BOX OBJECT's coordinates.
138 * \par Function Description
139 * Modifies the coordinates of all four corners of \a box, by setting
140 * the box to the rectangle enclosed by the points (\a x1, \a y1) and
141 * (\a x2, \a y2).
142 *
143 * \param [in] toplevel current #TOPLEVEL.
144 * \param [in,out] object box #OBJECT to be modified.
145 * \param [in] x1 x coordinate of first corner of box.
146 * \param [in] y1 y coordinate of first corner of box.
147 * \param [in] x2 x coordinate of second corner of box.
148 * \param [in] y2 y coordinate of second corner of box,
149 */
150 void
o_box_modify_all(TOPLEVEL * toplevel,OBJECT * object,int x1,int y1,int x2,int y2)151 o_box_modify_all (TOPLEVEL *toplevel, OBJECT *object,
152 int x1, int y1, int x2, int y2)
153 {
154 o_emit_pre_change_notify (toplevel, object);
155
156 object->box->lower_x = (x1 > x2) ? x1 : x2;
157 object->box->lower_y = (y1 > y2) ? y2 : y1;
158
159 object->box->upper_x = (x1 > x2) ? x2 : x1;
160 object->box->upper_y = (y1 > y2) ? y1 : y2;
161
162 /* recalculate the world coords and bounds */
163 o_box_recalc(toplevel, object);
164 o_emit_change_notify (toplevel, object);
165 }
166
167 /*! \brief Modify a BOX OBJECT's coordinates.
168 * \par Function Description
169 * This function modifies the coordinates of one of the four corner of
170 * the box. The new coordinates of the corner identified by <B>whichone</B>
171 * are given by <B>x</B> and <B>y</B> in world unit.
172 *
173 * The coordinates of the corner is modified in the world coordinate system.
174 * Screen coordinates and boundings are then updated.
175 *
176 * \param [in] toplevel The TOPLEVEL object.
177 * \param [in,out] object BOX OBJECT to be modified.
178 * \param [in] x x coordinate.
179 * \param [in] y y coordinate.
180 * \param [in] whichone coordinate to change.
181 *
182 * \note
183 * <B>whichone</B> can take the following values:
184 * <DL>
185 * <DT>*</DT><DD>BOX_UPPER_LEFT
186 * <DT>*</DT><DD>BOX_LOWER_LEFT
187 * <DT>*</DT><DD>BOX_UPPER_RIGHT
188 * <DT>*</DT><DD>BOX_LOWER_RIGHT
189 * </DL>
190 */
o_box_modify(TOPLEVEL * toplevel,OBJECT * object,int x,int y,int whichone)191 void o_box_modify(TOPLEVEL *toplevel, OBJECT *object,
192 int x, int y, int whichone)
193 {
194 int tmp;
195
196 o_emit_pre_change_notify (toplevel, object);
197
198 /* change the position of the selected corner */
199 switch(whichone) {
200 case BOX_UPPER_LEFT:
201 object->box->upper_x = x;
202 object->box->upper_y = y;
203 break;
204
205 case BOX_LOWER_LEFT:
206 object->box->upper_x = x;
207 object->box->lower_y = y;
208 break;
209
210 case BOX_UPPER_RIGHT:
211 object->box->lower_x = x;
212 object->box->upper_y = y;
213 break;
214
215 case BOX_LOWER_RIGHT:
216 object->box->lower_x = x;
217 object->box->lower_y = y;
218 break;
219
220 default:
221 return;
222 }
223
224 /* need to update the upper left and lower right corners */
225 if(object->box->upper_x > object->box->lower_x) {
226 tmp = object->box->upper_x;
227 object->box->upper_x = object->box->lower_x;
228 object->box->lower_x = tmp;
229 }
230
231 if(object->box->upper_y < object->box->lower_y) {
232 tmp = object->box->upper_y;
233 object->box->upper_y = object->box->lower_y;
234 object->box->lower_y = tmp;
235 }
236
237 /* recalculate the world coords and the boundings */
238 o_box_recalc(toplevel, object);
239 o_emit_change_notify (toplevel, object);
240
241 }
242
243 /*! \brief Create a box from a character string.
244 * \par Function Description
245 * This function gets the description of a box from the <B>*buf</B> character
246 * string.
247 *
248 * Depending on <B>*version</B>, the correct file format is considered.
249 * Currently two file format revisions are supported :
250 * <DL>
251 * <DT>*</DT><DD>the file format used until 20000704 release
252 * <DT>*</DT><DD>the file format used for the releases after 2000704.
253 * </DL>
254 *
255 * \param [in] toplevel The TOPLEVEL object.
256 * \param [in] buf Character string with box description.
257 * \param [in] release_ver libgeda release version number.
258 * \param [in] fileformat_ver libgeda file format version number.
259 * \return The BOX OBJECT that was created, or NULL on error.
260 */
o_box_read(TOPLEVEL * toplevel,const char buf[],unsigned int release_ver,unsigned int fileformat_ver,GError ** err)261 OBJECT *o_box_read (TOPLEVEL *toplevel, const char buf[],
262 unsigned int release_ver, unsigned int fileformat_ver, GError **err)
263 {
264 OBJECT *new_obj;
265 char type;
266 int x1, y1;
267 int width, height;
268 int d_x1, d_y1;
269 int d_x2, d_y2;
270 int color;
271 int box_width, box_space, box_length;
272 int fill_width, angle1, pitch1, angle2, pitch2;
273 int box_end;
274 int box_type;
275 int box_filling;
276
277 if (release_ver <= VERSION_20000704) {
278
279 /*! \note
280 * The old geda file format, i.e. releases 20000704 and older, does not
281 * handle the line type and the filling of the box object. They are set
282 * to default.
283 */
284
285 if (sscanf (buf, "%c %d %d %d %d %d\n",
286 &type, &x1, &y1, &width, &height, &color) != 6) {
287 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object"));
288 return NULL;
289 }
290
291 box_width = 0;
292 box_end = END_NONE;
293 box_type = TYPE_SOLID;
294 box_length = -1;
295 box_space = -1;
296
297 box_filling = FILLING_HOLLOW;
298 fill_width = 0;
299 angle1 = -1;
300 pitch1 = -1;
301 angle2 = -1;
302 pitch2 = -1;
303
304 } else {
305
306 /*! \note
307 * The current line format to describe a box is a space separated list of
308 * characters and numbers in plain ASCII on a single line. The meaning of
309 * each item is described in the file format documentation.
310 */
311 if (sscanf (buf, "%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
312 &type, &x1, &y1, &width, &height, &color,
313 &box_width, &box_end, &box_type, &box_length,
314 &box_space, &box_filling,
315 &fill_width, &angle1, &pitch1, &angle2, &pitch2) != 17) {
316 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object"));
317 return NULL;
318 }
319 }
320
321 if (width == 0 || height == 0) {
322 s_log_message (_("Found a zero width/height box [ %c %d %d %d %d %d ]\n"),
323 type, x1, y1, width, height, color);
324 }
325
326 if (color < 0 || color > MAX_COLORS) {
327 s_log_message (_("Found an invalid color [ %s ]\n"), buf);
328 s_log_message (_("Setting color to default color\n"));
329 color = DEFAULT_COLOR;
330 }
331
332 /*! \note
333 * A box is internally described by its lower right and upper left corner
334 * whereas the line describe it with the lower left corner and the width
335 * and height.
336 *
337 * A new object is allocated, initialized and added to the object list.
338 * Its filling and line type are set according to the values of the field
339 * on the line.
340 */
341
342 /* upper left corner of the box */
343 d_x1 = x1;
344 d_y1 = y1 + height; /* move box origin to top left */
345
346 /* lower right corner of the box */
347 d_x2 = x1 + width; /* end points of the box */
348 d_y2 = y1;
349
350 /* create a new box */
351 new_obj = o_box_new (toplevel, type, color, d_x1, d_y1, d_x2, d_y2);
352 /* set its line options */
353 o_set_line_options (toplevel, new_obj,
354 box_end, box_type, box_width,
355 box_length, box_space);
356 /* set its fill options */
357 o_set_fill_options (toplevel, new_obj,
358 box_filling, fill_width,
359 pitch1, angle1, pitch2, angle2);
360
361 return new_obj;
362 }
363
364 /*! \brief Create a character string representation of a BOX.
365 * \par Function Description
366 * This function formats a string in the buffer <B>*buff</B> to describe the
367 * box object <B>*object</B>.
368 * It follows the post-20000704 release file format that handle the line type
369 * and fill options.
370 *
371 * \param [in] toplevel The TOPLEVEL structure.
372 * \param [in] object The BOX OBJECT to create string from.
373 * \return A pointer to the BOX character string.
374 *
375 * \warning
376 * Caller must g_free returned character string.
377 */
o_box_save(TOPLEVEL * toplevel,OBJECT * object)378 char *o_box_save(TOPLEVEL *toplevel, OBJECT *object)
379 {
380 int x1, y1;
381 int width, height;
382 int box_width, box_space, box_length;
383 int fill_width, angle1, pitch1, angle2, pitch2;
384 OBJECT_END box_end;
385 OBJECT_TYPE box_type;
386 OBJECT_FILLING box_fill;
387 char *buf;
388
389 /*! \note
390 * A box is internally represented by its lower right and upper left corner
391 * whereas it is described in the file format as its lower left corner and
392 * its width and height.
393 */
394
395 /* calculate the width and height of the box */
396 width = abs(object->box->lower_x - object->box->upper_x);
397 height = abs(object->box->upper_y - object->box->lower_y);
398
399 /* calculate the lower left corner of the box */
400 x1 = object->box->upper_x;
401 y1 = object->box->upper_y - height; /* move the origin to 0, 0*/
402
403 #if DEBUG
404 printf("box: %d %d %d %d\n", x1, y1, width, height);
405 #endif
406
407 /* description of the line type for the outline */
408 box_end = object->line_end;
409 box_width = object->line_width;
410 box_type = object->line_type;
411 box_length = object->line_length;
412 box_space = object->line_space;
413
414 /* description of the filling of the box */
415 box_fill = object->fill_type;
416 fill_width = object->fill_width;
417 angle1 = object->fill_angle1;
418 pitch1 = object->fill_pitch1;
419 angle2 = object->fill_angle2;
420 pitch2 = object->fill_pitch2;
421
422 buf = g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
423 object->type,
424 x1, y1, width, height, object->color,
425 box_width, box_end, box_type, box_length, box_space,
426 box_fill,
427 fill_width, angle1, pitch1, angle2, pitch2);
428
429 return(buf);
430 }
431
432 /*! \brief Translate a BOX position in WORLD coordinates by a delta.
433 * \par Function Description
434 * This function applies a translation of (<B>x1</B>,<B>y1</B>) to the box
435 * described by <B>*object</B>. <B>x1</B> and <B>y1</B> are in world unit.
436 *
437 * \param [in] toplevel The TOPLEVEL object.
438 * \param [in] dx x distance to move.
439 * \param [in] dy y distance to move.
440 * \param [in,out] object BOX OBJECT to translate.
441 */
o_box_translate_world(TOPLEVEL * toplevel,int dx,int dy,OBJECT * object)442 void o_box_translate_world(TOPLEVEL *toplevel, int dx, int dy, OBJECT *object)
443 {
444 /* Do world coords */
445 object->box->upper_x = object->box->upper_x + dx;
446 object->box->upper_y = object->box->upper_y + dy;
447 object->box->lower_x = object->box->lower_x + dx;
448 object->box->lower_y = object->box->lower_y + dy;
449
450 /* recalc the screen coords and the bounding box */
451 o_box_recalc(toplevel, object);
452 }
453
454 /*! \brief Rotate BOX OBJECT using WORLD coordinates.
455 * \par Function Description
456 * The function #o_box_rotate_world() rotate the box described by
457 * <B>*object</B> around the (<B>world_centerx</B>, <B>world_centery</B>) point by
458 * <B>angle</B> degrees.
459 * The center of rotation is in world unit.
460 *
461 * \param [in] toplevel The TOPLEVEL object.
462 * \param [in] world_centerx Rotation center x coordinate in WORLD units.
463 * \param [in] world_centery Rotation center y coordinate in WORLD units.
464 * \param [in] angle Rotation angle in degrees (See note below).
465 * \param [in,out] object BOX OBJECT to rotate.
466 *
467 */
o_box_rotate_world(TOPLEVEL * toplevel,int world_centerx,int world_centery,int angle,OBJECT * object)468 void o_box_rotate_world(TOPLEVEL *toplevel,
469 int world_centerx, int world_centery, int angle,
470 OBJECT *object)
471 {
472 int newx1, newy1;
473 int newx2, newy2;
474
475 /*! \note
476 * Only 90 degree multiple and positive angles are allowed.
477 */
478
479 /* angle must be positive */
480 if(angle < 0) angle = -angle;
481 /* angle must be a 90 multiple or no rotation performed */
482 if((angle % 90) != 0) return;
483
484 /*! \note
485 * The center of rotation (<B>world_centerx</B>, <B>world_centery</B>) is
486 * translated to the origin. The rotation of the upper left and lower right
487 * corner are then performed. Finally, the rotated box is translated back
488 * to its previous location.
489 */
490 /* translate object to origin */
491 object->box->upper_x -= world_centerx;
492 object->box->upper_y -= world_centery;
493 object->box->lower_x -= world_centerx;
494 object->box->lower_y -= world_centery;
495
496 /* rotate the upper left corner of the box */
497 rotate_point_90(object->box->upper_x, object->box->upper_y, angle,
498 &newx1, &newy1);
499
500 /* rotate the lower left corner of the box */
501 rotate_point_90(object->box->lower_x, object->box->lower_y, angle,
502 &newx2, &newy2);
503
504 /* reorder the corners after rotation */
505 object->box->upper_x = min(newx1,newx2);
506 object->box->upper_y = max(newy1,newy2);
507 object->box->lower_x = max(newx1,newx2);
508 object->box->lower_y = min(newy1,newy2);
509
510 /* translate object back to normal position */
511 object->box->upper_x += world_centerx;
512 object->box->upper_y += world_centery;
513 object->box->lower_x += world_centerx;
514 object->box->lower_y += world_centery;
515
516 /* recalc boundings and world coords */
517 o_box_recalc(toplevel, object);
518 }
519
520 /*! \brief Mirror BOX using WORLD coordinates.
521 * \par Function Description
522 * This function mirrors the box from the point
523 * (<B>world_centerx</B>,<B>world_centery</B>) in world unit.
524 *
525 * The box is first translated to the origin, then mirrored and finally
526 * translated back at its previous position.
527 *
528 * \param [in] toplevel The TOPLEVEL object.
529 * \param [in] world_centerx Origin x coordinate in WORLD units.
530 * \param [in] world_centery Origin y coordinate in WORLD units.
531 * \param [in,out] object BOX OBJECT to mirror.
532 */
o_box_mirror_world(TOPLEVEL * toplevel,int world_centerx,int world_centery,OBJECT * object)533 void o_box_mirror_world(TOPLEVEL *toplevel,
534 int world_centerx, int world_centery,
535 OBJECT *object)
536 {
537 int newx1, newy1;
538 int newx2, newy2;
539
540 /* translate object to origin */
541 object->box->upper_x -= world_centerx;
542 object->box->upper_y -= world_centery;
543 object->box->lower_x -= world_centerx;
544 object->box->lower_y -= world_centery;
545
546 /* mirror the corners */
547 newx1 = -object->box->upper_x;
548 newy1 = object->box->upper_y;
549 newx2 = -object->box->lower_x;
550 newy2 = object->box->lower_y;
551
552 /* reorder the corners */
553 object->box->upper_x = min(newx1,newx2);
554 object->box->upper_y = max(newy1,newy2);
555 object->box->lower_x = max(newx1,newx2);
556 object->box->lower_y = min(newy1,newy2);
557
558 /* translate back in position */
559 object->box->upper_x += world_centerx;
560 object->box->upper_y += world_centery;
561 object->box->lower_x += world_centerx;
562 object->box->lower_y += world_centery;
563
564 /* recalc boundings and world coords */
565 o_box_recalc(toplevel, object);
566
567 }
568
569 /*! \brief Recalculate BOX coordinates in WORLD units.
570 * \par Function Description
571 * This function recalculates the box coordinates and its
572 * bounding are recalculated as well.
573 *
574 * \param [in] toplevel The TOPLEVEL object.
575 * \param [in,out] o_current BOX OBJECT to be recalculated.
576 */
o_box_recalc(TOPLEVEL * toplevel,OBJECT * o_current)577 void o_box_recalc(TOPLEVEL *toplevel, OBJECT *o_current)
578 {
579 int left, top, right, bottom;
580
581 if (o_current->box == NULL) {
582 return;
583 }
584
585 /* update the bounding box - world unit */
586 world_get_box_bounds(toplevel, o_current, &left, &top, &right, &bottom);
587 o_current->w_left = left;
588 o_current->w_top = top;
589 o_current->w_right = right;
590 o_current->w_bottom = bottom;
591 o_current->w_bounds_valid = TRUE;
592 }
593
594 /*! \brief Get BOX bounding rectangle in WORLD coordinates.
595 * \par Function Description
596 * This function sets the <B>left</B>, <B>top</B>, <B>right</B> and <B>bottom</B>
597 * parameters to the boundings of the box object described in <B>*box</B>
598 * in world units.
599 *
600 * \param [in] toplevel The TOPLEVEL object.
601 * \param [in] object BOX OBJECT to read coordinates from.
602 * \param [out] left Left box coordinate in WORLD units.
603 * \param [out] top Top box coordinate in WORLD units.
604 * \param [out] right Right box coordinate in WORLD units.
605 * \param [out] bottom Bottom box coordinate in WORLD units.
606 */
world_get_box_bounds(TOPLEVEL * toplevel,OBJECT * object,int * left,int * top,int * right,int * bottom)607 void world_get_box_bounds(TOPLEVEL *toplevel, OBJECT *object,
608 int *left, int *top, int *right, int *bottom)
609 {
610 int halfwidth;
611
612 halfwidth = object->line_width / 2;
613
614 *left = min(object->box->upper_x, object->box->lower_x);
615 *top = min(object->box->upper_y, object->box->lower_y);
616 *right = max(object->box->upper_x, object->box->lower_x);
617 *bottom = max(object->box->upper_y, object->box->lower_y);
618
619 /* This isn't strictly correct, but a 1st order approximation */
620 *left -= halfwidth;
621 *top -= halfwidth;
622 *right += halfwidth;
623 *bottom += halfwidth;
624 }
625
626 /*! \brief get the position of the left bottom point
627 * \par Function Description
628 * This function gets the position of the bottom left point of a box object.
629 *
630 * \param [in] toplevel The toplevel environment.
631 * \param [out] x pointer to the x-position
632 * \param [out] y pointer to the y-position
633 * \param [in] object The object to get the position.
634 * \return TRUE if successfully determined the position, FALSE otherwise
635 */
o_box_get_position(TOPLEVEL * toplevel,gint * x,gint * y,OBJECT * object)636 gboolean o_box_get_position (TOPLEVEL *toplevel, gint *x, gint *y,
637 OBJECT *object)
638 {
639 *x = min(object->box->lower_x, object->box->upper_x);
640 *y = min(object->box->lower_y, object->box->upper_y);
641 return TRUE;
642 }
643
644 /*! \brief Print BOX to Postscript document.
645 * \par Function Description
646 * This function prints the box described by the <B>o_current</B>
647 * parameter to a Postscript document. It takes into account its line
648 * type and fill type.
649 * The Postscript document is descibed by the file pointer <B>fp</B>.
650 *
651 * The validity of the <B>o_current</B> parameter is verified : a null pointer
652 * causes an error message and a return.
653 *
654 * The description of the box is extracted from
655 * the <B>o_current</B> parameter :
656 * the coordinates of the box - upper left corner and width and
657 * height of the box -, its line type, its fill type.
658 *
659 * The outline and the inside of the box are successively handled by two
660 * differend sets of functions.
661 *
662 * \param [in] toplevel The TOPLEVEL object.
663 * \param [in] fp FILE pointer to Postscript document.
664 * \param [in] o_current BOX OBJECT to write to document.
665 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
666 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
667 */
o_box_print(TOPLEVEL * toplevel,FILE * fp,OBJECT * o_current,int origin_x,int origin_y)668 void o_box_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current,
669 int origin_x, int origin_y)
670 {
671 int x, y, width, height;
672 int color;
673 int line_width, length, space;
674 int fill_width, angle1, pitch1, angle2, pitch2;
675 void (*outl_func)() = NULL;
676 void (*fill_func)() = NULL;
677
678 if (o_current == NULL) {
679 printf("got null in o_box_print\n");
680 return;
681 }
682
683 x = o_current->box->upper_x;
684 y = o_current->box->upper_y;
685 width = abs(o_current->box->lower_x - o_current->box->upper_x);
686 height = abs(o_current->box->lower_y - o_current->box->upper_y);
687 color = o_current->color;
688
689 /*! \note
690 * Depending on the type of the line for this particular box, the
691 * appropriate function is chosen among #o_box_print_solid(),
692 * #o_box_print_dotted(), #o_box_print_dashed(),
693 * #o_box_print_center() and #o_box_print_phantom().
694 *
695 * The needed parameters for each of these type is extracted from the
696 * <B>o_current</B> object. Depending on the type, unused parameters are
697 * set to -1.
698 *
699 * In the eventuality of a length and/or space null, the line is printed
700 * solid to avoid and endless loop produced by other functions in such a
701 * case.
702 */
703 line_width = o_current->line_width;
704
705 if(line_width <=2) {
706 if(toplevel->line_style == THICK) {
707 line_width=LINE_WIDTH;
708 } else {
709 line_width=2;
710 }
711 }
712 length = o_current->line_length;
713 space = o_current->line_space;
714
715 switch(o_current->line_type) {
716 case(TYPE_SOLID):
717 length = -1; space = -1;
718 outl_func = o_box_print_solid;
719 break;
720
721 case(TYPE_DOTTED):
722 length = -1;
723 outl_func = o_box_print_dotted;
724 break;
725
726 case(TYPE_DASHED):
727 outl_func = o_box_print_dashed;
728 break;
729
730 case(TYPE_CENTER):
731 outl_func = o_box_print_center;
732 break;
733
734 case(TYPE_PHANTOM):
735 outl_func = o_box_print_phantom;
736 break;
737
738 case(TYPE_ERASE):
739 /* Unused for now, print it solid */
740 length = -1; space = -1;
741 outl_func = o_box_print_solid;
742 break;
743 }
744
745 if((length == 0) || (space == 0)) {
746 length = -1; space = -1;
747 outl_func = o_box_print_solid;
748 }
749
750 (*outl_func)(toplevel, fp,
751 x, y, width, height,
752 color,
753 line_width,
754 length, space,
755 origin_x, origin_y);
756
757 /*! \note
758 * If the filling type of the box is not <B>HOLLOW</B>, the appropriate
759 * function is chosen among #o_box_print_filled(), #o_box_print_mesh()
760 * and #o_box_print_hatch(). The corresponding parameters are extracted
761 * from the <B>o_current</B> object and corrected afterward.
762 *
763 * The case where <B>pitch1</B> and <B>pitch2</B> are null or negative is
764 * avoided as it leads to an endless loop in most of the called functions.
765 * In such a case, the box is printed filled. Unused parameters for each of
766 * these functions are set to -1 or any passive value.
767 */
768 if(o_current->fill_type != FILLING_HOLLOW) {
769 fill_width = o_current->fill_width;
770 angle1 = o_current->fill_angle1;
771 pitch1 = o_current->fill_pitch1;
772 angle2 = o_current->fill_angle2;
773 pitch2 = o_current->fill_pitch2;
774
775 switch(o_current->fill_type) {
776 case(FILLING_FILL):
777 angle1 = -1; pitch1 = 1;
778 angle2 = -1; pitch2 = 1;
779 fill_width = -1;
780 fill_func = o_box_print_filled;
781 break;
782
783 case(FILLING_MESH):
784 fill_func = o_box_print_mesh;
785 break;
786
787 case(FILLING_HATCH):
788 angle2 = -1; pitch2 = 1;
789 fill_func = o_box_print_hatch;
790 break;
791
792 case(FILLING_VOID):
793 /* Unused for now, print it filled */
794 angle1 = -1; pitch1 = 1;
795 angle2 = -1; pitch2 = 1;
796 fill_width = -1;
797 fill_func = o_box_print_filled;
798 break;
799 case(FILLING_HOLLOW):
800 /* nop */
801 break;
802
803 }
804
805 if((pitch1 <= 0) || (pitch2 <= 0)) {
806 angle1 = -1; pitch1 = 1;
807 angle2 = -1; pitch2 = 1;
808 fill_func = o_box_print_filled;
809 }
810
811 (*fill_func)(toplevel, fp,
812 x, y, width, height,
813 color,
814 fill_width,
815 angle1, pitch1, angle2, pitch2,
816 origin_x, origin_y);
817 }
818 }
819
820 /*! \brief Print a solid BOX to Postscript document.
821 * \par Function Description
822 * This function prints the outline of a box when a solid line type is
823 * required. The box is defined by the coordinates of its upper left corner
824 * in (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
825 * <B>height</B> parameters.
826 * The postscript file is defined by the file pointer <B>fp</B>.
827 * The parameters <B>length</B> and <B>space</B> are ignored.
828 *
829 * It uses the function #o_line_print_solid() to print the outline.
830 * It performs four calls to this function, one for each of its side.
831 *
832 * All dimensions are in mils.
833 *
834 * \param [in] toplevel The TOPLEVEL object.
835 * \param [in] fp FILE pointer to Postscript document.
836 * \param [in] x Upper x coordinate of BOX.
837 * \param [in] y Upper y coordinate of BOX.
838 * \param [in] width Width of BOX.
839 * \param [in] height Height of BOX.
840 * \param [in] color BOX color.
841 * \param [in] line_width BOX Line width.
842 * \param [in] length Dashed line length.
843 * \param [in] space Amount of space between dashes.
844 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
845 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
846 */
847 void
o_box_print_solid(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int line_width,int length,int space,int origin_x,int origin_y)848 o_box_print_solid(TOPLEVEL *toplevel, FILE *fp,
849 int x, int y,
850 int width, int height,
851 int color,
852 int line_width, int length, int space,
853 int origin_x, int origin_y)
854 {
855 int x1, y1;
856
857 f_print_set_color(toplevel, fp, color);
858
859 x1 = x;
860 y1 = y - height; /* move the origin to 0, 0*/
861
862 o_line_print_solid(toplevel, fp,
863 x1, y1, x1 + width, y1,
864 color,
865 line_width, length, space,
866 origin_x, origin_y);
867 o_line_print_solid(toplevel, fp,
868 x1 + width, y1, x1 + width, y1 + height,
869 color,
870 line_width, length, space,
871 origin_x, origin_y);
872 o_line_print_solid(toplevel, fp,
873 x1 + width, y1 + height, x1, y1 + height,
874 color,
875 line_width, length, space,
876 origin_x, origin_y);
877 o_line_print_solid(toplevel, fp,
878 x1, y1 + height, x1, y1,
879 color,
880 line_width, length, space,
881 origin_x, origin_y);
882 }
883
884 /*! \brief Print a dotted BOX to Postscript document.
885 * \par Function Description
886 * This function prints the outline of a box when a dotted line type is
887 * required. The box is defined by the coordinates of its upper left corner
888 * in (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
889 * <B>height</B> parameters.
890 * The postscript file is defined by the file pointer <B>fp</B>.
891 * The parameters <B>length</B> is ignored.
892 *
893 * It uses the function #o_line_print_dotted() to print the outline.
894 * It performs four calls to this function, one for each of its side.
895 *
896 * All dimensions are in mils.
897 *
898 * \param [in] toplevel The TOPLEVEL object.
899 * \param [in] fp FILE pointer to Postscript document.
900 * \param [in] x Upper x coordinate of BOX.
901 * \param [in] y Upper y coordinate of BOX.
902 * \param [in] width Width of BOX.
903 * \param [in] height Height of BOX.
904 * \param [in] color BOX color.
905 * \param [in] line_width BOX Line width.
906 * \param [in] length Dashed line length.
907 * \param [in] space Amount of space between dashes.
908 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
909 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
910 */
o_box_print_dotted(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int line_width,int length,int space,int origin_x,int origin_y)911 void o_box_print_dotted(TOPLEVEL *toplevel, FILE *fp,
912 int x, int y,
913 int width, int height,
914 int color,
915 int line_width, int length, int space,
916 int origin_x, int origin_y)
917 {
918 int x1, y1;
919
920 f_print_set_color(toplevel, fp, color);
921
922 x1 = x;
923 y1 = y - height; /* move the origin to 0, 0*/
924
925 o_line_print_dotted(toplevel, fp,
926 x1, y1, x1 + width, y1,
927 color,
928 line_width, length, space,
929 origin_x, origin_y);
930 o_line_print_dotted(toplevel, fp,
931 x1 + width, y1, x1 + width, y1 + height,
932 color,
933 line_width, length, space,
934 origin_x, origin_y);
935 o_line_print_dotted(toplevel, fp,
936 x1 + width, y1 + height, x1, y1 + height,
937 color,
938 line_width, length, space,
939 origin_x, origin_y);
940 o_line_print_dotted(toplevel, fp,
941 x1, y1 + height, x1, y1,
942 color,
943 line_width, length, space,
944 origin_x, origin_y);
945 }
946
947 /*! \brief Print a dashed BOX to Postscript document.
948 * \par Function Description
949 * This function prints the outline of a box when a dashed line type is
950 * required. The box is defined by the coordinates of its upper left corner
951 * in (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
952 * <B>height</B> parameters.
953 * The postscript file is defined by the file pointer <B>fp</B>.
954 *
955 * It uses the function #o_line_print_dashed() to print the outline.
956 * It performs four calls to this function, one for each of its side.
957 *
958 * All dimensions are in mils.
959 *
960 * \param [in] toplevel The TOPLEVEL object.
961 * \param [in] fp FILE pointer to Postscript document.
962 * \param [in] x Upper x coordinate of BOX.
963 * \param [in] y Upper y coordinate of BOX.
964 * \param [in] width Width of BOX.
965 * \param [in] height Height of BOX.
966 * \param [in] color BOX color.
967 * \param [in] line_width BOX Line width.
968 * \param [in] length Dashed line length.
969 * \param [in] space Amount of space between dashes.
970 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
971 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
972 */
o_box_print_dashed(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int line_width,int length,int space,int origin_x,int origin_y)973 void o_box_print_dashed(TOPLEVEL *toplevel, FILE *fp,
974 int x, int y,
975 int width, int height,
976 int color,
977 int line_width, int length, int space,
978 int origin_x, int origin_y)
979 {
980 int x1, y1;
981
982 f_print_set_color(toplevel, fp, color);
983
984
985 x1 = x;
986 y1 = y - height; /* move the origin to 0, 0*/
987
988 o_line_print_dashed(toplevel, fp,
989 x1, y1, x1 + width, y1,
990 color,
991 line_width, length, space,
992 origin_x, origin_y);
993 o_line_print_dashed(toplevel, fp,
994 x1 + width, y1, x1 + width, y1 + height,
995 color,
996 line_width, length, space,
997 origin_x, origin_y);
998 o_line_print_dashed(toplevel, fp,
999 x1 + width, y1 + height, x1, y1 + height,
1000 color,
1001 line_width, length, space,
1002 origin_x, origin_y);
1003 o_line_print_dashed(toplevel, fp,
1004 x1, y1 + height, x1, y1,
1005 color,
1006 line_width, length, space,
1007 origin_x, origin_y);
1008 }
1009
1010 /*! \brief Print centered line type BOX to Postscript document.
1011 * \par Function Description
1012 * This function prints the outline of a box when a centered line type is
1013 * required. The box is defined by the coordinates of its upper left corner
1014 * in (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
1015 * <B>height</B> parameters.
1016 * The postscript file is defined by the file pointer <B>fp</B>.
1017 *
1018 * It uses the function #o_line_print_center() to print the outline.
1019 * It performs four calls to this function, one for each of its side.
1020 *
1021 * All dimensions are in mils.
1022 *
1023 * \param [in] toplevel The TOPLEVEL object.
1024 * \param [in] fp FILE pointer to Postscript document.
1025 * \param [in] x Upper x coordinate of BOX.
1026 * \param [in] y Upper y coordinate of BOX.
1027 * \param [in] width Width of BOX.
1028 * \param [in] height Height of BOX.
1029 * \param [in] color BOX color.
1030 * \param [in] line_width BOX Line width.
1031 * \param [in] length Dashed line length.
1032 * \param [in] space Amount of space between dashes.
1033 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
1034 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
1035 */
o_box_print_center(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int line_width,int length,int space,int origin_x,int origin_y)1036 void o_box_print_center(TOPLEVEL *toplevel, FILE *fp,
1037 int x, int y,
1038 int width, int height,
1039 int color,
1040 int line_width, int length, int space,
1041 int origin_x, int origin_y)
1042 {
1043 int x1, y1;
1044
1045 f_print_set_color(toplevel, fp, color);
1046
1047 x1 = x;
1048 y1 = y - height; /* move the origin to 0, 0*/
1049
1050 o_line_print_center(toplevel, fp,
1051 x1, y1, x1 + width, y1,
1052 color,
1053 line_width, length, space,
1054 origin_x, origin_y);
1055 o_line_print_center(toplevel, fp,
1056 x1 + width, y1, x1 + width, y1 + height,
1057 color,
1058 line_width, length, space,
1059 origin_x, origin_y);
1060 o_line_print_center(toplevel, fp,
1061 x1 + width, y1 + height, x1, y1 + height,
1062 color,
1063 line_width, length, space,
1064 origin_x, origin_y);
1065 o_line_print_center(toplevel, fp,
1066 x1, y1 + height, x1, y1,
1067 color,
1068 line_width, length, space,
1069 origin_x, origin_y);
1070 }
1071
1072 /*! \brief Print phantom line type BOX to Postscript document.
1073 * \par Function Description
1074 * This function prints the outline of a box when a phantom line type is
1075 * required. The box is defined by the coordinates of its upper left corner
1076 * in (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
1077 * <B>height</B> parameters.
1078 * The postscript file is defined by the file pointer <B>fp</B>.
1079 *
1080 * It uses the function #o_line_print_phantom() to print the outline.
1081 * It performs four calls to this function, one for each of its side.
1082 *
1083 * All dimensions are in mils.
1084 *
1085 * \param [in] toplevel The TOPLEVEL object.
1086 * \param [in] fp FILE pointer to Postscript document.
1087 * \param [in] x Upper x coordinate of BOX.
1088 * \param [in] y Upper y coordinate of BOX.
1089 * \param [in] width Width of BOX.
1090 * \param [in] height Height of BOX.
1091 * \param [in] color BOX color.
1092 * \param [in] line_width BOX Line width.
1093 * \param [in] length Dashed line length.
1094 * \param [in] space Amount of space between dashes.
1095 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
1096 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
1097 */
o_box_print_phantom(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int line_width,int length,int space,int origin_x,int origin_y)1098 void o_box_print_phantom(TOPLEVEL *toplevel, FILE *fp,
1099 int x, int y,
1100 int width, int height,
1101 int color,
1102 int line_width, int length, int space,
1103 int origin_x, int origin_y)
1104 {
1105 int x1, y1;
1106
1107 f_print_set_color(toplevel, fp, color);
1108
1109 x1 = x;
1110 y1 = y - height; /* move the origin to 0, 0*/
1111
1112 o_line_print_phantom(toplevel, fp,
1113 x1, y1, x1 + width, y1,
1114 color,
1115 line_width, length, space,
1116 origin_x, origin_y);
1117 o_line_print_phantom(toplevel, fp,
1118 x1 + width, y1, x1 + width, y1 + height,
1119 color,
1120 line_width, length, space,
1121 origin_x, origin_y);
1122 o_line_print_phantom(toplevel, fp,
1123 x1 + width, y1 + height, x1, y1 + height,
1124 color,
1125 line_width, length, space,
1126 origin_x, origin_y);
1127 o_line_print_phantom(toplevel, fp,
1128 x1, y1 + height, x1, y1,
1129 color,
1130 line_width, length, space,
1131 origin_x, origin_y);
1132 }
1133
1134 /*! \brief Print a solid pattern BOX to Postscript document.
1135 * \par Function Description
1136 * The function prints a filled box with a solid pattern. No outline is
1137 * printed.
1138 * The box is defined by the coordinates of its upper left corner in
1139 * (<B>x</B>,<B>y</B>) and its width and height given by the <B>width</B> and
1140 * <B>height</B> parameters. The postscript file is defined by the file
1141 * pointer <B>fp</B>.
1142 * <B>fill_width</B>, <B>angle1</B> and <B>pitch1</B>, <B>angle2</B> and <B>pitch2</B>
1143 * parameters are ignored in this functions but kept for compatibility
1144 * with other fill functions.
1145 *
1146 * It uses the fbox postscript function defined in the prolog to
1147 * specify a filled box.
1148 *
1149 * All dimensions are in mils.
1150 *
1151 * \param [in] toplevel The TOPLEVEL object.
1152 * \param [in] fp FILE pointer to Postscript document.
1153 * \param [in] x Upper x coordinate of BOX.
1154 * \param [in] y Upper y coordinate of BOX.
1155 * \param [in] width Width of BOX.
1156 * \param [in] height Height of BOX.
1157 * \param [in] color BOX color.
1158 * \param [in] fill_width BOX fill width. (unused).
1159 * \param [in] angle1 (unused).
1160 * \param [in] pitch1 (unused).
1161 * \param [in] angle2 (unused).
1162 * \param [in] pitch2 (unused).
1163 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
1164 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
1165 */
o_box_print_filled(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int fill_width,int angle1,int pitch1,int angle2,int pitch2,int origin_x,int origin_y)1166 void o_box_print_filled(TOPLEVEL *toplevel, FILE *fp,
1167 int x, int y,
1168 int width, int height,
1169 int color,
1170 int fill_width,
1171 int angle1, int pitch1,
1172 int angle2, int pitch2,
1173 int origin_x, int origin_y)
1174 {
1175 int x1, y1;
1176
1177 f_print_set_color(toplevel, fp, color);
1178
1179 x1 = x;
1180 y1 = y-height; /* move the origin to 0, 0*/
1181 fprintf(fp, "%d %d %d %d fbox\n",
1182 width, height,
1183 x1-origin_x, y1-origin_y);
1184
1185 }
1186
1187 /*! \brief Print a mesh pattern BOX to Postscript document.
1188 * \par Function Description
1189 * This function prints a meshed box. No outline is printed. The box is
1190 * defined by the coordinates of its upper left corner in (<B>x</B>,<B>y</B>) and
1191 * its width and height given by the <B>width</B> and <B>height</B> parameters.
1192 * The postscript file is defined by the file pointer <B>fp</B>.
1193 *
1194 * The inside mesh is achieved by two successive call to the
1195 * #o_box_print_hatch() function, given <B>angle1</B> and <B>pitch1</B> the first
1196 * time and <B>angle2</B> and <B>pitch2</B> the second time.
1197 *
1198 * Negative or null values for <B>pitch1</B> and/or <B>pitch2</B> are not allowed
1199 * as it leads to an endless loop in #o_box_print_hatch().
1200 *
1201 * All dimensions are in mils.
1202 *
1203 * \param [in] toplevel The TOPLEVEL object.
1204 * \param [in] fp FILE pointer to Postscript document.
1205 * \param [in] x Upper x coordinate of BOX.
1206 * \param [in] y Upper y coordinate of BOX.
1207 * \param [in] width Width of BOX.
1208 * \param [in] height Height of BOX.
1209 * \param [in] color BOX color.
1210 * \param [in] fill_width BOX fill width.
1211 * \param [in] angle1 1st angle for mesh pattern.
1212 * \param [in] pitch1 1st pitch for mesh pattern.
1213 * \param [in] angle2 2nd angle for mesh pattern.
1214 * \param [in] pitch2 2nd pitch for mesh pattern.
1215 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
1216 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
1217 */
o_box_print_mesh(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int fill_width,int angle1,int pitch1,int angle2,int pitch2,int origin_x,int origin_y)1218 void o_box_print_mesh(TOPLEVEL *toplevel, FILE *fp,
1219 int x, int y,
1220 int width, int height,
1221 int color,
1222 int fill_width,
1223 int angle1, int pitch1,
1224 int angle2, int pitch2,
1225 int origin_x, int origin_y)
1226 {
1227 o_box_print_hatch(toplevel, fp,
1228 x, y, width, height,
1229 color,
1230 fill_width,
1231 angle1, pitch1, -1, -1,
1232 origin_x, origin_y);
1233 o_box_print_hatch(toplevel, fp,
1234 x, y, width, height,
1235 color,
1236 fill_width,
1237 angle2, pitch2, -1, -1,
1238 origin_x, origin_y);
1239
1240 }
1241
1242 /*! \brief Print a hatch pattern BOX to Postscript document.
1243 * \par Function Description
1244 * The function prints a hatched box. No outline is printed. The box is
1245 * defined by the coordinates of its upper left corner in (<B>x</B>,<B>y</B>) and
1246 * its width and height given by the <B>width</B> and <B>height</B> parameters.
1247 * The postscript file is defined by the file pointer <B>fp</B>.
1248 * <B>fill_width</B>, <B>angle1</B>, <B>pitch1</B> parameters define the way the box
1249 * has to be hatched.
1250 * <B>angle2</B> and <B>pitch2</B> parameters are unused but kept for compatibility
1251 * with other fill functions.
1252 *
1253 * Negative or null values for <B>pitch1</B> are not allowed as it leads to an
1254 * endless loop.
1255 *
1256 * All dimensions are in mils.
1257 *
1258 * \param [in] toplevel The TOPLEVEL object.
1259 * \param [in] fp FILE pointer to Postscript document.
1260 * \param [in] x Upper x coordinate of BOX.
1261 * \param [in] y Upper y coordinate of BOX.
1262 * \param [in] width Width of BOX.
1263 * \param [in] height Height of BOX.
1264 * \param [in] color BOX color.
1265 * \param [in] fill_width BOX fill width.
1266 * \param [in] angle1 Angle of hatch pattern.
1267 * \param [in] pitch1 Pitch of hatch pattern.
1268 * \param [in] angle2 (unused).
1269 * \param [in] pitch2 (unused).
1270 * \param [in] origin_x Page x coordinate to place BOX OBJECT.
1271 * \param [in] origin_y Page y coordinate to place BOX OBJECT.
1272 */
o_box_print_hatch(TOPLEVEL * toplevel,FILE * fp,int x,int y,int width,int height,int color,int fill_width,int angle1,int pitch1,int angle2,int pitch2,int origin_x,int origin_y)1273 void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp,
1274 int x, int y,
1275 int width, int height,
1276 int color,
1277 int fill_width,
1278 int angle1, int pitch1,
1279 int angle2, int pitch2,
1280 int origin_x, int origin_y)
1281 {
1282 BOX box;
1283 gint index;
1284 GArray *lines;
1285
1286 g_return_if_fail(toplevel != NULL);
1287 g_return_if_fail(fp != NULL);
1288
1289 f_print_set_color(toplevel, fp, color);
1290
1291 /* Avoid printing line widths too small */
1292 if (fill_width <= 1) fill_width = 2;
1293
1294 lines = g_array_new(FALSE, FALSE, sizeof(LINE));
1295
1296 box.upper_x = x;
1297 box.upper_y = y;
1298 box.lower_x = x + width;
1299 box.lower_y = y - height; /* Hmmm... */
1300
1301 m_hatch_box(&box, angle1, pitch1, lines);
1302
1303 for(index=0; index<lines->len; index++) {
1304 LINE *line = &g_array_index(lines, LINE, index);
1305
1306 fprintf(fp,"%d %d %d %d %d line\n",
1307 line->x[0], line->y[0],
1308 line->x[1], line->y[1],
1309 fill_width);
1310 }
1311
1312 g_array_free(lines, TRUE);
1313 }
1314
1315 /*! \brief Calculates the distance between the given point and the closest
1316 * point on the perimeter of the box.
1317 *
1318 * \param [in] object The box OBJECT.
1319 * \param [in] x The x coordinate of the given point.
1320 * \param [in] y The y coordinate of the given point.
1321 * \param [in] force_solid If true, force treating the object as solid.
1322 * \return The shortest distance from the object to the point. With an
1323 * invalid parameter, this function returns G_MAXDOUBLE.
1324 */
o_box_shortest_distance(OBJECT * object,int x,int y,int force_solid)1325 double o_box_shortest_distance (OBJECT *object, int x, int y, int force_solid)
1326 {
1327 int solid;
1328
1329 g_return_val_if_fail (object->box != NULL, G_MAXDOUBLE);
1330
1331 solid = force_solid || object->fill_type != FILLING_HOLLOW;
1332
1333 return m_box_shortest_distance (object->box, x, y, solid);
1334 }
1335
1336