Index: src_plugins/io_pads/delay_create.c =================================================================== --- src_plugins/io_pads/delay_create.c (revision 34599) +++ src_plugins/io_pads/delay_create.c (revision 34600) @@ -656,36 +656,33 @@ return nsc; } -TODO("this is pads-specific, figure how to handle this; see also: TODO#71"); static void proto_layer_lookup(pcb_dlcr_t *dlcr, pcb_pstk_shape_t *shp) { - int level = shp->layer_mask; - switch(level) { /* set layer type */ - case -2: shp->layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; break; - case -1: shp->layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; break; - case 0: shp->layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; break; - default: - { - pcb_dlcr_layer_t *ly, **lyp = (pcb_dlcr_layer_t **)vtp0_get(&dlcr->id2layer, level, 0); - if ((lyp != NULL) && (*lyp != NULL)) { - ly = *lyp; - if (!(ly->lyt & PCB_LYT_COPPER)) { - shp->layer_mask = ly->lyt; - if (ly->lyt & PCB_LYT_MASK) - shp->comb = PCB_LYC_SUB; - } - else { - rnd_message(RND_MSG_ERROR, "Padstack prototype can not have a different shape on copper layer %d\n", level); - } - } - else { - rnd_message(RND_MSG_ERROR, "Padstack prototype references non-existing layer %d\n", level); - } + int level = shp->layer_mask, std_lookup = 1; + + if (dlcr->proto_layer_lookup != NULL) + std_lookup = dlcr->proto_layer_lookup(dlcr, shp); + + if (std_lookup == 1) { + pcb_dlcr_layer_t *ly, **lyp = (pcb_dlcr_layer_t **)vtp0_get(&dlcr->id2layer, level, 0); + if ((lyp != NULL) && (*lyp != NULL)) { + ly = *lyp; + if (!(ly->lyt & PCB_LYT_COPPER)) { + shp->layer_mask = ly->lyt; + if (ly->lyt & PCB_LYT_MASK) + shp->comb = PCB_LYC_SUB; } - break; + else { + rnd_message(RND_MSG_ERROR, "Padstack prototype can not have a different shape on copper layer %d\n", level); + } + } + else { + rnd_message(RND_MSG_ERROR, "Padstack prototype references non-existing layer %d\n", level); + } } } + static void pcb_dlcr_create_pstk_protos(pcb_board_t *pcb, pcb_dlcr_t *dlcr, pcb_data_t *dst, const pcb_data_t *src) { rnd_cardinal_t n, m; Index: src_plugins/io_pads/delay_create.h =================================================================== --- src_plugins/io_pads/delay_create.h (revision 34599) +++ src_plugins/io_pads/delay_create.h (revision 34600) @@ -91,7 +91,12 @@ unsigned subc_relative:1;/* coords are relative to the parent subc */ } pcb_dlcr_draw_t; -typedef struct { +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 */ + /* layers */ htsp_t name2layer; vtp0_t id2layer; /* key=->id, val=(pcb_dlcr_layer_t *) */ @@ -116,7 +121,7 @@ /* 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 */ -} pcb_dlcr_t; +}; void pcb_dlcr_init(pcb_dlcr_t *dlcr); void pcb_dlcr_uninit(pcb_dlcr_t *dlcr); Index: src_plugins/io_pads/read.c =================================================================== --- src_plugins/io_pads/read.c (revision 34599) +++ src_plugins/io_pads/read.c (revision 34600) @@ -299,6 +299,20 @@ return -1; } +static int pads_proto_layer_lookup(pcb_dlcr_t *dlcr, pcb_pstk_shape_t *shp) +{ + int level = shp->layer_mask; + switch(level) { /* set layer type on PADS-specific cases */ + case -2: shp->layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; break; + case -1: shp->layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; break; + case 0: shp->layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; break; + default: return 1; /* run the default layer lookup */ + } + + return 0; /* handled here */ +} + + static const char *postproc_thermal_lookup(void *uctx, pcb_any_obj_t *obj) { htpp_t *ht = uctx; @@ -359,6 +373,7 @@ pcb_dlcr_init(&rctx.dlcr); rctx.dlcr.flip_y = 1; rctx.dlcr.save_netname_objs = 1; + rctx.dlcr.proto_layer_lookup = pads_proto_layer_lookup; /* read the header */ if (pads_parse_header(&rctx) != 0) {