*/
#include <pango/pango-matrix.h>
-#include <complex>
#include "box.hh"
#include "bezier.hh"
#include "dimensions.hh"
#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;
-void create_path_cap (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, Offset pt, Real rad, Real slope, Direction d);
+void create_path_cap (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, Offset pt, Real rad, Offset dir);
struct Transform_matrix_and_expression
{
if (scm_is_number (scm_car (l)))
return l;
SCM res = get_number_list (scm_car (l));
- if (res == SCM_BOOL_F)
+ if (scm_is_false (res))
return get_number_list (scm_cdr (l));
return res;
}
{
if (scm_is_pair (l))
{
- if (scm_memv (scm_car (l),
- scm_list_n (ly_symbol2scm ("moveto"),
- ly_symbol2scm ("rmoveto"),
- ly_symbol2scm ("lineto"),
- ly_symbol2scm ("rlineto"),
- ly_symbol2scm ("curveto"),
- ly_symbol2scm ("rcurveto"),
- ly_symbol2scm ("closepath"),
- SCM_UNDEFINED))
- != SCM_BOOL_F)
+ if (scm_is_true (scm_memv (scm_car (l),
+ scm_list_n (ly_symbol2scm ("moveto"),
+ ly_symbol2scm ("rmoveto"),
+ ly_symbol2scm ("lineto"),
+ ly_symbol2scm ("rlineto"),
+ ly_symbol2scm ("curveto"),
+ ly_symbol2scm ("rcurveto"),
+ ly_symbol2scm ("closepath"),
+ SCM_UNDEFINED))))
return l;
SCM res = get_path_list (scm_car (l));
- if (res == SCM_BOOL_F)
+ if (scm_is_false (res))
return get_path_list (scm_cdr (l));
return res;
}
return SCM_BOOL_F;
}
-Real
-perpendicular_slope (Real s)
+// Gets an orthogonal vector with same size to orig, pointing left
+// (in the complex domain, a multiplication by i)
+
+Offset
+get_normal (Offset orig)
{
- if (s == 0.0)
- return infinity_f;
- if (s == infinity_f)
- return 0.0;
- return -1.0 / s;
+ return Offset (-orig[Y_AXIS], orig[X_AXIS]);
}
//// END UTILITY FUNCTIONS
Real x1 = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
Real y1 = robust_scm2double (scm_car (expr), 0.0);
- Real slope = x1 == x0 ? infinity_f : (y1 - y0) / (x1 - x0);
+
//////////////////////
if (x1 < x0)
{
}
Offset left (x0, y0);
Offset right (x1, y1);
- Direction d = DOWN;
- do
+ Offset dir = (right - left).direction ();
+ for (DOWN_and_UP (d))
{
- 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 outward = d * get_normal ((thick / 2) * dir);
+ Offset inter_l = left + outward;
+ Offset inter_r = right + outward;
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);
buildings.push_back (Drul_array<Offset> (inter_l, inter_r));
else
{
- 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);
- 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]);
- Real length = sqrt (((inter_l[X_AXIS] - inter_r[X_AXIS]) * (inter_l[X_AXIS] - inter_r[X_AXIS])) + ((inter_l[Y_AXIS] - inter_r[Y_AXIS]) * (inter_l[Y_AXIS] - inter_r[Y_AXIS])));
+ Real length = (inter_l - inter_r).length ();
vsize passes = (vsize) ((length * 2) + 1);
vector<Offset> points;
{
Offset pt (linear_map (x0, x1, 0, passes, i),
linear_map (y0, y1, 0, passes, i));
- Offset inter = get_point_in_y_direction (pt, perpendicular_slope (slope), thick / 2, d);
+ Offset inter = pt + outward;
pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]);
points.push_back (inter);
}
}
}
}
- while (flip (&d) != DOWN);
if (thick > 0.0)
{
create_path_cap (boxes,
buildings,
trans,
- Offset (x0, y0),
+ left,
thick / 2,
- perpendicular_slope (slope),
- Direction (sign (slope)));
+ -dir);
// end line cap
create_path_cap (boxes,
buildings,
trans,
- Offset (x1, y1),
+ right,
thick / 2,
- perpendicular_slope (slope),
- Direction (sign (-slope)));
+ dir);
}
}
void
-make_partial_ellipse_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_partial_ellipse_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
Real x_rad = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
Real y_rad = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
+ Offset rad (x_rad, y_rad);
Real start = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
Real end = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
bool fill = to_boolean (scm_car (expr));
//////////////////////
- start = M_PI * start / 180;
- end = M_PI * end / 180;
if (end == start)
- end += (2 * M_PI);
- complex<Real> sunit = polar (1.0, start);
- complex<Real> eunit = polar (1.0, end);
- Offset sp (real (sunit) * x_rad, imag (sunit) * y_rad);
- Offset ep (real (eunit) * x_rad, imag (eunit) * y_rad);
+ end += 360;
+ Offset sp (offset_directed (start).scale (rad));
+ Offset ep (offset_directed (end).scale (rad));
//////////////////////
Drul_array<vector<Offset> > points;
- Direction d = DOWN;
int quantization = max (1, (int) (((x_rad * trans.xx) + (y_rad * trans.yy)) * M_PI / QUANTIZATION_UNIT));
- do
+ for (DOWN_and_UP (d))
{
- 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);
- Offset pt (real (coord) * x_rad,
- imag (coord) * y_rad);
- Real slope = pt[Y_AXIS] / pt[X_AXIS];
- Offset inter = get_point_in_y_direction (pt, perpendicular_slope (slope), th / 2, d);
+ Offset pt (offset_directed (ang).scale (rad));
+ Offset inter = pt + d * get_normal ((th/2) * pt.direction ());
pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]);
points[d].push_back (inter);
}
}
- while (flip (&d) != DOWN);
for (vsize i = 0; i < points[DOWN].size () - 1; i++)
{
Box b;
- do
+ for (DOWN_and_UP (d))
{
b.add_point (points[d][i]);
b.add_point (points[d][i + 1]);
}
- while (flip (&d) != DOWN);
boxes.push_back (b);
}
if (connect || fill)
{
- make_draw_line_boxes (boxes, buildings, trans, scm_list_5 (scm_from_double (th),
- scm_from_double (sp[X_AXIS]),
- scm_from_double (sp[Y_AXIS]),
- scm_from_double (ep[X_AXIS]),
- scm_from_double (ep[Y_AXIS])),
+ make_draw_line_boxes (boxes, buildings, trans,
+ scm_list_5 (scm_from_double (th),
+ scm_from_double (sp[X_AXIS]),
+ scm_from_double (sp[Y_AXIS]),
+ scm_from_double (ep[X_AXIS]),
+ scm_from_double (ep[Y_AXIS])),
false);
}
if (th > 0.0)
{
// beg line cap
- complex<Real> coord = polar (1.0, start);
- Offset pt (real (coord) * x_rad,
- imag (coord) * y_rad);
- Real slope = pt[Y_AXIS] / pt[X_AXIS];
+ Offset pt (offset_directed (start).scale (rad));
create_path_cap (boxes,
buildings,
trans,
pt,
th / 2,
- perpendicular_slope (slope),
- Direction (sign (slope)));
+ -get_normal (pt));
// end line cap
- coord = polar (1.0, start);
- pt = Offset (real (coord) * x_rad,
- imag (coord) * y_rad);
- slope = pt[Y_AXIS] / pt[X_AXIS];
+ pt = offset_directed (end).scale (rad);
create_path_cap (boxes,
buildings,
trans,
pt,
th / 2,
- perpendicular_slope (slope),
- Direction (sign (-slope)));
+ get_normal (pt));
}
}
}
void
-create_path_cap (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, Offset pt, Real rad, Real slope, Direction d)
+create_path_cap (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, Offset pt, Real rad, Offset dir)
{
- Real angle = atan (slope) * 180 / M_PI;
- Real other = angle > 180 ? angle - 180 : angle + 180;
- if (angle < other)
- {
- Real holder = other;
- other = angle;
- angle = holder;
- }
- other = (slope >= 0 && d == DOWN) || (slope < 0 && d == UP)
- ? other + 360.0
- : other;
+ Real angle = dir.angle_degrees ();
PangoMatrix new_trans (trans);
pango_matrix_translate (&new_trans, pt[X_AXIS], pt[Y_AXIS]);
make_partial_ellipse_boxes (boxes, buildings, new_trans,
scm_list_n (scm_from_double (rad),
scm_from_double (rad),
- scm_from_double (angle),
- scm_from_double (other),
+ scm_from_double (angle-90.01),
+ scm_from_double (angle+90.01),
scm_from_double (0.0),
SCM_BOOL_F,
SCM_BOOL_F,
}
void
-make_draw_bezier_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_draw_bezier_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
Real th = robust_scm2double (scm_car (expr), 0.0);
expr = scm_cdr (expr);
pango_matrix_transform_point (&trans, &temp3[X_AXIS], &temp3[Y_AXIS]);
//////////////////////
Drul_array<vector<Offset> > points;
- Direction d = DOWN;
int quantization = int (((temp1 - temp0).length ()
+ (temp2 - temp1).length ()
+ (temp3 - temp2).length ())
/ QUANTIZATION_UNIT);
- do
+ for (DOWN_and_UP (d))
{
- Offset first = get_point_in_y_direction (curve.control_[0], perpendicular_slope (curve.slope_at_point (0.0)), th / 2, d);
+ Offset first = curve.control_[0]
+ + d * get_normal ((th / 2) * curve.dir_at_point (0.0));
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);
+ Offset inter = curve.curve_point (pt)
+ + d * get_normal ((th / 2) *curve.dir_at_point (pt));
pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]);
points[d].push_back (inter);
}
- Offset last = get_point_in_y_direction (curve.control_[3], curve.slope_at_point (1.0), th / 2, d);
+ Offset last = curve.control_[3]
+ + d * get_normal ((th / 2) * curve.dir_at_point (1.0));
pango_matrix_transform_point (&trans, &last[X_AXIS], &last[Y_AXIS]);
points[d].push_back (last);
}
- while (flip (&d) != DOWN);
for (vsize i = 0; i < points[DOWN].size () - 1; i++)
{
Box b;
- do
+ for (DOWN_and_UP (d))
{
b.add_point (points[d][i]);
b.add_point (points[d][i + 1]);
}
- while (flip (&d) != DOWN);
boxes.push_back (b);
}
- // beg line cap
if (th >= 0)
{
- Real slope = curve.slope_at_point (0.0);
- d = Direction (sign (slope == 0.0 || abs (slope) == infinity_f
- ? curve.slope_at_point (0.0001)
- : slope));
-
+ // beg line cap
create_path_cap (boxes,
buildings,
trans,
curve.control_[0],
th / 2,
- perpendicular_slope (curve.slope_at_point (0.0)),
- d);
+ -curve.dir_at_point (0.0));
// end line cap
- slope = curve.slope_at_point (1.0);
- d = Direction (sign (slope == 0.0 || abs (slope) == infinity_f
- ? curve.slope_at_point (0.9999)
- : slope));
-
create_path_cap (boxes,
buildings,
trans,
curve.control_[3],
th / 2,
- perpendicular_slope (curve.slope_at_point (1.0)),
- d);
+ curve.dir_at_point (1.0));
}
}
/*
converts a path into lists of 4 (line) or 8 (curve) absolute coordinates
for example:
- '(moveto 1 2 lineto 3 4 rlineto -1 -1 curveto 3 3 5 5 6 6 rcurveto -1 -1 -1 -1 -1 -1 closepath)
+ '(moveto 1 2 lineto 3 4 rlineto -1 -1 curveto
+ 3 3 5 5 6 6 rcurveto -1 -1 -1 -1 -1 -1 closepath)
becomes
'((1 2 3 4)
(3 4 2 3)
bool first = true;
while (scm_is_pair (expr))
{
- if (scm_car (expr) == ly_symbol2scm ("moveto")
- || (scm_car (expr) == ly_symbol2scm ("rmoveto") && first))
+ if (scm_is_eq (scm_car (expr), ly_symbol2scm ("moveto"))
+ || (scm_is_eq (scm_car (expr), ly_symbol2scm ("rmoveto")) && first))
{
Real x = robust_scm2double (scm_cadr (expr), 0.0);
Real y = robust_scm2double (scm_caddr (expr), 0.0);
current = start;
expr = scm_cdddr (expr);
}
- if (scm_car (expr) == ly_symbol2scm ("rmoveto"))
+ if (scm_is_eq (scm_car (expr), ly_symbol2scm ("rmoveto")))
{
Real x = robust_scm2double (scm_cadr (expr), 0.0);
Real y = robust_scm2double (scm_caddr (expr), 0.0);
current = start;
expr = scm_cdddr (expr);
}
- else if (scm_car (expr) == ly_symbol2scm ("lineto"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("lineto")))
{
Real x = robust_scm2double (scm_cadr (expr), 0.0);
Real y = robust_scm2double (scm_caddr (expr), 0.0);
current = Offset (x, y);
expr = scm_cdddr (expr);
}
- else if (scm_car (expr) == ly_symbol2scm ("rlineto"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("rlineto")))
{
Real x = robust_scm2double (scm_cadr (expr), 0.0);
Real y = robust_scm2double (scm_caddr (expr), 0.0);
current = (Offset (x, y) + current);
expr = scm_cdddr (expr);
}
- else if (scm_car (expr) == ly_symbol2scm ("curveto"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("curveto")))
{
Real x1 = robust_scm2double (scm_cadr (expr), 0.0);
expr = scm_cddr (expr);
out);
current = Offset (x3, y3);
}
- else if (scm_car (expr) == ly_symbol2scm ("rcurveto"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("rcurveto")))
{
Real x1 = robust_scm2double (scm_cadr (expr), 0.0);
expr = scm_cddr (expr);
out);
current = (Offset (x3, y3) + current);
}
- else if (scm_car (expr) == ly_symbol2scm ("closepath"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("closepath")))
{
- if ((current[X_AXIS] != start[X_AXIS]) || (current[Y_AXIS] != start[Y_AXIS]))
+ if ((current[X_AXIS] != start[X_AXIS])
+ || (current[Y_AXIS] != start[Y_AXIS]))
{
out = scm_cons (scm_list_4 (scm_from_double (current[X_AXIS]),
scm_from_double (current[Y_AXIS]),
}
void
-internal_make_path_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr, bool use_building)
+internal_make_path_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr, bool use_building)
{
SCM blot = scm_car (expr);
expr = scm_cdr (expr);
}
void
-make_path_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_path_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
return internal_make_path_boxes (boxes, buildings, trans, scm_cons (scm_car (expr), get_path_list (scm_cdr (expr))), false);
}
void
-make_polygon_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_polygon_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
SCM coords = get_number_list (scm_car (expr));
expr = scm_cdr (expr);
first = false;
}
l = scm_cons (ly_symbol2scm ("closepath"), l);
- internal_make_path_boxes (boxes, buildings, trans, scm_cons (blot_diameter, scm_reverse_x (l, SCM_EOL)), true);
+ internal_make_path_boxes (boxes, buildings, trans,
+ scm_cons (blot_diameter, scm_reverse_x (l, SCM_EOL)), true);
}
void
-make_named_glyph_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_named_glyph_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
SCM fm_scm = scm_car (expr);
- Font_metric *fm = unsmob_metrics (fm_scm);
+ Font_metric *fm = unsmob<Font_metric> (fm_scm);
expr = scm_cdr (expr);
SCM glyph = scm_car (expr);
string glyph_s = ly_scm2string (glyph);
// Bbox is the best approximation of the width based on how it would be
// calculated in open-type-font.cc if it were based on real extents
Box bbox = open_fm->get_unscaled_indexed_char_dimensions (gidx);
- bbox.scale (dynamic_cast<Modified_font_metric *>(fm)->get_magnification () * open_fm->design_size () / open_fm->get_units_per_EM ());
+ bbox.scale (dynamic_cast<Modified_font_metric *> (fm)->get_magnification ()
+ * open_fm->design_size () / open_fm->get_units_per_EM ());
// Real bbox is the real bbox of the object
Box real_bbox = open_fm->get_glyph_outline_bbox (gidx);
s = scm_cdr (s))
{
scm_to_int (scm_length (scm_car (s))) == 4
- ? make_draw_line_boxes (boxes, buildings, trans, scm_cons (scm_from_double (0), scm_car (s)), false)
- : make_draw_bezier_boxes (boxes, buildings, trans, scm_cons (scm_from_double (0), scm_car (s)));
+ ? make_draw_line_boxes (boxes, buildings, trans,
+ scm_cons (scm_from_double (0), scm_car (s)),
+ false)
+ : make_draw_bezier_boxes (boxes, buildings, trans,
+ scm_cons (scm_from_double (0), scm_car (s)));
}
}
void
-make_glyph_string_boxes (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+make_glyph_string_boxes (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
SCM fm_scm = scm_car (expr);
- Font_metric *fm = unsmob_metrics (fm_scm);
+ Font_metric *fm = unsmob<Font_metric> (fm_scm);
expr = scm_cdr (expr);
expr = scm_cdr (expr); // font-name
expr = scm_cdr (expr); // size
Real scale_factor = max (xlen, ylen);
// the three operations below move the stencil from its original coordinates to current coordinates
- pango_matrix_translate (&transcopy, kerned_bbox[X_AXIS][LEFT], kerned_bbox[Y_AXIS][DOWN] - real_bbox[Y_AXIS][DOWN]);
- pango_matrix_translate (&transcopy, real_bbox[X_AXIS][LEFT], real_bbox[Y_AXIS][DOWN]);
+ pango_matrix_translate (&transcopy, kerned_bbox[X_AXIS][LEFT],
+ kerned_bbox[Y_AXIS][DOWN] - real_bbox[Y_AXIS][DOWN]);
+ pango_matrix_translate (&transcopy, real_bbox[X_AXIS][LEFT],
+ real_bbox[Y_AXIS][DOWN]);
pango_matrix_scale (&transcopy, scale_factor, scale_factor);
- pango_matrix_translate (&transcopy, -bbox[X_AXIS][LEFT], -bbox[Y_AXIS][DOWN]);
+ pango_matrix_translate (&transcopy, -bbox[X_AXIS][LEFT],
+ -bbox[Y_AXIS][DOWN]);
}
//////////////////////
for (SCM s = outline;
s = scm_cdr (s))
{
scm_to_int (scm_length (scm_car (s))) == 4
- ? make_draw_line_boxes (boxes, buildings, transcopy, scm_cons (scm_from_double (0), scm_car (s)), false)
- : make_draw_bezier_boxes (boxes, buildings, transcopy, scm_cons (scm_from_double (0), scm_car (s)));
+ ? make_draw_line_boxes (boxes, buildings, transcopy,
+ scm_cons (scm_from_double (0), scm_car (s)),
+ false)
+ : make_draw_bezier_boxes (boxes, buildings, transcopy,
+ scm_cons (scm_from_double (0), scm_car (s)));
}
}
}
*/
void
-stencil_dispatcher (vector<Box> &boxes, vector<Drul_array<Offset> > &buildings, PangoMatrix trans, SCM expr)
+stencil_dispatcher (vector<Box> &boxes,
+ vector<Drul_array<Offset> > &buildings,
+ PangoMatrix trans, SCM expr)
{
if (not scm_is_pair (expr))
return;
- if (scm_car (expr) == ly_symbol2scm ("draw-line"))
+ if (scm_is_eq (scm_car (expr), ly_symbol2scm ("draw-line")))
make_draw_line_boxes (boxes, buildings, trans, scm_cdr (expr), true);
- else if (scm_car (expr) == ly_symbol2scm ("dashed-line"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("dashed-line")))
{
expr = scm_cdr (expr);
SCM th = scm_car (expr);
SCM x1 = scm_car (expr);
expr = scm_cdr (expr);
SCM x2 = scm_car (expr);
- make_draw_line_boxes (boxes, buildings, trans, scm_list_5 (th, scm_from_double (0.0), scm_from_double (0.0), x1, x2), true);
+ make_draw_line_boxes (boxes, buildings, trans,
+ scm_list_5 (th, scm_from_double (0.0),
+ scm_from_double (0.0), x1, x2), true);
}
- else if (scm_car (expr) == ly_symbol2scm ("circle"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("circle")))
{
expr = scm_cdr (expr);
SCM rad = scm_car (expr);
SCM_BOOL_T,
SCM_UNDEFINED));
}
- else if (scm_car (expr) == ly_symbol2scm ("ellipse"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("ellipse")))
{
expr = scm_cdr (expr);
SCM x_rad = scm_car (expr);
SCM_BOOL_T,
SCM_UNDEFINED));
}
- else if (scm_car (expr) == ly_symbol2scm ("partial-ellipse"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("partial-ellipse")))
make_partial_ellipse_boxes (boxes, buildings, trans, scm_cdr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("round-filled-box"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("round-filled-box")))
make_round_filled_box_boxes (boxes, trans, scm_cdr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("named-glyph"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("named-glyph")))
make_named_glyph_boxes (boxes, buildings, trans, scm_cdr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("polygon"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("polygon")))
make_polygon_boxes (boxes, buildings, trans, scm_cdr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("path"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("path")))
make_path_boxes (boxes, buildings, trans, scm_cdr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("glyph-string"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("glyph-string")))
make_glyph_string_boxes (boxes, buildings, trans, scm_cdr (expr));
else
{
vector<Transform_matrix_and_expression>
stencil_traverser (PangoMatrix trans, SCM expr)
{
- if (scm_is_null (expr))
- return vector<Transform_matrix_and_expression> ();
- else if (expr == ly_string2scm (""))
+ if (scm_is_null (expr)
+ || (scm_is_string (expr) && scm_is_true (scm_string_null_p (expr))))
return vector<Transform_matrix_and_expression> ();
- else if (scm_car (expr) == ly_symbol2scm ("combine-stencil"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("combine-stencil")))
{
vector<Transform_matrix_and_expression> out;
for (SCM s = scm_cdr (expr); scm_is_pair (s); s = scm_cdr (s))
{
- vector<Transform_matrix_and_expression> res = stencil_traverser (trans, scm_car (s));
+ vector<Transform_matrix_and_expression> res =
+ stencil_traverser (trans, scm_car (s));
out.insert (out.end (), res.begin (), res.end ());
}
return out;
}
- else if (scm_car (expr) == ly_symbol2scm ("footnote"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("footnote")))
return vector<Transform_matrix_and_expression> ();
- else if (scm_car (expr) == ly_symbol2scm ("translate-stencil"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("translate-stencil")))
{
Real x = robust_scm2double (scm_caadr (expr), 0.0);
Real y = robust_scm2double (scm_cdadr (expr), 0.0);
pango_matrix_translate (&trans, x, y);
return stencil_traverser (trans, scm_caddr (expr));
}
- else if (scm_car (expr) == ly_symbol2scm ("scale-stencil"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("scale-stencil")))
{
Real x = robust_scm2double (scm_caadr (expr), 0.0);
Real y = robust_scm2double (scm_cadadr (expr), 0.0);
pango_matrix_scale (&trans, x, y);
return stencil_traverser (trans, scm_caddr (expr));
}
- else if (scm_car (expr) == ly_symbol2scm ("rotate-stencil"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("rotate-stencil")))
{
Real ang = robust_scm2double (scm_caadr (expr), 0.0);
Real x = robust_scm2double (scm_car (scm_cadadr (expr)), 0.0);
pango_matrix_translate (&trans, -x, -y);
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)));
- else if (scm_car (expr) == ly_symbol2scm ("grob-cause"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("delay-stencil-evaluation")))
+ // should not use the place-holder text, but no need for the warning below
+ return vector<Transform_matrix_and_expression> ();
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("grob-cause")))
return stencil_traverser (trans, scm_caddr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("color"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("color")))
return stencil_traverser (trans, scm_caddr (expr));
- else if (scm_car (expr) == ly_symbol2scm ("id"))
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("transparent-stencil")))
+ return stencil_traverser (trans, scm_cadr (expr));
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("output-attributes")))
return stencil_traverser (trans, scm_caddr (expr));
+ else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("with-outline")))
+ return stencil_traverser (trans, scm_cadr (expr));
else
{
vector<Transform_matrix_and_expression> out;
}
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
Stencil::skylines_from_stencil (SCM sten, Real pad, Axis a)
{
- Stencil *s = unsmob_stencil (sten);
+ Stencil *s = unsmob<Stencil> (sten);
if (!s)
return Skyline_pair ().smobbed_copy ();
for (DOWN_and_UP (d))
out[d] = out[d].padded (pad);
- out.deholify ();
return out.smobbed_copy ();
}
SCM
Grob::vertical_skylines_from_stencil (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
Real pad = robust_scm2double (me->get_property ("skyline-horizontal-padding"), 0.0);
SCM out = Stencil::skylines_from_stencil (me->get_property ("stencil"), pad, X_AXIS);
SCM
Grob::horizontal_skylines_from_stencil (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
Real pad = robust_scm2double (me->get_property ("skyline-vertical-padding"), 0.0);
SCM out = Stencil::skylines_from_stencil (me->get_property ("stencil"), pad, Y_AXIS);
}
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;
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 = unsmob<Skyline_pair> (elts[i]->get_maybe_pure_property (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines", pure, beg, end));
if (skyp)
{
/*
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);
}