@@ -612,4 +612,75 @@ function tie.activate_endpoints(note, tie_mod, for_pageview, tie_prefs)
612
612
end
613
613
end
614
614
615
+ local calc_tie_length = function (note , tie_mod , for_pageview , direction , tie_prefs )
616
+ local cell_metrics_start = finale .FCCellMetrics ()
617
+ local entry_metrics_start = finale .FCEntryMetrics ()
618
+ cell_metrics_start :LoadAtEntry (note .Entry )
619
+ entry_metrics_start :Load (note .Entry )
620
+
621
+ local cell_metrics_end = finale .FCCellMetrics ()
622
+ local entry_metrics_end = finale .FCEntryMetrics ()
623
+ local note_entry_layer , start_note , end_note = tie_span (note , false )
624
+ if tie_mod :IsStartTie () then
625
+ if end_note then
626
+ cell_metrics_end :LoadAtEntry (end_note .Entry )
627
+ entry_metrics_end :Load (end_note .Entry )
628
+ end
629
+ end
630
+
631
+ local lplacement , rplacement = tie .calc_placement (note , tie_mod , for_pageview , direction , tie_prefs )
632
+ local horz_start = 0
633
+ local horz_end = 0
634
+ local incr_start = 0
635
+ local incr_end = 0
636
+
637
+ -- the following default locations are empirically determined.
638
+ local OUTER_NOTE_OFFSET_PCTG = 7.0 / 16.0
639
+ local INNER_INCREMENT = 6
640
+
641
+ local staff_scaling = cell_metrics_start .StaffScaling / 10000.0
642
+ local horz_stretch = for_pageview and 1 or cell_metrics_start .HorizontalStretch / 10000.0
643
+
644
+ if tie_mod :IsStartTie () then
645
+ horz_start = entry_metrics_start :GetNoteLeftPosition (note .NoteIndex ) / horz_stretch
646
+ if lplacement == finale .TIEPLACE_OVERINNER or lplacement == finale .TIEPLACE_OVEROUTERSTEM or lplacement == finale .TIEPLACE_UNDERINNER then
647
+ horz_start = horz_start + entry_metrics_start :GetNoteWidth (note .NoteIndex )
648
+ incr_start = INNER_INCREMENT
649
+ else
650
+ horz_start = horz_start + (entry_metrics_start :GetNoteWidth (note .NoteIndex ) * OUTER_NOTE_OFFSET_PCTG )
651
+ end
652
+ else
653
+ horz_start = (cell_metrics_start .MusicStartPos * staff_scaling ) / horz_stretch
654
+ end
655
+
656
+ if tie_mod :IsStartTie () and (not end_note or cell_metrics_start .StaffSystem ~= cell_metrics_end .StaffSystem ) then
657
+ local next_cell_metrics = finale .FCCellMetrics ()
658
+ local next_metrics_loaded = next_cell_metrics :LoadAtCell (finale .FCCell (note .Entry .Measure + 1 , note .entry .Staff ))
659
+ if not next_metrics_loaded or cell_metrics_start .StaffSystem ~= cell_metrics_end .StaffSystem then
660
+ -- note: a tie to an empty measure on the same system will get here, but
661
+ -- currently we do not correctly calculate its span. To do so we would have to
662
+ -- read the measure separations from the prefs.
663
+ horz_end = (cell_metrics_start .MusicStartPos + cell_metrics_start .Width ) * staff_scaling
664
+ incr_end = cell_metrics_start .RightBarlineWidth
665
+ else
666
+ horz_end = next_cell_metrics .MusicStartPos * staff_scaling
667
+ end
668
+ horz_end = horz_end / horz_stretch
669
+ else
670
+ local entry_metrics = tie_mod :IsStartTie () and cell_metrics_end or cell_metrics_start
671
+ local note_index = start_note .NoteIndex
672
+ if end_note then
673
+ -- if tie_mod:IsStartTie() is true, then end_note will never be nil here (see top if statement),
674
+ -- but the Lua delinter can't figure it out, so use an explicit if statement for end_note.
675
+ note_index = tie_mod :IsStartTie () and end_note .NoteIndex or note_index
676
+ end
677
+ horz_end = entry_metrics :GetNoteLeftPosition (note_index ) / horz_stretch
678
+ if rplacement == finale .TIEPLACE_OVERINNER or rplacement == finale .TIEPLACE_UNDERINNER or rplacement == finale .TIEPLACE_UNDEROUTERSTEM then
679
+ incr_end = - INNER_INCREMENT
680
+ else
681
+ horz_end = horz_end + (entry_metrics_start :GetNoteWidth (note .NoteIndex ) * (1.0 - OUTER_NOTE_OFFSET_PCTG ))
682
+ end
683
+ end
684
+ end
685
+
615
686
return tie
0 commit comments