Autor Thema: Notenköpfe ändern  (Gelesen 8365 mal)

Arnold

  • Member
Re: Notenköpfe ändern
« Antwort #15 am: Freitag, 4. November 2011, 11:36 »
Hallo,

auch ich gebe hier keinen Postscript-Unterricht - da sollte man sich entsprechende Unterlagen im Internet suchen und mit gostscript üben.
In lilypond, wenn man Postscript-Notenköpfe definiert, sollte man im text-markup auch \with-dimensions #'(x_min . x_max) #'(y_min . y_max) nicht vergessen.
Dies teilt lilypond die Größe des »Beschreibungsgitters« für das Zeichen mit, Maßeinheit ist der Linienabstand der Notenzeile.
Ein typischer Notenkopf (Viertel) hat so z. Bsp »\with-dimensions #'(0 . 1.2) #'(-0.5 . 0.5) - die genaue X-Lage hat eigentlich keinen Effekt in der Ausgabe, wenn das Postscript seine Koordinaten relativ dazu angibt.
Ein Notenkopf »Quadrat auf Spitze, nicht gefüllt« könnte also so lauten:
\markup {
  \with-dimensions #'(-0.5 . 0.5) #'(-0.5 0.5)
  \postscript #"
  1 setlinecap 1 setlinejoin
  newpath
  -0.45 0 moveto
  0 0.45 lineto
  0.45 0 lineto
  0 -0.45 lineto
  -0.45 0 lineto
  0.1 setlinewidth stroke
"
}
Übrigens kapselt lilypond diese Postscript-Seqenz in eine gsave-grestore-Paar in der Postscript-Datei, die dann ins PDF übersetzt wird.
Nachteil der Postscript-Einbindung ist aber, daß diese nicht auf die font-size reagieren - also immer gleich groß sind entsprechend dem globalen Staff-Size. Um das zu umgehen, muß man sich eine scheme-Funktion schreiben, welche das markup zurückgibt, aber zuvor im GROB (Übergabeparameter) nach der font-size sucht, mittels magstep den Skalierungsfaktor berechnet, in der Größenangabe (\with-dimensions) die skalierte Größe zurückgibt, und im Postscript-Code (\postscript) noch ein passendes »scale« voranstellt, eventuell auch noch ein »translate«.

(Wer Interesse an einem solchen Beispiel hat, der melde sich bitte)

Arnold


harm6

  • Member
Re: Notenköpfe ändern
« Antwort #16 am: Donnerstag, 17. November 2011, 00:15 »
Hallo zusammen,

aktuell gibts auf der englischen Liste gerade einen Thread mit diesem Thema.

Ich habe takumi ikeda's Code mit der Verbesserung von Keith OHara benutzt und viereckige Notenköpfe gebastelt. Schön an takumi's Code ist, daß sich um all die Probleme gekümmert wird, die bei solchen Änderungen halt entstehen. Wer eine Vorlage für eigene Projekte braucht - hier ist eine!

\version "2.14.2"

% http://old.nabble.com/collision-of-special-notehead-and-accidental-td32839237.html

filledQr =
#(ly:make-stencil
       (list 'embedded-ps
       "gsave
       currentpoint translate
       newpath
       .125 0 moveto
       .79 -0.67 lineto
       1.45 0 lineto
       0.79 0.67 lineto
       closepath
       fill
       grestore" )
       (cons -.1875 1.5)
       (cons -.5 .5)
)

unfilledQr =
#(ly:make-stencil
       (list 'embedded-ps
       "gsave
       currentpoint translate
       newpath
       0.2 0 moveto
       .79 -0.6 lineto
       1.39 0 lineto
       0.79 0.6 lineto
       closepath
       0.14 setlinewidth
       stroke
       grestore" )
       (cons -.1875 1.5)
       (cons -.5 .5)
)

#(define (stencil-notehead grob)
       (if (> 2 (ly:grob-property grob 'duration-log))
       unfilledQr filledQr
       )
)

#(define (harms-special grob)
  (ly:stencil-add
       (if (> 2 (ly:grob-property grob 'duration-log))
         unfilledQr filledQr)
    (ly:stencil-translate
       (if (> 2 (ly:grob-property grob 'duration-log))
         (grob-interpret-markup grob (markup #:fontsize -8 #:with-color red #:rotate -90 ":)" ))
         (grob-interpret-markup grob (markup #:fontsize -6 #:with-color white #:rotate -90 ":)" )))
    (cons 0.45 -0.3))))

upStem          = #'(0.94 . -0.05)
downStem        = #'(0.625 . -0.05)

#(define (pitch-to-stem stemdir)
       (if (= UP stemdir) upStem downStem)
)

#(define (notehead-get-notecolumn nhgrob)
       (ly:grob-parent nhgrob X))

#(define (notehead-get-stem nhgrob)
       (let ((notecolumn (notehead-get-notecolumn nhgrob)))
               (ly:grob-object notecolumn 'stem)))

#(define (stem-adjuster nhgrob)
       (pitch-to-stem
               (ly:grob-property (notehead-get-stem nhgrob) 'direction) ))


notes = \relative c' {
       c4 cis d dis e8 f fis g gis a ais b
       c16 cis d dis e4 eis f fis g gis8 a ais b
       c4 c c c b2 bes a aes g ges f e ees d des
       c b bes a aes g ges f e ees d des c
       <a c>
       <d f a c e g>
}

\score {
        \new Staff
        {
       <<
               \notes
       >>
        }
       \layout {
               \context {
                   \Score
                       \override NoteHead #'stencil = #stencil-notehead
                       %\override NoteHead #'stencil = #harms-special
                       \override NoteHead #'stem-attachment = #stem-adjuster
                       % folgende Zeile kann mit "2.15.x" gelöscht werden:
                       \override NoteHead #'minimum-Y-extent = #'(-0.1 . 0.1)
               }
       }
}

@Arnold
Ich habe immer Interesse an solchen Beispielen. Zwar beschäftige ich mich im Moment hauptsächlich mit anderen Problemen, es wäre aber sehr lehrreich die Unterschiede in der Herangehensweise und Ausführung zu studieren.

Gruß,
  Harm

P.S. Wer ein bißchen Aufheiterung braucht (als Musikschullehrer brauch ich immer welche) kann ja mal \override NoteHead #'stencil = #harms-special einkommentieren und das PDF bei mindestens 400% Vergrößerung betrachten.
« Letzte Änderung: Donnerstag, 17. November 2011, 00:18 von harm6 »

Arnold

  • Member
Re: Notenköpfe ändern
« Antwort #17 am: Freitag, 18. November 2011, 13:08 »
Sehr gut, Harm! Einen stem-adjuster werde ich in Zukunft auch noch brauchen, wenn ich eimal so richtig mit einer bestimmten Griffnotenschrift anfange.

Nun zu meinen Postscript-Beispielen - auch wenn sie noch mit der Verision 2.12.3 erstellt sind:
%{
Postscript

%}
\version "2.12.3"
%PREPROCESS: C:\Programme_privat_32\Spezial\close_acrobat -c ${BASENAME} ${BASENAME}-print



FootLeft = #(string-append "Music engraving by LILYPOND, Version " (lilypond-version))
FootRight = #(string-append "compiled at " (strftime "%Y-%m-%d %H:%M:%S" (localtime (current-time))))
FootCenter = #(let*
  ((cmdl (object->string (command-line)))
   (laloc (+ (string-rindex cmdl #\space) 2))
   (cmdlen (- (string-length cmdl) 2))
   (filen (substring cmdl laloc cmdlen))
   (workdir (getcwd))
   (basename (let ((ppos (string-rindex filen #\. )))
     (if (number? ppos) (substring filen 0 ppos) filen)))
   (lastdir (let*
     ((dpos (string-rindex workdir (string->char-set "\\/")))
      (laenge (string-length workdir)))
     (if (< (+ dpos 1) laenge) (string-append (substring workdir (+ dpos 1)) "/") "/"))))
  (string-append lastdir basename))


\paper {
  oddFooterMarkup = \markup \fill-line {
    \abs-fontsize #6.5 { \FootLeft }
    \abs-fontsize #9.0 { \bold { \FootCenter } }
    \abs-fontsize #6.5 { \FootRight }
  }
  left-margin         =  12 \mm
  line-width          = 188 \mm
  indent              =   3 \mm
}


\header {
  title = "»Postscript« Beispiele"
}

#(define (scaled-ps-markup scale x-min x-max y-min y-max ps-string)
  (markup #:line (#:with-dimensions
    (cons (* x-min scale) (* x-max scale))
    (cons (* y-min scale) (* y-max scale))
    (#:postscript (string-concatenate
      (list " " (number->string scale) " dup scale \n"
       ps-string))))))

#(define (scale-postscript my-grob x-min x-max y-min y-max ps-string)
  (let*
   ((sz (ly:grob-property my-grob 'font-size 0.0))
    (mult (magstep sz)))
   (scaled-ps-markup mult x-min x-max y-min y-max ps-string)))

#(define (coda-caesur-ps notehead-grob)
  (let*
   ((sz (ly:grob-property notehead-grob 'font-size 0.0))
    (mult (magstep sz)))
   (markup #:line (#:with-dimensions
     (cons (* -1.5 mult) (* 1.5 mult))
     (cons (* -0.5 mult) (* 2.5 mult))
     (#:postscript (string-concatenate (list
        " " (number->string mult) " dup scale \n"
        " newpath 0 setlinewidth 1 setlinejoin 0 setlinecap \n"
        " gsave \n"
        " 0 1 1 0 360 arc \n"
        " 0.6 1 scale \n"
        " 0 1 0.9 360 0 arcn \n"
        " closepath fill \n"
        " grestore 0.125 setlinewidth \n"
        " -1.3 1 moveto 1.3 1 lineto \n"
        " 0 -0.3 moveto 0 2.3 lineto \n"
        " stroke \n")))))))

CodaCaesura = {
  \once \override BreathingSign #'text = #coda-caesur-ps \breathe
}

#(define (fine-caesur-ps notehead-grob)
  (let*
   ((sz (ly:grob-property notehead-grob 'font-size 0.0))
    (mult (magstep sz)))
   (markup #:line (#:with-dimensions
     (cons (* -1.0625 mult) (* 4.6375 mult))
     (cons (* -3.5 mult) (* 2.25 mult))
     (#:postscript (string-concatenate (list
        " " (number->string mult) " dup scale \n"
        " newpath 0 setlinewidth 1 setlinejoin 1 setlinecap \n"
        " -0.1875 0.25 moveto \n"
        " -0.9375 0.25 lineto \n"
        " -1.0625 -0.25 lineto \n"
        " -0.3125 -0.25 lineto \n"
        " -1.0625 -3.25 lineto \n"
        " -0.625 -3.5 lineto \n"
        " 0.1875 -0.25 lineto \n"
        " 3.4375 -0.25 lineto \n"
        " 3.8125 0.25 lineto \n"
        " 0.3125 0.25 lineto \n"
        " 0.5 1.0 "
        " 1.0875 1.75 "
        " 1.9375 1.75 curveto \n"
        " 2.7875 1.75 "
        " 3.2375 1.55 "
        " 3.65 1.0 curveto \n"
        " 4.0625 1.25 lineto \n"
        " 3.6125 1.85 "
        " 3.0625 2.25 "
        " 2.0625 2.25 curveto \n"
        " 1.0125 2.25 "
        " 0.1125 1.45 "
        " -0.1875 0.25 curveto closepath fill \n"
        " 0.0625 -2.75 moveto \n"
        " 0.5625 -2.75 lineto \n"
        " 1.0625 -0.75 lineto \n"
        " 0.5625 -0.75 lineto \n"
        " 0.0625 -2.75 lineto closepath fill \n"
        " 1.0625 -2.75 moveto \n"
        " 1.5625 -2.75 lineto \n"
        " 1.8625 -1.55 lineto \n"
        " 2.4875 -1.05 lineto \n"
        " 2.0625 -2.75 lineto \n"
        " 2.5625 -2.75 lineto \n"
        " 3.0625 -0.75 lineto \n"
        " 2.5625 -0.75 lineto \n"
        " 1.9375 -1.25 lineto \n"
        " 2.0625 -0.75 lineto \n"
        " 1.5625 -0.75 lineto \n"
        " 1.0625 -2.75 lineto closepath fill \n"
        " 1.75 1.0 "
        " 0.5 0 360 arc closepath fill \n"
        " 3.1375 -2.25 moveto \n"
        " 3.625 -2.9 lineto \n"
        " 4.1875 -2.45 lineto \n"
        " 4.2125 -2.35 lineto \n"
        " 3.8375 -2.65 lineto \n"
        " 3.6125 -2.35 lineto \n"
        " 3.7 -2.0 lineto \n"
        " 4.6375 -1.25 lineto \n"
        " 4.15 -0.6 lineto \n"
        " 3.4 -1.2 lineto \n"
        " 3.1375 -2.25 lineto \n"
        " 3.9 -1.2 moveto \n"
        " 4.2125 -0.95 lineto \n"
        " 4.5125 -1.35 lineto \n"
        " 4.4 -1.2 lineto \n"
        " 3.775 -1.7 lineto \n"
        " 3.9 -1.2 lineto closepath fill \n")))))))


FineCaesura = {
  \once \override BreathingSign #'text = #fine-caesur-ps \breathe
}


Melodie = {
  c'4
  \once \override BreathingSign #'text = #(lambda (grob)
    (scale-postscript grob -1.0 1.0 -1.0 1.0 "
  1 setlinecap 1 setlinejoin newpath
  -0.8 0 moveto
  0 0.8 lineto
  0.8 0 lineto
  0 -0.8 lineto
  -0.8 0 lineto
  0.4 setlinewidth stroke
  ")) \breathe
  e' \CodaCaesura g' \FineCaesura c''
  \override NoteHead #'stencil = #ly:text-interface::print
  \override NoteHead #'text = #(lambda (grob)
    (scale-postscript grob -0.5 0.5 -0.5 0.5 "
     newpath 0.04 setlinewidth 1 setlinejoin 1 setlinecap
    -0.48 -0.48 moveto
    -0.14 -0.46 lineto
    -0.13 -0.30  -0.09 -0.17  -0.00 -0.08 curveto
     0.09 -0.17   0.13 -0.30   0.14 -0.46 curveto
     0.48 -0.48 lineto
     0.46 -0.14 lineto
     0.30 -0.13   0.17 -0.09   0.08  0.00 curveto
     0.17  0.09   0.30  0.13   0.46  0.14 curveto
     0.48  0.48 lineto
     0.14  0.46 lineto
     0.13  0.30   0.09  0.17   0.00  0.08 curveto
    -0.09  0.17  -0.13  0.30  -0.14  0.46 curveto
    -0.48  0.48 lineto
    -0.46  0.14 lineto
    -0.30  0.13  -0.17  0.09  -0.08  0.00 curveto
    -0.17 -0.09  -0.30 -0.13  -0.46 -0.14 curveto
    -0.48 -0.48 lineto
     closepath gsave fill grestore stroke
    "))
  \grace { e''32[ es'' d'' des'' b'] } \pitchedTrill c''4\startTrillSpan dis'' \stopTrillSpan
  \bar "|."
}

\score {
  <<
  \new Staff {
    \clef treble #(set-accidental-style 'modern-cautionary)
    \Melodie
  }
  \new Staff \with {
    fontSize = #-4
    \override StaffSymbol #'staff-space = #(magstep -4)
    \override StaffSymbol #'thickness = #(magstep -4)
  } {
    \clef treble #(set-accidental-style 'modern-cautionary)
    \Melodie
  }
  >>
  \header { piece = " " }
}


scaled-ps-markup mit den Parametern scale, x-min, x-max, y-min, y-max (bis hierher alles Realzahlen) und ps-string gibt ein Markup zurück, in den das Postscript um den Faktor scale skaliert wurde, und die Beschreibung der Ausdehnung wird selbstredend auch mit skaliert. Wieder gehe ich davon aus, das Lilypond den Postscript-Einschub in ein »gsave - grestore«-Paar kapselt.

scale-postscript, fast die gleichen Aufrufparameter, nur ein grob statt dem scale, denn der Skalierungsmaßstab soll ja aus dem GRafikOBjekt ermittelt werden.

Als Beispiele sind dann definiert:
CodaCaesure - das breathe bekommt als druckbares Zeichen ein Coda-Symbol.
FineCaesure - das breathe bekommt als gedurcktes Zeichen einen »Fine«-Schriftzug.
Bei Erstellen dieser beiden Kommandos hatte ich noch nicht die oben genannten Funktionen als Unteraufruf benutzt, statt dessen liegt die gesamte Syntax in einem einzigen Unterprogramm.

In der »Melodie« gehts dann richtig zur Sache, da definiere ich »on the fly« (über »lambda«) mal ein alternatives BreathingSign, und etwas später sogar einen Postskript-Notenkopf in Form eines Doppelkreuzes. Und das alles muß bei Vorschlägen bzw. verkleinerten Notenzeilen mitskaliert werden.

Was noch fehlt, wäre ein Markup, welches ein Kalender-Monatsblatt erstellt (Parameter Jahr, Monat und Skalierungsfaktor sind zu übergeben) - in Postscript habe ich so ein Programm, welches sogar die beweglichen Feiertage ausrechnet.


Viel Spaß und Erfolg damit,

Arnold