static void update_canvas_labels (PartItem *item) { PartItemPriv *priv; Part *part; GSList *labels, *label_items; GooCanvasItem *canvas_item; g_return_if_fail (item != NULL); g_return_if_fail (IS_PART_ITEM (item)); priv = item->priv; part = PART (sheet_item_get_data (SHEET_ITEM (item))); label_items = priv->label_items; // Put the label of each item for (labels = part_get_labels (part); labels; labels = labels->next, label_items = label_items->next) { char *text; PartLabel *label = (PartLabel*) labels->data; g_assert (label_items != NULL); canvas_item = label_items->data; text = part_property_expand_macros (part, label->text); g_object_set (canvas_item, "text", text, NULL); g_free (text); } }
static void create_canvas_labels (PartItem *item, Part *part) { GooCanvasItem *canvas_item; GSList *list, *item_list; GooCanvasGroup *group; g_return_if_fail (item != NULL); g_return_if_fail (IS_PART_ITEM (item)); g_return_if_fail (part != NULL); g_return_if_fail (IS_PART (part)); group = GOO_CANVAS_GROUP (item->priv->label_group); item_list = NULL; for (list = part_get_labels (part); list; list = list->next) { PartLabel *label = list->data; char *text; text = part_property_expand_macros (part, label->text); canvas_item = goo_canvas_text_new (GOO_CANVAS_ITEM (group), text, (double) label->pos.x, (double) label->pos.y, 0, GOO_CANVAS_ANCHOR_SOUTH_WEST, "fill_color", LABEL_COLOR, "font", "Sans 8", NULL); item_list = g_slist_prepend (item_list, canvas_item); g_free (text); } g_slist_free_full (list, g_object_unref); item_list = g_slist_reverse (item_list); part_item_set_label_items (item, item_list); }
static void part_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx) { GSList *objects, *labels; SymbolObject *object; LibrarySymbol *symbol; double x0, y0; int i, rotation; Part *part; PartPriv *priv; Coords pos; IDFlip flip; GooCanvasPoints *line; g_return_if_fail (data != NULL); g_return_if_fail (IS_PART (data)); part = PART (data); priv = part->priv; symbol = library_get_symbol (priv->symbol_name); if (symbol == NULL) { return; } item_data_get_pos (ITEM_DATA (part), &pos); x0 = pos.x; y0 = pos.y; cairo_save (cr); gdk_cairo_set_source_rgba (cr, &ctx->colors.components); rotation = part_get_rotation (part); flip = part_get_flip (part); if ((flip & ID_FLIP_HORIZ) && (flip & ID_FLIP_VERT)) rotation += 180; else if (flip == ID_FLIP_HORIZ) cairo_scale (cr, -1, 1); else if (flip == ID_FLIP_VERT) cairo_scale (cr, 1, -1); if (rotation %= 360) cairo_rotate (cr, rotation*M_PI/180); for (objects = symbol->symbol_objects; objects; objects = objects->next) { object = (SymbolObject *)(objects->data); switch (object->type) { case SYMBOL_OBJECT_LINE: line = object->u.uline.line; for (i = 0; i < line->num_points; i++) { double x, y; x = line->coords[i * 2]; y = line->coords[i * 2 + 1]; if (i == 0) cairo_move_to (cr, x0 + x, y0 + y); else cairo_line_to (cr, x0 + x, y0 + y); } break; case SYMBOL_OBJECT_ARC: { gdouble x1 = object->u.arc.x1; gdouble y1 = object->u.arc.y1; gdouble x2 = object->u.arc.x2; gdouble y2 = object->u.arc.y2; gdouble width, height, x, y; x = (x2 + x1) / 2; y = (y2 + y1) / 2; width = x2 - x1; height = y2 - y1; cairo_save (cr); cairo_translate (cr, x0 + x, y0 + y); cairo_scale (cr, width / 2.0, height / 2.0); cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 2 * M_PI); cairo_restore (cr); } break; default: g_warning ( "Print part: Part %s contains unknown object.", priv->name ); continue; } cairo_stroke (cr); } // We don't want to rotate labels text, only the (x,y) coordinate gdk_cairo_set_source_rgba (cr, &ctx->colors.labels); for (labels = part_get_labels (part); labels; labels = labels->next) { gdouble x, y; PartLabel *label = (PartLabel *)labels->data; gchar *text; /* gint text_width, text_height; */ x = label->pos.x + x0; y = label->pos.y + y0; text = part_property_expand_macros (part, label->text); /* Align the label. switch (rotation) { case 90: y += text_height*opc->scale; break; case 180: break; case 270: x -= text_width*opc->scale; break; case 0: default: break; } */ cairo_save (cr); cairo_move_to (cr, x, y); cairo_show_text (cr, text); cairo_restore (cr); g_free (text); } cairo_restore (cr); }
char *part_property_expand_macros (Part *part, char *string) { static char mcode[] = {"@?~#&"}; char *value; char *tmp0, *temp, *qn, *q0, *t0; char *cls1, *cls2; GString *out; size_t sln; char *ret; g_return_val_if_fail (part != NULL, NULL); g_return_val_if_fail (IS_PART (part), NULL); g_return_val_if_fail (string != NULL, NULL); cls1 = cls2 = q0 = NULL; // Rules: // @<id> value of <id>. If no value, error // &<id> value of <id> if <id> is defined // ?<id>s...s text between s...s separators if <id> defined // ?<id>s...ss...s text between 1st s...s separators if <id> defined // else 2nd s...s clause // ~<id>s...s text between s...s separators if <id> undefined // ~<id>s...ss...s text between 1st s...s separators if <id> undefined // else 2nd s...s clause // #<id>s...s text between s...s separators if <id> defined, but // delete rest of tempalte if <id> undefined // Separators can be any of (, . ; / |) For an opening-closing pair of // separators the same character ahs to be used. // Examples: R^@refdes %1 %2 @value // V^@refdes %+ %- SIN(@offset @ampl @freq 0 0) // ?DC|DC @DC| tmp0 = temp = g_strdup (string); out = g_string_new (""); for (temp = string; *temp;) { // Look for any of the macro char codes. if (strchr (mcode, *temp)) { qn = get_macro_name (temp + 1, &cls1, &cls2, &sln); if (qn == NULL) return NULL; value = part_get_property (part, qn); if ((*temp == '@' || *temp == '&') && value) { out = g_string_append (out, value); } else if (*temp == '&' && !value) { g_warning ("expand macro error: macro %s undefined", qn); g_free (qn); return NULL; } else if (*temp == '?' || *temp == '~') { if (cls1 == NULL) { g_warning ("error in template: %s", temp); g_free (qn); return NULL; } q0 = (value ? (*temp == '?' ? cls1 : cls2) : (*temp == '?' ? cls2 : cls1)); if (q0) { t0 = part_property_expand_macros (part, q0); if (!t0) { g_warning ("error in template: %s", temp); g_free (qn); } else { out = g_string_append (out, t0); g_free (t0); } } } else if (*temp == '#') { if (value) { t0 = part_property_expand_macros (part, value); if (!t0) { g_warning ("error in template: %s", temp); g_free (qn); } else { out = g_string_append (out, t0); g_free (t0); } } else *(temp + sln) = 0; } temp += 1; temp += sln; if (qn) g_free (qn); if (cls1) g_free (cls1); if (cls2) g_free (cls2); } else { if (*temp == '\\') { temp++; switch (*temp) { case 'n': out = g_string_append_c (out, '\n'); break; case 't': out = g_string_append_c (out, '\t'); break; case 'r': out = g_string_append_c (out, '\r'); break; case 'f': out = g_string_append_c (out, '\f'); } temp++; } else { out = g_string_append_c (out, *temp); temp++; } } } if (tmp0) g_free (tmp0); out = g_string_append_c (out, '\0'); ret = g_strdup (out->str); g_string_free (out, TRUE); return ret; }