]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/accidental-placement.cc (position_accidentals): document
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 21 Jul 2002 23:19:19 +0000 (23:19 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 21 Jul 2002 23:19:19 +0000 (23:19 +0000)
two bugcases.

* lily/skyline.cc (skyline_meshing_distance): bugfixes.

ChangeLog
input/regression/accidental-placement.ly
lily/accidental-placement.cc
lily/accidental.cc
lily/include/accidental-interface.hh [new file with mode: 0644]
lily/skyline.cc
mf/feta-toevallig.mf

index c37fee04841b0db0d40a66c99b8d4da43093985b..edcfb73721be08280870df0a1a2d4ce76ff10031 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+
+2002-07-22  Han-Wen  <hanwen@cs.uu.nl>
+
+       * lily/accidental-placement.cc (position_accidentals): document
+       two bugcases.
+
+       * lily/skyline.cc (skyline_meshing_distance): bugfixes.
+
 2002-07-22  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * scripts/lilypond-book.py (make_pixmap): Don't use quiet_system,
@@ -11,6 +19,9 @@
 
 2002-07-21  Han-Wen  <hanwen@cs.uu.nl>
 
+       * lily/accidental.cc (accurate_boxes): add function to represent
+       flat with 2 boxes. Improves flat-flat accidental spacing. 
+
        * lily/accidental-placement.cc (stagger_apes): try to arrange accs
        in a C form, with the top accidental closet to the chord.
 
index 6011fcc201ae88b2da723fb6ba747afd7ef426a7..ce86f02981b4334fffeb773defa628cbad419fa3 100644 (file)
@@ -13,7 +13,7 @@ flats in a sixth shoudl be staggered.  "
   <bis4 es gis>
   <es! as!>
   <gis! cis!>
-  <g! des!>
+  <g! des'>
   <ges! es'!>
 }    
     <cis4 d es fis gis ases bes ces d dis >
index 1f102415c5f9538b66080bd6690870111171810d..eae952d0eb9517df093d945fea630143031320a1 100644 (file)
@@ -18,6 +18,7 @@ source file of the GNU LilyPond music typesetter
 #include "note-column.hh"
 #include "group-interface.hh"
 #include "note-collision.hh"
+#include "accidental-interface.hh"
 
 MAKE_SCHEME_CALLBACK(Accidental_placement,extent_callback, 2);
 SCM
@@ -186,11 +187,9 @@ stagger_apes (Link_array<Accidental_placement_entry> *apes)
    The naturals should be left of the C as well; they should
    be separate accs.
 
-   TODO: Try to combine Apes before sorting them: this will allow a
-   better placement.
+   Note that this placement problem looks NP hard, so we just use a
+   simple strategy, not an optimal choice.
 
-   Note that this placement problem is almost certainly NP hard, so we
-   just use a simple strategy, not an optimal choice.
 */
 
 SCM
@@ -198,6 +197,10 @@ Accidental_placement::position_accidentals (Grob * me)
 {
   SCM accs = me->get_grob_property ("accidentals");
 
+  /*
+    TODO: there is a bug in this code. If two accs are on the same
+    Y-position, they share an Ape, and will be pritned in overstrike.
+   */
   Link_array<Accidental_placement_entry> apes;
   for (SCM s = accs; gh_pair_p (s); s =gh_cdr (s))
     {
@@ -211,7 +214,7 @@ Accidental_placement::position_accidentals (Grob * me)
     }
 
 
-  Grob *commony =0 ;
+  Grob *common[] = {me, 0};
 
   /*
     First we must extract *all* pointers. We can only determine
@@ -224,8 +227,12 @@ Accidental_placement::position_accidentals (Grob * me)
       for (int j = ape->grobs_.size(); j--;)
        {
          Grob * a = ape->grobs_[j];
+
+         if (common[Y_AXIS])
+           common[Y_AXIS] = common[Y_AXIS]->common_refpoint (a, Y_AXIS);
+         else
+           common[Y_AXIS] = a;
          
-         commony = commony->common_refpoint (a, Y_AXIS);
          Grob *head = a->get_parent (Y_AXIS);
 
          Grob * col = head->get_parent (X_AXIS);
@@ -261,7 +268,7 @@ Accidental_placement::position_accidentals (Grob * me)
     }
   heads.default_sort();
   heads.uniq();
-  commony = common_refpoint_of_array (heads, commony, Y_AXIS);
+  common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS);
 
   
   for (int i= apes.size (); i--;)
@@ -273,18 +280,15 @@ Accidental_placement::position_accidentals (Grob * me)
       for (int j = apes[i]->grobs_.size(); j--;)
        {
          Grob * a = apes[i]->grobs_[j];
-         Box b;
-         b[X_AXIS] = a->extent (me, X_AXIS);
-         b[Y_AXIS] = a->extent (commony, Y_AXIS);
 
-         ape->extents_.push (b);
+         Array<Box> boxes = Accidental_interface::accurate_boxes (a, common);
          
-         /*
-           TODO: replace the extents of a flat by combination of two
-           bboxes, so that we use the shape of the flat better.
-         */
-         insert_extent_into_skyline (&ape->left_skyline_, b, Y_AXIS, LEFT);
-         insert_extent_into_skyline (&ape->right_skyline_ , b,Y_AXIS, RIGHT);
+         ape->extents_.concat (boxes);
+         for (int j  = boxes.size(); j--;)
+           {
+             insert_extent_into_skyline (&ape->left_skyline_, boxes[j], Y_AXIS, LEFT);
+             insert_extent_into_skyline (&ape->right_skyline_ , boxes[j], Y_AXIS, RIGHT);
+           }
        }
     }
 
@@ -305,13 +309,13 @@ Accidental_placement::position_accidentals (Grob * me)
   stagger_apes (&apes);
 
   Accidental_placement_entry * head_ape = new Accidental_placement_entry;
-  Grob *commonx = common_refpoint_of_array (heads, me, X_AXIS);  
+  common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS);  
   Array<Skyline_entry> head_skyline (empty_skyline (LEFT));
   Array<Box> head_extents;
   for (int i = heads.size(); i--;)
     {
-      Box b(heads[i]->extent (commonx, X_AXIS),
-           heads[i]->extent (commony, Y_AXIS));
+      Box b(heads[i]->extent (common[X_AXIS] , X_AXIS),
+           heads[i]->extent (common[Y_AXIS], Y_AXIS));
 
       insert_extent_into_skyline (&head_skyline, b , Y_AXIS, LEFT);
     }
@@ -328,7 +332,19 @@ Accidental_placement::position_accidentals (Grob * me)
   SCM spad = me->get_grob_property ("padding");
   if (gh_number_p (spad))
     padding = gh_scm2double (spad);
-  
+
+
+  /*
+    TODO:
+
+    There is a bug in this code: the left_skylines should be
+    accumulated, otherwise the b will collide with bb in
+
+      bb
+    b 
+      n 
+    
+   */
   apes.push (head_ape);
   for (int i= apes.size () -1 ; i-- > 0;)
     {
index 3792933d873599d6c734dabc1d1fccdb6f8dbfa8..39d43277c4f48dab22fb7b6000d2508e4b95665b 100644 (file)
@@ -1,6 +1,7 @@
 #include "font-interface.hh"
 #include "item.hh"
 #include "molecule.hh"
+#include "accidental-interface.hh"
 
 /*
   TODO: insert support for smaller cautionaries, tie-break-reminders.
   accidental-placement.cc
 
 */
-class Accidental_interface
-{
-public:
-  DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM));
-  DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));  
-  static bool has_interface (Grob*);
-};
+
 
 Molecule
 parenthesize (Grob*me, Molecule m)
@@ -43,7 +38,63 @@ Accidental_interface::after_line_breaking (SCM smob)
     }
   return SCM_UNSPECIFIED;
 }
+
+Array<Box>
+Accidental_interface::accurate_boxes (Grob *a,Grob**common)
+{
+  Box b;
+  b[X_AXIS] = a->extent (a, X_AXIS);
+  b[Y_AXIS] = a->extent (a, Y_AXIS);
+
+  Array<Box> boxes;
+  
+  bool parens = false;
+  if (to_boolean (a->get_grob_property ("cautionary")))
+    {
+      SCM cstyle = a->get_grob_property ("cautionary-style");
+      parens = gh_equal_p (cstyle, ly_symbol2scm ("parentheses"));
+
+    }
+
+  SCM accs = a->get_grob_property ("accidentals");
+  SCM scm_style = a->get_grob_property ("style");
+  if (!gh_symbol_p (scm_style)
+      && !parens
+      && scm_ilength (accs) == 1)
+    {
+      if (gh_scm2int (gh_car (accs)) == -1)
+       {
+         Box stem = b;
+         Box bulb = b;
+
+         /*
+           we could make the stem thinner, but that places the flats
+           really close.
+         */
+         stem[X_AXIS][RIGHT] *= .5;
+         bulb[Y_AXIS][UP] *= .35;
+
+         boxes.push (bulb);
+         boxes.push (stem);
+       }
+      /*
+       TODO: add support for natural, double flat.
+       */
+    }
+
+  if (!boxes.size())
+    boxes.push (b);
+
+  Offset o (a->relative_coordinate (common[X_AXIS],  X_AXIS),
+           a->relative_coordinate (common[Y_AXIS],  Y_AXIS));
+  for(int i = boxes.size(); i--;)
+    {
+      boxes[i].translate(o);
+    }
   
+  return boxes;
+}
+
 MAKE_SCHEME_CALLBACK (Accidental_interface,brew_molecule,1);
 SCM
 Accidental_interface::brew_molecule (SCM smob)
diff --git a/lily/include/accidental-interface.hh b/lily/include/accidental-interface.hh
new file mode 100644 (file)
index 0000000..c2dd022
--- /dev/null
@@ -0,0 +1,26 @@
+/*   
+accidental-interface.hh -- declare  Accidental_interface
+
+source file of the GNU LilyPond music typesetter
+
+(c) 2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#ifndef ACCIDENTAL_INTERFACE_HH
+#define ACCIDENTAL_INTERFACE_HH
+
+#include "grob.hh"
+
+class Accidental_interface
+{
+public:
+  DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM));
+  DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));  
+  static bool has_interface (Grob*);
+  
+  static Array<Box> Accidental_interface::accurate_boxes (Grob *me,Grob**common);
+};
+
+
+#endif
index 9857fe495506ac089005ec9054a897e1203eb151..5fa51eed62ba3e9acc45d48e3b3b22849af14d43 100644 (file)
@@ -38,6 +38,8 @@
  */
 
 
+const Real EPS = 1e-12;  
+
 /*
   TODO: avoid unnecessary fragmentation.
 
@@ -53,27 +55,33 @@ insert_extent_into_skyline (Array<Skyline_entry> *line, Box b, Axis line_axis,
     return;
   
   Real stick_out = b[other_axis (line_axis)][d];
-  
+
+  /*
+    Intersect each segment of LINE with EXTENT, and if non-empty, insert relevant segments. 
+   */
   for (int i = line->size(); i--;)
     {
       Interval w = line->elem(i).width_;
-      if (extent[LEFT] > w[RIGHT])
+      w.intersect (extent);
+
+      if (extent[LEFT] >= w[RIGHT])
        break;
       
-      w.intersect (extent);
       Real my_height = line->elem(i).height_;
 
-      if (!w.empty_b () && d* (my_height - stick_out) < 0)
+      if (!w.empty_b () &&
+         w.length() > EPS
+         && d* (my_height - stick_out) < 0)
        {
          Interval e1 (line->elem(i).width_[LEFT], extent[LEFT]);
          Interval e3 (extent[RIGHT], line->elem(i).width_[RIGHT]);
 
-         if (!e3.empty_b ())
+         if (!e3.empty_b () && e3.length() > EPS)
            line->insert (Skyline_entry (e3, my_height), i+1);
 
          line->elem_ref(i).height_ = stick_out;
          line->elem_ref(i).width_ = w;
-         if (!e1.empty_b ())
+         if (!e1.empty_b () && e1.length() > EPS)
            line->insert (Skyline_entry (e1, my_height), i );
        }
 
index 3363568582ce60ac246369f97ee4fe13918088d8..b9e2b48fab06e24f99020da18f743cbb9d93756c 100644 (file)
@@ -261,7 +261,7 @@ fet_beginchar("Double Flat", "-2", "flatflat")
        left_wid = .7;
        right_wid = .8;
        overlap = .05;
-       set_char_box(1.2 stafflinethickness#, (left_wid + right_wid -overlap) *staff_space#, .5 staff_space#, 2 staff_space#);
+       set_char_box(1.2 stafflinethickness#, (left_wid + right_wid -overlap) *staff_space#, .6 staff_space#, 2 staff_space#);
        draw_meta_flat(0, left_wid*  staff_space, 1/3 staff_space);
        draw_meta_flat((left_wid - overlap) *staff_space,  
                right_wid *staff_space, 1/3 staff_space);