1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
#include <genht/htsp.h>
#include <genlist/gendlist.h>
#include <genvector/vtp0.h>
#include <librnd/core/vtc0.h>
#include "board.h"
#include "data.h"
#include "layer.h"
#include "obj_common.h"
#include "obj_subc.h"
/* When creating padstacks save integer layer ID in padstack shp->dlcr_psh_layer_id */
#define dlcr_psh_layer_id layer_mask
#define PCB_DLCR_INVALID_LAYER_ID -32768
typedef struct {
char *name;
long id;
pcb_layer_type_t lyt;
pcb_layer_combining_t comb;
const char *purpose;
int can_have_components;
pcb_layer_t *ly; /* the final assignment */
void *user_data;
union {
char start;
void *bulkp[32];
double bulkd[32];
} local_user_data;
} pcb_dlcr_layer_t;
typedef enum {
DLCR_OBJ,
DLCR_CALL, /* call user function on previous or next object */
DLCR_ATTR, /* set attribute on previous object */
DLCR_SUBC_BEGIN,
DLCR_SUBC_END,
DLCR_SUBC_FROM_LIB /* place a subc from local lib by a list of names */
/* DLCR_SEQPOLY_BEGIN,
DLCR_SEQPOLY_END*/
} pcb_dlcr_type_t;
#define PCB_OBJ_DLCR_POLY 0x0000801
#define PCB_OBJ_DLCR_TEXT_BY_BBOX 0x0000802
typedef struct {
PCB_ANY_PRIMITIVE_FIELDS;
rnd_font_t *font;
rnd_coord_t x, y, bbw, bbh, anchx, anchy;
double scxy, rot;
pcb_text_mirror_t mirror;
rnd_coord_t thickness;
char *str;
long flags;
} pcb_dlcr_text_by_bbox_t;
typedef struct {
pcb_dlcr_type_t type;
union {
struct {
union {
pcb_any_obj_t any;
pcb_line_t line;
pcb_arc_t arc;
pcb_text_t text;
pcb_pstk_t pstk;
struct {
PCB_ANY_PRIMITIVE_FIELDS;
vtc0_t xy;
} poly;
pcb_dlcr_text_by_bbox_t text_by_bbox;
} obj;
long layer_id;
pcb_layer_type_t lyt;
char *layer_name;
} obj;
struct {
pcb_subc_t *subc;
} subc_begin; /* in DLCR_SUBC_BEGIN */
struct {
rnd_coord_t x;
rnd_coord_t y;
double rot;
int on_bottom;
char *names; /* \0 separated list with an empty string at the end (double \0) */
} subc_from_lib;
struct {
void (*cb)(void *rctx, pcb_any_obj_t *obj, void *callctx);
void *rctx, *callctx;
int on_next; /* or on prev if 0 */
} call;
struct {
char *key, *val;
} attr;
} val;
char *name; /* for pstk: terminal name */
char *netname;
long loc_line; /* for debug */
gdl_elem_t link;
unsigned in_last_subc:1; /* create object within the last created subc instead of on the board */
unsigned subc_relative:1;/* coords are relative to the parent subc */
} pcb_dlcr_draw_t;
typedef struct pcb_dlcr_s pcb_dlcr_t;
struct pcb_dlcr_s {
/* caller provided config/callbacks */
int (*proto_layer_lookup)(pcb_dlcr_t *dlcr, pcb_pstk_shape_t *shp); /* optional: set shp's layer on special cases and return 0; return 1 for executing the standard layer lookup; required only if there are layer ID special cases, e.g. for -1; layer id is in shp->dlcr_psh_layer_id */
/* layers */
htsp_t name2layer;
vtp0_t id2layer; /* key=->id, val=(pcb_dlcr_layer_t *) */
/* local footprint lib, if any */
htsp_t name2subc; /* val=(pcb_subc_t *) */
/* board global */
gdl_list_t drawing; /* of pcb_dlcr_draw_t; */
rnd_box_t board_bbox;
pcb_data_t pstks; /* wrapper for padstack prototypes, otherwise empty */
/* current context/state */
pcb_dlcr_draw_t *subc_begin; /* NULL when drawing on the board, pointing to the SUBC_BEGIN node in between DLCR_SUBC_BEGIN and DLCR_SUBC_END */
pcb_any_obj_t *prev_obj; /* for CALL prev */
pcb_dlcr_draw_t *call_next; /* for CALL next */
pcb_subc_t *last_subc_placed; /* for adding objects in the last subc instead of board */
/* aux output */
vtp0_t netname_objs; /* (pcb_any_obj_t *):(char *netname) pairs; filled in only if ->save_netname_objs is 1 */
/* config */
unsigned flip_y:1; /* if 1, mirror y coordinates over the X axis */
unsigned save_netname_objs:1; /* if 1, save each object:netname pair in ->netname_objs */
};
void pcb_dlcr_init(pcb_dlcr_t *dlcr);
void pcb_dlcr_uninit(pcb_dlcr_t *dlcr);
void pcb_dlcr_layer_reg(pcb_dlcr_t *dlcr, pcb_dlcr_layer_t *layer);
void pcb_dlcr_layer_free(pcb_dlcr_layer_t *layer);
/* allocate a new named subcircuit within the local dlcr lib */
pcb_subc_t *pcb_dlcr_subc_new_in_lib(pcb_dlcr_t *dlcr, const char *name);
pcb_dlcr_draw_t *pcb_dlcr_line_new(pcb_dlcr_t *dlcr, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t width, rnd_coord_t clearance);
pcb_dlcr_draw_t *pcb_dlcr_arc_new(pcb_dlcr_t *dlcr, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r, double start_deg, double delta_deg, rnd_coord_t width, rnd_coord_t clearance);
pcb_dlcr_draw_t *pcb_dlcr_text_new(pcb_dlcr_t *dlcr, rnd_coord_t x, rnd_coord_t y, double rot, int scale, rnd_coord_t thickness, const char *str, long flags);
pcb_dlcr_draw_t *pcb_dlcr_text_by_bbox_new(pcb_dlcr_t *dlcr, rnd_font_t *font, rnd_coord_t x, rnd_coord_t y, rnd_coord_t bbw, rnd_coord_t bbh, rnd_coord_t anchx, rnd_coord_t anchy, double scxy, pcb_text_mirror_t mirror, double rot, rnd_coord_t thickness, const char *str, long flags);
pcb_dlcr_draw_t *pcb_dlcr_via_new(pcb_dlcr_t *dlcr, rnd_coord_t x, rnd_coord_t y, rnd_coord_t clearance, long proto_id, const char *proto_name, const char *term);
pcb_dlcr_draw_t *pcb_dlcr_poly_new(pcb_dlcr_t *dlcr, int hole, long prealloc_len);
pcb_dlcr_draw_t *pcb_dlcr_poly_lineto(pcb_dlcr_t *dlcr, pcb_dlcr_draw_t *poly, rnd_coord_t x, rnd_coord_t y);
/* attach a netname to an existing to-be-created object */
void pcb_dlcr_set_net(pcb_dlcr_draw_t *obj, const char *netname);
/* Call back cb() on the previous (last created) or next object after the
object is created */
pcb_dlcr_draw_t *pcb_dlcr_call_on(pcb_dlcr_t *dlcr, void (*cb)(void *rctx, pcb_any_obj_t *obj, void *callctx), void *rctx, void *callctx, int on_next);
pcb_dlcr_draw_t *pcb_dlcr_call_prev(pcb_dlcr_t *dlcr, void (*cb)(void *rctx, pcb_any_obj_t *obj, void *callctx), void *rctx, void *callctx);
pcb_dlcr_draw_t *pcb_dlcr_call_next(pcb_dlcr_t *dlcr, void (*cb)(void *rctx, pcb_any_obj_t *obj, void *callctx), void *rctx, void *callctx);
/* Set an attribute on the previous (last created) object */
pcb_dlcr_draw_t *pcb_dlcr_attrib_set_prev(pcb_dlcr_t *dlcr, const char *key, const char *val);
/* delayed place a subcricuit from the local dlcr lib by name; names is either
a single string or a \0 separated list of strings with an empty string at
the end */
pcb_dlcr_draw_t *pcb_dlcr_subc_new_from_lib(pcb_dlcr_t *dlcr, rnd_coord_t x, rnd_coord_t y, double rot, int on_bottom, const char *names, long names_len);
pcb_pstk_proto_t *pcb_dlcr_pstk_proto_new(pcb_dlcr_t *dlcr, long int *pid_out);
void pcb_dlcr_subc_begin(pcb_dlcr_t *dlcr, pcb_subc_t *subc);
void pcb_dlcr_subc_end(pcb_dlcr_t *dlcr);
/* Create all objects; call this only after layers are finalized */
void pcb_dlcr_create(pcb_board_t *pcb, pcb_dlcr_t *dlcr);
|