static void text_insert_char(Text *text, gunichar c) { gchar ch[7]; int unilen; int row; gchar *line, *str; gchar *utf8_before; gchar *str1; /* Make a string of the the char */ unilen = g_unichar_to_utf8 (c, ch); ch[unilen] = 0; row = text->cursor_row; /* Copy the before and after parts with the new char in between */ line = text_get_line(text, row); utf8_before = g_utf8_offset_to_pointer(line, (glong)(text->cursor_pos)); str1 = g_strndup(line, utf8_before - line); str = g_strconcat(str1, ch, utf8_before, NULL); text_set_line_text(text, row, str); g_free(str); g_free(str1); text->cursor_pos++; text->max_width = MAX(text->max_width, text_get_line_width(text, row)); }
static void node_draw(Node *node, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Element *elem; real x, y, w, h; Point points[7]; int i; assert(node != NULL); assert(renderer != NULL); elem = &node->element; x = elem->corner.x; y = elem->corner.y; w = elem->width; h = elem->height; renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID); renderer_ops->set_linewidth(renderer, node->line_width); renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID, 0.0); /* Draw outer box */ points[0].x = x; points[0].y = y; points[1].x = x + NODE_DEPTH; points[1].y = y - NODE_DEPTH; points[2].x = x + w + NODE_DEPTH; points[2].y = y - NODE_DEPTH; points[3].x = x + w + NODE_DEPTH; points[3].y = y + h - NODE_DEPTH; points[4].x = x + w; points[4].y = y + h; points[5].x = x; points[5].y = y + h; points[6].x = x; points[6].y = y; renderer_ops->draw_polygon(renderer, points, 7, &node->fill_color, &node->line_color); /* Draw interior lines */ points[0].x = x; points[0].y = y; points[1].x = x + w; points[1].y = y; renderer_ops->draw_line(renderer, &points[0], &points[1], &node->line_color); points[0].x = x + w; points[0].y = y; points[1].x = x + w + NODE_DEPTH; points[1].y = y - NODE_DEPTH; renderer_ops->draw_line(renderer, &points[0], &points[1], &node->line_color); points[0].x = x + w; points[0].y = y; points[1].x = x + w; points[1].y = y + h; renderer_ops->draw_line(renderer, &points[0], &points[1], &node->line_color); /* Draw text */ text_draw(node->name, renderer); /* Draw underlines (!) */ renderer_ops->set_linewidth(renderer, NODE_LINEWIDTH); points[0].x = node->name->position.x; points[0].y = points[1].y = node->name->position.y + node->name->descent; for (i = 0; i < node->name->numlines; i++) { points[1].x = points[0].x + text_get_line_width(node->name, i); renderer_ops->draw_line(renderer, points, points + 1, &node->name->color); points[0].y = points[1].y += node->name->height; } }
static void text_split_line(Text *text) { int i; char *line; real width; gchar *utf8_before; gchar *str1, *str2; /* Split the lines at cursor_pos */ line = text_get_line(text, text->cursor_row); text_insert_line(text, text->cursor_row); utf8_before = g_utf8_offset_to_pointer(line, (glong)(text->cursor_pos)); str1 = g_strndup(line, utf8_before - line); str2 = g_strdup(utf8_before); /* Must copy before dealloc */ text_set_line_text(text, text->cursor_row, str1); text_set_line_text(text, text->cursor_row + 1, str2); g_free(str2); g_free(str1); text->cursor_row ++; text->cursor_pos = 0; width = 0.0; for (i=0;i<text->numlines;i++) { width = MAX(width, text_get_line_width(text, i)); } text->max_width = width; }
real text_distance_from(Text *text, Point *point) { real dx, dy; real topy, bottomy; real left, right; int line; topy = text->position.y - text->ascent; bottomy = text->position.y + text->descent + text->height*(text->numlines-1); if (point->y <= topy) { dy = topy - point->y; line = 0; } else if (point->y >= bottomy) { dy = point->y - bottomy; line = text->numlines - 1; } else { dy = 0.0; line = (int) floor( (point->y - topy) / text->height ); if (line >= text->numlines) line = text->numlines - 1; } left = text->position.x; switch (text->alignment) { case ALIGN_LEFT: break; case ALIGN_CENTER: left -= text_get_line_width(text, line) / 2.0; break; case ALIGN_RIGHT: left -= text_get_line_width(text, line); break; } right = left + text_get_line_width(text, line); if (point->x <= left) { dx = left - point->x; } else if (point->x >= right) { dx = point->x - right; } else { dx = 0.0; } return dx + dy; }
static void calc_width(Text *text) { real width; int i; width = 0.0; for (i = 0; i < text->numlines; i++) { width = MAX(width, text_get_line_width(text, i)); } text->max_width = width; }
static void text_join_lines(Text *text, int first_line) { gchar *combined_line; int len1; len1 = text_get_line_strlen(text, first_line); combined_line = g_strconcat(text_get_line(text, first_line), text_get_line(text, first_line + 1), NULL); text_delete_line(text, first_line); text_set_line_text(text, first_line, combined_line); g_free(combined_line); text->max_width = MAX(text->max_width, text_get_line_width(text, first_line)); text->cursor_row = first_line; text->cursor_pos = len1; }
static void text_delete_backward(Text *text) { int row; int i; real width; gchar *line; gchar *utf8_before, *utf8_after; gchar *str1, *str; row = text->cursor_row; if (text->cursor_pos <= 0) { if (row > 0) text_join_lines(text, row-1); return; } line = text_get_line(text, row); utf8_before = g_utf8_offset_to_pointer(line, (glong)(text->cursor_pos - 1)); utf8_after = g_utf8_offset_to_pointer(utf8_before, 1); str1 = g_strndup(line, utf8_before - line); str = g_strconcat(str1, utf8_after, NULL); text_set_line_text(text, row, str); g_free(str); g_free(str1); text->cursor_pos --; if (text->cursor_pos > text_get_line_strlen(text, text->cursor_row)) text->cursor_pos = text_get_line_strlen(text, text->cursor_row); width = 0.0; for (i = 0; i < text->numlines; i++) { width = MAX(width, text_get_line_width(text, i)); } text->max_width = width; }
static void objet_draw(Objet *ob, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Element *elem; real bw, x, y, w, h; Point p1, p2; int i; assert(ob != NULL); assert(renderer != NULL); elem = &ob->element; x = elem->corner.x; y = elem->corner.y; w = elem->width; h = elem->height; bw = (ob->is_active) ? OBJET_ACTIVEBORDERWIDTH: ob->line_width; renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID); renderer_ops->set_linewidth(renderer, bw); renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID); p1.x = x; p1.y = y; p2.x = x+w; p2.y = y+h; if (ob->is_multiple) { p1.x += OBJET_MARGIN_M(ob); p2.y -= OBJET_MARGIN_M(ob); renderer_ops->fill_rect(renderer, &p1, &p2, &ob->fill_color); renderer_ops->draw_rect(renderer, &p1, &p2, &ob->line_color); p1.x -= OBJET_MARGIN_M(ob); p1.y += OBJET_MARGIN_M(ob); p2.x -= OBJET_MARGIN_M(ob); p2.y += OBJET_MARGIN_M(ob); y += OBJET_MARGIN_M(ob); } renderer_ops->fill_rect(renderer, &p1, &p2, &ob->fill_color); renderer_ops->draw_rect(renderer, &p1, &p2, &ob->line_color); text_draw(ob->text, renderer); renderer_ops->set_font(renderer, ob->text->font, ob->text->height); if ((ob->st_stereotype != NULL) && (ob->st_stereotype[0] != '\0')) { renderer_ops->draw_string(renderer, ob->st_stereotype, &ob->st_pos, ALIGN_CENTER, &ob->text_attrs.color); } if ((ob->exstate != NULL) && (ob->exstate[0] != '\0')) { renderer_ops->draw_string(renderer, ob->exstate, &ob->ex_pos, ALIGN_CENTER, &ob->text_attrs.color); } /* Is there a better way to underline? */ p1.x = x + (w - text_get_max_width(ob->text))/2; p1.y = ob->text->position.y + text_get_descent(ob->text); p2.x = p1.x + text_get_max_width(ob->text); p2.y = p1.y; renderer_ops->set_linewidth(renderer, ob->line_width/2); for (i=0; i<ob->text->numlines; i++) { p1.x = x + (w - text_get_line_width(ob->text, i))/2; p2.x = p1.x + text_get_line_width(ob->text, i); renderer_ops->draw_line(renderer, &p1, &p2, &ob->text_attrs.color); p1.y = p2.y += ob->text->height; } if (ob->show_attributes) { p1.x = x; p2.x = x + w; p1.y = p2.y = ob->attributes->position.y - ob->attributes->ascent - OBJET_MARGIN_Y(ob); renderer_ops->set_linewidth(renderer, bw); renderer_ops->draw_line(renderer, &p1, &p2, &ob->line_color); text_draw(ob->attributes, renderer); } }
static void classicon_draw(Classicon *icon, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Element *elem; real r, x, y, w; Point center, p1, p2; int i; assert(icon != NULL); assert(renderer != NULL); elem = &icon->element; x = elem->corner.x; y = elem->corner.y; w = elem->width; r = CLASSICON_RADIOUS; center.x = x + elem->width/2; center.y = y + r + CLASSICON_ARROW; if (icon->stereotype==CLASSICON_BOUNDARY) center.x += r/2.0; renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID); renderer_ops->set_linewidth(renderer, icon->line_width); renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID, 0.0); renderer_ops->draw_ellipse(renderer, ¢er, 2*r, 2*r, &icon->fill_color, &icon->line_color); switch (icon->stereotype) { case CLASSICON_CONTROL: p1.x = center.x - r*0.258819045102521; p1.y = center.y-r*0.965925826289068; p2.x = p1.x + CLASSICON_ARROW; p2.y = p1.y + CLASSICON_ARROW/1.5; renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); p2.x = p1.x + CLASSICON_ARROW; p2.y = p1.y - CLASSICON_ARROW/1.5; renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); break; case CLASSICON_BOUNDARY: p1.x = center.x - r; p2.x = p1.x - r; p1.y = p2.y = center.y; renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); p1.x = p2.x; p1.y = center.y - r; p2.y = center.y + r; renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); break; case CLASSICON_ENTITY: p1.x = center.x - r; p2.x = center.x + r; p1.y = p2.y = center.y + r; renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); break; } text_draw(icon->text, renderer); if (icon->is_object) { renderer_ops->set_linewidth(renderer, 0.01); if (icon->stereotype==CLASSICON_BOUNDARY) x += r/2.0; p1.y = p2.y = icon->text->position.y + text_get_descent(icon->text); for (i=0; i<icon->text->numlines; i++) { p1.x = x + (w - text_get_line_width(icon->text, i))/2; p2.x = p1.x + text_get_line_width(icon->text, i); renderer_ops->draw_line(renderer, &p1, &p2, &icon->line_color); p1.y = p2.y += icon->text->height; } } }