#!/bin/sh # fp2preview - convert a library footprint to preview image # Copyright (C) 2015,2019 Tibor 'Igor2' Palinkas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # http://repo.hu/projects/pcb-rnd # depends on the diag and the autocrop plugins photo=0 grid_unit="mil" dpi=600 outfile=fp2preview.png annotation=pins while test $# -gt 0 do case "$1" in --outfile) outfile="$2"; shift 1;; --dpi) dpi="$2"; shift 1;; --photo|p) photo=1;; --grid-unit|g) grid_unit="$2"; shift 1;; --mm) grid_unit="mm";; --annotation) annotation="$2"; shift 1;; *) if test ! -z "$fp" then echo "only one footprint name is accepted; got: '$fp' and '$1'" >&1 exit 1 else fp="$1" fi esac shift 1 done rfp=`realpath $fp` echo ' DumpLibFootprint("'$fp'", origin, bbox); ' | pcb-rnd --gui batch | awk -v "fp=$rfp" -v grid_unit=$grid_unit -v "outfile=$outfile" -v "dpi=$dpi" -v "annotation=$annotation" -v "photo=$photo" ' BEGIN { q="\"" dim_arrow_len = 0.7 if (annotation ~ "pins") enable_pinnum = 1 if (annotation ~ "dimname") enable_dim_name = 1 if (annotation ~ "dimvalue") enable_dim_value = 1 dims = 0 } /^[ \t]*#dimension/ { if ((enable_dim_name) || (enable_dim_value)) { DIM[dims, "x1"] = $2*0.0254 DIM[dims, "y1"] = $3*0.0254 DIM[dims, "x2"] = $4*0.0254 DIM[dims, "y2"] = $5*0.0254 DIM[dims, "dist"] = $6*0.0254 DIM[dims, "name"] = $7 DIM[dims, "val"] = $8 dims++ } } /^ error/ { exit(1) } /^ bbox mm/ { bbx1 = $4; bby1 = $5; bbx2 = $6; bby2 = $7; } /^ origin mm/ { ox = $4; oy = $5; } function line(layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags) { if (Clearance == "") Clearance = 0; if (Thickness == "") Thickness = 1; print "LineNew(noundo, pcb, " layer "," X1 "mm," Y1 "mm," X2 "mm," Y2 "mm," Thickness "," Clearance "mm," q "clearline" q ")" } function text(layer, x, y, rot, scale, thickness, text_string) { print "TextNew(noundo, pcb, " layer ", 0, " x "mm," y "mm," rot "," scale "," thickness "," q text_string q ", clearline)" } function unit_txt(s) { if ((s < 0.001) && (s > -0.001)) return "0 " grid_unit if (grid_unit == "mil") return sprintf("%.2f mil", s/0.0254) else return sprintf("%.2f mm", s) } function annot(x, y, txt, rot, elev, hcenter ,sx,sy) { sx = length(txt)*0.5 sy = 1.2 if (rot) text("#0", x-sy, y-sx/2, 90, 70, 1, txt) else text("#0", x-sx/2, y-sy, 0, 70, 1, txt) } function dimension(x1, y1, x2, y2, dist, name, value ,vx,vy,nx,ny,X1,Y1,X2,Y2,len,alen,awidth,tmp, ang,negdist,cx,cy,dx,dy,D) { alen = dim_arrow_len vx = x2-x1 vy = y2-y1 len = vx*vx+vy*vy if (len == 0) return len = sqrt(len) vx = vx/len vy = vy/len nx = vy ny = -vx if (dist ~ "^[@]") { cx = (x1+x2)/2 cy = (y1+y2)/2 sub("@", "", dist) split(dist, D, ";") nx = D[1] - cx ny = D[2] - cy X1 = x1+nx Y1 = y1+ny X2 = x2+nx Y2 = y2+ny dist = nx*nx+ny*ny if (dist > 0) dist = sqrt(dist) nx /= dist ny /= dist } else { if (dist < 0) { tmp = x1 x1 = x2 x2 = tmp tmp = y1 y1 = y2 y2 = tmp dist = -dist vx = -vx vy = -vy nx = -nx ny = -ny } X1 = x1+nx*dist Y1 = y1+ny*dist X2 = x2+nx*dist Y2 = y2+ny*dist } if (alen > len/4) alen=len/4 awidth=alen/6 ang = atan2(vx, vy) line("#0", x1, y1, X1+nx*awidth, Y1+ny*awidth, "0.1mm") line("#0", x2, y2, X2+nx*awidth, Y2+ny*awidth, "0.1mm") line("#0", X1, Y1, X2, Y2, "0.1mm") #arrowheads line("#0", X1, Y1, X1+vx*alen+nx*awidth, Y1+vy*alen+ny*awidth, "0.1mm") line("#0", X1, Y1, X1+vx*alen-nx*awidth, Y1+vy*alen-ny*awidth, "0.1mm") line("#0", X2, Y2, X2-vx*alen+nx*awidth, Y2-vy*alen+ny*awidth, "0.1mm") line("#0", X2, Y2, X2-vx*alen-nx*awidth, Y2-vy*alen-ny*awidth, "0.1mm") if (enable_dim_value) { if (value == "") value = len else if (value == "!") value = "" if (value != "") value = unit_txt(value) } else value = "" if (!enable_dim_name) name = "" if ((name != "") && (value != "")) name = name "=|" value else if ((value != "") && (name == "")) name = value if (name != "") { if (ang < 0) ang = -ang if ((ang < 3.1415*3/4) && (ang > 3.1415*1/4)) annot((X1+X2)/2, (Y1+Y2)/2, name, 0, awidth*1.1,0) else annot((X1+X2)/2, (Y1+Y2)/2, name, 1, awidth*1.1,0) } } END { if (grid_unit == "mil") grid = 2.54; else grid = 1; margin = grid*2 print "LoadFrom(SubcToBuffer, " q fp q ")" print "PasteBuffer(ToLayout, " (-1*bbx1+ox)+margin ", " (-1*bby1+oy)+margin ", mm)" # draw the grid x1 = (ox-bbx1-margin) - int((ox-bbx1-margin)) * grid y1 = (oy-bby1-margin) - int((oy-bby1-margin)) * grid for(y = y1; y < bby2-bby1+margin*1.5; y +=grid) { to=bbx2-bbx1+margin*1.5 line("#1", x1, y, to, y); text("#1", to+0.75, y-0.75, 0, 70, 1, unit_txt(y+bby1-oy-margin)) } for(x = x1; x < bbx2-bbx1+margin*1.5; x +=grid) { line("#1", x, y1, x, bby2-bby1+margin*1.5); text("#1", x-0.75, to+5, 90, 70, 1, unit_txt(x+bbx1-ox-margin)) } dx = -bbx1+margin dy = -bby1+margin for(n = 0; n < dims; n++) { dimension(DIM[n, "x1"]+dx, DIM[n, "y1"]+dy, DIM[n, "x2"]+dx, DIM[n, "y2"]+dy, DIM[n, "dist"], DIM[n, "name"], DIM[n, "val"]); } if (enable_pinnum) { print "query(select, \"@.type==SUBC||@.type==PSTK\")" print "propset(selection, p/flags/termname, 1)" print "query(unselect, @)" } if (photo) { photo = "--photo-mode, " } else photo = "" print "autocrop()" print "Export(png, --dpi, " dpi ", --as-shown, " photo " --outfile, " q outfile q ")" print "Save(LayoutAs, \"A.lht\")" } ' | pcb-rnd --gui batch