Beispiel #1
0
static void
textobj_update_data(Textobj *textobj)
{
  Point to2;
  DiaObject *obj = &textobj->object;
  Rectangle tx_bb;

  text_set_position(textobj->text, &obj->position);
  text_calc_boundingbox(textobj->text, &obj->bounding_box);

  to2 = obj->position;
  textobj_valign_point(textobj, &to2);
  /* shift text position depending on text alignment */
  if (VALIGN_TOP == textobj->vert_align)
    to2.y += textobj->margin; /* down */
  else if (VALIGN_BOTTOM == textobj->vert_align)
    to2.y -= textobj->margin; /* up */
  if (ALIGN_LEFT == textobj->text->alignment)
    to2.x += textobj->margin; /* right */
  else if (ALIGN_RIGHT == textobj->text->alignment)
    to2.x -= textobj->margin; /* left */
  text_set_position(textobj->text, &to2);

  /* always use the unrotated box ... */
  text_calc_boundingbox(textobj->text, &tx_bb);
  /* grow the bounding box by 2x margin */
  obj->bounding_box.top    -= textobj->margin;
  obj->bounding_box.left   -= textobj->margin;
  obj->bounding_box.bottom += textobj->margin;
  obj->bounding_box.right  += textobj->margin;

  textobj->text_handle.pos = obj->position;
  if (textobj->text_angle == 0) {
    obj->bounding_box = tx_bb;
    g_return_if_fail (obj->enclosing_box != NULL);
    *obj->enclosing_box = tx_bb;
  } else {
    /* ... and grow it when necessary */
    Point poly[4];
    int i;

    _textobj_get_poly (textobj, poly);
    /* we don't want the joined box for boundingbox because
     * selection would become too greedy than.
     */
    obj->bounding_box.left = obj->bounding_box.right = poly[0].x;
    obj->bounding_box.top = obj->bounding_box.bottom = poly[0].y;
    for (i = 1; i < 4; ++i)
      rectangle_add_point (&obj->bounding_box, &poly[i]);
    g_return_if_fail (obj->enclosing_box != NULL);
    *obj->enclosing_box = obj->bounding_box;
    /* join for editing/selection bbox */
    rectangle_union (obj->enclosing_box, &tx_bb);
  }
}
Beispiel #2
0
static void
basestation_update_data(Basestation *basestation)
{
    Element *elem = &basestation->element;
    DiaObject *obj = &elem->object;
    Rectangle text_box;
    Point p;

    elem->width = BASESTATION_WIDTH;
    elem->height = BASESTATION_HEIGHT+basestation->text->height;

    p = elem->corner;
    p.x += elem->width/2;
    p.y += elem->height + basestation->text->ascent;
    text_set_position(basestation->text, &p);

    text_calc_boundingbox(basestation->text, &text_box);

    /* Update connections: */
    element_update_connections_rectangle (elem, basestation->connections);

    element_update_boundingbox(elem);

    /* Add bounding box for text: */
    rectangle_union(&obj->bounding_box, &text_box);

    obj->position = elem->corner;
    obj->position.x += elem->width/2.0;
    obj->position.y += elem->height/2.0;

    element_update_handles(elem);
}
Beispiel #3
0
Datei: node.c Projekt: UIKit0/dia
static void 
node_update_data(Node *node)
{
  Element *elem = &node->element;
  DiaObject *obj = &node->element.object;
  Point p1;
  real h;

  text_calc_boundingbox(node->name, NULL);

  h = elem->corner.y + NODE_TEXT_MARGIN;

  p1.x = elem->corner.x + NODE_TEXT_MARGIN;
  p1.y = h + node->name->ascent;  /* position of text */
  text_set_position(node->name, &p1);
  h += node->name->height * node->name->numlines;

  elem->width = MAX(elem->width, node->name->max_width + 2*NODE_TEXT_MARGIN);
  elem->height = MAX(elem->height, node->name->height * node->name->numlines + 2*NODE_TEXT_MARGIN);
  
  /* Update connections: */
  element_update_connections_rectangle(elem, node->connections);
  
  element_update_boundingbox(elem);
  /* fix boundingbox for depth: */
  obj->bounding_box.top -= NODE_DEPTH;
  obj->bounding_box.right += NODE_DEPTH;

  obj->position = elem->corner;

  element_update_handles(elem);
}
Beispiel #4
0
Datei: note.c Projekt: UIKit0/dia
static void
note_update_data(Note *note)
{
  Element *elem = &note->element;
  DiaObject *obj = &elem->object;
  Point p;

  text_calc_boundingbox(note->text, NULL);

  elem->width = note->text->max_width + NOTE_MARGIN_X + NOTE_CORNER;
  elem->height =
    note->text->height*note->text->numlines + NOTE_MARGIN_Y + NOTE_CORNER;

  p = elem->corner;
  p.x += note->line_width/2.0 + NOTE_MARGIN_X;
  p.y += note->line_width/2.0 + NOTE_CORNER + note->text->ascent;
  text_set_position(note->text, &p);

  /* Update connections: */
  element_update_connections_rectangle(elem, note->connections);
  
  element_update_boundingbox(elem);

  obj->position = elem->corner;
  element_update_handles(elem);
}
Beispiel #5
0
static void
textobj_update_data(Textobj *textobj)
{
  Point to2;
  DiaObject *obj = &textobj->object;
  
  text_set_position(textobj->text, &obj->position);
  text_calc_boundingbox(textobj->text, &obj->bounding_box);

  to2 = obj->position;
  textobj_valign_point(textobj, &to2, 1);
  text_set_position(textobj->text, &to2);
  text_calc_boundingbox(textobj->text, &obj->bounding_box);
  
  textobj->text_handle.pos = obj->position;
}
Beispiel #6
0
static void 
aadlbox_update_text_position(Aadlbox *aadlbox)
{
  Point p;
  
  aadlbox->specific->text_position(aadlbox, &p);
  text_set_position(aadlbox->name, &p);
}
Beispiel #7
0
static void
compfeat_get_props(Compfeat *compfeat, GPtrArray *props)
{
  if (compfeat->roletmp)
    compfeat->role = compfeat->roletmp;
  text_set_position(compfeat->text, &compfeat->text_pos);
  object_get_props_from_offsets(&compfeat->orth.object,
                                compfeat_offsets, props);
}
Beispiel #8
0
static void
compfeat_set_props(Compfeat *compfeat, GPtrArray *props)
{
  object_set_props_from_offsets(&compfeat->orth.object,
                                compfeat_offsets, props);
  compfeat->text_handle.pos = compfeat->text_pos;
  text_set_position(compfeat->text, &compfeat->text_handle.pos);
  compfeat_update_data(compfeat);
}
Beispiel #9
0
static void
state_update_data(State *state)
{
  real w, h;

  Element *elem = &state->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point p;
  
  text_calc_boundingbox(state->text, NULL);
  w = state->text->max_width + 2*STATE_MARGIN_X;
  h = state->text->height*state->text->numlines +2*STATE_MARGIN_Y;
  if (w < STATE_WIDTH)
    w = STATE_WIDTH;
  p.x = elem->corner.x + w/2.0;
  p.y = elem->corner.y + STATE_MARGIN_Y + state->text->ascent;
  text_set_position(state->text, &p);

  elem->width = w;
  elem->height = h;
  extra->border_trans = STATE_LINEWIDTH / 2.0;

  /* Update connections: */
  state->connections[0].pos = elem->corner;
  state->connections[1].pos.x = elem->corner.x + elem->width / 2.0;
  state->connections[1].pos.y = elem->corner.y;
  state->connections[2].pos.x = elem->corner.x + elem->width;
  state->connections[2].pos.y = elem->corner.y;
  state->connections[3].pos.x = elem->corner.x;
  state->connections[3].pos.y = elem->corner.y + elem->height / 2.0;
  state->connections[4].pos.x = elem->corner.x + elem->width;
  state->connections[4].pos.y = elem->corner.y + elem->height / 2.0;
  state->connections[5].pos.x = elem->corner.x;
  state->connections[5].pos.y = elem->corner.y + elem->height;
  state->connections[6].pos.x = elem->corner.x + elem->width / 2.0;
  state->connections[6].pos.y = elem->corner.y + elem->height;
  state->connections[7].pos.x = elem->corner.x + elem->width;
  state->connections[7].pos.y = elem->corner.y + elem->height;
  
  state->connections[0].directions = DIR_NORTH|DIR_WEST;
  state->connections[1].directions = DIR_NORTH;
  state->connections[2].directions = DIR_NORTH|DIR_EAST;
  state->connections[3].directions = DIR_WEST;
  state->connections[4].directions = DIR_EAST;
  state->connections[5].directions = DIR_SOUTH|DIR_WEST;
  state->connections[6].directions = DIR_SOUTH;
  state->connections[7].directions = DIR_SOUTH|DIR_EAST;
                                                                                          
  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);
}
static void
rendobj_update_data(RenderObject *rend_obj)
{
  Point p;
  const RenderObjectDescriptor *desc;
  Element *elem;
  Object *obj;
  int i;

  elem = &rend_obj->element;
  obj = &elem->object;
  desc = rend_obj->desc;

  rend_obj->magnify = elem->width / rend_obj->desc->width;
  
  /* Update connections: */
  for (i=0;i<desc->num_connection_points;i++) {
    rend_obj->connections[i].pos = desc->connection_points[i];
    point_scale(&rend_obj->connections[i].pos, rend_obj->magnify);
    point_add(&rend_obj->connections[i].pos, &elem->corner);
  }

  if (desc->use_text) {
    p = desc->text_pos;
    point_scale(&p, rend_obj->magnify);
    point_add(&p, &elem->corner);
    p.y += rend_obj->text->ascent;
    text_set_position(rend_obj->text, &p);
  }
  
  element_update_boundingbox(elem);
  /* fix boundingbox for extra_border: */
  obj->bounding_box.top -= desc->extra_border;
  obj->bounding_box.left -= desc->extra_border;
  obj->bounding_box.bottom += desc->extra_border;
  obj->bounding_box.right += desc->extra_border;

  if (desc->use_text) {
    Rectangle text_box;
    
    text_calc_boundingbox(rend_obj->text, &text_box);
    rectangle_union(&obj->bounding_box, &text_box);
  }
  
  obj->position = elem->corner;

  p = desc->move_position;
  point_scale(&p, rend_obj->magnify);
  point_add(&obj->position, &p);
  
  element_update_handles(elem);
}
static void
smallpackage_move(SmallPackage *pkg, Point *to)
{
  Point p;
  
  pkg->element.corner = *to;

  p = *to;
  p.x += SMALLPACKAGE_MARGIN_X;
  p.y += pkg->text->ascent + SMALLPACKAGE_MARGIN_Y;
  text_set_position(pkg->text, &p);
  
  smallpackage_update_data(pkg);
}
Beispiel #12
0
Datei: node.c Projekt: UIKit0/dia
static ObjectChange*
node_move(Node *node, Point *to)
{
  Point p;
  
  node->element.corner = *to;

  p = *to;
  p.x += NODE_TEXT_MARGIN;
  p.y += node->name->ascent + NODE_TEXT_MARGIN;
  text_set_position(node->name, &p);

  node_update_data(node);

  return NULL;
}
Beispiel #13
0
static void
state_update_data(State *state)
{
  real w, h;

  Element *elem = &state->element;
  Object *obj = (Object *) state;
  Point p;
  
  if (state->state_type==STATE_NORMAL) { 
      w = state->text->max_width + 2*STATE_MARGIN_X;
      h = state->text->height*state->text->numlines +2*STATE_MARGIN_Y;
      if (w < STATE_WIDTH)
	  w = STATE_WIDTH;
      p.x = elem->corner.x + w/2.0;
      p.y = elem->corner.y + STATE_MARGIN_Y + state->text->ascent;
      text_set_position(state->text, &p);
  } else {
      w = h = (state->state_type==STATE_END) ? STATE_ENDRATIO: STATE_RATIO;
  }

  elem->width = w;
  elem->height = h;

 /* Update connections: */
  state->connections[0].pos = elem->corner;
  state->connections[1].pos.x = elem->corner.x + elem->width / 2.0;
  state->connections[1].pos.y = elem->corner.y;
  state->connections[2].pos.x = elem->corner.x + elem->width;
  state->connections[2].pos.y = elem->corner.y;
  state->connections[3].pos.x = elem->corner.x;
  state->connections[3].pos.y = elem->corner.y + elem->height / 2.0;
  state->connections[4].pos.x = elem->corner.x + elem->width;
  state->connections[4].pos.y = elem->corner.y + elem->height / 2.0;
  state->connections[5].pos.x = elem->corner.x;
  state->connections[5].pos.y = elem->corner.y + elem->height;
  state->connections[6].pos.x = elem->corner.x + elem->width / 2.0;
  state->connections[6].pos.y = elem->corner.y + elem->height;
  state->connections[7].pos.x = elem->corner.x + elem->width;
  state->connections[7].pos.y = elem->corner.y + elem->height;
  
  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);
}
Beispiel #14
0
static ObjectChange*
req_move(Requirement *req, Point *to)
{
  real h;
  Point p;

  req->element.corner = *to;
  h = req->text->height*req->text->numlines;

  p = *to;
  p.x += req->element.width/2.0;
  p.y += (req->element.height - h)/2.0 + req->text->ascent;

  text_set_position(req->text, &p);
  req_update_data(req);
  return NULL;
}
Beispiel #15
0
static ObjectChange *
compfeat_move(Compfeat *compfeat, Point *to)
{
  ObjectChange *change;
  Point delta = *to;

  delta = *to;
  point_sub(&delta, &compfeat->orth.points[0]);

  /* I don't understand this, but the text position is wrong directly
     after compfeat_create()! */
  point_add(&delta, &compfeat->text->position);
  text_set_position(compfeat->text, &delta);
  change = orthconn_move(&compfeat->orth, to);
  compfeat_update_data(compfeat);

  return change;
}
Beispiel #16
0
static ObjectChange*
usecase_move(Usecase *usecase, Point *to)
{
  real h;
  Point p;

  usecase->element.corner = *to;
  h = usecase->text->height*usecase->text->numlines;

  p = *to;
  p.x += usecase->element.width/2.0;
  if (usecase->text_outside) {
      p.y += usecase->element.height - h + usecase->text->ascent;
  } else {
      p.y += (usecase->element.height - h)/2.0 + usecase->text->ascent;
  }
  text_set_position(usecase->text, &p);
  usecase_update_data(usecase);

  return NULL;
}
Beispiel #17
0
static ObjectChange *
compfeat_move_handle(Compfeat *compfeat, Handle *handle,
		     Point *to, ConnectionPoint *cp,
		     HandleMoveReason reason,
		     ModifierKeys modifiers)
{
  ObjectChange *change;

  assert(compfeat!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    text_set_position(compfeat->text, to);
    change = NULL;
  } else  {
    change = orthconn_move_handle(&compfeat->orth, handle, to, cp, 
				  reason, modifiers);
  }
  compfeat_update_data(compfeat);

  return change;
}
Beispiel #18
0
static void
radiocell_update_data(RadioCell *radiocell)
{
  PolyShape *poly = &radiocell->poly;
  DiaObject *obj = &poly->object;
  ElementBBExtras *extra = &poly->extra_spacing;
  Rectangle text_box;
  Point textpos;
  int i;
  /* not exactly a regular hexagon, but this fits better in the grid */
  Point points[] = { {  1., 0. }, {  .5,  .75 }, { -.5,  .75 },
		     { -1., 0. }, { -.5, -.75 }, {  .5, -.75 } };

  radiocell->center.x = (poly->points[0].x + poly->points[3].x) / 2.;
  radiocell->center.y = poly->points[0].y;

  for (i = 0; i < 6; i++) {
    poly->points[i] = radiocell->center;
    poly->points[i].x += radiocell->radius * points[i].x;
    poly->points[i].y += radiocell->radius * points[i].y;
  }

  /* Add bounding box for text: */
  text_calc_boundingbox(radiocell->text, NULL);
  textpos.x = (poly->points[0].x + poly->points[3].x) / 2.;
  textpos.y = poly->points[0].y -
    (radiocell->text->height * (radiocell->text->numlines - 1) +
     radiocell->text->descent) / 2.;
  text_set_position(radiocell->text, &textpos);
  text_calc_boundingbox(radiocell->text, &text_box);
  polyshape_update_data(poly);
  extra->border_trans = radiocell->line_width / 2.0;
  polyshape_update_boundingbox(poly);
  rectangle_union(&obj->bounding_box, &text_box);
  obj->position = poly->points[0];
}
Beispiel #19
0
static void
usecase_update_data(Usecase *usecase)
{
  real w, h, ratio;
  Point c, half, r,p;

  Element *elem = &usecase->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;

  text_calc_boundingbox(usecase->text, NULL);
  w = usecase->text->max_width;
  h = usecase->text->height*usecase->text->numlines;

  if (!usecase->text_outside) {
      ratio = w/h;

      if (ratio > USECASE_MAX_RATIO)
	  ratio = USECASE_MAX_RATIO;

      if (ratio < USECASE_MIN_RATIO) {
	  ratio = USECASE_MIN_RATIO;
	  r.y = w / ratio + h;
	  r.x = r.y * ratio;
      } else {
	  r.x = ratio*h + w;
	  r.y = r.x / ratio;
      }
      if (r.x < USECASE_WIDTH)
	      r.x = USECASE_WIDTH;
      if (r.y < USECASE_HEIGHT)
	      r.y = USECASE_HEIGHT;
  } else {
      r.x = USECASE_WIDTH;
      r.y = USECASE_HEIGHT;
  }

  elem->width = r.x;
  elem->height = r.y;
  extra->border_trans = usecase->line_width / 2.0;

  if (usecase->text_outside) {
	  elem->width = MAX(elem->width, w);
	  elem->height += h + USECASE_MARGIN_Y;
  }

  r.x /= 2.0;
  r.y /= 2.0;
  c.x = elem->corner.x + elem->width / 2.0;
  c.y = elem->corner.y + r.y;
  half.x = r.x * M_SQRT1_2;
  half.y = r.y * M_SQRT1_2;

  /* Update connections: */
  usecase->connections[0].pos.x = c.x - half.x;
  usecase->connections[0].pos.y = c.y - half.y;
  usecase->connections[1].pos.x = c.x;
  usecase->connections[1].pos.y = elem->corner.y;
  usecase->connections[2].pos.x = c.x + half.x;
  usecase->connections[2].pos.y = c.y - half.y;
  usecase->connections[3].pos.x = c.x - r.x;
  usecase->connections[3].pos.y = c.y;
  usecase->connections[4].pos.x = c.x + r.x;
  usecase->connections[4].pos.y = c.y;

  if (usecase->text_outside) {
      usecase->connections[5].pos.x = elem->corner.x;
      usecase->connections[5].pos.y = elem->corner.y + elem->height;
      usecase->connections[6].pos.x = c.x;
      usecase->connections[6].pos.y = elem->corner.y + elem->height;
      usecase->connections[7].pos.x = elem->corner.x + elem->width;
      usecase->connections[7].pos.y = elem->corner.y + elem->height;
  } else {
      usecase->connections[5].pos.x = c.x - half.x;
      usecase->connections[5].pos.y = c.y + half.y;
      usecase->connections[6].pos.x = c.x;
      usecase->connections[6].pos.y = elem->corner.y + elem->height;
      usecase->connections[7].pos.x = c.x + half.x;
      usecase->connections[7].pos.y = c.y + half.y;
  }
  usecase->connections[8].pos.x = c.x;
  usecase->connections[8].pos.y = c.y;

  usecase->connections[0].directions = DIR_NORTH|DIR_WEST;
  usecase->connections[1].directions = DIR_NORTH;
  usecase->connections[2].directions = DIR_NORTH|DIR_EAST;
  usecase->connections[3].directions = DIR_WEST;
  usecase->connections[4].directions = DIR_EAST;
  usecase->connections[5].directions = DIR_SOUTH|DIR_WEST;
  usecase->connections[6].directions = DIR_SOUTH;
  usecase->connections[7].directions = DIR_SOUTH|DIR_EAST;
  usecase->connections[8].directions = DIR_ALL;

  h = usecase->text->height*usecase->text->numlines;
  p = usecase->element.corner;
  p.x += usecase->element.width/2.0;
  if (usecase->text_outside) {
      p.y += usecase->element.height - h + usecase->text->ascent;
  } else {
      p.y += (usecase->element.height - h)/2.0 + usecase->text->ascent;
  }
  text_set_position(usecase->text, &p);

  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);

}
Beispiel #20
0
static void
ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &ellipse->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p, c;
  real dw, dh;
  real width, height;
  real radius1, radius2;
  int i;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(ellipse->text, NULL);
  width = ellipse->text->max_width + 2 * ellipse->padding;
  height = ellipse->text->height * ellipse->text->numlines +
    2 * ellipse->padding;

  /* stop ellipse from getting infinite width/height */
  if (elem->width / elem->height > 4)
    elem->width = elem->height * 4;
  else if (elem->height / elem->width > 4)
    elem->height = elem->width * 4;

  c.x = elem->corner.x + elem->width / 2;
  c.y = elem->corner.y + elem->height / 2;
  p.x = c.x - width  / 2;
  p.y = c.y - height / 2;
  radius1 = ellipse_radius(ellipse, p.x, p.y) - ellipse->border_width/2;
  radius2 = distance_point_point(&c, &p);
  
  if (   radius1 < radius2
      && (   ellipse->text_fitting == TEXTFIT_ALWAYS
          || ellipse->text_fitting == TEXTFIT_WHEN_NEEDED)) {
    /* increase size of the ellipse while keeping its aspect ratio */
    elem->width  *= radius2 / radius1;
    elem->height *= radius2 / radius1;
  }

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - ellipse->text->height*ellipse->text->numlines/2 +
    ellipse->text->ascent;
  switch (ellipse->text->alignment) {
  case ALIGN_LEFT:
    p.x -= (elem->width - 2*(ellipse->padding + ellipse->border_width))/2;
    break;
  case ALIGN_RIGHT:
    p.x += (elem->width - 2*(ellipse->padding + ellipse->border_width))/2;
    break;
  case ALIGN_CENTER:
    break;
  }
  text_set_position(ellipse->text, &p);

  /* Update connections: */
  c.x = elem->corner.x + elem->width / 2;
  c.y = elem->corner.y + elem->height / 2;
  dw = elem->width  / 2.0;
  dh = elem->height / 2.0;
  for (i = 0; i < NUM_CONNECTIONS-1; i++) {
    real theta = M_PI / 8.0 * i;
    real costheta = cos(theta);
    real sintheta = sin(theta);
    connpoint_update(&ellipse->connections[i],
		      c.x + dw * costheta,
		      c.y - dh * sintheta,
		      (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))|
		      (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0)));
  }
  connpoint_update(&ellipse->connections[16],
		   c.x, c.y, DIR_ALL);

  extra->border_trans = ellipse->border_width / 2.0;
  element_update_boundingbox(elem);

  obj->position = elem->corner;
  
  element_update_handles(elem);
}
Beispiel #21
0
static void
other_update_data(Other *other, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &other->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p;
  real width, height;
  Point nw,ne,se,sw;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(other->text, NULL);
  width = other->text->max_width + other->padding*2;
  height = other->text->height * other->text->numlines + other->padding*2;

  /* autoscale here */
  if (width > elem->width) elem->width = width;
  if (height > elem->height) elem->height = height;
  if (elem->width<elem->height*1.5) elem->width=elem->height*1.5;

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;

  p.y += elem->height / 2.0 - other->text->height * other->text->numlines / 2 +
    other->text->ascent;
  text_set_position(other->text, &p);

  extra->border_trans = OTHER_LINE_WIDTH / 2.0;
  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);

  /* Update connections: */
  nw = elem->corner;
  se.x = nw.x + elem->width;
  se.y = nw.y + elem->height;
  ne.x = se.x;
  ne.y = nw.y;
  sw.y = se.y;
  sw.x = nw.x;

  connpointline_update(other->north);
  connpointline_putonaline(other->north,&ne,&nw,DIR_NORTH);
  connpointline_update(other->west);
  connpointline_putonaline(other->west,&nw,&sw,DIR_WEST);
  connpointline_update(other->south);
  connpointline_putonaline(other->south,&sw,&se,DIR_SOUTH);
  connpointline_update(other->east);
  connpointline_putonaline(other->east,&se,&ne,DIR_EAST);
}
Beispiel #22
0
static void
diamond_update_data(Diamond *diamond, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &diamond->element;
  DiaObject *obj = &elem->object;
  ElementBBExtras *extra = &elem->extra_spacing;
  Point center, bottom_right;
  Point p;
  real dw, dh;
  real width, height;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(diamond->text, NULL);
  width = diamond->text->max_width + 2*diamond->padding+diamond->border_width;
  height = diamond->text->height * diamond->text->numlines +
    2 * diamond->padding + diamond->border_width;

  if (diamond->text_fitting == TEXTFIT_ALWAYS
      || (   diamond->text_fitting == TEXTFIT_WHEN_NEEDED
          && height > (elem->width - width) * elem->height / elem->width)) {
    /* increase size of the diamond while keeping its aspect ratio */
    real grad = elem->width/elem->height;
    if (grad < 1.0/4) grad = 1.0/4;
    if (grad > 4)     grad = 4;
    elem->width  = width  + height * grad;
    elem->height = height + width  / grad;
  } else {
    /* Need this for text alignment soon */
    real grad = elem->width/elem->height;
    if (grad < 1.0/4) grad = 1.0/4;
    if (grad > 4)     grad = 4;
    width = elem->width - height*grad;
  }

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - diamond->text->height*diamond->text->numlines/2 +
      diamond->text->ascent;
  switch (diamond->text->alignment) {
  case ALIGN_LEFT:
    p.x -= width/2;
    break;
  case ALIGN_RIGHT:
    p.x += width/2;
    break;
  case ALIGN_CENTER:
    break;
  }
  text_set_position(diamond->text, &p);

  dw = elem->width / 8.0;
  dh = elem->height / 8.0;
  /* Update connections: */
  diamond->connections[0].pos.x = elem->corner.x + 4*dw;
  diamond->connections[0].pos.y = elem->corner.y;
  diamond->connections[1].pos.x = elem->corner.x + 5*dw;
  diamond->connections[1].pos.y = elem->corner.y + dh;
  diamond->connections[2].pos.x = elem->corner.x + 6*dw;
  diamond->connections[2].pos.y = elem->corner.y + 2*dh;
  diamond->connections[3].pos.x = elem->corner.x + 7*dw;
  diamond->connections[3].pos.y = elem->corner.y + 3*dh;
  diamond->connections[4].pos.x = elem->corner.x + elem->width;
  diamond->connections[4].pos.y = elem->corner.y + 4*dh;
  diamond->connections[5].pos.x = elem->corner.x + 7*dw;
  diamond->connections[5].pos.y = elem->corner.y + 5*dh;
  diamond->connections[6].pos.x = elem->corner.x + 6*dw;
  diamond->connections[6].pos.y = elem->corner.y + 6*dh;
  diamond->connections[7].pos.x = elem->corner.x + 5*dw;
  diamond->connections[7].pos.y = elem->corner.y + 7*dh;
  diamond->connections[8].pos.x = elem->corner.x + 4*dw;
  diamond->connections[8].pos.y = elem->corner.y + elem->height;
  diamond->connections[9].pos.x = elem->corner.x + 3*dw;
  diamond->connections[9].pos.y = elem->corner.y + 7*dh;
  diamond->connections[10].pos.x = elem->corner.x + 2*dw;
  diamond->connections[10].pos.y = elem->corner.y + 6*dh;
  diamond->connections[11].pos.x = elem->corner.x + dw;
  diamond->connections[11].pos.y = elem->corner.y + 5*dh;
  diamond->connections[12].pos.x = elem->corner.x;
  diamond->connections[12].pos.y = elem->corner.y + 4*dh;
  diamond->connections[13].pos.x = elem->corner.x + dw;
  diamond->connections[13].pos.y = elem->corner.y + 3*dh;
  diamond->connections[14].pos.x = elem->corner.x + 2*dw;
  diamond->connections[14].pos.y = elem->corner.y + 2*dh;
  diamond->connections[15].pos.x = elem->corner.x + 3*dw;
  diamond->connections[15].pos.y = elem->corner.y + dh;
  diamond->connections[16].pos.x = elem->corner.x + 4*dw;
  diamond->connections[16].pos.y = elem->corner.y + 4*dh;

  /* help autorouting */
  element_update_connections_directions (elem, diamond->connections);

  extra->border_trans = diamond->border_width / 2.0;
  element_update_boundingbox(elem);
  
  obj->position = elem->corner;
  
  element_update_handles(elem);
}
Beispiel #23
0
static void
box_update_data(Box *box, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &box->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p;
  real radius;
  real width, height;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(box->text, NULL);
  width = box->text->max_width + box->padding*2 + box->border_width;
  height = box->text->height * box->text->numlines + box->padding*2 +
    box->border_width;

  /*
   *  If elem->width (e.g. the new requested dimensions of this object
   *  from move_handle()) is smaller than the minimum width (i.e. the
   *  width calculated from text-width, padding and border), then
   *  set the width to the minimum.  Or else;)
   */
  if (box->text_fitting != TEXTFIT_NEVER) {
    if (   box->text_fitting == TEXTFIT_ALWAYS
        || width > elem->width)
      elem->width = width;
    if (   box->text_fitting == TEXTFIT_ALWAYS
        || height > elem->height)
      elem->height = height;
  }

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - box->text->height * box->text->numlines / 2 +
    box->text->ascent;
  switch (box->text->alignment) {
  case ALIGN_LEFT:
    p.x -= (elem->width - box->padding*2 + box->border_width)/2;
    break;
  case ALIGN_RIGHT:
    p.x += (elem->width - box->padding*2 + box->border_width)/2;
    break;
  case ALIGN_CENTER:
    break;
  }

  text_set_position(box->text, &p);

  radius = box->corner_radius;
  radius = MIN(radius, elem->width/2);
  radius = MIN(radius, elem->height/2);
  radius *= (1-M_SQRT1_2);
  
  /* Update connections: */
  connpoint_update(&box->connections[0],
		    elem->corner.x + radius,
		    elem->corner.y + radius,
		    DIR_NORTHWEST);
  connpoint_update(&box->connections[1],
		    elem->corner.x + elem->width / 4.0,
		    elem->corner.y,
		    DIR_NORTH);
  connpoint_update(&box->connections[2],
		    elem->corner.x + elem->width / 2.0,
		    elem->corner.y,
		    DIR_NORTH);
  connpoint_update(&box->connections[3],
		    elem->corner.x + elem->width * 3.0 / 4.0,
		    elem->corner.y,
		    DIR_NORTH);
  connpoint_update(&box->connections[4],
		    elem->corner.x + elem->width - radius,
		    elem->corner.y + radius,
		    DIR_NORTHEAST);
  connpoint_update(&box->connections[5],
		    elem->corner.x,
		    elem->corner.y + elem->height / 4.0,
		    DIR_WEST);
  connpoint_update(&box->connections[6],
		    elem->corner.x + elem->width,
		    elem->corner.y + elem->height / 4.0,
		    DIR_EAST);
  connpoint_update(&box->connections[7],
		    elem->corner.x,
		    elem->corner.y + elem->height / 2.0,
		    DIR_WEST);
  connpoint_update(&box->connections[8],
		    elem->corner.x + elem->width,
		    elem->corner.y + elem->height / 2.0,
		    DIR_EAST);
  connpoint_update(&box->connections[9],
		    elem->corner.x,
		    elem->corner.y + elem->height * 3.0 / 4.0,
		    DIR_WEST);
  connpoint_update(&box->connections[10],
		    elem->corner.x + elem->width,
		    elem->corner.y + elem->height * 3.0 / 4.0,
		    DIR_EAST);
  connpoint_update(&box->connections[11],
		    elem->corner.x + radius,
		    elem->corner.y + elem->height - radius,
		    DIR_SOUTHWEST);
  connpoint_update(&box->connections[12],
		    elem->corner.x + elem->width / 4.0,
		    elem->corner.y + elem->height,
		    DIR_SOUTH);
  connpoint_update(&box->connections[13],
		    elem->corner.x + elem->width / 2.0,
		    elem->corner.y + elem->height,
		    DIR_SOUTH);
  connpoint_update(&box->connections[14],
		    elem->corner.x + elem->width * 3.0 / 4.0,
		    elem->corner.y + elem->height,
		    DIR_SOUTH);
  connpoint_update(&box->connections[15],
		    elem->corner.x + elem->width - radius,
		    elem->corner.y + elem->height - radius,
		    DIR_SOUTHEAST);
  connpoint_update(&box->connections[16],
		    elem->corner.x + elem->width / 2,
		    elem->corner.y + elem->height / 2,
		    DIR_ALL);

  extra->border_trans = box->border_width / 2.0;
  element_update_boundingbox(elem);
  
  obj->position = elem->corner;
  
  element_update_handles(elem);

  if (radius > 0.0) {
    /* Fix the handles, too */
    elem->resize_handles[0].pos.x += radius;
    elem->resize_handles[0].pos.y += radius;
    elem->resize_handles[2].pos.x -= radius;
    elem->resize_handles[2].pos.y += radius;
    elem->resize_handles[5].pos.x += radius;
    elem->resize_handles[5].pos.y -= radius;
    elem->resize_handles[7].pos.x -= radius;
    elem->resize_handles[7].pos.y -= radius;
  }
}
Beispiel #24
0
static void
classicon_update_data(Classicon *cicon)
{
  Element *elem = &cicon->element;
  DiaObject *obj = &elem->object;
  Point p1;
  real h, wt, w = 0;
  int is_boundary = (cicon->stereotype==CLASSICON_BOUNDARY);
	
  text_calc_boundingbox(cicon->text, NULL);
  h = CLASSICON_AIR + CLASSICON_MARGIN + CLASSICON_ARROW + 2*CLASSICON_RADIOUS;

  w = 2*CLASSICON_RADIOUS;
  wt = cicon->text->max_width;

  if (cicon->stereotype==CLASSICON_BOUNDARY) {
      w += 2*CLASSICON_RADIOUS;
      wt += CLASSICON_RADIOUS;
  }

  w = MAX(w, wt) + CLASSICON_AIR;

  p1.y = h + elem->corner.y; 
  h += cicon->text->height*cicon->text->numlines + CLASSICON_AIR;
  
  p1.y += cicon->text->ascent;
  p1.x = elem->corner.x + w/2.0;
  if (cicon->stereotype==CLASSICON_BOUNDARY)
      p1.x += CLASSICON_RADIOUS/2.0;
  text_set_position(cicon->text, &p1);
    
  elem->width = w;
  elem->height = h;
	
  p1.x = elem->corner.x + elem->width / 2.0;
  p1.y = elem->corner.y + CLASSICON_RADIOUS + CLASSICON_ARROW;
  w = CLASSICON_RADIOUS + CLASSICON_ARROW;
  h = (CLASSICON_RADIOUS + CLASSICON_ARROW) * M_SQRT1_2;

  if (is_boundary)
    p1.x += CLASSICON_RADIOUS/2.0;
	
  /* Update connections: */
  cicon->connections[0].pos.x = (is_boundary) ? p1.x-2*w: p1.x - h;
  cicon->connections[0].pos.y = (is_boundary) ? elem->corner.y: p1.y - h;
  cicon->connections[0].directions = DIR_WEST|DIR_NORTH;
  cicon->connections[1].pos.x = p1.x;
  cicon->connections[1].pos.y = p1.y - w;
  cicon->connections[1].directions = DIR_NORTH;
  cicon->connections[2].pos.x = p1.x + h;
  cicon->connections[2].pos.y = p1.y - h; 
  cicon->connections[2].directions = DIR_NORTH|DIR_EAST;
	
  cicon->connections[3].pos.x = (is_boundary) ? p1.x-2*w: p1.x - w;
  cicon->connections[3].pos.y = p1.y;
  cicon->connections[3].directions = DIR_WEST;
  cicon->connections[4].pos.x = p1.x + w;
  cicon->connections[4].pos.y = p1.y;
  cicon->connections[4].directions = DIR_EAST;
  cicon->connections[5].pos.x = elem->corner.x;
  cicon->connections[5].pos.y = elem->corner.y + elem->height;
  cicon->connections[5].directions = DIR_SOUTH|DIR_WEST;
  cicon->connections[6].pos.x = p1.x;
  cicon->connections[6].pos.y = elem->corner.y + elem->height;
  cicon->connections[6].directions = DIR_SOUTH;
  cicon->connections[7].pos.x = elem->corner.x + elem->width;
  cicon->connections[7].pos.y = elem->corner.y + elem->height;
  cicon->connections[7].directions = DIR_SOUTH|DIR_EAST;
  cicon->connections[8].pos.x = elem->corner.x + elem->width/2;
  cicon->connections[8].pos.y = elem->corner.y + elem->height/2;
  cicon->connections[8].directions = DIR_ALL;
  
  element_update_boundingbox(elem);

  obj->position = elem->corner;
  obj->position.x += (elem->width + ((is_boundary)?CLASSICON_RADIOUS:0))/2.0;
  obj->position.y += CLASSICON_RADIOUS + CLASSICON_ARROW;

  element_update_handles(elem);
}
Beispiel #25
0
/**
 * Sets the absolute position for the timestamp.
 */
void subtitle_set_position(int x, int y) {
  text_set_position(text_id, x, y);
}
Beispiel #26
0
static void
actor_update_data(Actor *actor, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &actor->element;
  DiaObject *obj = &elem->object;
  ElementBBExtras *extra = &elem->extra_spacing;

  Point center, bottom_right,p,c;
  real width, height, dw, dh;
  real radius, mradius;
  int i;

  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(actor->text, NULL);
  width = actor->text->max_width+0.5;
  height = actor->text->height * (actor->text->numlines + 3); /* added 3 blank lines for top */

  /* minimal radius */
  mradius=width;
  if (mradius<height) mradius=height;
  if (mradius<ACTOR_RADIUS) mradius=ACTOR_RADIUS;
  
  /* radius */
  radius=elem->width;
  if (radius<elem->height) radius=elem->height;
  
  /* enforce (minimal or resized) radius */
  if (radius<mradius) radius=mradius;
  elem->width=elem->height=radius;

  /* move shape if necessary ... (untouched) */
  switch (horiz) {
    case ANCHOR_MIDDLE:
      elem->corner.x = center.x - elem->width/2; break;
    case ANCHOR_END:
      elem->corner.x = bottom_right.x - elem->width; break;
    default:
      break;
  }
  switch (vert) {
    case ANCHOR_MIDDLE:
      elem->corner.y = center.y - elem->height/2; break;
    case ANCHOR_END:
      elem->corner.y = bottom_right.y - elem->height; break;
    default:
      break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - actor->text->height*actor->text->numlines/2 +
    actor->text->ascent;
  text_set_position(actor->text, &p);

  /* compute connection positions */
  c.x = elem->corner.x + elem->width / 2;
  c.y = elem->corner.y + elem->height / 2;
  dw = elem->width  / 2.0;
  dh = elem->height / 2.0;
  for (i = 0; i < NUM_CONNECTIONS-1; i++) {
    real theta = M_PI / 8.0 * i;
    /* TODO: Set up directions for autorouting */
    actor->connections[i].pos.x = c.x + dw * cos(theta);
    actor->connections[i].pos.y = c.y - dh * sin(theta);
  }
  actor->connections[16].pos.x = c.x;
  actor->connections[16].pos.y = c.y;

  extra->border_trans = ACTOR_BORDER_WIDTH / 2.0;
  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);
}
Beispiel #27
0
static void
goal_update_data(Goal *goal, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &goal->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p;
  real w, h;
  ConnectionPoint *c;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(goal->text, NULL);
  w = goal->text->max_width + goal->padding*2;
  h = goal->text->height * goal->text->numlines + goal->padding*2;

  /* autoscale here */
  if (w > elem->width) elem->width = w;
  if (h > elem->height) elem->height = h;
  if (elem->width<elem->height) elem->width=elem->height;

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - goal->text->height * goal->text->numlines / 2 +
    goal->text->ascent;
  text_set_position(goal->text, &p);

  extra->border_trans = GOAL_LINE_WIDTH;
  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);

  /* Update connections: */
  p = elem->corner;
  w = elem->width;
  h = elem->height;
  c = goal->connector;
  switch (goal->type) {
    case SOFTGOAL: update_softgoal_connectors(c,p,w,h); break;
    case GOAL:     update_goal_connectors(c,p,w,h); break;
  }
}
Beispiel #28
0
static void
req_update_data(Requirement *req)
{
  real w, h, ratio;
  Point c, half, r,p;

  Element *elem = &req->element;
  DiaObject *obj = &elem->object;

  text_calc_boundingbox(req->text, NULL);
  w = req->text->max_width;
  h = req->text->height*req->text->numlines;

  ratio = w/h;

  if (ratio > REQ_MAX_RATIO)
    ratio = REQ_MAX_RATIO;

  if (ratio < REQ_MIN_RATIO) {
    ratio = REQ_MIN_RATIO;
    r.y = w / ratio + h;
    r.x = r.y * ratio;
  } else {
    r.x = ratio*h + w;
    r.y = r.x / ratio;
  }
  if (r.x < REQ_WIDTH)
    r.x = REQ_WIDTH;
  if (r.y < REQ_HEIGHT)
    r.y = REQ_HEIGHT;

  elem->width = r.x;
  elem->height = r.y;

  r.x /= 2.0;
  r.y /= 2.0;
  c.x = elem->corner.x + elem->width / 2.0;
  c.y = elem->corner.y + r.y;
  half.x = r.x * M_SQRT1_2;
  half.y = r.y * M_SQRT1_2;

  /* Update connections: */
  req->connections[0].pos.x = c.x - half.x;
  req->connections[0].pos.y = c.y - half.y;
  req->connections[1].pos.x = c.x;
  req->connections[1].pos.y = elem->corner.y;
  req->connections[2].pos.x = c.x + half.x;
  req->connections[2].pos.y = c.y - half.y;
  req->connections[3].pos.x = c.x - r.x;
  req->connections[3].pos.y = c.y;
  req->connections[4].pos.x = c.x + r.x;
  req->connections[4].pos.y = c.y;

  req->connections[5].pos.x = c.x - half.x;
  req->connections[5].pos.y = c.y + half.y;
  req->connections[6].pos.x = c.x;
  req->connections[6].pos.y = elem->corner.y + elem->height;
  req->connections[7].pos.x = c.x + half.x;
  req->connections[7].pos.y = c.y + half.y;

  req->connections[8].pos.x = elem->corner.x + elem->width/2;
  req->connections[8].pos.y = elem->corner.y + elem->height/2;

  h = req->text->height*req->text->numlines;
  p = req->element.corner;
  p.x += req->element.width/2.0;
  p.y += (req->element.height - h)/2.0 + req->text->ascent;
  text_set_position(req->text, &p);

  element_update_boundingbox(elem);

  obj->position = elem->corner;

  element_update_handles(elem);

  /* Boundingbox calculation including the line width */
  {
    Rectangle bbox;

    ellipse_bbox (&c, elem->width, elem->height, &elem->extra_spacing, &bbox);
    rectangle_union(&obj->bounding_box, &bbox);
  }
}
Beispiel #29
0
static void
pgram_update_data(Pgram *pgram, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &pgram->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p;
  real offs;
  real width, height;
  real avail_width;
  real top_left;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  /* this takes the shearing of the parallelogram into account, so the
   * text can be extend to the edges of the parallelogram */
  text_calc_boundingbox(pgram->text, NULL);
  height = pgram->text->height * pgram->text->numlines + pgram->padding*2 +
    pgram->border_width;
  if (   pgram->text_fitting == TEXTFIT_ALWAYS
      || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED
          && height > elem->height))
    elem->height = height;

  avail_width = elem->width - (pgram->padding*2 + pgram->border_width +
    fabs(pgram->shear_grad) * (elem->height + pgram->text->height
			       * pgram->text->numlines));
  if (   pgram->text_fitting == TEXTFIT_ALWAYS
      || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED
          && avail_width < pgram->text->max_width)) {
    elem->width = (elem->width-avail_width) + pgram->text->max_width;
    avail_width = pgram->text->max_width;
  }

  /*
  width = pgram->text->max_width + pgram->padding*2 + pgram->border_width +
    fabs(pgram->shear_grad) * (elem->height + pgram->text->height
			       * pgram->text->numlines);
  if (width > elem->width) elem->width = width;
  */
  
  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - pgram->text->height * pgram->text->numlines / 2 +
      pgram->text->ascent;
  switch (pgram->text->alignment) {
  case ALIGN_LEFT:
    p.x -= avail_width/2;
    break;
  case ALIGN_RIGHT:
    p.x += avail_width/2;
    break;
  case ALIGN_CENTER:
    break;
  }
  text_set_position(pgram->text, &p);
  
  /* 1/4 of how much more to the left the bottom line is */
  offs = -(elem->height / 4.0 * pgram->shear_grad);
  width = elem->width - 4.0*fabs(offs);
  top_left = elem->corner.x;
  if (offs < 0.0) {
    top_left -= 4*offs;
  }

  /* Update connections: */
  connpoint_update(&pgram->connections[0],
		   top_left,
		   elem->corner.y,
		   DIR_NORTHWEST);
  connpoint_update(&pgram->connections[1],
		   top_left + width / 4.0,
		   elem->corner.y,
		   DIR_NORTH);
  connpoint_update(&pgram->connections[2],
		   top_left + width / 2.0,
		   elem->corner.y,
		   DIR_NORTH);
  connpoint_update(&pgram->connections[3],
		   top_left + width * 3.0 / 4.0,
		   elem->corner.y,
		   DIR_NORTH);
  connpoint_update(&pgram->connections[4],
		   top_left + width,
		   elem->corner.y,
		   DIR_NORTHEAST);
  connpoint_update(&pgram->connections[5],
		   top_left + offs,
		   elem->corner.y + elem->height / 4.0,
		   DIR_WEST);
  connpoint_update(&pgram->connections[6],
		   top_left + width + offs,
		   elem->corner.y + elem->height / 4.0,
		   DIR_EAST);
  connpoint_update(&pgram->connections[7],
		   top_left + 2.0 * offs,
		   elem->corner.y + elem->height / 2.0,
		   DIR_WEST);
  connpoint_update(&pgram->connections[8],
		   top_left + width + 2.0 * offs,
		   elem->corner.y + elem->height / 2.0,
		   DIR_EAST);
  connpoint_update(&pgram->connections[9],
		   top_left + 3.0 * offs,
		   elem->corner.y + elem->height * 3.0 / 4.0,
		   DIR_WEST);
  connpoint_update(&pgram->connections[10],
		   top_left + width + 3.0 * offs,
		   elem->corner.y + elem->height * 3.0 / 4.0,
		   DIR_EAST);
  connpoint_update(&pgram->connections[11],
		   top_left + 4.0 * offs,
		   elem->corner.y + elem->height,
		   DIR_SOUTHWEST);
  connpoint_update(&pgram->connections[12],
		   top_left + 4.0 * offs + width / 4.0,
		   elem->corner.y + elem->height,
		   DIR_SOUTH);
  connpoint_update(&pgram->connections[13],
		   top_left + 4.0 * offs + width / 2.0,
		   elem->corner.y + elem->height,
		   DIR_SOUTH);
  connpoint_update(&pgram->connections[14],
		   top_left + 4.0 * offs + 3.0 * width / 4.0,
		   elem->corner.y + elem->height,
		   DIR_SOUTH);
  connpoint_update(&pgram->connections[15],
		   top_left + 4.0 * offs + width,
		   elem->corner.y + elem->height,
		   DIR_SOUTHEAST);
  connpoint_update(&pgram->connections[16],
		   top_left + 2.0 * offs + width / 2,
		   elem->corner.y + elem->height / 2,
		   DIR_ALL);

  extra->border_trans = pgram->border_width/2.0;
  element_update_boundingbox(elem);
  
  obj->position = elem->corner;
  
  element_update_handles(elem);
}
Beispiel #30
0
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);
}