#include "font-interface.hh"
#include "math.h" // rint
-/*
- This function is a patched and hopefully much more understandable
- rewrite of Note_head::ledger_line (). It still has some
- bugs/limitations:
- *
- (1) The term thick/2 probably should be thick*2 (probably a bug,
- see the code below).
- *
- (2) The minimal width of the resulting ledger line equals the width
- of the noteheads-ledgerending symbol (a limitation):
- *
- (---- left ledger ending
- ----) right ledger ending
- (---) resulting ledger line (just ok)
- *
- If x_extent ("xwid" in Note_head) is less than the width of the
- ledger ending, the width of the total ledger line is even *greater*
- than the width of a ledger ending (I would call this a bug). In
- the below code, the condition "if (x_extent.length () >
- slice_x_extent.length ())" avoids outputting the left ending in such
- cases (rather a silly workaround, but better than nothing).
- *
- (---- left ledger ending
- ----) right ledger ending
- (-) desired ledger line
- ------- resulting ledger line (too long)
- ----) resulting ledger line with additional "if" (still too long)
- *
- The algorithm works properly only for a desired ledger line width
- greater than the width of the ledger ending:
- *
- (---- left ledger ending
- ----) right ledger ending
- (------) desired ledger line
- (------) resulting ledger line (ok)
- *
- * (3) The thickness of the ledger line is fixed (limitation).
- */
-Molecule
-Custos::create_ledger_line (Interval x_extent, Grob *me)
-{
- Molecule line;
- Molecule slice = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending");
- Interval slice_x_extent = slice.extent (X_AXIS);
- Interval slice_y_extent = slice.extent (Y_AXIS);
-
- // Create left ending of ledger line.
- Molecule left_ending = slice;
- left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS);
- if (x_extent.length () > slice_x_extent.length ())
- line.add_molecule (left_ending);
-
- // Create right ending of ledger line.
- Molecule right_ending = slice;
- right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT],
- X_AXIS);
- line.add_molecule (right_ending);
-
- // Fill out space between left and right ending of ledger line by
- // lining up a series of slices in a row between them.
- Molecule fill_out_slice = left_ending;
- Real thick = slice_y_extent.length ();
- Real delta_x = slice_x_extent.length () - thick;
- Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2?
- while (xpos <= x_extent[RIGHT])
- {
- fill_out_slice.translate_axis (delta_x, X_AXIS);
- line.add_molecule (fill_out_slice);
- xpos += delta_x;
- }
-
- return line;
-}
-
-void
-Custos::add_streepjes (Grob* me,
- int pos,
- int interspaces,
- Molecule* custos_p_)
-{
- // TODO: This is (almost) duplicated code (see
- // Note_head::brew_molecule). Junk me.
- Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
- int streepjes_i = abs (pos) < interspaces
- ? 0
- : (abs (pos) - interspaces) /2;
- if (streepjes_i)
- {
- Direction dir = (Direction)sign (pos);
- Molecule ledger_line (create_ledger_line (custos_p_->extent (X_AXIS),
- me));
- ledger_line.set_empty (true);
- Real offs = (Staff_symbol_referencer::on_staffline (me))
- ? 0.0
- : -dir * inter_f;
- for (int i = 0; i < streepjes_i; i++)
- {
- Molecule streep (ledger_line);
- streep.translate_axis (-dir * inter_f * i * 2 + offs,
- Y_AXIS);
- custos_p_->add_molecule (streep);
- }
- }
-}
-
MAKE_SCHEME_CALLBACK (Custos,brew_molecule,1);
SCM
Custos::brew_molecule (SCM smob)
String style = ly_scm2string (scm_symbol_to_string (scm_style));
/*
- DOCME:
-
- Why would we want it differently? What's the meaning of adjust ?
+ * Shall we use a common custos font character regardless if on
+ * staffline or not, or shall we use individual font characters
+ * for both cases?
*/
bool adjust =
to_boolean (me->get_grob_property ("adjust-if-on-staffline"));
}
else
{
- add_streepjes (me, (int)pos, sz, &molecule);
- return molecule.smobbed_copy ();
+ // add ledger lines
+ int pos = (int)rint (Staff_symbol_referencer::position_f (me));
+ int interspaces = Staff_symbol_referencer::line_count (me)-1;
+ if (abs (pos) - interspaces > 1)
+ {
+ Molecule ledger_lines =
+ Note_head::brew_ledger_lines (me, pos, interspaces,
+ molecule.extent (X_AXIS), true);
+ molecule.add_molecule (ledger_lines);
+ }
+ return molecule.smobbed_copy ();
}
}
else
return m && m->has_interface (ly_symbol2scm ("custos-interface"));
}
-
ADD_INTERFACE (Custos, "custos-interface",
"A custos is a staff context symbol that appears at the end of a
staff line with monophonic musical contents (i.e. with a single
static Molecule bracket (Axis a, Interval iv, Direction d, Real thick, Real protude);
static Molecule accordion (SCM arg, Real interline_f, Font_metric*fm);
static Molecule frame (Box b, Real thick);
- static Molecule slur (Bezier controls, Real cthick, Real thick) ;
- static Molecule bezier_sandwich (Bezier, Bezier);
- static Molecule horizontal_slope (Real, Real, Real);
- static Molecule beam (Real, Real, Real) ;
- static Molecule dashed_slur (Bezier, Real thick, Real dash) ;
- static Molecule blank (Box b) ;
- static Molecule filledbox (Box b) ;
- static Molecule repeat_slash( Real w, Real slope, Real th);
+ static Molecule slur (Bezier controls, Real cthick, Real thick);
+ static Molecule bezier_sandwich (Bezier top_curve, Bezier bottom_curve);
+ static Molecule horizontal_slope (Real width, Real slope, Real height);
+ static Molecule beam (Real slope, Real width, Real thick);
+ static Molecule dashed_slur (Bezier, Real thick, Real dash);
+ static Molecule blank (Box b);
+ static Molecule filledbox (Box b);
+ static Molecule roundfilledbox (Box b, Real blotdiameter);
+ static Molecule repeat_slash (Real w, Real slope, Real th);
};
#endif // LOOKUP_HH
{
public:
DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
- static Interval head_extent (Grob*,Axis);
- static Molecule ledger_lines (Grob*, bool, int,Direction,Interval);
- static Molecule ledger_line ( Grob*, Interval);
+ static Interval head_extent (Grob*, Axis);
+ static Molecule brew_ledger_lines (Grob *me, int pos, int interspaces,
+ Interval x_extent, bool take_space);
DECLARE_SCHEME_CALLBACK (brew_ez_molecule, (SCM ));
static bool has_interface (Grob*);
static Real stem_attachment_coordinate (Grob *, Axis a);
return Molecule (b, at);
}
-
Molecule
Lookup::dashed_slur (Bezier b, Real thick, Real dash)
{
return Molecule (b, SCM_EOL);
}
-
Molecule
Lookup::filledbox (Box b)
{
return Molecule (b,at);
}
+/*
+ * round filled box:
+ *
+ * __________________________
+ * / \ ^ / \
+ * | |blot |
+ * | + | |dia | +---|------
+ * | |meter | ^
+ * |\ _ _ / v \ _ _ /| |
+ * | | |
+ * | | | Box
+ * | <------>| | extent
+ * | blot | | (Y_AXIS)
+ * | diameter| |
+ * | | |
+ * | _ _ _ _ | |
+ * |/ \ / \| |
+ * | (0,0) | v
+ * | x | | +---|------
+ * | | | |
+ * \__|__/______________\__|__/
+ * | |
+ * | |
+ * | |
+ * |<------------------>|
+ * Box extent(X_AXIS)
+ */
+Molecule
+Lookup::roundfilledbox (Box b, Real blotdiameter)
+{
+ SCM at = (scm_list_n (ly_symbol2scm ("roundfilledbox"),
+ gh_double2scm (-b[X_AXIS][LEFT]),
+ gh_double2scm (b[X_AXIS][RIGHT]),
+ gh_double2scm (-b[Y_AXIS][DOWN]),
+ gh_double2scm (b[Y_AXIS][UP]),
+ gh_double2scm (blotdiameter),
+ SCM_UNDEFINED));
+
+ return Molecule (b,at);
+}
Molecule
Lookup::frame (Box b, Real thick)
}
-
/*
Make a smooth curve along the points
*/
return Molecule (b, slashnodot); // http://slashnodot.org
}
-
-
Molecule
Lookup::bracket (Axis a, Interval iv, Direction d, Real thick, Real protude)
{
#include "bezier.hh"
#include "font-interface.hh"
#include "paper-def.hh"
+#include "note-head.hh"
#include "math.h" // rint
void
}
}
-// Uugh. The following two functions are almost duplicated code from
-// custos.cc, which itself is similar to code in note-head.cc. Maybe
-// this should be moved to staff-symbol-referencer.cc?
-Molecule
-Porrectus::create_ledger_line (Interval x_extent, Grob *me)
-{
- Molecule line;
- Molecule slice = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending");
- Interval slice_x_extent = slice.extent (X_AXIS);
- Interval slice_y_extent = slice.extent (Y_AXIS);
-
- // Create left ending of ledger line.
- Molecule left_ending = slice;
- left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS);
- if (x_extent.length () > slice_x_extent.length ())
- line.add_molecule (left_ending);
-
- // Create right ending of ledger line.
- Molecule right_ending = slice;
- right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT],
- X_AXIS);
- line.add_molecule (right_ending);
-
- // Fill out space between left and right ending of ledger line by
- // lining up a series of slices in a row between them.
- Molecule fill_out_slice = left_ending;
- Real thick = slice_y_extent.length ();
- Real delta_x = slice_x_extent.length () - thick;
- Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2?
- while (xpos <= x_extent[RIGHT])
- {
- fill_out_slice.translate_axis (delta_x, X_AXIS);
- line.add_molecule (fill_out_slice);
- xpos += delta_x;
- }
-
- return line;
-}
-
-Molecule
-Porrectus::create_streepjes (Grob *me,
- int pos,
- int interspaces,
- Interval extent)
-{
- Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
- int streepjes_i = abs (pos) < interspaces
- ? 0
- : (abs (pos) - interspaces) /2;
- Molecule molecule = Molecule();
- if (streepjes_i)
- {
- Direction dir = (Direction)sign (pos);
- Molecule ledger_line (create_ledger_line (extent, me));
- ledger_line.set_empty (true);
- Real offs = (Staff_symbol_referencer::on_staffline (me, pos))
- ? 0.0
- : -dir * inter_f;
- for (int i = 0; i < streepjes_i; i++)
- {
- Molecule streep (ledger_line);
- streep.translate_axis (-dir * inter_f * i * 2 + offs,
- Y_AXIS);
- molecule.add_molecule (streep);
- }
- }
- return molecule;
-}
-
MAKE_SCHEME_CALLBACK (Porrectus,brew_molecule,1);
SCM
Porrectus::brew_molecule (SCM smob)
bool add_stem = to_boolean (me->get_grob_property ("add-stem"));
/*
-
- TODO:
-
- ugr. why not called direction?
-
+ * This property is called stem-direction (rather than direction)
+ * since it only refers to this grob's stem (or, more precisely, its
+ * "cauda"), but not the grob as a whole.
*/
SCM stem_direction_scm = me->get_grob_property ("direction");
Direction stem_direction =
if (!stem_direction)
stem_direction = DOWN;
-
/*
TODO: revise name.
*/
molecule.translate_axis (left_position_f * space/2, Y_AXIS);
- Molecule left_head_streepjes =
- create_streepjes (me, (int)rint (left_position_f), interspaces, extent);
- left_head_streepjes.translate_axis (left_position_f * space/2, Y_AXIS);
- molecule.add_molecule (left_head_streepjes);
+ int left_pos = (int)rint (left_position_f);
+ if (abs (left_pos) - interspaces > 1)
+ {
+ Molecule left_head_ledger_lines =
+ Note_head::brew_ledger_lines (me, left_pos, interspaces, extent, true);
+ left_head_ledger_lines.translate_axis (left_position_f * space/2,
+ Y_AXIS);
+ molecule.add_molecule (left_head_ledger_lines);
+ }
- Molecule right_head_streepjes =
- create_streepjes (me, (int)rint (right_position_f), interspaces, extent);
- right_head_streepjes.translate_axis (right_position_f * space/2, Y_AXIS);
- molecule.add_molecule (right_head_streepjes);
+ int right_pos = (int)rint (right_position_f);
+ if (abs (right_pos) - interspaces > 1)
+ {
+ Molecule right_head_ledger_lines =
+ Note_head::brew_ledger_lines (me, right_pos, interspaces, extent, true);
+ right_head_ledger_lines.translate_axis (right_position_f * space/2,
+ Y_AXIS);
+ molecule.add_molecule (right_head_ledger_lines);
+ }
return molecule.smobbed_copy();
}
ADD_INTERFACE (Porrectus,"porrectus-interface",
"A porrectus ligature, joining two note heads into a single grob.",
"left-head right-head width add-stem auto-properties solid direction");
-
(if (<= dy 1) "-" "="))
(func "h-line" dx))))))
+(define (roundfilledbox breapth width depth height)
+ (filledbox breapth width depth height))
+
(define (font-load-command name-mag command)
;; (display "name-mag: ")
;; (write name-mag)
(ly-number->string (+ depth height))
" re f "))
+;; TODO:
+;;
+;;(define (dot x y diam)
+;; (let (radius (/ diam 2))
+;; (string-append (ly-number->string (x))
+;; (ly-number->string (y))
+;; (ly-number->string (radius))
+;; " ??? "))) ;; how to draw a circle in PDF?
+;;
+;;(define (roundfilledbox x width y height blotdiam)
+;; (string-append " "
+;; (dot x y blotdiam)
+;; (dot (+ x width) y blotdiam)
+;; (dot (+ x width) (+ y height) blotdiam)
+;; (dot x (+ y height) blotdiam)
+;; (filledbox (+ x (/ blotdiam 2)) (+ width (/ blotdiam 2)) y height)
+;; (filledbox x width (+ y (/ blotdiam 2)) (+ height (/ blotdiam 2)))))
+;;
+;;
+;; WORKAROUND:
+;;
+ (define (roundfilledbox breadth width depth height)
+ (filledbox breadth width depth height))
+;;
+
(define (font-def i s) "")
(define (font-switch i) "")
(define end-output ,end-output)
(define experimental-on ,experimental-on)
(define filledbox ,filledbox)
+ (define roundfilledbox ,roundfilledbox)
(define font-def ,font-def)
(define font-switch ,font-switch)
(define header-end ,header-end)
((eq? action-name 'experimental-on) experimental-on)
((eq? action-name 'ez-ball) ez-ball)
((eq? action-name 'filledbox) filledbox)
+ ((eq? action-name 'roundfilledbox) roundfilledbox)
((eq? action-name 'repeat-slash) repeat-slash)
((eq? action-name 'select-font) select-font)
((eq? action-name 'volta) volta)
"depth " (number->dim depth)
"height " (number->dim height) " "))
+ (define (roundfilledbox x width y height blotdiam)
+ (embedded-pdf ((pdf-scm 'roundfilledbox) x width y height blotdiam)))
+
(define (text s)
(string-append "\\hbox{" (output-tex-string s) "}"))
(string-append (numbers->string (list breapth width depth height))
" draw_box" ))
+(define (dot x y radius)
+ (string-append " "
+ (numbers->string
+ (list x y radius)) " draw_dot"))
+
+(define (roundfilledbox x width y height blotdiam)
+ (string-append " "
+ (dot (- 0 x) (- 0 y) (/ blotdiam 2))
+ (dot width (- 0 y) (/ blotdiam 2))
+ (dot width height (/ blotdiam 2))
+ (dot (- 0 x) height (/ blotdiam 2))
+ (filledbox (+ x (/ blotdiam 2)) (+ width (/ blotdiam 2)) y height)
+ (filledbox x width (+ y (/ blotdiam 2)) (+ height (/ blotdiam 2)))))
+
;; obsolete?
(define (font-def i s)
(string-append
; TODO: use HEIGHT argument
-
-(define (start-line height)
+ (define (start-line height)
(string-append
"\n"
(ly-number->string height)
"depth " (number->dim depth)
"height " (number->dim height) " ")))
+(define (roundfilledbox x y width height blotdiam)
+ (embedded-ps (list 'roundfilledbox x y width height blotdiam)))
+
(define (text s)
(string-append "\\hbox{" (output-tex-string s) "}"))