2005-05-28 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/stencil-scheme.cc (LY_DEFINE): ly:stencil-in-color
+
+ * ps/music-drawing-routines.ps:
+
+ * scm/output-ps.scm: remove draw ez_ball.
+
+ * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove
+ EasyNotation context definition.
+
+ * lily/easy-notation.cc (brew_ez_stencil): new file. Use
+ Text_interface and color for making easy note heads.
+
+ * lily/stencil.cc (with_color): new function.
+
+ * ps/music-drawing-routines.ps: remove draw_zigzag_line
+
+ * lily/line-spanner.cc (zigzag_stencil): rewrite to use draw-line
+ output routine. Zigzag now works in SVG too.
+
+ * scm/output-tex.scm (filledbox): idem.
+
+ * scm/output-svg.scm (filledbox): idem.
+
+ * scm/output-ps.scm (lily-def): remove horizontal-line.
+
+ * lily/lookup.cc (horizontal_line): use draw-line.
+
+ * lily/system-start-delimiter.cc: remove old staff bracket code.
+
* mf/feta-haak.mf: further tweaks.
* lily/system-start-delimiter.cc (staff_bracket): use glyphs.
* scm/output-svg.scm (circle): support circle.
(bracket): stub for bracket.
- * scripts/lilypond-book.py (main): make sure --psfonts warning is correct.
+ * scripts/lilypond-book.py (main): make sure --psfonts warning is
+ correct.
2005-05-26 Graham Percival <gperlist@shaw.ca>
\version "2.5.0"
+\paper { raggedright = ##t }
+
\relative {
- \new StaffGroup <<
+ \new StaffGroup \new PianoStaff <<
\new Staff <<
{
#(set-octavation 1)
\skip 1 >>
\new Staff \relative c'' {
\makeClusters { <g a>8 <e a> }
+ \override Glissando #'style = #'zigzag
+ f2 \glissando f'
+ \override NoteHead #'print-function = #Note_head::brew_ez_stencil
+ \override NoteHead #'Y-extent-callback = #'()
+ \override NoteHead #'X-extent-callback = #'()
+ f e
}
>>
}
You also get ledger lines, of course."
}
-\score {
- {
- \setEasyHeads
- c'2 g'2 | g'1
- \override NoteHead #'note-names = ##("U" "V" "W" "X" "Y" "Z" "z")
- c'2 e'4 f' | b'1
- }
- \layout {
- raggedright = ##t
- }
+
+\layout {
+ raggedright = ##t
+}
+
+\relative {
+ \setEasyHeads
+ f1 e
+ f2 e
+ f4 e
+
+ \override NoteHead #'note-names = ##("U" "V" "W" "X" "Y" "Z" "z")
+ c2 d4 e
}
--- /dev/null
+/*
+ easy-notation.cc -- implement easy notation heads
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "note-head.hh"
+
+#include "text-item.hh"
+#include "grob.hh"
+#include "output-def.hh"
+#include "music.hh"
+#include "pitch.hh"
+#include "font-interface.hh"
+#include "staff-symbol-referencer.hh"
+#include "stem.hh"
+
+MAKE_SCHEME_CALLBACK (Note_head, brew_ez_stencil, 1);
+SCM
+Note_head::brew_ez_stencil (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ int log = Note_head::get_balltype (me);
+
+ SCM cause = me->get_property ("cause");
+ SCM spitch = unsmob_music (cause)->get_property ("pitch");
+ Pitch *pit = unsmob_pitch (spitch);
+
+ SCM idx = scm_int2num (pit->get_notename ());
+ SCM names = me->get_property ("note-names");
+ SCM charstr = SCM_EOL;
+ if (scm_is_vector (names))
+ charstr = scm_vector_ref (names, idx);
+ else
+ {
+ char s[2] = "a";
+ s[0] = (pit->get_notename () + 2) % 7 + 'a';
+ s[0] = toupper (s[0]);
+ charstr = scm_makfrom0str (s);
+ }
+
+
+ SCM letter
+ = Text_interface::interpret_string (me->get_layout()->self_scm (),
+ Font_interface::text_font_alist_chain (me),
+ charstr);
+
+ Stencil l (*unsmob_stencil (letter));
+ l.align_to (X_AXIS, CENTER);
+ l.align_to (Y_AXIS, CENTER);
+
+
+ l = Stencil (Box (), l.expr ());
+ Real ss = Staff_symbol_referencer::staff_space (me);
+ Real lt = Staff_symbol_referencer::line_thickness (me);
+
+ Real radius = (ss + lt) / 2.0;
+ Real stem_thick = 1.3 * lt;
+ if (Grob *stem = unsmob_grob (me->get_property ("stem")))
+ {
+ stem_thick = Stem::thickness (stem);
+ }
+
+ int black = (log >= 2);
+
+ Stencil head;
+ Box extent (Interval (-radius, radius),
+ Interval (-radius, radius));
+
+ Stencil black_head (extent,
+ scm_list_4 (ly_symbol2scm ("circle"),
+ scm_from_double (radius),
+ scm_from_double (0.0),
+ SCM_BOOL_T));
+ Stencil white_head;
+ if (black)
+ {
+ l = l.in_color (1, 1, 1);
+ }
+ else
+ {
+ white_head = Stencil (extent,
+ scm_list_4 (ly_symbol2scm ("circle"),
+ scm_from_double (radius - stem_thick),
+ scm_from_double (0.0),
+ SCM_BOOL_T));
+
+ white_head = white_head.in_color (1, 1, 1);
+ }
+
+
+ Stencil total;
+ total.add_stencil (l);
+ total.add_stencil (white_head);
+ total.add_stencil (black_head);
+ total.translate_axis (radius, X_AXIS);
+
+ return total.smobbed_copy ();
+}
+
Interval extent (Axis) const;
Box extent_box () const;
bool is_empty () const;
+ Stencil in_color (Real r, Real g, Real b) const;
static SCM ly_get_stencil_extent (SCM mol, SCM axis);
static SCM ly_set_stencil_extent_x (SCM, SCM, SCM);
Stencil create_stencil (SCM print);
SCM find_expression_fonts (SCM expr);
+
#endif /* STENCIL_HH */
Offset to)
{
Offset dz = to -from;
- Real dx = dz[X_AXIS];
- Real dy = dz[Y_AXIS];
Real thick = Staff_symbol_referencer::line_thickness (me);
thick *= robust_scm2double (me->get_property ("thickness"), 1.0); // todo: staff sym referencer?
Real staff_space = Staff_symbol_referencer::staff_space (me);
- double w = robust_scm2double (me->get_property ("zigzag-width"), 1) * staff_space;
- double l = robust_scm2double (me->get_property ("zigzag-length"), 1) * w;
- double h = l > w / 2 ? sqrt (l * l - w * w / 4) : 0;
-
- SCM list = scm_list_n (ly_symbol2scm ("zigzag-line"),
- ly_bool2scm (true),
- scm_make_real (w),
- scm_make_real (h),
- scm_make_real (thick),
- scm_make_real (dx),
- scm_make_real (dy),
- SCM_UNDEFINED);
+ Real w = robust_scm2double (me->get_property ("zigzag-width"), 1) * staff_space;
+ int count = (int) ceil (dz.length() / w);
+ w = dz.length () / count;
+
+ Real l = robust_scm2double (me->get_property ("zigzag-length"), 1) * w;
+ Real h = l > w / 2 ? sqrt (l * l - w * w / 4) : 0;
+
+ Offset rotation_factor = complex_exp (Offset (0, dz.arg ()));
+
+ Offset points[3];
+ points[0] = Offset (0, -h/2);
+ points[1] = Offset (w/2, h/2);
+ points[2] = Offset (w, -h/2);
+ for (int i = 0; i < 3; i++)
+ points[i] = complex_multiply (points[i], rotation_factor);
+
+ Stencil squiggle (Line_interface::make_line (thick,points[0], points[1]));
+ squiggle.add_stencil (Line_interface::make_line (thick,points[1], points[2]));
+
+ Stencil total;
+ for (int i = 0; i < count; i++)
+ {
+ Stencil moved_squiggle (squiggle);
+ moved_squiggle.translate (from + Offset (i * w, 0) * rotation_factor);
+ total.add_stencil (moved_squiggle);
+ }
+
Box b;
b.add_point (Offset (0, 0));
b.add_point (dz);
b[X_AXIS].widen (thick / 2);
b[Y_AXIS].widen (thick / 2);
- return Stencil (b, list);
+ return Stencil (b, total.expr ());
}
MAKE_SCHEME_CALLBACK (Line_spanner, after_line_breaking, 1);
Stencil
Lookup::horizontal_line (Interval w, Real th)
{
- SCM at = scm_list_n (ly_symbol2scm ("horizontal-line"),
+ SCM at = scm_list_n (ly_symbol2scm ("draw-line"),
+ scm_make_real (th),
scm_make_real (w[LEFT]),
+ scm_make_real (0),
scm_make_real (w[RIGHT]),
- scm_make_real (th),
+ scm_make_real (0),
SCM_UNDEFINED);
Box box;
Stencil
Lookup::repeat_slash (Real w, Real s, Real t)
{
+#if 0
+ // TODO
+ Array<Offset> points ;
+ Real blotdiameter = 0.0;
+
+ Offset p1(0, 0);
+ Offset p2(w, w*s);
+
+
+
+ return Lookup::round_filled_polygon (points, blotdiameter);
+#endif
+
SCM wid = scm_make_real (w);
SCM sl = scm_make_real (s);
SCM thick = scm_make_real (t);
return internal_print (me, &idx).smobbed_copy ();
}
-MAKE_SCHEME_CALLBACK (Note_head, brew_ez_stencil, 1);
-SCM
-Note_head::brew_ez_stencil (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- int l = Note_head::get_balltype (me);
-
- int b = (l >= 2);
-
- SCM cause = me->get_property ("cause");
- SCM spitch = unsmob_music (cause)->get_property ("pitch");
- Pitch *pit = unsmob_pitch (spitch);
-
- SCM idx = scm_int2num (pit->get_notename ());
- SCM names = me->get_property ("note-names");
- SCM charstr = SCM_EOL;
- if (scm_is_vector (names))
- charstr = scm_vector_ref (names, idx);
- else
- {
- char s[2] = "a";
- s[0] = (pit->get_notename () + 2)%7 + 'a';
- s[0] = toupper (s[0]);
- charstr = scm_makfrom0str (s);
- }
-
- SCM at = scm_list_n (ly_symbol2scm ("ez-ball"),
- charstr,
- scm_int2num (b),
- scm_int2num (1 - b),
- SCM_UNDEFINED);
- Box bx (Interval (0, 1.0), Interval (-0.5, 0.5));
- Stencil m (bx, at);
-
- return m.smobbed_copy ();
-}
-
Real
Note_head::stem_attachment_coordinate (Grob *me, Axis a)
{
return find_expression_fonts (stil->expr ());
}
+
+LY_DEFINE (ly_stencil_in_color, "ly:stencil-in-color",
+ 4, 0, 0, (SCM stc, SCM r, SCM g, SCM b),
+ "Put @var{stc} in a different color.")
+{
+ Stencil *stil = unsmob_stencil (stc);
+ SCM_ASSERT_TYPE (stil, stc, SCM_ARG1, __FUNCTION__, "Stencil");
+ return Stencil (stil->extent_box (),
+ scm_list_3 (ly_symbol2scm ("color"),
+ scm_list_3 (r, g, b),
+ stil->expr ())).smobbed_copy ();
+}
+
+
struct Stencil_interpret_arguments
{
SCM func;
add_stencil (moved_to_edge (a, d, s, padding, minimum));
}
+
+
+Stencil
+Stencil::in_color (Real r, Real g, Real b) const
+{
+ Stencil new_stencil (extent_box (),
+ scm_list_3 (ly_symbol2scm ("color"),
+ scm_list_3 (scm_from_double (r),
+ scm_from_double (g),
+ scm_from_double (b)),
+ expr ()));
+ return new_stencil;
+}
+
/****************************************************************/
void
return fl.fonts_;
}
-
#include "lookup.hh"
#include "item.hh"
-Stencil
-System_start_delimiter::old_staff_bracket (Grob *me, Real height)
-{
- Real arc_height = scm_to_double (me->get_property ("arch-height"));
-
- SCM at = scm_list_n (ly_symbol2scm ("bracket"),
- me->get_property ("arch-angle"),
- me->get_property ("arch-width"),
- scm_make_real (arc_height),
- scm_make_real (height),
- me->get_property ("arch-thick"),
- me->get_property ("thickness"),
- SCM_UNDEFINED);
-
- /*
- TODO: sort this out.
-
- Another thing:
- In system-start-delimiter.cc I see the line
-
- Real h = height + 2 * arc_height;
-
- But I really think that you mean
-
- Real h = height + 2 * arc_width;
-
- (arc_height changes the x-axis-size of arc ; arc_width changes the
- y-axis-size)
- Will not fix it since I'm not sure.
-
- */
-
- Real h = height + 2 * arc_height;
- Box b (Interval (0, 1.5), Interval (-h / 2, h / 2));
- Stencil mol (b, at);
- mol.align_to (X_AXIS, CENTER);
- return mol;
-}
-
Stencil
verticallySpacedContexts = #'(Staff)
}
-EasyNotation = \context { %% TODO: why \context override?
- \Score
- \override NoteHead #'print-function = #Note_head::brew_ez_stencil
- \override NoteHead #'Y-extent-callback = #'()
- \override NoteHead #'X-extent-callback = #'()
-}
setEasyHeads = \sequential {
\override NoteHead #'print-function = #Note_head::brew_ez_stencil
- \override NoteHead #'Y-extent-callback = #'()
- \override NoteHead #'X-extent-callback = #'()
+ \override NoteHead #'font-size = #-7
+ \override NoteHead #'font-family = #'sans
}
aikenHeads = \set shapeNoteStyles = ##(do re mi fa #f la ti)
closepath fill
} bind def
-
-/draw_white_text % text scale font
-{
- %font
- findfont
- %scale
- exch scalefont setfont
- 1 setgray
- 0 0 moveto
- %-0.05 -0.05 moveto
- % text
- show
-} bind def
-
-/draw_ez_ball % ch letter_col ball_col font
-{
- % font
- findfont 0.7 scalefont setfont
- 0.1 setlinewidth
- 0 0 moveto
- 0 setgray
- 0.5 0 0.5 0 360 arc closepath fill stroke
- % ball_col
- 1 eq {
- 0.01 setlinewidth
- 1 setgray
- 0.5 0 0.4 0 360 arc closepath
- fill stroke
- } if
- % letter_col
- setgray
- % 0.25 is empiric centering. Change to taste
- 0.25 -0.25 moveto
- % ch
- show
-} bind def
-
-% Simple, but does it work everywhere?
-% Han-Wen reports that one printer (brand?) at cs.uu.nl chokes on this,
-% reverted for now -- jcn
-%
-% The filled circles are drawn by setting the linewidth
-% to 2*radius and drawing a point.
-/simple_draw_ez_ball % ch letter_col ball_col font
-{
- % font
- findfont 0.85 scalefont setfont
- /origin { 0.45 0 } def
- 0 setgray
- 1.1 setlinewidth
- origin moveto
- origin lineto stroke
- % ball_col
- setgray
- 0.9 setlinewidth
- origin moveto
- origin lineto stroke
- % letter_col
- setgray
- % 0.25 is empiric centering. Change to taste
- origin moveto
- -0.28 -0.30 rmoveto
- % ch
- show
-} bind def
-
% this is for drawing slurs.
/draw_bezier_sandwich % thickness controls
{
filled { fill } if
} bind def
-/draw_white_dot % x1 y2 R
-{
-% 0 360 arc fill stroke
- 0 360 arc closepath % fill stroke
-gsave
- 1 setgray fill
-grestore
-% 0 360 arc closepath % fill stroke
- 0.05 setlinewidth 0 setgray stroke
-} bind def
+
/draw_dashed_line % dash thickness dx dy
{
} bind def
-% a b c d subvec == a-c b-d
-/subvec {
- 3 2 roll exch sub
- 3 1 roll
- sub exch
-} bind def
-
-
-% centre? zzwidth zzheight thickness x0 y0 x1 y1
-/draw_zigzag_line {
- newpath
- 6 dict begin
-
- 4 2 roll % zzuw zzh th x1 y1 x0 y0
- 2 copy
- moveto
- subvec % zzuw zzh th dx dy
-
- 2 copy euclidean_length /l exch def
- l div /uy exch def
- l div /ux exch def
- setlinewidth
- /zzh exch def
- l exch div round /n exch def
- n 0 gt { %if
- /zzw l n 2 mul div def
- {
- uy zzh mul 2 div ux zzh mul -2 div rmoveto
- } if
- 1 1 n {
- ux zzw mul uy zzh mul sub
- uy zzw mul ux zzh mul add
- rlineto
- ux zzw mul uy zzh mul add
- uy zzw mul ux zzh mul sub
- rlineto
- } bind for
- }{ %else
- pop
- ux l mul uy l mul rlineto
- } ifelse
- stroke
- end
-} bind def
-
-/bracket_traject
-{
- /traject_ds exch def
- /traject_alpha exch def
- traject_ds traject_alpha sin mul add
- exch
- traject_ds traject_alpha cos mul add
- exch
-} bind def
-
-
-
-/half_bracket
-{
-%6
- 0 0
-%5a
- bracket_thick arch_height add half_height arch_thick sub arch_width add
- arch_angle arch_height -0.15 mul bracket_traject
-%5b
- bracket_thick 0.5 mul half_height
- 0 arch_height 0.5 mul bracket_traject
-%5c
- 0 half_height
-%4a
- bracket_thick half_height arch_thick sub
- 0 arch_height 0.4 mul bracket_traject
-%4b
- bracket_thick arch_height add half_height arch_thick sub arch_width add
- arch_angle arch_height -0.25 mul bracket_traject
-%4c
- bracket_thick arch_height add half_height arch_thick sub arch_width add
-%3
- bracket_thick half_height arch_thick sub
-%2
- bracket_thick 0
-%1
- 0 0
-} bind def
-
-/draw_half_bracket {
- moveto
- lineto
- lineto
- curveto
- curveto
- lineto
- gsave
- fill
- grestore
-} bind def
-
-/draw_bracket % arch_angle arch_width arch_height bracket_height arch_thick bracket_thick
-{
- % urg
-
- /bracket_thick exch def
- /arch_thick exch def
- /bracket_height exch def
- /arch_height exch def
- /arch_width exch def
- /arch_angle exch def
-
- bracket_height 2 div bracket_thick add /half_height exch def
- bracket_thick 0.5 mul setlinewidth
- 1 setlinecap
- 1 setlinejoin
- half_bracket
- 20 copy
- 1 -1 scale
- draw_half_bracket
- stroke
- 1 -1 scale
- draw_half_bracket
- stroke
-} bind def
-
%end music-drawing-routines.ps
dashed-slur
dot
draw-line
- ez-ball
filledbox
glyph-string
- horizontal-line
named-glyph
polygon
repeat-slash
(define (grob-cause offset grob)
grob)
-;; WTF is this in every backend?
-(define (horizontal-line x1 x2 thickness)
- (filledbox (- x1) (- x2 x1) (* .5 thickness) (* .5 thickness)))
(define (named-glyph font name)
(text font (ly:font-glyph-name-to-charcode font name)))
dot
white-dot
beam
- bracket
dashed-slur
char
setcolor
named-glyph
dashed-line
zigzag-line
- ez-ball
comment
repeat-slash
placebox
bezier-sandwich
- horizontal-line
embedded-ps
filledbox
round-filled-box
(ly:number->string thick)
" draw_bezier_sandwich"))
-(define (bracket arch_angle arch_width arch_height height arch_thick thick)
- (string-append
- (ly:numbers->string
- (list arch_angle arch_width arch_height height arch_thick thick))
- " draw_bracket"))
-
(define (char font i)
(string-append
(ps-font-command font) " setfont "
(define (embedded-ps string)
string)
-;; FIXME.
-(define (ez-ball ch letter-col ball-col)
- (string-append
- " (" ch ") "
- (ly:numbers->string (list letter-col ball-col))
- ;; FIXME: barf
- " /Helvetica-Bold "
- " draw_ez_ball"))
-
;; FIXME: use draw_round_box
(define (filledbox breapth width depth height)
(string-append (ly:numbers->string (list breapth width depth height))
(caddr location))
"")))))
-;; WTF is this in every backend?
-(define (horizontal-line x1 x2 th)
- (draw-line th x1 0 x2 0))
-
(define (lily-def key val)
(let ((prefix "lilypondlayout"))
(if (string=?
(define (utf8-string pango-font-description string)
(ly:warning (_ "utf8-string encountered in PS backend")))
+
+;; TODO: FIX THIS.
+;;
(define (white-dot x y radius)
(string-append
" "
(define (dashed-line thick on off dx dy)
(draw-line thick 0 0 dx dy `(style . ,(format "stroke-dasharray:~a,~a;" on off))))
-;; WTF is this in every backend?
-(define (horizontal-line x1 x2 th)
- (filledbox (- x1) (- x2 x1) (* .5 th) (* .5 th)))
-
(define (filledbox breapth width depth height)
(round-filled-box breapth width depth height 0))
(define (utf8-string pango-font-description string)
(dispatch `(fontify ,pango-font-description ,(entity 'tspan string))))
-(define (bracket arch_angle arch_width arch_height height arch_thick thick)
- ;; FIXME.
- ""
- )
dot
white-dot
beam
- bracket
dashed-slur
named-glyph
dashed-line
zigzag-line
- ez-ball
comment
repeat-slash
placebox
bezier-sandwich
- horizontal-line
filledbox
round-filled-box
text
(define (beam width slope thick blot)
(embedded-ps (list 'beam width slope thick blot)))
-(define (bracket arch_angle arch_width arch_height height arch_thick thick)
- (embedded-ps (list 'bracket arch_angle arch_width arch_height height arch_thick thick)))
-
(define (dashed-slur thick on off lst)
(embedded-ps (list 'dashed-slur thick on off `(quote ,lst))))
(define (zigzag-line centre? zzw zzh thick dx dy)
(embedded-ps (list 'zigzag-line centre? zzw zzh thick dx dy)))
-(define (ez-ball c lst b)
- (embedded-ps (list 'ez-ball c lst b)))
-
(define (embedded-ps expr)
(let ((ps-string
(with-output-to-string
(define (bezier-sandwich lst thick)
(embedded-ps (list 'bezier-sandwich `(quote ,lst) thick)))
-;; WTF is this in every backend?
-(define (horizontal-line x1 x2 th)
- (filledbox (- x1) (- x2 x1) (* .5 th) (* .5 th)))
-
(define (filledbox breapth width depth height)
(if (and #f (defined? 'ps-testing))
(embedded-ps