#include #include #include #include #include "studio/geometry.h" #include "picture.h" #include "unreliableobjects.h" static const char *layout(void) { return ( "{\n" " begin {\n" " /Contents {\n" " /draw {\n" " save exch matrix currentmatrix exch\n" " linewidth 100 mul mediasize 2 {2 index sub 2 div exch} repeat translate dup scale\n" " border {\n" " gsave\n" " 0 setlinewidth 0 0 1 1 rectstroke\n" " grestore\n" " } if\n" " /l {lineto} bind def /m {moveto} bind def exec\n" " setmatrix linewidth setlinewidth 1 setlinecap 1 setlinejoin stroke\n" " restore\n" " } def\n" " /Contents [\n" " [currentfile cvx exec] dup length dup 0 eq {\n" " (%stderr) (w) file (%%[ Error: no pages read ]%%\\n) writestring stop\n" " } if\n" " [2 index 0 get /draw cvx] cvx {} {}\n" " 5 -2 roll 1 sub 1 exch getinterval {[exch /draw cvx] cvx} forall\n" " {} {} {\n" " margin dup crop add exch 20 1.2 mul add translate\n" " guides {\n" " gsave\n" " 0 setlinewidth 0 0 320 144 rectstroke\n" " grestore\n" " } if\n" " mark /Courier-Bold 20 [\n" " (unreliable objects)\n" " ()\n" " ()\n" " (David W. Speck, 2024)\n" " (rndmao.org/dws)\n" " ] /Courier-BoldOblique 20 [\n" " (unzuverl\\344ssige objekte)\n" " ()\n" " ()\n" " ()\n" " ] counttomark 3 idiv {\n" " 3 2 roll dup findfont dup length dict begin {\n" " 1 index /FID ne {def} {pop pop} ifelse\n" " } forall /Encoding ISOLatin1Encoding def\n" " currentdict end definefont 2 index scalefont setfont\n" " exch 1.2 mul exch dup length 1 sub 2 index mul exch {\n" " 0 2 index moveto show 1 index sub\n" " } forall pop pop\n" " } repeat pop\n" " }\n" " ] dup 3 1 roll def\n" " } bind def\n" " <> setpagedevice\n" " booklet {\n" " /PageCount 0 def\n" " 4up {[\n" " Contents length dup\n" " /quarter exch 4 idiv def\n" " /reverse exch 1 sub [ exch /exch cvx /sub cvx] cvx bind def\n" " 0 1 quarter 1 sub {\n" " dup 1 and 0 eq {\n" " dup reverse exch\n" " dup quarter add dup reverse\n" " } {\n" " dup reverse\n" " dup quarter sub dup reverse\n" " } ifelse\n" " } for\n" " ]} {[0 1 Contents length 1 sub {} for]} ifelse {\n" " save exch\n" " /showpage {} def\n" " pageoffset PageCount 4up {4 and 4} {2 and 2} ifelse eq {duplexerror 2 {3 -1 roll add exch} repeat} if translate\n" " 4up PageCount 0 eq and {\n" " guides {\n" " gsave\n" " mediasize 2 div 0 exch moveto 0 rlineto 0 setlinewidth stroke\n" " grestore\n" " } if\n" " staples {\n" " gsave\n" " mediasize 8 div exch 2 div 1 index 27 sub moveto\n" " 0 27 rlineto 2 mul 0 exch rmoveto 0 27 rlineto\n" " 0 setlinewidth stroke\n" " grestore\n" " } if\n" " } if\n" " 4up {0.5 dup scale} if\n" " crop PageCount 1 and 1 eq {mediasize pop exch sub} if 0 translate\n" " 4up PageCount 2 and 2 eq and {mediasize 2 mul translate -1 dup scale} if\n" " guides {\n" " gsave\n" " 0 setlinewidth mediasize margin dup 2 {3 index margin 2 mul sub} repeat rectstroke pop pop\n" " /Courier 18 selectfont mediasize pop 96 sub 72 moveto dup 1 add ( ) cvs show\n" " grestore\n" " } if\n" " Contents exch get exec\n" " restore\n" " 4up not PageCount 3 and 3 eq or {showpage} if\n" //" PageCount 3 eq {quit} if\n" // !!!!!!!!!!!!!! " /PageCount PageCount 1 add def\n" " } forall\n" " } {\n" " Contents {\n" " dup length 0 gt {save exch /showpage {} def exec restore showpage} {pop} ifelse\n" " } forall\n" " } ifelse\n" " } bind stopped {\n" " flush (%stderr) (w) file (%%[ stopped: operandstack ]%%\\n) writestring\n" " pstack flush stop\n" " } if\n" " end\n" "} exec\n" ); } static void postscript(void * const device, const char * const format, ...) { assert(format); va_list arguments = {0}; va_start(arguments, format); (void)output(device, format, arguments); va_end(arguments); } static struct picture draw(void * const output, struct picture image) { image = picture(image); postscript(output, "{\n", 0); for (size_t index = 0; index < count(image.object); ++index) { const struct object object = image.object[index]; if (object.vectors > 1) { assert(object.vector); for (size_t number = 1; number < object.vectors; ++number) { const vector moveto = transform(object.vector[number - 1], object.transformation); const vector lineto = transform(object.vector[number], object.transformation); postscript(output, "%.6f %.6f m %.6f %.6f l\n", moveto.x, moveto.y, lineto.x, lineto.y); } } } postscript(output, "}\n", 0); return erase(image); } int booklet(void * const output, int parameter) { (void)parameter; const double linewidth = 1.5; postscript(output, "%%!PS\n" "/mm {25.4 div 72 mul} readonly def\n" "<<\n" " /booklet true\n" " /4up false\n" " /border true\n" " /crop 10 mm\n" " /guides true\n" " /margin 20 mm\n" " /staples true\n" " /linewidth %g mm\n" " /mediasize [210 mm 297 mm] cvx readonly\n" " /pageoffset [0 mm 2.0 mm] cvx readonly\n" " /duplexerror [0.0 mm -3.5 mm] cvx readonly\n" ">> %s", linewidth, layout() ); struct picture image = draw(output, (struct picture){.chaos = 1, .linewidth = linewidth}); for (image.sides = 1; image.sides <= 9; ++image.sides) { for (image.chaos = 0; image.chaos <= 1; ++image.chaos) image = draw(output, image); } return 1; }