static void message_update_data(Message *message) { Connection *conn = &message->connection; DiaObject *obj = &conn->object; Rectangle rect; if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; message->text_handle.pos = message->text_pos; connection_update_handles(conn); connection_update_boundingbox(conn); message->text_width = dia_font_string_width(message->text, message->font, message->font_height); /* Add boundingbox for text: */ rect.left = message->text_pos.x-message->text_width/2; rect.right = rect.left + message->text_width; rect.top = message->text_pos.y - dia_font_ascent(message->text, message->font, message->font_height); rect.bottom = rect.top + message->font_height; rectangle_union(&obj->bounding_box, &rect); }
/* Parensblock : */ static void parensblock_get_boundingbox(Block *block, Point *relpos, Boolequation *booleq, Rectangle *rect) { real pheight,pwidth; Point temppos; g_assert(block); g_assert(block->type == BLOCK_PARENS); temppos = block->pos = *relpos; block->d.inside->ops->get_boundingbox(block->d.inside,&temppos,booleq,rect); pheight = 1.1 * (block->d.inside->bl.y - block->d.inside->ur.y); pwidth = dia_font_string_width("()",booleq->font,pheight) / 2; temppos.x += pwidth; block->d.inside->ops->get_boundingbox(block->d.inside,&temppos,booleq,rect); block->bl.x = block->pos.x; block->bl.y = block->pos.y + dia_font_descent("()",booleq->font,pheight); block->ur.x = block->d.inside->ur.x + pwidth; block->ur.y = block->bl.y - pheight; rect->left = block->bl.x; rect->top = block->ur.y; rect->bottom = block->bl.y; rect->right = block->ur.x; }
static DiaObject * attribute_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2) { Attribute *attribute; Element *elem; DiaObject *obj; int i; attribute = g_malloc0(sizeof(Attribute)); elem = &attribute->element; obj = &elem->object; obj->type = &attribute_type; obj->ops = &attribute_ops; elem->corner = *startpoint; elem->width = DEFAULT_WIDTH; elem->height = DEFAULT_HEIGHT; attribute->border_width = attributes_get_default_linewidth(); attribute->border_color = attributes_get_foreground(); attribute->inner_color = attributes_get_background(); element_init(elem, 8, NUM_CONNECTIONS); for (i=0;i<NUM_CONNECTIONS;i++) { obj->connections[i] = &attribute->connections[i]; attribute->connections[i].object = obj; attribute->connections[i].connected = NULL; } attribute->connections[8].flags = CP_FLAGS_MAIN; attribute->key = FALSE; attribute->weakkey = FALSE; attribute->derived = FALSE; attribute->multivalue = FALSE; attribute->font = dia_font_new_from_style(DIA_FONT_MONOSPACE,FONT_HEIGHT); attribute->font_height = FONT_HEIGHT; attribute->name = g_strdup(_("Attribute")); attribute->name_width = dia_font_string_width(attribute->name, attribute->font, attribute->font_height); attribute_update_data(attribute); for (i=0;i<8;i++) { obj->handles[i]->type = HANDLE_NON_MOVABLE; } *handle1 = NULL; *handle2 = obj->handles[0]; return &attribute->element.object; }
static void mbr_update_data(Mbr *mbr) { Connection *conn = &mbr->connection; DiaObject *obj = &conn->object; Rectangle rect; Point p1,p2; Point p3,p4; gchar *text; /* Too complex to easily decide -- this is essentially a bezier curve */ /* if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } */ obj->position = conn->endpoints[0]; mbr->pm_handle.pos = mbr->pm; connection_update_handles(conn); connection_update_boundingbox(conn); /* text width */ text=compute_text(mbr); mbr->text_width = dia_font_string_width(text, mbr_font, MBR_DECFONTHEIGHT); mbr->text_ascent = dia_font_ascent(text, mbr_font, MBR_DECFONTHEIGHT); /* endpoint */ p1 = conn->endpoints[0]; p2 = conn->endpoints[1]; /* bezier */ compute_line(&p1,&p2,&mbr->pm,mbr->line); /* Add boundingbox for mid decoration (slightly overestimated) : */ p3.x=mbr->pm.x-MBR_DEC_SIZE; p3.y=mbr->pm.y-MBR_DEC_SIZE; p4.x=p3.x+MBR_DEC_SIZE*2; p4.y=p3.y+MBR_DEC_SIZE*2; rect.left=p3.x; rect.right=p4.x; rect.top=p3.y; rect.bottom=p4.y; rectangle_union(&obj->bounding_box, &rect); /* Add boundingbox for text: */ rect.left = mbr->pm.x-mbr->text_width/2; rect.right = rect.left + mbr->text_width; rect.top = mbr->pm.y - mbr->text_ascent; rect.bottom = rect.top + MBR_DECFONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); g_free(text); /* free auxilliary text */ }
static void largepackage_update_data(LargePackage *pkg) { Element *elem = &pkg->element; DiaObject *obj = &elem->object; pkg->stereotype = remove_stereotype_from_string(pkg->stereotype); if (!pkg->st_stereotype) { pkg->st_stereotype = string_to_stereotype(pkg->stereotype); } pkg->topheight = LARGEPACKAGE_FONTHEIGHT + 0.1*2; pkg->topwidth = 2.0; if (pkg->name != NULL) pkg->topwidth = MAX(pkg->topwidth, dia_font_string_width(pkg->name, pkg->font, LARGEPACKAGE_FONTHEIGHT)+2*0.1); if (pkg->st_stereotype != NULL && pkg->st_stereotype[0] != '\0') { pkg->topwidth = MAX(pkg->topwidth, dia_font_string_width(pkg->st_stereotype, pkg->font, LARGEPACKAGE_FONTHEIGHT)+2*0.1); pkg->topheight += LARGEPACKAGE_FONTHEIGHT; } if (elem->width < (pkg->topwidth + 0.2)) elem->width = pkg->topwidth + 0.2; if (elem->height < 1.0) elem->height = 1.0; /* Update connections: */ element_update_connections_rectangle(elem, pkg->connections); element_update_boundingbox(elem); /* fix boundingbox for top rectangle: */ obj->bounding_box.top -= pkg->topheight; obj->position = elem->corner; element_update_handles(elem); }
static void constraint_update_data(Constraint *constraint) { Connection *conn = &constraint->connection; DiaObject *obj = &conn->object; Rectangle rect; LineBBExtras *extra; if ((constraint->text) && (constraint->text[0] == '{')) { /* we might have a string loaded from an older dia. Clean it up. */ g_free(constraint->brtext); constraint->brtext = constraint->text; constraint->text = bracketted_to_string(constraint->text,"{","}"); } else if (!constraint->brtext) { constraint->brtext = string_to_bracketted(constraint->text, "{", "}"); } if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; constraint->text_width = dia_font_string_width(constraint->brtext, constraint->font, constraint->font_height); constraint->text_handle.pos = constraint->text_pos; connection_update_handles(conn); /* Boundingbox: */ extra = &conn->extra_spacing; extra->start_long = extra->start_trans = extra->end_long = constraint->line_width/2.0; extra->end_trans = MAX(constraint->line_width,CONSTRAINT_ARROWLEN)/2.0; connection_update_boundingbox(conn); /* Add boundingbox for text: */ rect.left = constraint->text_pos.x; rect.right = rect.left + constraint->text_width; rect.top = constraint->text_pos.y - dia_font_ascent(constraint->brtext, constraint->font, constraint->font_height); rect.bottom = rect.top + constraint->font_height; rectangle_union(&obj->bounding_box, &rect); }
/*! Not in the object interface but very important anyway. Used to recalculate the object data after a change */ static void measure_update_data (Measure *measure) { Connection *conn = &measure->connection; DiaObject *obj = &measure->connection.object; real value; Point *ends = measure->connection.endpoints; LineBBExtras *extra = &conn->extra_spacing; Rectangle bbox; Arrow arrow = MEASURE_ARROW(measure); real ascent, width; g_return_if_fail (obj->handles != NULL); connection_update_handles(conn); extra->start_trans = extra->end_trans = extra->start_long = extra->end_long = (measure->line_width / 2.0); g_free (measure->name); value = distance_point_point (&ends[0], &ends[1]); value *= measure->scale; value *= (28.346457 / units[measure->unit].factor); measure->name = g_strdup_printf ("%.*g %s", measure->precision, value, units[measure->unit].unit); ascent = dia_font_ascent (measure->name, measure->font, measure->font_height); width = dia_font_string_width (measure->name, measure->font, measure->font_height); measure->text_pos.x = (ends[0].x + ends[1].x) / 2; measure->text_pos.y = (ends[0].y + ends[1].y) / 2; /* for horizontal we could try to center over the line */ line_bbox (&ends[0], &ends[0], &conn->extra_spacing,&conn->object.bounding_box); arrow_bbox (&arrow, measure->line_width, &ends[0], &ends[1], &bbox); rectangle_union(&obj->bounding_box, &bbox); arrow_bbox (&arrow, measure->line_width, &ends[1], &ends[0], &bbox); rectangle_union(&obj->bounding_box, &bbox); bbox.left = measure->text_pos.x; bbox.top = measure->text_pos.y - ascent; bbox.bottom = bbox.top + measure->font_height; bbox.right = bbox.left + width; rectangle_union(&obj->bounding_box, &bbox); obj->position = conn->endpoints[0]; }
static void expand_bbox_for_text(Rectangle* bbox, Point* text_pos, gchar* text) { Rectangle text_box; real text_width; text_width = dia_font_string_width(text, transition_font, TRANSITION_FONTHEIGHT); text_box.left = text_pos->x - text_width/2; text_box.right = text_box.left + text_width; text_box.top = text_pos->y - dia_font_ascent(text, transition_font, TRANSITION_FONTHEIGHT); text_box.bottom = text_box.top + TRANSITION_FONTHEIGHT; rectangle_union(bbox, &text_box); }
static void overlineblock_draw(Block *block,Boolequation *booleq,DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Point ul,ur; g_assert(block); g_assert(block->type == BLOCK_OVERLINE); block->d.inside->ops->draw(block->d.inside,booleq,renderer); renderer_ops->set_linestyle(renderer,LINESTYLE_SOLID); renderer_ops->set_linewidth(renderer,booleq->fontheight * OVERLINE_RATIO); ul.x = block->bl.x; ur.y = ul.y = block->ur.y; /* FIXME: try to get the actual block width */ ur.x = block->ur.x - (dia_font_string_width("_", booleq->font,booleq->fontheight) / 2); renderer_ops->draw_line(renderer,&ul,&ur,&booleq->color); }
static void opblock_get_boundingbox(Block *block, Point *relpos, Boolequation *booleq, Rectangle *rect) { const gchar* ops; g_assert(block); g_assert(block->type == BLOCK_OPERATOR); ops = opstring(block->d.operator); block->pos = *relpos; block->bl.x = block->pos.x; block->bl.y = block->pos.y + dia_font_descent(ops,booleq->font,booleq->fontheight); block->ur.y = block->bl.y - booleq->fontheight; block->ur.x = block->bl.x + dia_font_string_width(ops, booleq->font, booleq->fontheight); rect->left = block->bl.x; rect->top = block->ur.y; rect->bottom = block->bl.y; rect->right = block->ur.x; }
/* Text block definition */ static void textblock_get_boundingbox(Block *block, Point *relpos, Boolequation *booleq, Rectangle *rect) { g_assert(block); g_assert(block->type == BLOCK_TEXT); block->pos = *relpos; block->bl.x = block->pos.x; block->bl.y = block->pos.y + dia_font_descent(block->d.text, booleq->font, booleq->fontheight); block->ur.y = block->pos.y - dia_font_ascent(block->d.text, booleq->font, booleq->fontheight); block->ur.x = block->bl.x + dia_font_string_width(block->d.text, booleq->font, booleq->fontheight); rect->left = block->bl.x; rect->top = block->ur.y; rect->bottom = block->bl.y; rect->right = block->ur.x; }
static void realizes_update_data(Realizes *realize) { OrthConn *orth = &realize->orth; DiaObject *obj = &orth->object; int num_segm, i; Point *points; Rectangle rect; PolyBBExtras *extra; orthconn_update_data(orth); realize->text_width = 0.0; realize->stereotype = remove_stereotype_from_string(realize->stereotype); if (!realize->st_stereotype) { realize->st_stereotype = string_to_stereotype(realize->stereotype); } if (realize->name) realize->text_width = dia_font_string_width(realize->name, realize_font, REALIZES_FONTHEIGHT); if (realize->stereotype) realize->text_width = MAX(realize->text_width, dia_font_string_width(realize->stereotype, realize_font, REALIZES_FONTHEIGHT)); extra = &orth->extra_spacing; extra->start_trans = REALIZES_WIDTH/2.0 + REALIZES_TRIANGLESIZE; extra->start_long = extra->middle_trans = extra->end_trans = extra->end_long = REALIZES_WIDTH/2.0; orthconn_update_boundingbox(orth); /* Calc text pos: */ num_segm = realize->orth.numpoints - 1; points = realize->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (realize->orth.orientation[i]==VERTICAL) i--; } switch (realize->orth.orientation[i]) { case HORIZONTAL: realize->text_align = ALIGN_CENTER; realize->text_pos.x = 0.5*(points[i].x+points[i+1].x); realize->text_pos.y = points[i].y; if (realize->name) realize->text_pos.y -= dia_font_descent(realize->name,realize_font, REALIZES_FONTHEIGHT); break; case VERTICAL: realize->text_align = ALIGN_LEFT; realize->text_pos.x = points[i].x + 0.1; realize->text_pos.y = 0.5*(points[i].y+points[i+1].y); if (realize->name) realize->text_pos.y -= dia_font_descent(realize->name, realize_font, REALIZES_FONTHEIGHT); break; } /* Add the text recangle to the bounding box: */ rect.left = realize->text_pos.x; if (realize->text_align == ALIGN_CENTER) rect.left -= realize->text_width/2.0; rect.right = rect.left + realize->text_width; rect.top = realize->text_pos.y; if (realize->name) rect.top -= dia_font_ascent(realize->name,realize_font, REALIZES_FONTHEIGHT); rect.bottom = rect.top + 2*REALIZES_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); }
static DiaObject * attribute_load(ObjectNode obj_node, int version,DiaContext *ctx) { Attribute *attribute; Element *elem; DiaObject *obj; int i; AttributeNode attr; attribute = g_malloc0(sizeof(Attribute)); elem = &attribute->element; obj = &elem->object; obj->type = &attribute_type; obj->ops = &attribute_ops; element_load(elem, obj_node, ctx); attribute->border_width = 0.1; attr = object_find_attribute(obj_node, "border_width"); if (attr != NULL) attribute->border_width = data_real(attribute_first_data(attr), ctx); attribute->border_color = color_black; attr = object_find_attribute(obj_node, "border_color"); if (attr != NULL) data_color(attribute_first_data(attr), &attribute->border_color, ctx); attribute->inner_color = color_white; attr = object_find_attribute(obj_node, "inner_color"); if (attr != NULL) data_color(attribute_first_data(attr), &attribute->inner_color, ctx); attribute->name = NULL; attr = object_find_attribute(obj_node, "name"); if (attr != NULL) attribute->name = data_string(attribute_first_data(attr), ctx); attr = object_find_attribute(obj_node, "key"); if (attr != NULL) attribute->key = data_boolean(attribute_first_data(attr), ctx); attr = object_find_attribute(obj_node, "weak_key"); if (attr != NULL) attribute->weakkey = data_boolean(attribute_first_data(attr), ctx); attr = object_find_attribute(obj_node, "derived"); if (attr != NULL) attribute->derived = data_boolean(attribute_first_data(attr), ctx); attr = object_find_attribute(obj_node, "multivalued"); if (attr != NULL) attribute->multivalue = data_boolean(attribute_first_data(attr), ctx); if (attribute->font != NULL) { /* This shouldn't happen, but doesn't hurt */ dia_font_unref(attribute->font); attribute->font = NULL; } attr = object_find_attribute (obj_node, "font"); if (attr != NULL) attribute->font = data_font (attribute_first_data (attr), ctx); attribute->font_height = FONT_HEIGHT; attr = object_find_attribute (obj_node, "font_height"); if (attr != NULL) attribute->font_height = data_real(attribute_first_data(attr), ctx); element_init(elem, 8, NUM_CONNECTIONS); for (i=0;i<NUM_CONNECTIONS;i++) { obj->connections[i] = &attribute->connections[i]; attribute->connections[i].object = obj; attribute->connections[i].connected = NULL; } attribute->connections[8].flags = CP_FLAGS_MAIN; if (attribute->font == NULL) attribute->font = dia_font_new_from_style(DIA_FONT_MONOSPACE, attribute->font_height); attribute->name_width = dia_font_string_width(attribute->name, attribute->font, attribute->font_height); attribute_update_data(attribute); for (i=0;i<8;i++) obj->handles[i]->type = HANDLE_NON_MOVABLE; return &attribute->element.object; }
static void component_update_data(Component *cmp) { Element *elem = &cmp->element; DiaObject *obj = &elem->object; Point p; real cw2, ch; cmp->stereotype = remove_stereotype_from_string(cmp->stereotype); if (!cmp->st_stereotype) { cmp->st_stereotype = string_to_stereotype(cmp->stereotype); } text_calc_boundingbox(cmp->text, NULL); elem->width = cmp->text->max_width + 2*COMPONENT_MARGIN_X + COMPONENT_CWIDTH; elem->width = MAX(elem->width, 2*COMPONENT_CWIDTH); elem->height = cmp->text->height*cmp->text->numlines + cmp->text->descent + 0.1 + 2*COMPONENT_MARGIN_Y ; elem->height = MAX(elem->height, 5*COMPONENT_CHEIGHT); p = elem->corner; p.x += COMPONENT_CWIDTH + COMPONENT_MARGIN_X; p.y += COMPONENT_CHEIGHT; p.y += cmp->text->ascent; if (cmp->stereotype && cmp->stereotype[0] != '\0') { p.y += cmp->text->height; } text_set_position(cmp->text, &p); if (cmp->st_stereotype && cmp->st_stereotype[0] != '\0') { DiaFont *font; font = cmp->text->font; elem->height += cmp->text->height; elem->width = MAX(elem->width, dia_font_string_width(cmp->st_stereotype, font, cmp->text->height) + 2*COMPONENT_MARGIN_X + COMPONENT_CWIDTH); } cw2 = COMPONENT_CWIDTH/2; ch = COMPONENT_CHEIGHT; /* Update connections: */ connpoint_update(&cmp->connections[0], elem->corner.x + cw2, elem->corner.y, DIR_NORTH|DIR_WEST); connpoint_update(&cmp->connections[1], elem->corner.x + cw2 + (elem->width - cw2) / 2, elem->corner.y, DIR_NORTH); connpoint_update(&cmp->connections[2], elem->corner.x + elem->width, elem->corner.y, DIR_NORTH|DIR_EAST); connpoint_update(&cmp->connections[3], elem->corner.x + cw2, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&cmp->connections[4], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&cmp->connections[5], elem->corner.x + cw2, elem->corner.y + elem->height, DIR_SOUTH|DIR_WEST); connpoint_update(&cmp->connections[6], elem->corner.x + cw2 + (elem->width - cw2)/2, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&cmp->connections[7], elem->corner.x + elem->width, elem->corner.y + elem->height, DIR_SOUTH|DIR_EAST); connpoint_update(&cmp->connections[8], elem->corner.x, elem->corner.y + elem->height / 2.0 - ch, DIR_WEST); connpoint_update(&cmp->connections[9], elem->corner.x, elem->corner.y + elem->height / 2.0 + ch, DIR_WEST); connpoint_update(&cmp->connections[10], elem->corner.x + (elem->width-cw2)/2, elem->corner.y + elem->height / 2.0 + ch, DIR_ALL); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void objet_update_data(Objet *ob) { Element *elem = &ob->element; DiaObject *obj = &elem->object; DiaFont *font; Point p1, p2; real h, w = 0; text_calc_boundingbox(ob->text, NULL); ob->stereotype = remove_stereotype_from_string(ob->stereotype); if (!ob->st_stereotype) { ob->st_stereotype = string_to_stereotype(ob->stereotype); } font = ob->text->font; h = elem->corner.y + OBJET_MARGIN_Y(ob); if (ob->is_multiple) { h += OBJET_MARGIN_M(ob); } if ((ob->stereotype != NULL) && (ob->stereotype[0] != '\0')) { w = dia_font_string_width(ob->st_stereotype, font, OBJET_FONTHEIGHT(ob)); h += OBJET_FONTHEIGHT(ob); ob->st_pos.y = h; h += OBJET_MARGIN_Y(ob)/2.0; } w = MAX(w, ob->text->max_width); p1.y = h + ob->text->ascent; /* position of text */ h += ob->text->height*ob->text->numlines; if ((ob->exstate != NULL) && (ob->exstate[0] != '\0')) { w = MAX(w, dia_font_string_width(ob->exstate, font, OBJET_FONTHEIGHT(ob))); h += OBJET_FONTHEIGHT(ob); ob->ex_pos.y = h; } h += OBJET_MARGIN_Y(ob); if (ob->show_attributes) { h += OBJET_MARGIN_Y(ob) + ob->attributes->ascent; p2.x = elem->corner.x + OBJET_MARGIN_X(ob); p2.y = h; text_set_position(ob->attributes, &p2); h += ob->attributes->height*ob->attributes->numlines; text_calc_boundingbox(ob->attributes, NULL); w = MAX(w, ob->attributes->max_width); } w += 2*OBJET_MARGIN_X(ob); p1.x = elem->corner.x + w/2.0; text_set_position(ob->text, &p1); ob->ex_pos.x = ob->st_pos.x = p1.x; if (ob->is_multiple) { w += OBJET_MARGIN_M(ob); } elem->width = w; elem->height = h - elem->corner.y; /* Update connections: */ element_update_connections_rectangle(elem, ob->connections); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static DiaObject * association_load(ObjectNode obj_node, int version, const char *filename) { Association *assoc; AttributeNode attr; DataNode composite; OrthConn *orth; DiaObject *obj; int i; /* first calls our _create() method */ obj = object_load_using_properties(&association_type, obj_node, version, filename); assoc = (Association *)obj; orth = &assoc->orth; /* ... butnot orthconn_load() */ if (version < 1) orth->autorouting = FALSE; if (version < 2) { /* vesrion 1 used to name it differently */ attr = object_find_attribute(obj_node, "autorouting"); if (attr != NULL) orth->autorouting = data_boolean(attribute_first_data(attr)); attr = object_find_attribute(obj_node, "ends"); composite = attribute_first_data(attr); for (i=0;i<2;i++) { assoc->end[i].role = NULL; attr = composite_find_attribute(composite, "role"); if (attr != NULL) { assoc->end[i].role = data_string(attribute_first_data(attr)); } if ( assoc->end[i].role != NULL && 0 == strcmp(assoc->end[i].role, "")) { g_free(assoc->end[i].role); assoc->end[i].role = NULL; } assoc->end[i].multiplicity = NULL; attr = composite_find_attribute(composite, "multiplicity"); if (attr != NULL) { assoc->end[i].multiplicity = data_string(attribute_first_data(attr)); } if ( assoc->end[i].multiplicity != NULL && 0 == strcmp(assoc->end[i].multiplicity, "")) { g_free(assoc->end[i].multiplicity); assoc->end[i].multiplicity = NULL; } assoc->end[i].arrow = FALSE; attr = composite_find_attribute(composite, "arrow"); if (attr != NULL) assoc->end[i].arrow = data_boolean(attribute_first_data(attr)); assoc->end[i].aggregate = AGGREGATE_NONE; attr = composite_find_attribute(composite, "aggregate"); if (attr != NULL) assoc->end[i].aggregate = data_enum(attribute_first_data(attr)); assoc->end[i].visibility = FALSE; attr = composite_find_attribute(composite, "visibility"); if (attr != NULL) assoc->end[i].visibility = data_enum( attribute_first_data(attr) ); assoc->end[i].text_width = 0.0; if (assoc->end[i].role != NULL) { assoc->end[i].text_width = dia_font_string_width(assoc->end[i].role, assoc_font, ASSOCIATION_FONTHEIGHT); } if (assoc->end[i].multiplicity != NULL) { assoc->end[i].text_width = MAX(assoc->end[i].text_width, dia_font_string_width(assoc->end[i].multiplicity, assoc_font, ASSOCIATION_FONTHEIGHT) ); } composite = data_next(composite); } /* derive new members state from ends */ assoc->show_direction = (assoc->direction != ASSOC_NODIR); if (assoc->end[0].aggregate == AGGREGATE_NORMAL) { assoc->assoc_type = AGGREGATE_NORMAL; assoc->direction = ASSOC_RIGHT; } else if (assoc->end[0].aggregate == AGGREGATE_COMPOSITION) { assoc->assoc_type = AGGREGATE_COMPOSITION; assoc->direction = ASSOC_RIGHT; } else if (assoc->end[1].aggregate == AGGREGATE_NORMAL) { assoc->assoc_type = AGGREGATE_NORMAL; assoc->direction = ASSOC_LEFT; } else if (assoc->end[1].aggregate == AGGREGATE_COMPOSITION) { assoc->assoc_type = AGGREGATE_COMPOSITION; assoc->direction = ASSOC_LEFT; } } /* version < 2 */ association_set_state(assoc, association_get_state(assoc)); return &assoc->orth.object; }
static void association_set_state(Association *assoc, AssociationState *state) { int i; AssociationEnd *end; g_free(assoc->name); assoc->name = state->name; assoc->text_width = 0.0; assoc->ascent = 0.0; assoc->descent = 0.0; if (assoc->name != NULL) { assoc->text_width = dia_font_string_width(assoc->name, assoc_font, ASSOCIATION_FONTHEIGHT); assoc->ascent = dia_font_ascent(assoc->name, assoc_font, ASSOCIATION_FONTHEIGHT); assoc->descent = dia_font_descent(assoc->name, assoc_font, ASSOCIATION_FONTHEIGHT); } assoc->direction = state->direction; for (i=0;i<2;i++) { end = &assoc->end[i]; g_free(end->role); g_free(end->multiplicity); end->role = state->end[i].role; end->multiplicity = state->end[i].multiplicity; end->arrow = state->end[i].arrow; end->aggregate = state->end[i].aggregate; end->visibility = state->end[i].visibility; end->text_width = 0.0; end->role_ascent = 0.0; end->role_descent = 0.0; end->multi_ascent = 0.0; end->multi_descent = 0.0; if (end->role != NULL && *end->role) { end->text_width = dia_font_string_width(end->role, assoc_font, ASSOCIATION_FONTHEIGHT); end->role_ascent = dia_font_ascent(end->role, assoc_font, ASSOCIATION_FONTHEIGHT); end->role_descent = dia_font_ascent(end->role, assoc_font, ASSOCIATION_FONTHEIGHT); } if (end->multiplicity != NULL) { end->text_width = MAX(end->text_width, dia_font_string_width(end->multiplicity, assoc_font, ASSOCIATION_FONTHEIGHT) ); end->role_ascent = dia_font_ascent(end->multiplicity, assoc_font,ASSOCIATION_FONTHEIGHT); end->role_descent = dia_font_descent(end->multiplicity, assoc_font,ASSOCIATION_FONTHEIGHT); } } g_free(state); association_update_data(assoc); }
static void transition_update_data(Transition *transition) { Element *elem = &transition->element; DiaObject *obj = &elem->object; Point *p; transition->element.extra_spacing.border_trans = TRANSITION_LINE_WIDTH / 2.0; obj->position = elem->corner; elem->width = TRANSITION_DECLAREDWIDTH; elem->height = TRANSITION_DECLAREDWIDTH; /* compute the useful points' positions : */ transition->A.x = transition->B.x = (TRANSITION_DECLAREDWIDTH / 2.0); transition->A.y = (TRANSITION_DECLAREDHEIGHT / 2.0) - (TRANSITION_HEIGHT / 2.0); transition->B.y = transition->A.y + TRANSITION_HEIGHT; transition->C.y = transition->D.y = (TRANSITION_DECLAREDHEIGHT / 2.0); transition->C.x = (TRANSITION_DECLAREDWIDTH / 2.0) - (TRANSITION_WIDTH / 2.0); transition->D.x = transition->C.x + TRANSITION_WIDTH; transition->Z.y = (TRANSITION_DECLAREDHEIGHT / 2.0) + (.3 * transition->receptivity->fontheight); transition->Z.x = transition->D.x + dia_font_string_width("_",transition->receptivity->font, transition->receptivity->fontheight); for (p = &transition->A; p <= &transition->Z; p++) point_add(p,&elem->corner); transition->receptivity->pos = transition->Z; /* Update handles: */ if (transition->north.pos.x == -65536.0) { transition->north.pos = transition->A; transition->south.pos = transition->B; } transition->NU1.x = transition->north.pos.x; transition->NU2.x = transition->A.x; transition->NU1.y = transition->NU2.y = (transition->north.pos.y + transition->A.y) / 2.0; transition->SD1.x = transition->B.x; transition->SD2.x = transition->south.pos.x; transition->SD1.y = transition->SD2.y = (transition->south.pos.y + transition->B.y) / 2.0; obj->connections[0]->pos = transition->A; obj->connections[0]->directions = DIR_EAST|DIR_WEST; obj->connections[1]->pos = transition->B; obj->connections[1]->directions = DIR_EAST|DIR_WEST; element_update_boundingbox(elem); rectangle_add_point(&obj->bounding_box,&transition->north.pos); rectangle_add_point(&obj->bounding_box,&transition->south.pos); /* compute the rcept's width and bounding box, then merge. */ boolequation_calc_boundingbox(transition->receptivity,&transition->rceptbb); rectangle_union(&obj->bounding_box,&transition->rceptbb); element_update_handles(elem); }
static void dependency_update_data(Dependency *dep) { OrthConn *orth = &dep->orth; DiaObject *obj = &orth->object; PolyBBExtras *extra = &orth->extra_spacing; int num_segm, i; Point *points; Rectangle rect; orthconn_update_data(orth); dep->stereotype = remove_stereotype_from_string(dep->stereotype); if (!dep->st_stereotype) { dep->st_stereotype = string_to_stereotype(dep->stereotype); } dep->text_width = 0.0; if (dep->name) dep->text_width = dia_font_string_width(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); if (dep->stereotype) dep->text_width = MAX(dep->text_width, dia_font_string_width(dep->stereotype, dep_font, DEPENDENCY_FONTHEIGHT)); extra->start_trans = extra->start_long = extra->middle_trans = DEPENDENCY_WIDTH/2.0; extra->end_trans = extra->end_long = (dep->draw_arrow? (DEPENDENCY_WIDTH + DEPENDENCY_ARROWLEN)/2.0: DEPENDENCY_WIDTH/2.0); orthconn_update_boundingbox(orth); /* Calc text pos: */ num_segm = dep->orth.numpoints - 1; points = dep->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (dep->orth.orientation[i]==VERTICAL) i--; } switch (dep->orth.orientation[i]) { case HORIZONTAL: dep->text_align = ALIGN_CENTER; dep->text_pos.x = 0.5*(points[i].x+points[i+1].x); dep->text_pos.y = points[i].y; if (dep->name) dep->text_pos.y -= dia_font_descent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); break; case VERTICAL: dep->text_align = ALIGN_LEFT; dep->text_pos.x = points[i].x + 0.1; dep->text_pos.y = 0.5*(points[i].y+points[i+1].y); if (dep->name) dep->text_pos.y -= dia_font_descent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); break; } /* Add the text recangle to the bounding box: */ rect.left = dep->text_pos.x; if (dep->text_align == ALIGN_CENTER) rect.left -= dep->text_width/2.0; rect.right = rect.left + dep->text_width; rect.top = dep->text_pos.y; if (dep->name) rect.top -= dia_font_ascent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); rect.bottom = rect.top + 2*DEPENDENCY_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); }
static void attribute_draw(Attribute *attribute, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Point center; Point start, end; Point p; Element *elem; real width; assert(attribute != NULL); assert(renderer != NULL); elem = &attribute->element; center.x = elem->corner.x + elem->width/2; center.y = elem->corner.y + elem->height/2; renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID); renderer_ops->fill_ellipse(renderer, ¢er, elem->width, elem->height, &attribute->inner_color); renderer_ops->set_linewidth(renderer, attribute->border_width); if (attribute->derived) { renderer_ops->set_linestyle(renderer, LINESTYLE_DASHED); renderer_ops->set_dashlength(renderer, 0.3); } else { renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID); } renderer_ops->draw_ellipse(renderer, ¢er, elem->width, elem->height, &attribute->border_color); if(attribute->multivalue) { renderer_ops->draw_ellipse(renderer, ¢er, elem->width - 2*MULTIVALUE_BORDER_WIDTH_X, elem->height - 2*MULTIVALUE_BORDER_WIDTH_Y, &attribute->border_color); } p.x = elem->corner.x + elem->width / 2.0; p.y = elem->corner.y + (elem->height - attribute->font_height)/2.0 + dia_font_ascent(attribute->name, attribute->font, attribute->font_height); renderer_ops->set_font(renderer, attribute->font, attribute->font_height); renderer_ops->draw_string(renderer, attribute->name, &p, ALIGN_CENTER, &color_black); if (attribute->key || attribute->weakkey) { if (attribute->weakkey) { renderer_ops->set_linestyle(renderer, LINESTYLE_DASHED); renderer_ops->set_dashlength(renderer, 0.3); } else { renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID); } width = dia_font_string_width(attribute->name, attribute->font, attribute->font_height); start.x = center.x - width / 2; start.y = center.y + 0.4; end.x = center.x + width / 2; end.y = center.y + 0.4; renderer_ops->draw_line(renderer, &start, &end, &color_black); } }
static void chronoref_update_data(Chronoref *chronoref) { Element *elem = &chronoref->element; DiaObject *obj = &elem->object; real time_span,t; Point p1,p2; Point ur_corner; int shouldbe,i; real labelwidth; char biglabel[10]; ElementBBExtras *extra = &elem->extra_spacing; chronoref->majgrad_height = elem->height; chronoref->mingrad_height = elem->height / 3.0; /* build i = -log_{10}(time_step), then make a %.if format out of it. */ t = 1; i = 0; while (t > chronoref->time_step) { t /= 10; i++; } chronoref->spec = i; /* update precision */ g_snprintf(biglabel,sizeof(biglabel),"%.*f", chronoref->spec, MIN(-ABS(chronoref->start_time),-ABS(chronoref->end_time))); labelwidth = dia_font_string_width(biglabel,chronoref->font, chronoref->font_size); /* Now, update the drawing helper counters */ time_span = chronoref->end_time - chronoref->start_time; if (time_span == 0) { chronoref->end_time = chronoref->start_time + .1; time_span = .1; } else if (time_span < 0) { chronoref->start_time = chronoref->end_time; time_span = -time_span; chronoref->end_time = chronoref->start_time + time_span; } chronoref->firstmaj = chronoref->time_step * ceil(chronoref->start_time / chronoref->time_step); if (chronoref->firstmaj < chronoref->start_time) chronoref->firstmaj += chronoref->time_step; chronoref->firstmin = chronoref->time_lstep * ceil(chronoref->start_time / chronoref->time_lstep); if (chronoref->firstmin < chronoref->start_time) chronoref->firstmin += chronoref->time_lstep; chronoref->firstmaj_x = elem->corner.x + elem->width*((chronoref->firstmaj-chronoref->start_time)/time_span); chronoref->firstmin_x = elem->corner.x + elem->width*((chronoref->firstmin-chronoref->start_time)/time_span); chronoref->majgrad = (chronoref->time_step * elem->width) / time_span; chronoref->mingrad = (chronoref->time_lstep * elem->width) / time_span; extra->border_trans = chronoref->main_lwidth/2; element_update_boundingbox(elem); /* fix boundingbox for special extras: */ obj->bounding_box.left -= (chronoref->font_size + labelwidth)/2; obj->bounding_box.bottom += chronoref->font_size; obj->bounding_box.right += (chronoref->font_size + labelwidth)/2; obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ ur_corner.x = elem->corner.x + elem->width; ur_corner.y = elem->corner.y; shouldbe = (int)(ceil((chronoref->end_time-chronoref->firstmin)/ chronoref->time_lstep)); if (shouldbe == 0) shouldbe++; if (shouldbe < 0) shouldbe = 0; shouldbe++; /* off by one.. */ connpointline_adjust_count(chronoref->scale,shouldbe,&ur_corner); connpointline_update(chronoref->scale); point_copy(&p1,&elem->corner); point_copy(&p2,&ur_corner); p1.x -= chronoref->mingrad; p2.x += chronoref->mingrad; connpointline_putonaline(chronoref->scale,&p1,&p2, DIR_SOUTH); }
static void attribute_update_data(Attribute *attribute) { Element *elem = &attribute->element; DiaObject *obj = &elem->object; Point center; ElementBBExtras *extra = &elem->extra_spacing; real half_x, half_y; attribute->name_width = dia_font_string_width(attribute->name, attribute->font, attribute->font_height); elem->width = attribute->name_width + 2*TEXT_BORDER_WIDTH_X; elem->height = attribute->font_height + 2*TEXT_BORDER_WIDTH_Y; center.x = elem->corner.x + elem->width / 2.0; center.y = elem->corner.y + elem->height / 2.0; half_x = elem->width * M_SQRT1_2 / 2.0; half_y = elem->height * M_SQRT1_2 / 2.0; /* Update connections: */ connpoint_update(&attribute->connections[0], center.x - half_x, center.y - half_y, DIR_NORTHWEST); connpoint_update(&attribute->connections[1], center.x, elem->corner.y, DIR_NORTH); connpoint_update(&attribute->connections[2], center.x + half_x, center.y - half_y, DIR_NORTHEAST); connpoint_update(&attribute->connections[3], elem->corner.x, center.y, DIR_WEST); connpoint_update(&attribute->connections[4], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&attribute->connections[5], center.x - half_x, center.y + half_y, DIR_SOUTHWEST); connpoint_update(&attribute->connections[6], elem->corner.x + elem->width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&attribute->connections[7], center.x + half_x, center.y + half_y, DIR_SOUTHEAST); connpoint_update(&attribute->connections[8], center.x, center.y, DIR_ALL); extra->border_trans = attribute->border_width/2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }