#usage "Generate a wider silk screen\n" "

" "Syntax: RUN silk2 [noclear] [top=nn[,nn...]] " "[bot=nn[,nn...]]" "

" "WARNING: Requires EAGLE version 4.10 minimum" "

" "Some board manufacturers want to have at least a width of 8mil " "to 10mil for silk screen lines in order to guarantee legible " "results. This ULP changes all silk screen elements to a " "minimum width of 10 mil. All elements of selected layers " "(default 21, 22, 25, 26 and 49) are written into new layers " "121(_tplace) and 122 (_bplace). Text ratios are changed as well. " "The new minimum ratio is calculated from the text size, with an upper " "limit of 25%, so texts as small as 39 mil get a wire width of at " "least 10 mil." "

" "Two new layers will be defined and the new silk screen will be " "generated. For generating GERBER data be aware that you have to " "activate layers 121 or 122 instead of the original layers." "

Optional arguments:" "" "" "" "" "" "" "" "
noclear Do not check whether the output layers are initially empty. " "By default, the user is given the option to (a) continue and add " "to whatever objects are already in those layers, (b) stop, or (c) " "group the objects in those layers and stop so that a simple group " "delete will clear layers 121 and 122.
top=nn[,nn...]A list of input layer numbers to use in place of the default " "21,25,49 for generating layer 121(_tplace). " "Use top=0 to suppress generation of " "_tplace.
bot=nn[,nn...]A list of input layer numbers to use in place of the default " "22,26,49 for generating layer 122(_bplace). " "Use bot=0 to suppress generation of " "_bplace.
" "Author: rnichols@interaccess.com
" "Derived from a ULP by support@cadsoft.de" "
" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // Define your own silk screen width here real Silkwidth = 10.0 ; // in mil int maxRatio = 26; // Upper limit for text ratio // Change the default input layers here int tlayers[] = {LAYER_TPLACE, LAYER_TNAMES, LAYER_TVALUES}; int blayers[] = {LAYER_BPLACE, LAYER_BNAMES, LAYER_REFERENCE}; int offset = 100; // Layer number offset (from 21 and 22) int TextRatio; real NewWidth; int sources[], n, src, newlay, cancelled = 0; int curr_layer = -1, curr_wstyle = -1, curr_tsize = -1, curr_tratio = -1; string TextOrientation; string cmd = "SET UNDO_LOG OFF;\n"; // advisable for speed reasons string h, dummy[]; string styles[]; styles[WIRE_STYLE_CONTINUOUS] = "Continuous"; styles[WIRE_STYLE_LONGDASH] = "LongDash"; styles[WIRE_STYLE_SHORTDASH] = "ShortDash"; styles[WIRE_STYLE_DASHDOT] = "DashDot"; string caps[]; caps[CAP_FLAT] = "Flat"; caps[CAP_ROUND] = "Round"; enum { CM_INTERACTIVE, CM_AUTO, CM_NONE }; int clearmode = CM_INTERACTIVE; void header(void) { sprintf(h, "layer %d _tplace;\n", LAYER_TPLACE+offset);cmd += h; // here you can change the new sprintf(h, "layer %d _bplace;\n", LAYER_BPLACE+offset);cmd += h; // layers names sprintf(h, "set color_layer %d yellow;\n", LAYER_TPLACE+offset);cmd += h; // and sprintf(h, "set color_layer %d yellow;\n", LAYER_BPLACE+offset);cmd += h; // colors sprintf(h, "set wire_bend 2;\n");cmd += h; sprintf(h, "\nGRID mil;\n\n");cmd += h; } void setlayer(void) { if(curr_layer != newlay) { sprintf(h, "Layer %d;\n", newlay);cmd += h; curr_layer = newlay; } } void do_arc(UL_ARC A) { for(n = 0; sources[n]; ++n) if (A.layer == sources[n]) { NewWidth = (Silkwidth > u2mil(A.width)) ? Silkwidth : u2mil(A.width); setlayer(); sprintf(h, "ARC ccw %s %5.3f (%5.3f %5.3f) (%5.3f %5.3f) (%5.3f %5.3f);\n", caps[A.cap], NewWidth, u2mil(A.x1), u2mil(A.y1), u2mil(2*(A.xc)-A.x1), u2mil(2*(A.yc) - A.y1), u2mil(A.x2), u2mil(A.y2)); cmd += h; break; } } void do_circle(UL_CIRCLE C) { for(n = 0; sources[n]; ++n) if (C.layer == sources[n]) { NewWidth = (Silkwidth > u2mil(C.width) && u2mil(C.width) != 0) ? Silkwidth : u2mil(C.width); setlayer(); sprintf(h, "CIRCLE %5.3f (%5.3f %5.3f) (%5.3f %5.3f);\n", NewWidth, u2mil(C.x), u2mil(C.y), u2mil(C.x + C.radius), u2mil(C.y)); cmd += h; break; } } void do_rect(UL_RECTANGLE R) { for(n = 0; sources[n]; ++n) if (R.layer == sources[n]) { setlayer(); sprintf(h, "RECT R%5.3f (%5.3f %5.3f) (%5.3f %5.3f);\n", R.angle, u2mil(R.x1), u2mil(R.y1), u2mil(R.x2), u2mil(R.y2)); cmd += h; break; } } void do_poly(UL_POLYGON P) { for(n = 0; sources[n]; ++n) if (P.layer == sources[n]) { NewWidth = (Silkwidth > u2mil(P.width)) ? Silkwidth : u2mil(P.width); P.wires(WP) { sprintf(h, "POLYGON %5.3f (%5.3f %5.3f)\n ",NewWidth, u2mil(WP.x1), u2mil(WP.y1)); cmd += h; break; } P.wires(WP) { sprintf(h, " (%5.3f %5.3f)", u2mil(WP.x2), u2mil(WP.y2));cmd += h; } sprintf(h, ";\n");cmd += h; break; } } void do_text(UL_TEXT T) { for(n = 0; sources[n]; ++n) if (T.layer == sources[n]) { TextRatio = ceil(100.0 * Silkwidth / u2mil(T.size)); // Needed ratio. if(TextRatio > maxRatio) TextRatio = maxRatio; // Limit? if(TextRatio < T.ratio) TextRatio = T.ratio; // Never reduce! setlayer(); if(curr_tratio != TextRatio) { sprintf(h, "Change Ratio %d;\n", TextRatio);cmd += h; curr_tratio = TextRatio; } if(curr_tsize != T.size) { sprintf(h, "Change Size %5.3f;\n", u2mil(T.size));cmd += h; curr_tsize = T.size; } sprintf(h, "TEXT '%s' %s%1.0f (%5.3f %5.3f);\n", T.value, TextOrientation, T.angle, u2mil(T.x), u2mil(T.y));cmd += h; break; } } void do_wire(UL_WIRE W) { for(n = 0; sources[n]; ++n) if(W.layer == sources[n]) { NewWidth = (Silkwidth > u2mil(W.width)) ? Silkwidth : u2mil(W.width); setlayer(); if(curr_wstyle != W.style) { sprintf(h, "Change Style %s;\n", styles[W.style]);cmd +=h; curr_wstyle = W.style; } if(W.arc) do_arc(W.arc); else { sprintf(h, "WIRE %5.3f %s (%5.3f %5.3f) (%5.3f %5.3f);\n", NewWidth, caps[W.cap], u2mil(W.x1), u2mil(W.y1), u2mil(W.x2), u2mil(W.y2)); cmd += h; } break; } } void searchelements(UL_ELEMENT E) { E.texts(T) do_text(T); E.package.circles(C) do_circle(C); E.package.polygons(P) do_poly(P); E.package.rectangles(R) do_rect(R); E.package.texts(T) do_text(T); E.package.wires(W) do_wire(W); } void do_delete(int x, int y) { sprintf(h, "Delete (%5.3f %5.3f);\n", u2mil(x), u2mil(y)); cmd += h; } void clearOld(UL_BOARD B, int ss) { B.circles(C) if(C.layer == ss) do_delete(C.x, C.y); B.polygons(P) if(P.layer == ss) { n = 0; P.wires(W) if(++n > 2) do_delete(W.x1, W.y1); } B.rectangles(R) if(R.layer == ss) do_delete(R.x1, R.y1); B.texts(T) if(T.layer == ss) do_delete(T.x, T.y); B.wires(W) if(W.layer == ss) do_delete(W.x1, W.y1); } int findOld(UL_BOARD B, int ss) { B.circles(C) if(C.layer == ss) return(1); B.polygons(P) if(P.layer == ss) return(1); B.rectangles(R) if(R.layer == ss) return(1); B.texts(T) if(T.layer == ss) return(1); B.wires(W) if(W.layer == ss) return(1); return(0); } int wantclear() { sprintf(h, "!Output layer%s not empty.\nContinue anyway?\n", ((tlayers[0] && blayers[0]) ? "s" : "") ); n = dlgMessageBox(h, "Continue", "Stop", "Make Group"); return(n); } int invalid(string s) { dlgMessageBox(":\nInvalid arg: \"" + s + "\"\n"); return(-1); } int chksrc(int val, string field, string fullarg) { sprintf(h, "%d", val); if(h != field) { dlgMessageBox(":\nInvalid arg: \"" + fullarg + "\"\n"); return(-1); } else if(val == LAYER_TPLACE+offset || val == LAYER_BPLACE+offset) { dlgMessageBox(":\"" + fullarg + "\"\nLayer " + field + " is an output layer"); return(-1); } else board(B) B.layers(L) if(L.number == val) return(0); dlgMessageBox(":\"" + fullarg + "\"\nLayer " + field + ": No such layer"); return(-1); } if (board) { for(n = 1; n < argc; ++n) { if(strupr(argv[n]) == "NOCLEAR") clearmode = CM_NONE; // Enable auto-clear only if you are brave and bold // (and patient -- it's slow). // else if(strupr(argv[n]) == "CLEAR") clearmode = CM_AUTO; // else if(strupr(argv[n]) == "TOP=0") tlayers[0] = 0; else if(strstr(strupr(argv[n]), "TOP=") == 0) { src = strsplit(dummy, strsub(argv[n], 4), ','); tlayers[src] = 0; for(--src; src >= 0; --src) { tlayers[src] = strtol(dummy[src]); if(chksrc(tlayers[src], dummy[src], argv[n])) exit(-1); } } else if(strupr(argv[n]) == "BOT=0") blayers[0] = 0; else if(strstr(strupr(argv[n]), "BOT=") == 0) { src = strsplit(dummy, strsub(argv[n], 4), ','); blayers[src] = 0; for(--src; src >= 0; --src) { blayers[src] = strtol(dummy[src]); if(chksrc(blayers[src], dummy[src], argv[n])) exit(-1); } } else exit(invalid(argv[n])); } board(B) { header(); if(tlayers[0] || blayers[0]) { cmd += "Display None"; if(tlayers[0]) { sprintf(h, " %d", LAYER_TPLACE+offset); cmd += h; } if(blayers[0]) { sprintf(h, " %d", LAYER_BPLACE+offset); cmd += h; } } cmd += ";\n"; if(clearmode == CM_AUTO) { if(tlayers[0]) clearOld(B, LAYER_TPLACE+offset); if(blayers[0]) clearOld(B, LAYER_BPLACE+offset); } else if(clearmode == CM_INTERACTIVE && ((tlayers[0] && findOld(B, LAYER_TPLACE+offset)) || (blayers[0] && findOld(B, LAYER_BPLACE+offset))) ) switch(wantclear()) { case 1: exit(EXIT_FAILURE); case 2: sprintf(h, "Group (%5.3f %5.3f) (%5.3f %5.3f) (%5.3f %5.3f) (%5.3f %5.3f) (%5.3f %5.3f);\n", u2mil(B.area.x1), u2mil(B.area.y1), u2mil(B.area.x2), u2mil(B.area.y1), u2mil(B.area.x2), u2mil(B.area.y2), u2mil(B.area.x1), u2mil(B.area.y2), u2mil(B.area.x1), u2mil(B.area.y1)); cmd += h; cancelled = 1; break; } if(! cancelled) { if(tlayers[0]) { for(n = 0; tlayers[n]; ++n) sources[n] = tlayers[n]; newlay = LAYER_TPLACE + offset; TextOrientation = "R"; B.circles(C) do_circle(C); B.polygons(P) do_poly(P); B.rectangles(R) do_rect(R); B.texts(T) do_text(T); B.wires(W) do_wire(W); B.elements(E) searchelements(E); } if(blayers[0]) { for(n = 0; blayers[n]; ++n) sources[n] = blayers[n]; newlay = LAYER_BPLACE + offset; TextOrientation = "MR"; B.circles(C) do_circle(C); B.polygons(P) do_poly(P); B.rectangles(R) do_rect(R); B.texts(T) do_text(T); B.wires(W) do_wire(W); B.elements(E) searchelements(E); } switch(curr_wstyle) { case -1: case WIRE_STYLE_CONTINUOUS: break; default: cmd += "Change Style Continuous;\n"; } } } cmd += "GRID LAST;\n"; cmd += "SET UNDO_LOG ON;\n"; // Dialog if(! cancelled) { int Result = dlgDialog("Script to generate the new silk screen") { dlgGridLayout { dlgCell(0,0, 0,4) dlgLabel("Edit only if you are sure what you do!"); dlgCell(1,0, 1,4) dlgTextEdit(cmd); dlgCell(2,0) dlgPushButton("+Execute") dlgAccept(); dlgCell(2,1) dlgSpacing(50); dlgCell(2,2) dlgPushButton("-Cancel") dlgReject(); dlgCell(2,3) dlgSpacing(50); dlgCell(2,4) dlgPushButton(" Save ") { string dest = dlgFileSave("Save Script File", "makesilk.scr", "*.scr"); if(dest != "" && (!fileglob(dummy, dest) || dlgMessageBox("File '" + dest + "' exists\n\nOverwrite?", "+&Yes", "-&No") == 0) ) { output(dest, "wt") { printf(cmd); } } } } }; if (Result == 0) exit(0); } exit(cmd); } else { dlgMessageBox("!\n Start this ULP in a Board \n"); exit (0); }