37
38
return Stencil (box, at);
52
* (0,0) x /slope=dy/dx
60
Lookup::beam (Real slope, Real width, Real thick, Real blot)
42
Lookup::beam (Real slope, Real width, Real thick, Real blot)
62
Real height = slope * width;
63
Real min_y = (0 <? height) - thick/2;
64
Real max_y = (0 >? height) + thick/2;
66
Box b (Interval (0, width),
67
Interval (min_y, max_y));
69
SCM at = scm_list_n (ly_symbol2scm ("beam"),
70
gh_double2scm (width),
71
gh_double2scm (slope),
72
gh_double2scm (thick),
75
return Stencil (b, at);
48
p = Offset (0, thick / 2);
50
p += Offset (1, -1) * (blot / 2);
54
points = scm_cons (scm_from_double (p[X_AXIS]),
55
scm_cons (scm_from_double (p[Y_AXIS]),
58
p = Offset (0, -thick / 2);
60
p += Offset (1, 1) * (blot / 2);
62
points = scm_cons (scm_from_double (p[X_AXIS]),
63
scm_cons (scm_from_double (p[Y_AXIS]),
66
p = Offset (width, width * slope - thick / 2);
68
p += Offset (-1, 1) * (blot / 2);
70
points = scm_cons (scm_from_double (p[X_AXIS]),
71
scm_cons (scm_from_double (p[Y_AXIS]),
74
p = Offset (width, width * slope + thick / 2);
76
p += Offset (-1, -1) * (blot / 2);
78
points = scm_cons (scm_from_double (p[X_AXIS]),
79
scm_cons (scm_from_double (p[Y_AXIS]),
82
SCM expr = scm_list_n (ly_symbol2scm ("polygon"),
83
ly_quote_scm (points),
84
scm_from_double (blot),
88
return Stencil (b, expr);
79
Lookup::dashed_slur (Bezier b, Real thick, Real dash)
92
Lookup::dashed_slur (Bezier b, Real thick, Real dash_period, Real dash_fraction)
83
for (int i= 4; i -- ;)
85
l = gh_cons (ly_offset2scm (b.control_[i]), l);
96
Real on = dash_fraction * dash_period;
97
Real off = dash_period - on;
100
l = scm_cons (ly_offset2scm (b.control_[i]), l);
88
102
SCM at = (scm_list_n (ly_symbol2scm ("dashed-slur"),
89
gh_double2scm (thick),
103
scm_from_double (thick),
104
scm_from_double (on),
105
scm_from_double (off),
94
Box box (Interval (0,0),Interval (0,0));
95
return Stencil (box, at);
109
Box box (Interval (0, 0), Interval (0, 0));
110
return Stencil (box, at);
101
114
Lookup::horizontal_line (Interval w, Real th)
103
SCM at = scm_list_n (ly_symbol2scm ("horizontal-line"),
104
gh_double2scm (w[LEFT]),
105
gh_double2scm (w[RIGHT]),
116
SCM at = scm_list_n (ly_symbol2scm ("draw-line"),
117
scm_from_double (th),
118
scm_from_double (w[LEFT]),
120
scm_from_double (w[RIGHT]),
112
box[Y_AXIS] = Interval (-th/2,th/2);
126
box[Y_AXIS] = Interval (-th / 2, th / 2);
114
128
return Stencil (box, at);
119
Lookup::blank (Box b)
132
Lookup::blank (Box b)
121
134
return Stencil (b, scm_makfrom0str (""));
125
Lookup::filled_box (Box b)
138
Lookup::filled_box (Box b)
127
SCM at = (scm_list_n (ly_symbol2scm ("filledbox"),
128
gh_double2scm (-b[X_AXIS][LEFT]),
129
gh_double2scm (b[X_AXIS][RIGHT]),
130
gh_double2scm (-b[Y_AXIS][DOWN]),
131
gh_double2scm (b[Y_AXIS][UP]),
134
return Stencil (b,at);
140
return round_filled_box (b, 0.0);
351
Make a smooth curve along the points
351
Make a smooth curve along the points
354
Lookup::slur (Bezier curve, Real curvethick, Real linethick)
354
Lookup::slur (Bezier curve, Real curvethick, Real linethick)
356
356
Real alpha = (curve.control_[3] - curve.control_[0]).arg ();
357
357
Bezier back = curve;
358
Offset perp = curvethick * complex_exp (Offset (0, alpha + M_PI/2)) * 0.5;
358
Offset perp = curvethick * complex_exp (Offset (0, alpha + M_PI / 2)) * 0.5;
360
360
back.control_[1] += perp;
361
361
back.control_[2] += perp;
363
363
curve.control_[1] -= perp;
364
364
curve.control_[2] -= perp;
366
366
SCM scontrols[8];
369
scontrols[ i ] = ly_offset2scm (back.control_[i]);
371
scontrols[i+4] = ly_offset2scm (curve.control_[i]);
368
for (int i = 0; i < 4; i++)
369
scontrols[i] = ly_offset2scm (back.control_[i]);
370
for (int i = 0; i < 4; i++)
371
scontrols[i + 4] = ly_offset2scm (curve.control_[i]);
374
Need the weird order b.o. the way PS want its arguments
376
int indices[]= {5, 6, 7, 4, 1, 2, 3, 0};
374
Need the weird order b.o. the way PS want its arguments
376
int indices[] = {5, 6, 7, 4, 1, 2, 3, 0};
377
377
SCM list = SCM_EOL;
380
list = gh_cons (scontrols[indices[i]], list);
378
for (int i = 8; i--;)
379
list = scm_cons (scontrols[indices[i]], list);
384
381
SCM at = (scm_list_n (ly_symbol2scm ("bezier-sandwich"),
386
gh_double2scm (linethick),
383
scm_from_double (linethick),
388
385
Box b (curve.extent (X_AXIS),
389
curve.extent (Y_AXIS));
386
curve.extent (Y_AXIS));
391
388
b[X_AXIS].unite (back.extent (X_AXIS));
392
389
b[Y_AXIS].unite (back.extent (Y_AXIS));
454
Lookup::accordion (SCM s, Real staff_space, Font_metric *fm)
451
Lookup::accordion (SCM s, Real staff_space, Font_metric *fm)
457
String sym = ly_scm2string (ly_car (s));
458
String reg = ly_scm2string (ly_car (ly_cdr (s)));
454
string sym = ly_scm2string (scm_car (s));
455
string reg = ly_scm2string (scm_car (scm_cdr (s)));
460
457
if (sym == "Discant")
462
Stencil r = fm->find_by_name ("accordion-accDiscant");
459
Stencil r = fm->find_by_name ("accordion.accDiscant");
463
460
m.add_stencil (r);
464
if (reg.left_string (1) == "F")
461
if (reg.substr (0, 1) == "F")
466
Stencil d = fm->find_by_name ("accordion-accDot");
463
Stencil d = fm->find_by_name ("accordion.accDot");
467
464
d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
468
465
m.add_stencil (d);
469
reg = reg.right_string (reg.length ()-1);
466
reg = reg.substr (1);
471
468
int eflag = 0x00;
472
if (reg.left_string (3) == "EEE")
469
if (reg.substr (0, 3) == "EEE")
475
reg = reg.right_string (reg.length ()-3);
472
reg = reg.substr (3);
477
else if (reg.left_string (2) == "EE")
474
else if (reg.substr (0, 2) == "EE")
480
reg = reg.right_string (reg.length ()-2);
477
reg = reg.substr (2);
482
else if (reg.left_string (2) == "Eh")
479
else if (reg.substr (0, 2) == "Eh")
485
reg = reg.right_string (reg.length ()-2);
482
reg = reg.substr (2);
487
else if (reg.left_string (1) == "E")
484
else if (reg.substr (0, 1) == "E")
490
reg = reg.right_string (reg.length ()-1);
487
reg = reg.substr (1);
492
489
if (eflag & 0x02)
494
Stencil d = fm->find_by_name ("accordion-accDot");
491
Stencil d = fm->find_by_name ("accordion.accDot");
495
492
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
496
493
m.add_stencil (d);
498
495
if (eflag & 0x04)
500
Stencil d = fm->find_by_name ("accordion-accDot");
497
Stencil d = fm->find_by_name ("accordion.accDot");
501
498
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
502
499
d.translate_axis (0.8 * staff_space PT, X_AXIS);
503
500
m.add_stencil (d);
505
502
if (eflag & 0x01)
507
Stencil d = fm->find_by_name ("accordion-accDot");
504
Stencil d = fm->find_by_name ("accordion.accDot");
508
505
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
509
506
d.translate_axis (-0.8 * staff_space PT, X_AXIS);
510
507
m.add_stencil (d);
512
if (reg.left_string (2) == "SS")
509
if (reg.substr (0, 2) == "SS")
514
Stencil d = fm->find_by_name ("accordion-accDot");
511
Stencil d = fm->find_by_name ("accordion.accDot");
515
512
d.translate_axis (0.5 * staff_space PT, Y_AXIS);
516
513
d.translate_axis (0.4 * staff_space PT, X_AXIS);
517
514
m.add_stencil (d);
518
515
d.translate_axis (-0.8 * staff_space PT, X_AXIS);
519
516
m.add_stencil (d);
520
reg = reg.right_string (reg.length ()-2);
517
reg = reg.substr (2);
522
if (reg.left_string (1) == "S")
519
if (reg.substr (0, 1) == "S")
524
Stencil d = fm->find_by_name ("accordion-accDot");
521
Stencil d = fm->find_by_name ("accordion.accDot");
525
522
d.translate_axis (0.5 * staff_space PT, Y_AXIS);
526
523
m.add_stencil (d);
527
reg = reg.right_string (reg.length ()-1);
524
reg = reg.substr (1);
530
527
else if (sym == "Freebase")
532
Stencil r = fm->find_by_name ("accordion-accFreebase");
529
Stencil r = fm->find_by_name ("accordion.accFreebase");
533
530
m.add_stencil (r);
534
if (reg.left_string (1) == "F")
531
if (reg.substr (0, 1) == "F")
536
Stencil d = fm->find_by_name ("accordion-accDot");
533
Stencil d = fm->find_by_name ("accordion.accDot");
537
534
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
538
535
m.add_stencil (d);
539
reg = reg.right_string (reg.length ()-1);
536
reg = reg.substr (1);
543
Stencil d = fm->find_by_name ("accordion-accDot");
540
Stencil d = fm->find_by_name ("accordion.accDot");
544
541
d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
545
542
m.add_stencil (d);
548
545
else if (sym == "Bayanbase")
550
Stencil r = fm->find_by_name ("accordion-accBayanbase");
547
Stencil r = fm->find_by_name ("accordion.accBayanbase");
551
548
m.add_stencil (r);
552
if (reg.left_string (1) == "T")
549
if (reg.substr (0, 1) == "T")
554
Stencil d = fm->find_by_name ("accordion-accDot");
551
Stencil d = fm->find_by_name ("accordion.accDot");
555
552
d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
556
553
m.add_stencil (d);
557
reg = reg.right_string (reg.length ()-1);
554
reg = reg.substr (1);
559
556
/* include 4' reed just for completeness. You don't want to use this. */
560
if (reg.left_string (1) == "F")
557
if (reg.substr (0, 1) == "F")
562
Stencil d = fm->find_by_name ("accordion-accDot");
559
Stencil d = fm->find_by_name ("accordion.accDot");
563
560
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
564
561
m.add_stencil (d);
565
reg = reg.right_string (reg.length ()-1);
562
reg = reg.substr (1);
567
if (reg.left_string (2) == "EE")
564
if (reg.substr (0, 2) == "EE")
569
Stencil d = fm->find_by_name ("accordion-accDot");
566
Stencil d = fm->find_by_name ("accordion.accDot");
570
567
d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
571
568
d.translate_axis (0.4 * staff_space PT, X_AXIS);
572
569
m.add_stencil (d);
573
570
d.translate_axis (-0.8 * staff_space PT, X_AXIS);
574
571
m.add_stencil (d);
575
reg = reg.right_string (reg.length ()-2);
572
reg = reg.substr (2);
577
if (reg.left_string (1) == "E")
574
if (reg.substr (0, 1) == "E")
579
Stencil d = fm->find_by_name ("accordion-accDot");
576
Stencil d = fm->find_by_name ("accordion.accDot");
580
577
d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
581
578
m.add_stencil (d);
582
reg = reg.right_string (reg.length ()-1);
579
reg = reg.substr (1);
585
582
else if (sym == "Stdbase")
587
Stencil r = fm->find_by_name ("accordion-accStdbase");
584
Stencil r = fm->find_by_name ("accordion.accStdbase");
588
585
m.add_stencil (r);
589
if (reg.left_string (1) == "T")
586
if (reg.substr (0, 1) == "T")
591
Stencil d = fm->find_by_name ("accordion-accDot");
588
Stencil d = fm->find_by_name ("accordion.accDot");
592
589
d.translate_axis (staff_space * 3.5 PT, Y_AXIS);
593
590
m.add_stencil (d);
594
reg = reg.right_string (reg.length ()-1);
591
reg = reg.substr (1);
596
if (reg.left_string (1) == "F")
593
if (reg.substr (0, 1) == "F")
598
Stencil d = fm->find_by_name ("accordion-accDot");
595
Stencil d = fm->find_by_name ("accordion.accDot");
599
596
d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
600
597
m.add_stencil (d);
601
reg = reg.right_string (reg.length ()-1);
598
reg = reg.substr (1);
603
if (reg.left_string (1) == "M")
600
if (reg.substr (0, 1) == "M")
605
Stencil d = fm->find_by_name ("accordion-accDot");
602
Stencil d = fm->find_by_name ("accordion.accDot");
606
603
d.translate_axis (staff_space * 2 PT, Y_AXIS);
607
604
d.translate_axis (staff_space PT, X_AXIS);
608
605
m.add_stencil (d);
609
reg = reg.right_string (reg.length ()-1);
606
reg = reg.substr (1);
611
if (reg.left_string (1) == "E")
608
if (reg.substr (0, 1) == "E")
613
Stencil d = fm->find_by_name ("accordion-accDot");
610
Stencil d = fm->find_by_name ("accordion.accDot");
614
611
d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
615
612
m.add_stencil (d);
616
reg = reg.right_string (reg.length ()-1);
613
reg = reg.substr (1);
618
if (reg.left_string (1) == "S")
615
if (reg.substr (0, 1) == "S")
620
Stencil d = fm->find_by_name ("accordion-accDot");
617
Stencil d = fm->find_by_name ("accordion.accDot");
621
618
d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
622
619
m.add_stencil (d);
623
reg = reg.right_string (reg.length ()-1);
620
reg = reg.substr (1);
626
623
/* ugh maybe try to use regular font for S.B. and B.B and only use one font
627
624
for the rectangle */
628
625
else if (sym == "SB")
630
Stencil r = fm->find_by_name ("accordion-accSB");
627
Stencil r = fm->find_by_name ("accordion.accSB");
631
628
m.add_stencil (r);
633
630
else if (sym == "BB")
635
Stencil r = fm->find_by_name ("accordion-accBB");
632
Stencil r = fm->find_by_name ("accordion.accBB");
636
633
m.add_stencil (r);
638
635
else if (sym == "OldEE")
640
Stencil r = fm->find_by_name ("accordion-accOldEE");
637
Stencil r = fm->find_by_name ("accordion.accOldEE");
641
638
m.add_stencil (r);
643
640
else if (sym == "OldEES")
645
Stencil r = fm->find_by_name ("accordion-accOldEES");
642
Stencil r = fm->find_by_name ("accordion.accOldEES");
646
643
m.add_stencil (r);
652
649
Lookup::repeat_slash (Real w, Real s, Real t)
654
SCM wid = gh_double2scm (w);
655
SCM sl = gh_double2scm (s);
656
SCM thick = gh_double2scm (t);
652
vector<Offset> points;
653
Real blotdiameter = 0.0;
656
Offset p2 (w, w * s);
658
return Lookup::round_filled_polygon (points, blotdiameter);
661
SCM wid = scm_from_double (w);
662
SCM sl = scm_from_double (s);
663
SCM thick = scm_from_double (t);
657
664
SCM slashnodot = scm_list_n (ly_symbol2scm ("repeat-slash"),
658
wid, sl, thick, SCM_UNDEFINED);
665
wid, sl, thick, SCM_UNDEFINED);
660
Box b (Interval (0, w + sqrt (sqr (t/s) + sqr (t))),
667
Box b (Interval (0, w + sqrt (sqr (t / s) + sqr (t))),
661
668
Interval (0, w * s));
663
670
return Stencil (b, slashnodot); // http://slashnodot.org
668
674
Lookup::bracket (Axis a, Interval iv, Real thick, Real protude, Real blot)
671
Axis other = Axis ((a+1)%2);
677
Axis other = Axis ((a + 1)%2);
673
679
b[other] = Interval (-1, 1) * thick * 0.5;
675
Stencil m = round_filled_box (b, blot);
681
Stencil m = round_filled_box (b, blot);
677
683
b[a] = Interval (iv[UP] - thick, iv[UP]);
678
Interval oi = Interval (-thick/2, thick/2 + fabs (protude)) ;
679
oi *= sign (protude);
684
Interval oi = Interval (-thick / 2, thick / 2 + fabs (protude));
685
oi *= sign (protude);
681
687
m.add_stencil (round_filled_box (b, blot));
682
b[a] = Interval (iv[DOWN], iv[DOWN] +thick);
683
m.add_stencil (round_filled_box (b,blot));
688
b[a] = Interval (iv[DOWN], iv[DOWN] + thick);
689
m.add_stencil (round_filled_box (b, blot));
689
695
Lookup::triangle (Interval iv, Real thick, Real protude)
693
b[Y_AXIS] = Interval (0 <? protude , 0 >? protude);
695
SCM s = scm_list_n (ly_symbol2scm ("symmetric-x-triangle"),
696
gh_double2scm (thick),
697
gh_double2scm (iv.length ()),
698
gh_double2scm (protude), SCM_UNDEFINED);
700
return Stencil (b, s);
704
LY_DEFINE (ly_bracket ,"ly:bracket",
706
(SCM a, SCM iv, SCM t, SCM p),
707
"Make a bracket in direction @var{a}. The extent of the bracket is "
708
"given by @var{iv}. The wings protude by an amount of @var{p}, which "
709
"may be negative. The thickness is given by @var{t}.")
711
SCM_ASSERT_TYPE (is_axis (a), a, SCM_ARG1, __FUNCTION__, "axis") ;
712
SCM_ASSERT_TYPE (is_number_pair (iv), iv, SCM_ARG2, __FUNCTION__, "number pair") ;
713
SCM_ASSERT_TYPE (gh_number_p (t), a, SCM_ARG3, __FUNCTION__, "number") ;
714
SCM_ASSERT_TYPE (gh_number_p (p), a, SCM_ARG4, __FUNCTION__, "number") ;
717
return Lookup::bracket ((Axis)gh_scm2int (a), ly_scm2interval (iv),
720
0.95 * gh_scm2double (t)).smobbed_copy ();
725
LY_DEFINE (ly_filled_box ,"ly:round-filled-box",
727
(SCM xext, SCM yext, SCM blot),
728
"Make a @code{Stencil} "
729
"that prints a black box of dimensions @var{xext}, "
730
"@var{yext} and roundness @var{blot}."
733
SCM_ASSERT_TYPE (is_number_pair (xext), xext, SCM_ARG1, __FUNCTION__, "number pair") ;
734
SCM_ASSERT_TYPE (is_number_pair (yext), yext, SCM_ARG2, __FUNCTION__, "number pair") ;
735
SCM_ASSERT_TYPE (gh_number_p (blot), blot, SCM_ARG3, __FUNCTION__, "number") ;
737
return Lookup::round_filled_box (Box (ly_scm2interval (xext), ly_scm2interval (yext)),
738
gh_scm2double (blot)).smobbed_copy ();
698
b[X_AXIS] = Interval (0, iv.length ());
699
b[Y_AXIS] = Interval (min (0., protude), max (0.0, protude));
701
Offset z1 (iv[LEFT], 0);
702
Offset z2 (iv[RIGHT], 0);
703
Offset z3 ((z1 + z2)[X_AXIS] / 2, protude);
706
TODO: move Triangle to Line_interface ?
708
Stencil tri = Line_interface::make_line (thick, z1, z2);
709
tri.add_stencil (Line_interface::make_line (thick, z2, z3));
710
tri.add_stencil (Line_interface::make_line (thick, z3, z1));