]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/stencil-scheme.cc
lilypond-manuals.css: edit color scheme and some spacing
[lilypond.git] / lily / stencil-scheme.cc
index fec4c13f1eae0db70c78e4b31fad601a572de0ee..da9f0a8214afcdf7d9fc74d8c9691542ad74a7ac 100644 (file)
 #include "font-metric.hh"
 #include "libc-extension.hh"
 #include "lookup.hh"
+#include "offset.hh"
 #include "stencil.hh"
 
-using std::vector;
+/*
+ * A few general helpers in degrees
+ */
+
+LY_DEFINE (ly_angle, "ly:angle",
+           1, 1, 0, (SCM x, SCM y),
+           "Calculates angle in degrees of given vector.  With one argument,"
+           " @var{x} is a number pair indicating the vector.  With two"
+           " arguments, @var{x} and @var{y} specify the respective coordinates.")
+{
+  Offset off;
+  if (SCM_UNBNDP (y)) {
+    LY_ASSERT_TYPE (is_number_pair, x, 1);
+    off = ly_scm2offset (x);
+  } else {
+    LY_ASSERT_TYPE (scm_is_number, x, 1);
+    LY_ASSERT_TYPE (scm_is_number, y, 2);
+    off = Offset (scm_to_double (x), scm_to_double (y));
+  }
+  return scm_from_double (off.angle_degrees ());
+}
+
+LY_DEFINE (ly_length, "ly:length",
+           1, 1, 0, (SCM x, SCM y),
+           "Calculates magnitude of given vector.  With one argument,"
+           " @var{x} is a number pair indicating the vector.  With two"
+           " arguments, @var{x} and @var{y} specify the respective coordinates.")
+{
+  Offset off;
+  if (SCM_UNBNDP (y)) {
+    LY_ASSERT_TYPE (is_number_pair, x, 1);
+    off = ly_scm2offset (x);
+  } else {
+    LY_ASSERT_TYPE (scm_is_number, x, 1);
+    LY_ASSERT_TYPE (scm_is_number, y, 2);
+    off = Offset (scm_to_double (x), scm_to_double (y));
+  }
+  return scm_from_double (off.length ());
+}
+
+LY_DEFINE (ly_directed, "ly:directed",
+           1, 1, 0, (SCM direction, SCM magnitude),
+           "Calculates an @code{(x . y)} pair with optional @var{magnitude}"
+           " (defaulting to @code{1.0}) and @var{direction} specified either"
+           " as an angle in degrees or a coordinate pair giving the direction. "
+           " If @var{magnitude} is a pair, the respective coordinates are"
+           " scaled independently, useful for ellipse drawings.")
+{
+  Offset res;
+  if (scm_is_pair (direction))
+    {
+      LY_ASSERT_TYPE (is_number_pair, direction, 1);
+      res = ly_scm2offset (direction).direction ();
+    }
+  else
+    {
+      LY_ASSERT_TYPE (scm_is_number, direction, 1);
+      res = offset_directed (scm_to_double (direction));
+    }
+  if (SCM_UNBNDP (magnitude))
+    return ly_offset2scm (res);
+  if (scm_is_pair (magnitude))
+    {
+      LY_ASSERT_TYPE (is_number_pair, magnitude, 2);
+      return ly_offset2scm (res.scale (ly_scm2offset (magnitude)));
+    }
+  LY_ASSERT_TYPE (scm_is_number, magnitude, 2);
+  return ly_offset2scm (scm_to_double (magnitude) * res);
+}
+
 
 /*
   TODO: naming add/combine.
@@ -415,14 +485,23 @@ LY_DEFINE (ly_round_filled_box, "ly:round-filled-box",
 }
 
 LY_DEFINE (ly_round_filled_polygon, "ly:round-filled-polygon",
-           2, 0, 0,
-           (SCM points, SCM blot),
+           2, 1, 0,
+           (SCM points, SCM blot, SCM extroversion),
            "Make a @code{Stencil} object that prints a black polygon with"
            " corners at the points defined by @var{points} (list of coordinate"
-           " pairs) and roundness @var{blot}.")
+           " pairs) and roundness @var{blot}.  Optional"
+           "@var{extroversion} shifts the outline outward, with the"
+           "default of@tie{}@code{-1.0} keeping the outer boundary of"
+           "the outline just inside of the polygon.")
 {
   SCM_ASSERT_TYPE (scm_ilength (points) > 0, points, SCM_ARG1, __FUNCTION__, "list of coordinate pairs");
   LY_ASSERT_TYPE (scm_is_number, blot, 2);
+  Real ext = -1;
+  if (!SCM_UNBNDP (extroversion))
+    {
+      LY_ASSERT_TYPE (scm_is_number, extroversion, 3);
+      ext = scm_to_double (extroversion);
+    }
   vector<Offset> pts;
   for (SCM p = points; scm_is_pair (p); p = scm_cdr (p))
     {
@@ -436,7 +515,8 @@ LY_DEFINE (ly_round_filled_polygon, "ly:round-filled-polygon",
           // TODO: Print out warning
         }
     }
-  return Lookup::round_filled_polygon (pts, scm_to_double (blot)).smobbed_copy ();
+  return Lookup::round_filled_polygon (pts, scm_to_double (blot), ext)
+    .smobbed_copy ();
 }
 
 LY_DEFINE (ly_register_stencil_expression, "ly:register-stencil-expression",
@@ -475,3 +555,14 @@ LY_DEFINE (ly_stencil_scale, "ly:stencil-scale",
   q->scale (scm_to_double (x), scm_to_double (y));
   return new_s;
 }
+
+LY_DEFINE (ly_stencil_outline, "ly:stencil-outline",
+           2, 0, 0, (SCM stil, SCM outline),
+           "Return a stencil with the stencil expression (inking)"
+           " of stencil @var{stil} but with outline and dimensions"
+           " from stencil @var{outline}.")
+{
+  Stencil s = *LY_ASSERT_SMOB (Stencil, stil, 1);
+  Stencil o = *LY_ASSERT_SMOB (Stencil, outline, 2);
+  return s.with_outline (o).smobbed_copy ();
+}