]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/system.cc
*** empty log message ***
[lilypond.git] / lily / system.cc
index 7ec636b7b5057b90b2ed2eea3f36f188d4f0f135..0237dbbd3f054110fc52a2e29690822b391622c2 100644 (file)
@@ -21,6 +21,7 @@
 #include "spacing-interface.hh"
 #include "staff-symbol-referencer.hh"
 #include "paper-book.hh"
+#include "paper-line.hh"
 
 System::System (SCM s)
   : Spanner (s)
@@ -55,41 +56,42 @@ scm_default_compare (const void * a, const void *b)
   SCM pa = *(SCM *)a;
   SCM pb = *(SCM *)b;
 
-  if (pa < pb) return -1 ;
-  else if (pa > pb) return 1;
-  else return 0;
+  if (pa < pb)
+    return -1;
+  else if (pa > pb)
+    return 1;
+  else
+    return 0;
 }
 
 /*
   modify L in place: sort it 
 */
-
 SCM
 uniquify_list (SCM l)
 {
   int len = scm_ilength (l);
   SCM  * arr = new SCM[len];
   int k = 0;
-  for (SCM s =; SCM_NNULLP (s); s = SCM_CDR (s))
+  for (SCM s = l; SCM_NNULLP (s); s = SCM_CDR (s))
     arr[k++] = SCM_CAR (s);
 
   assert (k == len);
   qsort (arr, len, sizeof (SCM), &scm_default_compare);
 
   k = 0;
-  SCM s =l;
+  SCM *tail = &l;
+  
   for (int i = 0; i < len ; i++)
     {
       if (i && arr[i] == arr[i-1])
        continue;
 
-      SCM_SETCAR (s, arr[i]);
-
-      if (i < len - 1)
-       s = SCM_CDR (s);
+      SCM_SETCAR (*tail, arr[i]);
+      tail = SCM_CDRLOC(*tail);
     }
 
-  SCM_SETCDR (s, SCM_EOL);
+  *tail = SCM_EOL;
   delete[] arr;
   
   return l; 
@@ -183,22 +185,15 @@ System::get_lines ()
   
    for (int i = 0; i < line_count; i++)
     {
-      System *system = dynamic_cast<System*> (broken_intos_[i]);
-
       if (verbose_global_b)
        progress_indication ("[");
 
-      // urg between-systems hack
-      bool last = (i + 1 == line_count);
-
+      System *system = dynamic_cast<System*> (broken_intos_[i]);
       system->post_processing ();
-      scm_vector_set_x (lines, scm_int2num (i), system->get_line (last));
+      scm_vector_set_x (lines, scm_int2num (i), system->get_line ());
 
       if (verbose_global_b)
-       {
-         progress_indication (to_string (i));
-         progress_indication ("]");
-       }
+       progress_indication (to_string (i) + "]");
     }
    return lines;
 }
@@ -380,7 +375,7 @@ System::post_processing ()
   /* Generate all stencils to trigger font loads.
      This might seem inefficient, but Stencils are cached per grob
      anyway. */
-  SCM all = get_property ("all-elements")  ;
+  SCM all = get_property ("all-elements");
   all = uniquify_list (all);
 
   this->get_stencil ();
@@ -391,43 +386,25 @@ System::post_processing ()
     }
 }
 
-/* Return line:
-   ((HEIGHT . WIDTH) LINE)
-   LINE: list of ((OFFSET-X . OFFSET-Y) . STENCIL)
-   Maybe make clas/smob?  */
 SCM
-System::get_line (bool is_last)
+System::get_line ()
 {  
   static int const LAYER_COUNT = 3;
-  SCM line = SCM_EOL;
-  if (Stencil *me = get_stencil ())
-    line = scm_cons (scm_cons (ly_offset2scm (Offset (0, 0)),
-                              me->smobbed_copy ()), line);
 
-  
-#ifndef PAGE_LAYOUT
-  // does not work: (\\par error) - do we really need this at all?
-  if (false && !is_last)
-    {
-      SCM lastcol = ly_car (get_property ("columns"));
-      Grob *g = unsmob_grob (lastcol);
-      
-      SCM between = ly_symbol2scm ("between-system-string");
-      SCM inter = g->internal_get_property (between);
-      if (gh_string_p (inter))
-       {
-         Stencil *stil = new Stencil (Box (), scm_list_2 (between, inter));
-         line = scm_cons (scm_cons (ly_offset2scm (Offset (0, 0)),
-                                    stil->smobbed_copy ()),
-                          line);
-       }
-    }
-#endif
+  SCM stencils = SCM_EOL;
+  if (Stencil *me = get_stencil ())
+    stencils = scm_cons (me->smobbed_copy (), stencils);
 
   /* Output stencils in three layers: 0, 1, 2.  The default layer is
-     1.  */
-  for (int i = 0; i < LAYER_COUNT; i++)
-    for (SCM s = get_property ("all-elements"); gh_pair_p (s); s = ly_cdr (s))
+     1.
+
+     Start with layer 3, since  scm_cons prepends to list.
+     
+  */
+  SCM all = get_property ("all-elements");
+  
+  for (int i = LAYER_COUNT; i--;)
+    for (SCM s = all; gh_pair_p (s); s = ly_cdr (s))
       {
        Grob *g = unsmob_grob (ly_car (s));
        Stencil *stil = g->get_stencil ();
@@ -436,20 +413,41 @@ System::get_line (bool is_last)
        if (!stil
            || robust_scm2int (g->get_property ("layer"), 1) != i)
          continue;
-       
+
        Offset o (g->relative_coordinate (this, X_AXIS),
                  g->relative_coordinate (this, Y_AXIS));
-       
+
        Offset extra = robust_scm2offset (g->get_property ("extra-offset"),
                                          Offset (0, 0))
          * Staff_symbol_referencer::staff_space (g);
-       line = scm_cons (scm_cons (ly_offset2scm (o + extra),
-                                  stil->smobbed_copy ()), line);
+
+       /*
+         must copy the stencil, for we cannot change the stencil
+         cached in G.
+       */
+       SCM my_stencil = stil->smobbed_copy ();
+       unsmob_stencil (my_stencil)->translate (o + extra);
+       stencils = scm_cons (my_stencil, stencils);
       }
 
+  if (output_format_global != PAGE_LAYOUT)
+    {
+      SCM lastcol = ly_car (get_property ("columns"));
+      Grob *g = unsmob_grob (lastcol);
+      
+      SCM between = ly_symbol2scm ("between-system-string");
+      SCM inter = g->internal_get_property (between);
+      if (gh_string_p (inter))
+       stencils = scm_cons (scm_cons (between, inter), stencils);
+    }
+
   Interval x (extent (this, X_AXIS));
   Interval y (extent (this, Y_AXIS));
-  return scm_cons (ly_offset2scm (Offset (x.length (), y.length ())), line);
+  Paper_line *pl = new Paper_line (Offset (x.length (), y.length ()),
+                                  stencils);
+
+  scm_gc_unprotect_object (pl->self_scm ());
+  return pl->self_scm ();
 }
 
 Link_array<Item> 
@@ -463,10 +461,10 @@ System::broken_col_range (Item const*l, Item const*r) const
 
   while (gh_pair_p (s) && ly_car (s) != r->self_scm ())
     s = ly_cdr (s);
-    
+
   if (gh_pair_p (s))
     s = ly_cdr (s);
-  
+
   while (gh_pair_p (s) && ly_car (s) != l->self_scm ())
     {
       Paper_column*c = dynamic_cast<Paper_column*> (unsmob_grob (ly_car (s)));