/* * COPYRIGHT * * cschem - modular/flexible schematics editor - libcschem (core library) * Copyright (C) 2018 Tibor 'Igor2' Palinkas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version.* * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA * * Contact: * Project page: http://repo.hu/projects/sch-rnd * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html */ #ifndef CSCH_CONCRETE_PEN_H #define CSCH_CONCRETE_PEN_H #include "libcschem/concrete.h" #include /* type=CSCH_CTYPE_PEN */ typedef enum csch_pen_shape_e { CSCH_PSHP_ROUND, CSCH_PSHP_SQUARE } csch_pen_shape_t; struct csch_cpen_s { csch_chdr_t hdr; csch_comm_str_t name; /* tip properties */ csch_pen_shape_t shape; csch_coord_t size; /* diameter or edge length */ rnd_color_t color; unsigned short dash; csch_coord_t dash_period; /* font properties */ csch_coord_t font_height; char *font_family; char *font_style; /* cache for the lib and io code */ unsigned copied_from_default:1; /* set to 1 when a pen is copied from default sheet; reset on any change */ /* fields that can be used by the application */ void *font_handle; unsigned font_handle_valid:1; }; /* the application is called back... (the application needs to load this) */ extern void (*csch_cb_pen_invalidate_font)(csch_sheet_t *sheet, csch_cpen_t *pen); /* remove font cache */ const char *csch_pen_shape_name(csch_pen_shape_t shape); csch_cpen_t *csch_pen_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, const char *name); csch_cpen_t *csch_pen_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src); csch_cpen_t *csch_pen_dup2(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpen_t *src, const char *new_name); void csch_pen_free(csch_cpen_t *pen); csch_cpen_t *csch_pen_get(csch_sheet_t *sheet, csch_cgrp_t *grp, const char *name); void csch_pen_modify_tip(csch_sheet_t *sheet, csch_cpen_t *pen, csch_pen_shape_t *shape, csch_coord_t *size, rnd_color_t *color, char **name, unsigned short *dash, csch_coord_t *dash_period, int undoable); void csch_pen_modify_font(csch_sheet_t *sheet, csch_cpen_t *pen, csch_coord_t *font_height, char **font_family, char **font_style, int undoable); unsigned csch_pen_hash(const csch_cpen_t *pen, csch_hash_ignore_t ignore); int csch_pen_keyeq(const csch_cpen_t *p1, const csch_cpen_t *p2, csch_hash_ignore_t ignore); extern csch_cpen_t csch_pen_default_unknown; /* Look up pen by name from within grp or NULL */ csch_cpen_t *csch_pen_resolve(csch_cgrp_t *grp, const char *pen_name); /* Return the object pen falling back to the "unknown pen" when not available */ RND_INLINE csch_cpen_t *csch_stroke_(csch_chdr_t *hdr) { if (hdr->stroke == NULL) { csch_cgrp_t *grp = hdr->parent; while((hdr->stroke == NULL) && (grp != NULL) && csch_obj_is_grp(&grp->hdr)) { hdr->stroke = csch_pen_get(hdr->sheet, grp, hdr->stroke_name.str); grp = grp->hdr.parent; } } if (hdr->stroke == NULL) return &csch_pen_default_unknown; return hdr->stroke; } #define csch_stroke(sheet, obj) csch_stroke_(&(obj->hdr)) /* same as csch_stroke_() but with an option to use fallback pens from a group */ RND_INLINE csch_cpen_t *csch_stroke_fallback_(csch_chdr_t *hdr, csch_cgrp_t *fallback) { csch_cpen_t *res = csch_stroke_(hdr); if ((res == &csch_pen_default_unknown) && (fallback != NULL)) { csch_cpen_t *fb = csch_pen_get(hdr->sheet, fallback, hdr->stroke_name.str); if (fb != NULL) return fb; } return res; } #define csch_stroke_fallback(sheet, obj, fb) csch_stroke_fallback_(&(obj->hdr), fb) /* Return the object pen falling back to the "unknown pen" when not available */ RND_INLINE csch_cpen_t *csch_fill_(csch_chdr_t *hdr) { if (hdr->fill == NULL) { csch_cgrp_t *grp = hdr->parent; while((hdr->fill == NULL) && (grp != NULL) && csch_obj_is_grp(&grp->hdr)) { hdr->fill = csch_pen_get(hdr->sheet, grp, hdr->fill_name.str); grp = grp->hdr.parent; } } if (hdr->fill == NULL) return &csch_pen_default_unknown; return hdr->fill; } #define csch_fill(sheet, obj) csch_fill_(&(obj->hdr)) /* same as csch_stroke_() but with an option to use fallback pens from a group */ RND_INLINE csch_cpen_t *csch_fill_fallback_(csch_chdr_t *hdr, csch_cgrp_t *fallback) { csch_cpen_t *res = csch_fill_(hdr); if ((res == &csch_pen_default_unknown) && (fallback != NULL)) { csch_cpen_t *fb = csch_pen_get(hdr->sheet, fallback, hdr->fill_name.str); if (fb != NULL) return fb; } return res; } #define csch_fill_fallback(sheet, obj, fb) csch_fill_fallback_(&(obj->hdr), fb) /* If tip is non-zero: remove cached ->pen pointers that depend on the given pen from all object headers that could have it, recursively down from pen's parent group. If remov is non-zero: the pen is also removed from the pen-name-hash (pen is being removed or renamed). If remov is non-zero: all text objects using this pen are font-invalidated */ void csch_pen_invalidate(csch_cpen_t *pen, int tip, int font, int remov); /* Update all objects that has a specific pen as stroke; this recalculates obj bbox assuming the pen change may have changed the object's size */ void csch_pen_update_objs_for(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_cpen_t *pen); #endif