libgeda
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * libgeda - gEDA's library 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00025 #include <config.h> 00026 #include <math.h> 00027 #include <stdio.h> 00028 00029 #include "libgeda_priv.h" 00030 00031 #ifdef HAVE_LIBDMALLOC 00032 #include <dmalloc.h> 00033 #endif 00034 00060 OBJECT *o_box_new(TOPLEVEL *toplevel, 00061 char type, int color, 00062 int x1, int y1, int x2, int y2) 00063 { 00064 OBJECT *new_node; 00065 BOX *box; 00066 00067 /* create the object */ 00068 new_node = s_basic_new_object(type, "box"); 00069 new_node->color = color; 00070 00071 box = (BOX *) g_malloc(sizeof(BOX)); 00072 new_node->box = box; 00073 00074 /* describe the box with its upper left and lower right corner */ 00075 box->upper_x = x1; 00076 box->upper_y = y1; 00077 box->lower_x = x2; 00078 box->lower_y = y2; 00079 00080 /* line type and filling initialized to default */ 00081 o_set_line_options(toplevel, new_node, 00082 END_NONE, TYPE_SOLID, 0, -1, -1); 00083 o_set_fill_options(toplevel, new_node, 00084 FILLING_HOLLOW, -1, -1, -1, -1, -1); 00085 00086 /* compute the bounding box */ 00087 o_box_recalc(toplevel, new_node); 00088 00089 return new_node; 00090 } 00091 00101 OBJECT *o_box_copy(TOPLEVEL *toplevel, OBJECT *o_current) 00102 { 00103 OBJECT *new_obj; 00104 00105 /* A new box object is created with #o_box_new(). 00106 * Values for its fields are default and need to be modified. */ 00107 new_obj = o_box_new (toplevel, OBJ_BOX, o_current->color, 0, 0, 0, 0); 00108 00109 /* 00110 * The dimensions of the new box are set with the ones of the original box. 00111 * The two boxes have the same line type and the same filling options. 00112 * 00113 * The coordinates and the values in world unit are computed with 00114 * #o_box_recalc(). 00115 */ 00116 00117 new_obj->box->upper_x = o_current->box->upper_x; 00118 new_obj->box->upper_y = o_current->box->upper_y; 00119 new_obj->box->lower_x = o_current->box->lower_x; 00120 new_obj->box->lower_y = o_current->box->lower_y; 00121 00122 o_set_line_options(toplevel, new_obj, o_current->line_end, 00123 o_current->line_type, o_current->line_width, 00124 o_current->line_length, o_current->line_space); 00125 o_set_fill_options(toplevel, new_obj, 00126 o_current->fill_type, o_current->fill_width, 00127 o_current->fill_pitch1, o_current->fill_angle1, 00128 o_current->fill_pitch2, o_current->fill_angle2); 00129 00130 o_box_recalc(toplevel, new_obj); 00131 00132 /* new_obj->attribute = 0;*/ 00133 00134 return new_obj; 00135 } 00136 00150 void 00151 o_box_modify_all (TOPLEVEL *toplevel, OBJECT *object, 00152 int x1, int y1, int x2, int y2) 00153 { 00154 o_emit_pre_change_notify (toplevel, object); 00155 00156 object->box->lower_x = (x1 > x2) ? x1 : x2; 00157 object->box->lower_y = (y1 > y2) ? y2 : y1; 00158 00159 object->box->upper_x = (x1 > x2) ? x2 : x1; 00160 object->box->upper_y = (y1 > y2) ? y1 : y2; 00161 00162 /* recalculate the world coords and bounds */ 00163 o_box_recalc(toplevel, object); 00164 o_emit_change_notify (toplevel, object); 00165 } 00166 00191 void o_box_modify(TOPLEVEL *toplevel, OBJECT *object, 00192 int x, int y, int whichone) 00193 { 00194 int tmp; 00195 00196 o_emit_pre_change_notify (toplevel, object); 00197 00198 /* change the position of the selected corner */ 00199 switch(whichone) { 00200 case BOX_UPPER_LEFT: 00201 object->box->upper_x = x; 00202 object->box->upper_y = y; 00203 break; 00204 00205 case BOX_LOWER_LEFT: 00206 object->box->upper_x = x; 00207 object->box->lower_y = y; 00208 break; 00209 00210 case BOX_UPPER_RIGHT: 00211 object->box->lower_x = x; 00212 object->box->upper_y = y; 00213 break; 00214 00215 case BOX_LOWER_RIGHT: 00216 object->box->lower_x = x; 00217 object->box->lower_y = y; 00218 break; 00219 00220 default: 00221 return; 00222 } 00223 00224 /* need to update the upper left and lower right corners */ 00225 if(object->box->upper_x > object->box->lower_x) { 00226 tmp = object->box->upper_x; 00227 object->box->upper_x = object->box->lower_x; 00228 object->box->lower_x = tmp; 00229 } 00230 00231 if(object->box->upper_y < object->box->lower_y) { 00232 tmp = object->box->upper_y; 00233 object->box->upper_y = object->box->lower_y; 00234 object->box->lower_y = tmp; 00235 } 00236 00237 /* recalculate the world coords and the boundings */ 00238 o_box_recalc(toplevel, object); 00239 o_emit_change_notify (toplevel, object); 00240 00241 } 00242 00261 OBJECT *o_box_read (TOPLEVEL *toplevel, const char buf[], 00262 unsigned int release_ver, unsigned int fileformat_ver, GError **err) 00263 { 00264 OBJECT *new_obj; 00265 char type; 00266 int x1, y1; 00267 int width, height; 00268 int d_x1, d_y1; 00269 int d_x2, d_y2; 00270 int color; 00271 int box_width, box_space, box_length; 00272 int fill_width, angle1, pitch1, angle2, pitch2; 00273 int box_end; 00274 int box_type; 00275 int box_filling; 00276 00277 if (release_ver <= VERSION_20000704) { 00278 00285 if (sscanf (buf, "%c %d %d %d %d %d\n", 00286 &type, &x1, &y1, &width, &height, &color) != 6) { 00287 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object")); 00288 return NULL; 00289 } 00290 00291 box_width = 0; 00292 box_end = END_NONE; 00293 box_type = TYPE_SOLID; 00294 box_length = -1; 00295 box_space = -1; 00296 00297 box_filling = FILLING_HOLLOW; 00298 fill_width = 0; 00299 angle1 = -1; 00300 pitch1 = -1; 00301 angle2 = -1; 00302 pitch2 = -1; 00303 00304 } else { 00305 00311 if (sscanf (buf, "%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", 00312 &type, &x1, &y1, &width, &height, &color, 00313 &box_width, &box_end, &box_type, &box_length, 00314 &box_space, &box_filling, 00315 &fill_width, &angle1, &pitch1, &angle2, &pitch2) != 17) { 00316 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object")); 00317 return NULL; 00318 } 00319 } 00320 00321 if (width == 0 || height == 0) { 00322 s_log_message (_("Found a zero width/height box [ %c %d %d %d %d %d ]\n"), 00323 type, x1, y1, width, height, color); 00324 } 00325 00326 if (color < 0 || color > MAX_COLORS) { 00327 s_log_message (_("Found an invalid color [ %s ]\n"), buf); 00328 s_log_message (_("Setting color to default color\n")); 00329 color = DEFAULT_COLOR; 00330 } 00331 00342 /* upper left corner of the box */ 00343 d_x1 = x1; 00344 d_y1 = y1 + height; /* move box origin to top left */ 00345 00346 /* lower right corner of the box */ 00347 d_x2 = x1 + width; /* end points of the box */ 00348 d_y2 = y1; 00349 00350 /* create a new box */ 00351 new_obj = o_box_new (toplevel, type, color, d_x1, d_y1, d_x2, d_y2); 00352 /* set its line options */ 00353 o_set_line_options (toplevel, new_obj, 00354 box_end, box_type, box_width, 00355 box_length, box_space); 00356 /* set its fill options */ 00357 o_set_fill_options (toplevel, new_obj, 00358 box_filling, fill_width, 00359 pitch1, angle1, pitch2, angle2); 00360 00361 return new_obj; 00362 } 00363 00378 char *o_box_save(TOPLEVEL *toplevel, OBJECT *object) 00379 { 00380 int x1, y1; 00381 int width, height; 00382 int box_width, box_space, box_length; 00383 int fill_width, angle1, pitch1, angle2, pitch2; 00384 OBJECT_END box_end; 00385 OBJECT_TYPE box_type; 00386 OBJECT_FILLING box_fill; 00387 char *buf; 00388 00395 /* calculate the width and height of the box */ 00396 width = abs(object->box->lower_x - object->box->upper_x); 00397 height = abs(object->box->upper_y - object->box->lower_y); 00398 00399 /* calculate the lower left corner of the box */ 00400 x1 = object->box->upper_x; 00401 y1 = object->box->upper_y - height; /* move the origin to 0, 0*/ 00402 00403 #if DEBUG 00404 printf("box: %d %d %d %d\n", x1, y1, width, height); 00405 #endif 00406 00407 /* description of the line type for the outline */ 00408 box_end = object->line_end; 00409 box_width = object->line_width; 00410 box_type = object->line_type; 00411 box_length = object->line_length; 00412 box_space = object->line_space; 00413 00414 /* description of the filling of the box */ 00415 box_fill = object->fill_type; 00416 fill_width = object->fill_width; 00417 angle1 = object->fill_angle1; 00418 pitch1 = object->fill_pitch1; 00419 angle2 = object->fill_angle2; 00420 pitch2 = object->fill_pitch2; 00421 00422 buf = g_strdup_printf("%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", 00423 object->type, 00424 x1, y1, width, height, object->color, 00425 box_width, box_end, box_type, box_length, box_space, 00426 box_fill, 00427 fill_width, angle1, pitch1, angle2, pitch2); 00428 00429 return(buf); 00430 } 00431 00442 void o_box_translate_world(TOPLEVEL *toplevel, int dx, int dy, OBJECT *object) 00443 { 00444 /* Do world coords */ 00445 object->box->upper_x = object->box->upper_x + dx; 00446 object->box->upper_y = object->box->upper_y + dy; 00447 object->box->lower_x = object->box->lower_x + dx; 00448 object->box->lower_y = object->box->lower_y + dy; 00449 00450 /* recalc the screen coords and the bounding box */ 00451 o_box_recalc(toplevel, object); 00452 } 00453 00468 void o_box_rotate_world(TOPLEVEL *toplevel, 00469 int world_centerx, int world_centery, int angle, 00470 OBJECT *object) 00471 { 00472 int newx1, newy1; 00473 int newx2, newy2; 00474 00479 /* angle must be positive */ 00480 if(angle < 0) angle = -angle; 00481 /* angle must be a 90 multiple or no rotation performed */ 00482 if((angle % 90) != 0) return; 00483 00490 /* translate object to origin */ 00491 object->box->upper_x -= world_centerx; 00492 object->box->upper_y -= world_centery; 00493 object->box->lower_x -= world_centerx; 00494 object->box->lower_y -= world_centery; 00495 00496 /* rotate the upper left corner of the box */ 00497 rotate_point_90(object->box->upper_x, object->box->upper_y, angle, 00498 &newx1, &newy1); 00499 00500 /* rotate the lower left corner of the box */ 00501 rotate_point_90(object->box->lower_x, object->box->lower_y, angle, 00502 &newx2, &newy2); 00503 00504 /* reorder the corners after rotation */ 00505 object->box->upper_x = min(newx1,newx2); 00506 object->box->upper_y = max(newy1,newy2); 00507 object->box->lower_x = max(newx1,newx2); 00508 object->box->lower_y = min(newy1,newy2); 00509 00510 /* translate object back to normal position */ 00511 object->box->upper_x += world_centerx; 00512 object->box->upper_y += world_centery; 00513 object->box->lower_x += world_centerx; 00514 object->box->lower_y += world_centery; 00515 00516 /* recalc boundings and world coords */ 00517 o_box_recalc(toplevel, object); 00518 } 00519 00533 void o_box_mirror_world(TOPLEVEL *toplevel, 00534 int world_centerx, int world_centery, 00535 OBJECT *object) 00536 { 00537 int newx1, newy1; 00538 int newx2, newy2; 00539 00540 /* translate object to origin */ 00541 object->box->upper_x -= world_centerx; 00542 object->box->upper_y -= world_centery; 00543 object->box->lower_x -= world_centerx; 00544 object->box->lower_y -= world_centery; 00545 00546 /* mirror the corners */ 00547 newx1 = -object->box->upper_x; 00548 newy1 = object->box->upper_y; 00549 newx2 = -object->box->lower_x; 00550 newy2 = object->box->lower_y; 00551 00552 /* reorder the corners */ 00553 object->box->upper_x = min(newx1,newx2); 00554 object->box->upper_y = max(newy1,newy2); 00555 object->box->lower_x = max(newx1,newx2); 00556 object->box->lower_y = min(newy1,newy2); 00557 00558 /* translate back in position */ 00559 object->box->upper_x += world_centerx; 00560 object->box->upper_y += world_centery; 00561 object->box->lower_x += world_centerx; 00562 object->box->lower_y += world_centery; 00563 00564 /* recalc boundings and world coords */ 00565 o_box_recalc(toplevel, object); 00566 00567 } 00568 00577 void o_box_recalc(TOPLEVEL *toplevel, OBJECT *o_current) 00578 { 00579 int left, top, right, bottom; 00580 00581 if (o_current->box == NULL) { 00582 return; 00583 } 00584 00585 /* update the bounding box - world unit */ 00586 world_get_box_bounds(toplevel, o_current, &left, &top, &right, &bottom); 00587 o_current->w_left = left; 00588 o_current->w_top = top; 00589 o_current->w_right = right; 00590 o_current->w_bottom = bottom; 00591 o_current->w_bounds_valid = TRUE; 00592 } 00593 00607 void world_get_box_bounds(TOPLEVEL *toplevel, OBJECT *object, 00608 int *left, int *top, int *right, int *bottom) 00609 { 00610 int halfwidth; 00611 00612 halfwidth = object->line_width / 2; 00613 00614 *left = min(object->box->upper_x, object->box->lower_x); 00615 *top = min(object->box->upper_y, object->box->lower_y); 00616 *right = max(object->box->upper_x, object->box->lower_x); 00617 *bottom = max(object->box->upper_y, object->box->lower_y); 00618 00619 /* This isn't strictly correct, but a 1st order approximation */ 00620 *left -= halfwidth; 00621 *top -= halfwidth; 00622 *right += halfwidth; 00623 *bottom += halfwidth; 00624 } 00625 00636 gboolean o_box_get_position (TOPLEVEL *toplevel, gint *x, gint *y, 00637 OBJECT *object) 00638 { 00639 *x = min(object->box->lower_x, object->box->upper_x); 00640 *y = min(object->box->lower_y, object->box->upper_y); 00641 return TRUE; 00642 } 00643 00668 void o_box_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current, 00669 int origin_x, int origin_y) 00670 { 00671 int x, y, width, height; 00672 int color; 00673 int line_width, length, space; 00674 int fill_width, angle1, pitch1, angle2, pitch2; 00675 void (*outl_func)() = NULL; 00676 void (*fill_func)() = NULL; 00677 00678 if (o_current == NULL) { 00679 printf("got null in o_box_print\n"); 00680 return; 00681 } 00682 00683 x = o_current->box->upper_x; 00684 y = o_current->box->upper_y; 00685 width = abs(o_current->box->lower_x - o_current->box->upper_x); 00686 height = abs(o_current->box->lower_y - o_current->box->upper_y); 00687 color = o_current->color; 00688 00703 line_width = o_current->line_width; 00704 00705 if(line_width <=2) { 00706 if(toplevel->line_style == THICK) { 00707 line_width=LINE_WIDTH; 00708 } else { 00709 line_width=2; 00710 } 00711 } 00712 length = o_current->line_length; 00713 space = o_current->line_space; 00714 00715 switch(o_current->line_type) { 00716 case(TYPE_SOLID): 00717 length = -1; space = -1; 00718 outl_func = o_box_print_solid; 00719 break; 00720 00721 case(TYPE_DOTTED): 00722 length = -1; 00723 outl_func = o_box_print_dotted; 00724 break; 00725 00726 case(TYPE_DASHED): 00727 outl_func = o_box_print_dashed; 00728 break; 00729 00730 case(TYPE_CENTER): 00731 outl_func = o_box_print_center; 00732 break; 00733 00734 case(TYPE_PHANTOM): 00735 outl_func = o_box_print_phantom; 00736 break; 00737 00738 case(TYPE_ERASE): 00739 /* Unused for now, print it solid */ 00740 length = -1; space = -1; 00741 outl_func = o_box_print_solid; 00742 break; 00743 } 00744 00745 if((length == 0) || (space == 0)) { 00746 length = -1; space = -1; 00747 outl_func = o_box_print_solid; 00748 } 00749 00750 (*outl_func)(toplevel, fp, 00751 x, y, width, height, 00752 color, 00753 line_width, 00754 length, space, 00755 origin_x, origin_y); 00756 00768 if(o_current->fill_type != FILLING_HOLLOW) { 00769 fill_width = o_current->fill_width; 00770 angle1 = o_current->fill_angle1; 00771 pitch1 = o_current->fill_pitch1; 00772 angle2 = o_current->fill_angle2; 00773 pitch2 = o_current->fill_pitch2; 00774 00775 switch(o_current->fill_type) { 00776 case(FILLING_FILL): 00777 angle1 = -1; pitch1 = 1; 00778 angle2 = -1; pitch2 = 1; 00779 fill_width = -1; 00780 fill_func = o_box_print_filled; 00781 break; 00782 00783 case(FILLING_MESH): 00784 fill_func = o_box_print_mesh; 00785 break; 00786 00787 case(FILLING_HATCH): 00788 angle2 = -1; pitch2 = 1; 00789 fill_func = o_box_print_hatch; 00790 break; 00791 00792 case(FILLING_VOID): 00793 /* Unused for now, print it filled */ 00794 angle1 = -1; pitch1 = 1; 00795 angle2 = -1; pitch2 = 1; 00796 fill_width = -1; 00797 fill_func = o_box_print_filled; 00798 break; 00799 case(FILLING_HOLLOW): 00800 /* nop */ 00801 break; 00802 00803 } 00804 00805 if((pitch1 <= 0) || (pitch2 <= 0)) { 00806 angle1 = -1; pitch1 = 1; 00807 angle2 = -1; pitch2 = 1; 00808 fill_func = o_box_print_filled; 00809 } 00810 00811 (*fill_func)(toplevel, fp, 00812 x, y, width, height, 00813 color, 00814 fill_width, 00815 angle1, pitch1, angle2, pitch2, 00816 origin_x, origin_y); 00817 } 00818 } 00819 00847 void 00848 o_box_print_solid(TOPLEVEL *toplevel, FILE *fp, 00849 int x, int y, 00850 int width, int height, 00851 int color, 00852 int line_width, int length, int space, 00853 int origin_x, int origin_y) 00854 { 00855 int x1, y1; 00856 00857 f_print_set_color(toplevel, fp, color); 00858 00859 x1 = x; 00860 y1 = y - height; /* move the origin to 0, 0*/ 00861 00862 o_line_print_solid(toplevel, fp, 00863 x1, y1, x1 + width, y1, 00864 color, 00865 line_width, length, space, 00866 origin_x, origin_y); 00867 o_line_print_solid(toplevel, fp, 00868 x1 + width, y1, x1 + width, y1 + height, 00869 color, 00870 line_width, length, space, 00871 origin_x, origin_y); 00872 o_line_print_solid(toplevel, fp, 00873 x1 + width, y1 + height, x1, y1 + height, 00874 color, 00875 line_width, length, space, 00876 origin_x, origin_y); 00877 o_line_print_solid(toplevel, fp, 00878 x1, y1 + height, x1, y1, 00879 color, 00880 line_width, length, space, 00881 origin_x, origin_y); 00882 } 00883 00911 void o_box_print_dotted(TOPLEVEL *toplevel, FILE *fp, 00912 int x, int y, 00913 int width, int height, 00914 int color, 00915 int line_width, int length, int space, 00916 int origin_x, int origin_y) 00917 { 00918 int x1, y1; 00919 00920 f_print_set_color(toplevel, fp, color); 00921 00922 x1 = x; 00923 y1 = y - height; /* move the origin to 0, 0*/ 00924 00925 o_line_print_dotted(toplevel, fp, 00926 x1, y1, x1 + width, y1, 00927 color, 00928 line_width, length, space, 00929 origin_x, origin_y); 00930 o_line_print_dotted(toplevel, fp, 00931 x1 + width, y1, x1 + width, y1 + height, 00932 color, 00933 line_width, length, space, 00934 origin_x, origin_y); 00935 o_line_print_dotted(toplevel, fp, 00936 x1 + width, y1 + height, x1, y1 + height, 00937 color, 00938 line_width, length, space, 00939 origin_x, origin_y); 00940 o_line_print_dotted(toplevel, fp, 00941 x1, y1 + height, x1, y1, 00942 color, 00943 line_width, length, space, 00944 origin_x, origin_y); 00945 } 00946 00973 void o_box_print_dashed(TOPLEVEL *toplevel, FILE *fp, 00974 int x, int y, 00975 int width, int height, 00976 int color, 00977 int line_width, int length, int space, 00978 int origin_x, int origin_y) 00979 { 00980 int x1, y1; 00981 00982 f_print_set_color(toplevel, fp, color); 00983 00984 00985 x1 = x; 00986 y1 = y - height; /* move the origin to 0, 0*/ 00987 00988 o_line_print_dashed(toplevel, fp, 00989 x1, y1, x1 + width, y1, 00990 color, 00991 line_width, length, space, 00992 origin_x, origin_y); 00993 o_line_print_dashed(toplevel, fp, 00994 x1 + width, y1, x1 + width, y1 + height, 00995 color, 00996 line_width, length, space, 00997 origin_x, origin_y); 00998 o_line_print_dashed(toplevel, fp, 00999 x1 + width, y1 + height, x1, y1 + height, 01000 color, 01001 line_width, length, space, 01002 origin_x, origin_y); 01003 o_line_print_dashed(toplevel, fp, 01004 x1, y1 + height, x1, y1, 01005 color, 01006 line_width, length, space, 01007 origin_x, origin_y); 01008 } 01009 01036 void o_box_print_center(TOPLEVEL *toplevel, FILE *fp, 01037 int x, int y, 01038 int width, int height, 01039 int color, 01040 int line_width, int length, int space, 01041 int origin_x, int origin_y) 01042 { 01043 int x1, y1; 01044 01045 f_print_set_color(toplevel, fp, color); 01046 01047 x1 = x; 01048 y1 = y - height; /* move the origin to 0, 0*/ 01049 01050 o_line_print_center(toplevel, fp, 01051 x1, y1, x1 + width, y1, 01052 color, 01053 line_width, length, space, 01054 origin_x, origin_y); 01055 o_line_print_center(toplevel, fp, 01056 x1 + width, y1, x1 + width, y1 + height, 01057 color, 01058 line_width, length, space, 01059 origin_x, origin_y); 01060 o_line_print_center(toplevel, fp, 01061 x1 + width, y1 + height, x1, y1 + height, 01062 color, 01063 line_width, length, space, 01064 origin_x, origin_y); 01065 o_line_print_center(toplevel, fp, 01066 x1, y1 + height, x1, y1, 01067 color, 01068 line_width, length, space, 01069 origin_x, origin_y); 01070 } 01071 01098 void o_box_print_phantom(TOPLEVEL *toplevel, FILE *fp, 01099 int x, int y, 01100 int width, int height, 01101 int color, 01102 int line_width, int length, int space, 01103 int origin_x, int origin_y) 01104 { 01105 int x1, y1; 01106 01107 f_print_set_color(toplevel, fp, color); 01108 01109 x1 = x; 01110 y1 = y - height; /* move the origin to 0, 0*/ 01111 01112 o_line_print_phantom(toplevel, fp, 01113 x1, y1, x1 + width, y1, 01114 color, 01115 line_width, length, space, 01116 origin_x, origin_y); 01117 o_line_print_phantom(toplevel, fp, 01118 x1 + width, y1, x1 + width, y1 + height, 01119 color, 01120 line_width, length, space, 01121 origin_x, origin_y); 01122 o_line_print_phantom(toplevel, fp, 01123 x1 + width, y1 + height, x1, y1 + height, 01124 color, 01125 line_width, length, space, 01126 origin_x, origin_y); 01127 o_line_print_phantom(toplevel, fp, 01128 x1, y1 + height, x1, y1, 01129 color, 01130 line_width, length, space, 01131 origin_x, origin_y); 01132 } 01133 01166 void o_box_print_filled(TOPLEVEL *toplevel, FILE *fp, 01167 int x, int y, 01168 int width, int height, 01169 int color, 01170 int fill_width, 01171 int angle1, int pitch1, 01172 int angle2, int pitch2, 01173 int origin_x, int origin_y) 01174 { 01175 int x1, y1; 01176 01177 f_print_set_color(toplevel, fp, color); 01178 01179 x1 = x; 01180 y1 = y-height; /* move the origin to 0, 0*/ 01181 fprintf(fp, "%d %d %d %d fbox\n", 01182 width, height, 01183 x1-origin_x, y1-origin_y); 01184 01185 } 01186 01218 void o_box_print_mesh(TOPLEVEL *toplevel, FILE *fp, 01219 int x, int y, 01220 int width, int height, 01221 int color, 01222 int fill_width, 01223 int angle1, int pitch1, 01224 int angle2, int pitch2, 01225 int origin_x, int origin_y) 01226 { 01227 o_box_print_hatch(toplevel, fp, 01228 x, y, width, height, 01229 color, 01230 fill_width, 01231 angle1, pitch1, -1, -1, 01232 origin_x, origin_y); 01233 o_box_print_hatch(toplevel, fp, 01234 x, y, width, height, 01235 color, 01236 fill_width, 01237 angle2, pitch2, -1, -1, 01238 origin_x, origin_y); 01239 01240 } 01241 01273 void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp, 01274 int x, int y, 01275 int width, int height, 01276 int color, 01277 int fill_width, 01278 int angle1, int pitch1, 01279 int angle2, int pitch2, 01280 int origin_x, int origin_y) 01281 { 01282 BOX box; 01283 gint index; 01284 GArray *lines; 01285 01286 g_return_if_fail(toplevel != NULL); 01287 g_return_if_fail(fp != NULL); 01288 01289 f_print_set_color(toplevel, fp, color); 01290 01291 /* Avoid printing line widths too small */ 01292 if (fill_width <= 1) fill_width = 2; 01293 01294 lines = g_array_new(FALSE, FALSE, sizeof(LINE)); 01295 01296 box.upper_x = x; 01297 box.upper_y = y; 01298 box.lower_x = x + width; 01299 box.lower_y = y - height; /* Hmmm... */ 01300 01301 m_hatch_box(&box, angle1, pitch1, lines); 01302 01303 for(index=0; index<lines->len; index++) { 01304 LINE *line = &g_array_index(lines, LINE, index); 01305 01306 fprintf(fp,"%d %d %d %d %d line\n", 01307 line->x[0], line->y[0], 01308 line->x[1], line->y[1], 01309 fill_width); 01310 } 01311 01312 g_array_free(lines, TRUE); 01313 } 01314 01325 double o_box_shortest_distance (OBJECT *object, int x, int y, int force_solid) 01326 { 01327 int solid; 01328 01329 g_return_val_if_fail (object->box != NULL, G_MAXDOUBLE); 01330 01331 solid = force_solid || object->fill_type != FILLING_HOLLOW; 01332 01333 return m_box_shortest_distance (object->box, x, y, solid); 01334 } 01335