#usage "en:Set Layer Sequence for PRINT command.
"
"For printing your drawing it might be important to determine the sequence of printed layers. "
"This ULP manages the 'Option.LayerSequence' setting in the file eaglerc.usr.
"
"From HELP SET:
"
"Option.LayerSequence
"
"The internal layers are rendered in a sequence that mimics the actual layer stack, "
"so that the result looks useful even on printers and PDF or Postscript files, where "
"layers are not transparent. Sometimes user defined layers may need to be rendered before "
"internal layers instead of after them. This parameter can be used to define the "
"sequence in which layers are rendered. It consists of a string of layer numbers or "
"layer ranges, followed by an optional 't' or 'b'.
"
"123 renders layer 123
"
"123t renders layer 123 if the output is \"viewed from top\" (not mirrored)
"
"123b renders layer 123 if the output is \"viewed from bottom\" (mirrored)
"
"123-140 renders layers 123 through 140 in the given sequence
"
"140-123 renders layers 140 through 123 in the given sequence
"
"* inserts the default sequence of the internal layers
"
"123b * 123t makes layer 123 always be rendered first
"
"Note that each layer is rendered only once, even if it is listed several times. "
"The default sequence of the internal layers is:
"
"48t 49t 19t 47t 20t 46t 23 27 25 59 57 55 53 50 51 21 44t 45t 37 35 31 29 33 39 41 43t 18t 17t 1-16 17b 18b 43b 42 40 34 30 32 36 38 45b 44b 22 52 54 56 58 60 26 28 24 46b 20b 47b 19b 49b 48b 61-99.
"
"When viewed from top, the layer sequence is rendered from right to left, while "
"when viewed from bottom (mirrored) it is rendered from left to right. For instance, "
"layer 48 (Document) is entered as 48t and 48b to always have it rendered as the last one.
"
"Layers 21 (tPlace) and 22 (bPlace), on the other hand, are listed only once, to have "
"them rendered at the proper place, depending on whether the output is mirrored or not.
"
"Any layers that are not explicitly mentioned in the layer sequence are rendered after "
"the given sequence in ascending order.
"
"
"
"Author: alf@cadsoft.de"
,
"de:Layerreihenfolge für den Ausdruck festlegen.
"
"Für den Ausdruck kann die Reihenfolge der Layer wichtig sein. Dieses ULP nutzt die Möglichkeit mit "
"'Option.LayerSequence' in der eaglerc.usr diese Reihenfolge fest zu legen.
"
"Auszug aus HELP SET:
"
"Option.LayerSequence
"
"Die internen Layer werden in der Reihenfolge dargestellt, die dem tatsächlichen Lagenaufbau entspricht, "
"so dass das Ergebnis auch auf Druckern und PDF- bzw. Postscript-Dateien brauchbar aussieht, wo die Layer "
"nicht transparent sind. Manchmal kann es erforderlich sein, dass benutzerdefinierte Layer vor den internen "
"Layern dargestellt werden müssen, anstatt nach diesen. Mit diesem Parameter kann die Reihenfolge, in der "
"die Layer dargestellt werden, festgelegt werden. Er besteht aus einer Folge von Layer-Nummern bzw. "
"Layer-Bereichen, optional gefolgt von 't' oder 'b'.
"
"123 stellt Layer 123 dar
"
"123t stellt Layer 123 dar, wenn die Ausgabe \"von oben gesehen\" erfolgt (nicht gespiegelt)
"
"123b stellt Layer 123 dar, wenn die Ausgabe \"von unten gesehen\" erfolgt (gespiegelt)
"
"123-140 stellt die Layer 123 bis 140 in der angegeben Reihenfolge dar
"
"140-123 stellt die Layer 140 bis 123 in der angegeben Reihenfolge dar
"
"* fügt die Standard-Sequenz der internen Layer ein
"
"123b * 123t sorgt dafür, dass Layer 123 immer als erster dargestellt wird
"
"Beachten Sie, dass jeder Layer nur einmal dargestellt wird, auch wenn er mehrmals aufgeführt ist. "
"Die Standard-Sequenz der internen Layer ist:
"
"48t 49t 19t 47t 20t 46t 23 27 25 59 57 55 53 50 51 21 44t 45t 37 35 31 29 33 39 41 43t 18t 17t 1-16 17b 18b 43b 42 40 34 30 32 36 38 45b 44b 22 52 54 56 58 60 26 28 24 46b 20b 47b 19b 49b 48b 61-99.
"
"Bei Ansicht von oben, wird die Layer-Sequenz von rechts nach links abgearbeitet, während sie bei Ansicht "
"von unten (gespiegelt) von links nach rechts abgearbeitet wird. Zum Beispiel ist Layer 48 (Document) als "
"48t und 48b enthalten, damit dieser immer als letzter dargestellt wird.
"
"Die Layer 21 (tPlace) und 22 (bPlace) hingegen sind nur jeweils einmal aufgelistet, damit Sie an der "
"richtigen Stelle erscheinen, je nachdem, ob die Ausgabe gespiegelt erfolgt oder nicht.
"
"Alle nicht explizit in der Layer-Sequenz aufgeführten Layer werden nach der gegebenen Sequenz, in "
"aufsteigender Reihenfolge, dargestellt.
"
"
"
"Author: alf@cadsoft.de"
string Version = "1.0.0"; // 2013-03-21 alf@cadsoft.de
string Default_Sequence = "48t 49t 19t 47t 20t 46t 23 27 25 59 57 55 53 50 51 21 44t 45t 37 35 31 29 33 39 41 43t 18t 17t 1-16 17b 18b 43b 42 40 34 30 32 36 38 45b 44b 22 52 54 56 58 60 26 28 24 46b 20b 47b 19b 49b 48b";
numeric string Lay[];
int CntLS;
string LayerSequence = cfgget("EAGLE:Option.LayerSequence", "48t 49t 19t 47t 20t 46t 23 27 25 59 57 55 53 50 51 21 44t 45t 37 35 31 29 33 39 41 43t 18t 17t 1-16 17b 18b 43b 42 40 34 30 32 36 38 45b 44b 22 52 54 56 58 60 26 28 24 46b 20b 47b 19b 49b 48b 61-99");
string LayerSequenceUndo = LayerSequence;
string LayerNam[];
int LayerNum[];
int Sel = 0;
int Srt = 0;
/*** Functions ***/
void help(void) {
dlgDialog("HELP LayerSequence") {
dlgLabel(usage);
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("+OK") dlgAccept();
dlgStretch(1);
}
};
}
void selerror(void) {
if (language() == "de") dlgMessageBox("!Selektieren Sie erst eine Zeile in der Liste.", "ok");
else dlgMessageBox("!First select a list entry.", "ok");
return;
}
string getnewlayer(void) {
int selnew = -1;
int srt = 0;
string newlayer = "";
dlgDialog("Insert Layer Sequence") {
dlgHBoxLayout dlgSpacing(280);
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(400);
dlgVBoxLayout {
dlgStretch(1);
dlgLabel("Layer num.");
dlgStringEdit(newlayer);
dlgStretch(1);
}
dlgListView("Layer", LayerNam, selnew, srt) {
if (selnew < 0) selerror();
else {
if (strstr(LayerNam[selnew], "do not use") > 0) {
}
else sprintf(newlayer, "%d", selnew);
}
}
}
dlgHBoxLayout {
dlgPushButton("+OK") {
if (newlayer) { dlgAccept(); return newlayer+"\t"+LayerNam[selnew]; }
else dlgMessageBox("First select a layer", "OK");
}
dlgPushButton("-CANCEL") dlgReject();
dlgStretch(1);
}
};
return "";
}
void MoveDown(int sel) {
if (sel < 0) {
selerror();
return;
}
if (sel < CntLS-1) {
string t[];
int cnt = strsplit(t, Lay[sel], '\t');
string t1[];
int cnt1 = strsplit(t1, Lay[sel+1], '\t');
Lay[sel] = t[0]+"\t"+t1[1]+"\t"+ t1[2];
Lay[sel+1] = t1[0]+"\t"+t[1]+"\t"+t[2];
Sel++;
}
return;
}
void MoveUp(int sel) {
if (sel < 0) {
selerror();
return;
}
if (sel > 0) {
string t[];
int cnt = strsplit(t, Lay[sel], '\t');
string t1[];
int cnt1 = strsplit(t1, Lay[sel-1], '\t');
Lay[sel] = t[0]+"\t"+t1[1]+"\t"+ t1[2];
Lay[sel-1] = t1[0]+"\t"+t[1]+"\t"+t[2];
Sel--;
}
return;
}
void Delete(int sel) {
if (sel < 0) {
selerror();
return;
}
for (int n = sel; n < CntLS-1; n++) {
MoveDown(n);
}
CntLS--;
Sel = -1;
Lay[CntLS] = "";
return;
}
void Insert(int sel) {
if (sel < 0) sel = CntLS; // hänge es hinten dran
string newlayer = getnewlayer();
if (newlayer) {
sprintf(Lay[CntLS], "%d\t\%s\t%s", CntLS+1, newlayer, "layernew");
CntLS++;
for (int n = CntLS-1; n > sel; n--) {
MoveUp(n);
}
Sel = sel;
}
return;
}
void Optiont(int sel) {
if (sel < 0) {
selerror();
return;
}
string l[];
strsplit(l, Lay[sel], '\t');
int len = strlen(l[1])-1;
if (l[1][len] == 't') return;
else if (l[1][len] == 'b') {
l[1][len] = 't';
}
else {
l[1]+= "t";
}
Lay[sel] = l[0]+"\t"+l[1]+"\t"+l[2];
return;
}
void Optionb(int sel) {
if (sel < 0) {
selerror();
return;
}
string l[];
strsplit(l, Lay[sel], '\t');
int len = strlen(l[1])-1;
if (l[1][len] == 'b') return;
else if (l[1][len] == 't') {
l[1][len] = 'b';
}
else {
l[1]+= "b";
}
Lay[sel] = l[0]+"\t"+l[1]+"\t"+l[2];
return;
}
void DelOpt(int sel) {
if (sel < 0) {
selerror();
return;
}
string l[];
strsplit(l, Lay[sel], '\t');
int len = strlen(l[1])-1;
if (l[1][len] == 'b' || l[1][len] == 't') l[1][len] = 0;
Lay[sel] = l[0]+"\t"+l[1]+"\t"+l[2];
return;
}
string gensequence(void) {
string l[];
int n = 0;
strsplit(l, Lay[n], '\t');
string setseq = l[1];
for (n = 1; n < CntLS; n++) {
strsplit(l, Lay[n], '\t');
setseq += " "+ l[1];
}
return setseq;
}
void setsequence(void) {
string setseq = gensequence();
if (dlgMessageBox("Set sequence:\n"+setseq, "OK", "CANCEL") != 0) return;
cfgset("EAGLE:Option.LayerSequence", setseq);
return;
}
void get_layer_name(string ls) {
if (project.schematic) project.schematic(SCH) SCH.layers(L) {
LayerNam[L.number] = L.name;
}
if (project.board) project.board(B) B.layers(L) {
LayerNam[L.number] = L.name;
}
for (int xl = 0; xl < 256; xl++) {
if (!LayerNam[xl]) sprintf(LayerNam[xl], "%d ~do not use~", xl);
}
string h;
CntLS = strsplit(Lay, ls, ' ');
int n = 0;
sprintf(Lay[n], "%d\t%s\t%s",n+1, Lay[n], LayerNam[strtol(Lay[n])]);
while (Lay[++n]) {
if(strchr(Lay[n], '-') < 1) sprintf(Lay[n], "%d\t%s\t%s",n+1, Lay[n], LayerNam[strtol(Lay[n])]);
else sprintf(Lay[n], "%d\t%s\t%s",n+1, Lay[n], "#");
}
CntLS = n;
return;
}
void set_default(void) {
LayerSequence = Default_Sequence;
get_layer_name(LayerSequence);
return;
}
void set_undo(void) {
LayerSequence = LayerSequenceUndo;
get_layer_name(LayerSequence);
return;
}
void getEditLine(void) {
string layseq = gensequence();
dlgDialog("Edit Layer Sequence") {
dlgHBoxLayout dlgSpacing(900);
dlgStringEdit(layseq);
dlgHBoxLayout {
dlgPushButton("OK") { dlgAccept(); get_layer_name(layseq); return; }
dlgPushButton("CANCEL") { dlgReject(); return; }
dlgStretch(1);
}
};
return;
}
get_layer_name(LayerSequence);
Sel = -1;
dlgDialog("Layer Sequence") {
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(700);
dlgVBoxLayout {
dlgPushButton("&Default") set_default();
dlgPushButton("Edit") getEditLine();
dlgStretch(1);
if (language() == "de") dlgPushButton("Verschieben &^") MoveUp(Sel);
else dlgPushButton("Move &^") MoveUp(Sel);
if (language() == "de") dlgPushButton("E&infügen") Insert(Sel);
else dlgPushButton("&Insert") Insert(Sel);
if (language() == "de") dlgPushButton("&Löschen") Delete(Sel);
else dlgPushButton("D&elete") Delete(Sel);
dlgPushButton("Option &t") Optiont(Sel);
dlgPushButton("Option &b") Optionb(Sel);
if (language() == "de") dlgPushButton("Lösche &Opt.") DelOpt(Sel);
else dlgPushButton("Del. &Opt.") DelOpt(Sel);
if (language() == "de") dlgPushButton("Verschieben &v") MoveDown(Sel);
else dlgPushButton("Move &v") MoveDown(Sel);
dlgStretch(1);
}
dlgListView("Num.\tLay.\tName", Lay, Sel, Srt);
dlgVBoxLayout {
dlgSpacing(22);
dlgLabel("
"); // relativer Pfad
if (language() == "de") dlgLabel("Reihenfolge
der Layer
beim Ausdruck
von unten
(gespiegelt)");
else dlgLabel("Layer sequence
to print
bottom view
(mirrored)");
dlgStretch(1);
dlgPushButton("&HELP") help();
dlgStretch(1);
if (language() == "de") dlgLabel("Reihenfolge
der Layer
beim Ausdruck
von oben
(nicht gespiegelt)");
else dlgLabel("Layer sequence
to print
top view
(not mirrored)");
dlgLabel("
"); // relativer Pfad
}
}
dlgHBoxLayout {
dlgPushButton("E&XIT") dlgAccept();
dlgStretch(1);
dlgPushButton("&SET") setsequence();
dlgStretch(1);
dlgPushButton("&UNDO") set_undo();
}
};