]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/stencil-integral.cc
Merge branch 'translation' into staging
[lilypond.git] / lily / stencil-integral.cc
index d8509a6286c3cf6d3fbab5df7eeab9b4478e7035..4ae14e4609a361b95170859d997a20200187ed01 100644 (file)
@@ -50,10 +50,12 @@ when this transforms a point (x,y), the point is written as matrix:
 #include "pointer-group-interface.hh"
 #include "lily-guile.hh"
 #include "real.hh"
+#include "rest.hh"
 #include "stencil.hh"
 #include "string-convert.hh"
 #include "skyline.hh"
 #include "skyline-pair.hh"
+#include "spanner.hh"
 using namespace std;
 
 Real QUANTIZATION_UNIT = 0.2;
@@ -192,12 +194,11 @@ make_draw_line_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings
   do
     {
       Offset inter_l = get_point_in_y_direction (left, perpendicular_slope (slope), thick / 2, d);
-      Offset inter_r = get_point_in_y_direction (right, perpendicular_slope (slope), thick / 2, d);//printf ("O %4.4f %4.4f\n", inter_l[X_AXIS], inter_r[X_AXIS]);printf ("TRANNY %4.4f %4.4f %4.4f %4.4f %4.4f %4.4f\n", trans.xx, trans.xy, trans.yx, trans.yy, trans.x0, trans.y0);
+      Offset inter_r = get_point_in_y_direction (right, perpendicular_slope (slope), thick / 2, d);
       pango_matrix_transform_point (&trans, &inter_l[X_AXIS], &inter_l[Y_AXIS]);
       pango_matrix_transform_point (&trans, &inter_r[X_AXIS], &inter_r[Y_AXIS]);
       if ((inter_l[X_AXIS] == inter_r[X_AXIS]) || (inter_l[Y_AXIS] == inter_r[Y_AXIS]))
         {
-          //printf ("OO %4.4f %4.4f\n", inter_l[X_AXIS], inter_r[X_AXIS]);
           Box b;
           b.add_point (inter_l);
           b.add_point (inter_r);
@@ -288,7 +289,7 @@ make_partial_ellipse_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &bui
   int quantization = max (1, (int) (((x_rad * trans.xx) + (y_rad * trans.yy)) * M_PI / QUANTIZATION_UNIT));
   do
     {
-      for (vsize i = 0; i < 1 + quantization; i++)
+      for (vsize i = 0; i < 1 + (vsize) quantization; i++)
         {
           Real ang = linear_map (start, end, 0, quantization, i);
           complex<Real> coord = polar (1.0, ang);
@@ -451,7 +452,7 @@ make_draw_bezier_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildin
       Offset first = get_point_in_y_direction (curve.control_[0], perpendicular_slope (curve.slope_at_point (0.0)), th / 2, d);
       pango_matrix_transform_point (&trans, &first[X_AXIS], &first[Y_AXIS]);
       points[d].push_back (first);
-      for (vsize i = 1; i < quantization; i++)
+      for (vsize i = 1; i < (vsize) quantization; i++)
         {
           Real pt = (i * 1.0) / quantization;
           Offset inter = get_point_in_y_direction (curve.curve_point (pt), perpendicular_slope (curve.slope_at_point (pt)), th / 2, d);
@@ -946,11 +947,14 @@ stencil_traverser (PangoMatrix trans, SCM expr)
       return stencil_traverser (trans, scm_caddr (expr));
     }
   else if (scm_car (expr) == ly_symbol2scm ("delay-stencil-evaluation"))
-    return stencil_traverser (trans, scm_force (scm_cadr (expr)));
+    // should not use the place-holder text, but no need for the warning below
+    return vector<Transform_matrix_and_expression> ();
   else if (scm_car (expr) == ly_symbol2scm ("grob-cause"))
     return stencil_traverser (trans, scm_caddr (expr));
   else if (scm_car (expr) == ly_symbol2scm ("color"))
     return stencil_traverser (trans, scm_caddr (expr));
+  else if (scm_car (expr) == ly_symbol2scm ("transparent-stencil"))
+    return stencil_traverser (trans, scm_cadr (expr));
   else if (scm_car (expr) == ly_symbol2scm ("id"))
     return stencil_traverser (trans, scm_caddr (expr));
   else
@@ -964,38 +968,69 @@ stencil_traverser (PangoMatrix trans, SCM expr)
 }
 
 SCM
-Grob::internal_simple_skylines_from_stencil (SCM smob, Axis a)
+Grob::maybe_pure_internal_simple_skylines_from_extents (Grob *me, Axis a, bool pure, int beg, int end, bool ignore_x, bool ignore_y)
 {
-  Grob *me = unsmob_grob (smob);
-
-  if (to_boolean (me->get_property ("cross-staff")))
+  vector<Box> boxes;
+  // we don't know how far spanners stretch along the X axis before
+  // line breaking. better have them take up the whole thing
+  Interval xex = ignore_x
+                 ? Interval (-infinity_f, infinity_f)
+                 : me->extent (me, X_AXIS);
+
+  // If we're looking at the x exent of a cross staff grob, it could be
+  // very early on in the computation process.  We won't know its height
+  // until way later, so we give a brute force approximation.
+  Interval yex = ignore_y
+                 ? Interval (-infinity_f, infinity_f)
+                 : me->maybe_pure_extent (me, Y_AXIS, pure, beg, end);
+
+  if (xex.is_empty () || yex.is_empty ())
     return Skyline_pair ().smobbed_copy ();
 
-  extract_grob_set (me, "elements", elts);
-  if (elts.size ())
-    return internal_skylines_from_element_stencils (smob, a);
+  boxes.push_back (Box (xex, yex));
+  return Skyline_pair (boxes, a).smobbed_copy ();
+}
 
-  Stencil *s = unsmob_stencil (me->get_property ("stencil"));
-  if (!s)
-    return Skyline_pair ().smobbed_copy ();
+MAKE_SCHEME_CALLBACK (Grob, pure_simple_vertical_skylines_from_extents, 3);
+SCM
+Grob::pure_simple_vertical_skylines_from_extents (SCM smob, SCM begscm, SCM endscm)
+{
+  Grob *me = unsmob_grob (smob);
+  int beg = robust_scm2int (begscm, 0);
+  int end = robust_scm2int (endscm, INT_MAX);
+  // We cannot measure the widths before line breaking,
+  // so we assume that the width is infinite: pass ignore_x=true
+  return maybe_pure_internal_simple_skylines_from_extents (me, X_AXIS, true, beg, end, true, false);
+}
 
-  vector<Box> boxes;
-  boxes.push_back (Box (s->extent (X_AXIS), s->extent (Y_AXIS)));
-  return Skyline_pair (boxes, a).smobbed_copy ();
+MAKE_SCHEME_CALLBACK (Grob, simple_vertical_skylines_from_extents, 1);
+SCM
+Grob::simple_vertical_skylines_from_extents (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  return maybe_pure_internal_simple_skylines_from_extents (me, X_AXIS, false, 0, 0, false, false);
 }
 
-MAKE_SCHEME_CALLBACK (Grob, simple_vertical_skylines_from_stencil, 1);
+MAKE_SCHEME_CALLBACK (Grob, pure_simple_horizontal_skylines_from_extents, 3);
 SCM
-Grob::simple_vertical_skylines_from_stencil (SCM smob)
+Grob::pure_simple_horizontal_skylines_from_extents (SCM smob, SCM begscm, SCM endscm)
 {
-  return internal_simple_skylines_from_stencil (smob, X_AXIS);
+  Grob *me = unsmob_grob (smob);
+  int beg = robust_scm2int (begscm, 0);
+  int end = robust_scm2int (endscm, INT_MAX);
+  // If the grob is cross staff, we cannot measure its Y-extent before
+  // wayyyy downstream (after spacing of axis groups is done).
+  // Thus, we assume that the Y extent is infinite for cross staff grobs.
+  return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, true, beg, end, false, to_boolean (me->get_property ("cross-staff")));
 }
 
-MAKE_SCHEME_CALLBACK (Grob, simple_horizontal_skylines_from_stencil, 1);
+MAKE_SCHEME_CALLBACK (Grob, simple_horizontal_skylines_from_extents, 1);
 SCM
-Grob::simple_horizontal_skylines_from_stencil (SCM smob)
+Grob::simple_horizontal_skylines_from_extents (SCM smob)
 {
-  return internal_simple_skylines_from_stencil (smob, Y_AXIS);
+  Grob *me = unsmob_grob (smob);
+  // See comment in function above.
+  return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, false, 0, 0, false, to_boolean (me->get_property ("cross-staff")));
 }
 
 SCM
@@ -1052,9 +1087,8 @@ Grob::horizontal_skylines_from_stencil (SCM smob)
 }
 
 SCM
-Grob::internal_skylines_from_element_stencils (SCM smob, Axis a)
+Grob::internal_skylines_from_element_stencils (Grob *me, Axis a, bool pure, int beg, int end)
 {
-  Grob *me = unsmob_grob (smob);
 
   extract_grob_set (me, "elements", elts);
   vector<Real> x_pos;
@@ -1064,14 +1098,15 @@ Grob::internal_skylines_from_element_stencils (SCM smob, Axis a)
   for (vsize i = 0; i < elts.size (); i++)
     {
       x_pos.push_back (elts[i]->relative_coordinate (x_common, X_AXIS));
-      y_pos.push_back (elts[i]->relative_coordinate (y_common, Y_AXIS));
+      y_pos.push_back (elts[i]->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end));
     }
   Real my_x = me->relative_coordinate (x_common, X_AXIS);
-  Real my_y = me->relative_coordinate (y_common, Y_AXIS);
+  Real my_y = me->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end);
+
   Skyline_pair res;
   for (vsize i = 0; i < elts.size (); i++)
     {
-      Skyline_pair *skyp = Skyline_pair::unsmob (elts[i]->get_property (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines"));
+      Skyline_pair *skyp = Skyline_pair::unsmob (elts[i]->get_maybe_pure_property (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines", pure, beg, end));
       if (skyp)
         {
           /*
@@ -1105,12 +1140,34 @@ MAKE_SCHEME_CALLBACK (Grob, vertical_skylines_from_element_stencils, 1);
 SCM
 Grob::vertical_skylines_from_element_stencils (SCM smob)
 {
-  return internal_skylines_from_element_stencils (smob, X_AXIS);
+  Grob *me = unsmob_grob (smob);
+  return internal_skylines_from_element_stencils (me, X_AXIS, false, 0, INT_MAX);
 }
 
 MAKE_SCHEME_CALLBACK (Grob, horizontal_skylines_from_element_stencils, 1);
 SCM
 Grob::horizontal_skylines_from_element_stencils (SCM smob)
 {
-  return internal_skylines_from_element_stencils (smob, Y_AXIS);
+  Grob *me = unsmob_grob (smob);
+  return internal_skylines_from_element_stencils (me, Y_AXIS, false, 0, INT_MAX);
+}
+
+MAKE_SCHEME_CALLBACK (Grob, pure_vertical_skylines_from_element_stencils, 3);
+SCM
+Grob::pure_vertical_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM end_scm)
+{
+  Grob *me = unsmob_grob (smob);
+  int beg = robust_scm2int (beg_scm, 0);
+  int end = robust_scm2int (end_scm, 0);
+  return internal_skylines_from_element_stencils (me, X_AXIS, true, beg, end);
+}
+
+MAKE_SCHEME_CALLBACK (Grob, pure_horizontal_skylines_from_element_stencils, 3);
+SCM
+Grob::pure_horizontal_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM end_scm)
+{
+  Grob *me = unsmob_grob (smob);
+  int beg = robust_scm2int (beg_scm, 0);
+  int end = robust_scm2int (end_scm, 0);
+  return internal_skylines_from_element_stencils (me, Y_AXIS, true, beg, end);
 }