%!PS-Adobe-2.0 % % Functions for direct and embedded PostScript % % This file is part of LilyPond, the GNU music typesetter. % % Copyright (C) 1998--2022 Han-Wen Nienhuys , % 2013--2019 David Kastrup % % LilyPond 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 3 of the License, or % (at your option) any later version. % % LilyPond 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 LilyPond. If not, see . % % Careful with double % as comment prefix. % Any %%X comment is interpreted as DSC comments. % TODO: use dicts or prefixes to prevent namespace pollution. /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % llx lly urx ury URI /mark_URI { /uri exch def /ury exch def /urx exch def /lly exch def /llx exch def [ /Rect [ llx lly urx ury ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI uri >> /Subtype /Link /ANN pdfmark } bind def % llx lly urx ury page /mark_page_link { /page exch def /ury exch def /urx exch def /lly exch def /llx exch def [ /Rect [ llx lly urx ury ] /Border [ 0 0 0 ] /Page page /Subtype /Link /ANN pdfmark } bind def % from adobe tech note 5002. /BeginEPSF { %def /b4_Inc_state save def % Save state for cleanup /dict_count countdictstack def % Count objects on dict stack /op_count count 1 sub def % Count objects on operand stack userdict begin % Push userdict on dict stack /showpage { } def % Redefine showpage, { } = null proc 0 setgray 0 setlinecap % Prepare graphics state 1 setlinewidth 0 setlinejoin 10 setmiterlimit [ ] 0 setdash newpath false setoverprint } bind def /EndEPSF { %def count op_count sub {pop} repeat % Clean up stacks countdictstack dict_count sub {end} repeat b4_Inc_state restore } bind def /stroke_and_fill? { { gsave false setstrokeadjust stroke grestore fill } { stroke } ifelse } bind def /vector_add { % x1 y1 x2 y2 vector_add x1+x2 y1+y2 exch 4 1 roll add 3 1 roll add exch } bind def /draw_round_box % width height x y blot { dup 0 lt { pop 0 } if setlinewidth matrix currentmatrix 5 1 roll currentpoint translate newpath translate 2 copy dup 0 gt { pop 0 } if exch dup 0 gt { pop 0 } if exch translate abs exch abs exch currentlinewidth 0 eq { % straight corners 2 copy 2 mul gt { % horizontal 0 1 index 2 div moveto setlinewidth 0 rlineto 0 setlinecap stroke } { 2 copy exch 2 mul gt { % vertical 1 index 2 div 0 moveto exch setlinewidth 0 exch rlineto 0 setlinecap stroke } { 0 0 4 2 roll rectfill } ifelse } ifelse } { % rounded corners 2 copy 0 eq exch 0 eq or { % line shape 0 0 moveto rlineto 1 setlinecap stroke 0 setlinecap } { % full shape currentstrokeadjust { currentlinewidth 2 div 0 0 2 index 180 270 arc 2 index 0 2 index 270 360 arc 3 copy 0 90 arc 0 2 index 3 -1 roll 90 180 arc closepath 2 copy 2 mul gt { % horizontal 2 copy add currentlinewidth add 10 add % large enough 0 1 index neg moveto 2 index 1 index neg lineto 2 index 1 index lineto 0 exch lineto closepath gsave clip newpath 0 1 index 2 div moveto currentlinewidth add setlinewidth 0 rlineto 2 setlinecap stroke grestore } { 2 copy exch 2 mul gt { % vertical 2 copy add currentlinewidth add 10 add % large enough dup neg 0 moveto dup 0 lineto dup 2 index lineto neg 1 index lineto closepath gsave clip newpath 1 index 2 div 0 moveto exch currentlinewidth add setlinewidth 0 exch rlineto 2 setlinecap stroke grestore } { pop pop fill } ifelse } ifelse newpath } { 1 setlinejoin 0 0 4 2 roll 4 copy rectstroke rectfill } ifelse } ifelse } ifelse setmatrix } bind def /draw_polygon % fill? x(n) y(n) x(n-1) y(n-1) ... x(0) y(0) n blot { setlinewidth %set to blot 0 setlinecap 1 setlinejoin 3 1 roll /polygon_x currentpoint /polygon_y exch def def rmoveto % x(0) y(0) { polygon_x polygon_y vector_add lineto } repeat % n times closepath stroke_and_fill? } bind def /draw_circle % filled? radius thickness draw_circle { setlinewidth % f? r currentpoint % f? r x0 y0 3 2 roll % f? x0 y0 r dup 0 rmoveto 0 360 arc closepath stroke_and_fill? } bind def /draw_ellipse % filled? x-radius y-radius thickness draw_ellipse { setlinewidth % f? x-r y-r /savematrix matrix currentmatrix def scale % f? currentpoint 1 0 rmoveto 1 0 360 arc closepath savematrix setmatrix stroke_and_fill? } bind def /draw_partial_ellipse % filled connect x-radius y-radius startangle endangle thickness draw_partial_ellipse % Note that filled is not boolean to permit for different graylevels (ie for trill keys) { gsave currentpoint translate /thickness exch def /endangle exch def /startangle exch def /y_radius exch def /x_radius exch def /endrad x_radius y_radius mul x_radius x_radius mul endangle cos endangle cos mul mul y_radius y_radius mul endangle sin endangle sin mul mul add sqrt div def /endangle endangle sin endrad mul y_radius div endangle cos endrad mul x_radius div atan def /startrad x_radius y_radius mul x_radius x_radius mul startangle cos startangle cos mul mul y_radius y_radius mul startangle sin startangle sin mul mul add sqrt div def /startangle startangle sin startrad mul y_radius div startangle cos startrad mul x_radius div atan def /connect exch def /filled exch def /savematrix matrix currentmatrix def thickness setlinewidth x_radius y_radius scale startangle cos startangle sin moveto 0 0 1 startangle startangle endangle eq { endangle 360 add } { endangle } ifelse arc connect { startangle cos startangle sin moveto endangle cos endangle sin lineto } if savematrix setmatrix filled stroke_and_fill? grestore } bind def /draw_line % dx dy x1 y1 thickness draw_line { setlinewidth % dx dy x1 y1 1 setlinecap rmoveto % dx dy rlineto stroke } bind def /draw_dashed_line % dx dy thickness dashpattern offset draw_dashed_line { 1 setlinecap setdash % dx dy thickness setlinewidth %dx dy rlineto stroke [] 0 setdash % reset dash pattern } bind def /print_glyphs % w dx dy glyph print_glyphs { { currentpoint %w dx dy glyph x0 y0 5 2 roll %w x0 y0 dx dy glyph 3 1 roll %w x0 y0 glyph dx dy rmoveto %w x0 y0 glyph glyphshow %w x0 y0 moveto %w 0 rmoveto }repeat }bind def %end music-drawing-routines.ps