@@ -10,6 +10,7 @@ from generator.engraving.attributes import barline, staff_attributes, tempo
|
||||
from generator.engraving.fonts import Fonts
|
||||
from generator.engraving.notation import ScoreIndex
|
||||
from generator.engraving.notes import draw_event
|
||||
from generator.engraving.repeats import draw_boundary, draw_endings
|
||||
from generator.engraving.spans import draw_beams, draw_lyric_spans, draw_spans, place_text_lanes
|
||||
from generator.engraving.types import Anchor, EngravingError, Fragment, LayoutDocument, Page, Primitive, Style, System, bounds, line
|
||||
|
||||
@@ -70,6 +71,12 @@ def make_system(index: ScoreIndex, start: Fraction, end: Fraction, fonts: Fonts,
|
||||
header = staff_attributes(index, state, start, fonts, style.space, measure['id'] + ':initial', ('clef', 'key', 'meter', 'staff_details'))
|
||||
items.extend(header)
|
||||
cursor = max((p.box.right for p in header), default=0) + 22
|
||||
boundary_positions = {start: cursor - 9}
|
||||
if start in index.boundaries and measure.get('repeats', {}).get('left'):
|
||||
initial = draw_boundary(None, measure, cursor, -style.space * (state['staff_details']['lines'] - 1), fonts, style)
|
||||
boundary_positions[start] = cursor
|
||||
items.extend(initial)
|
||||
cursor = max(p.box.right for p in initial) + 18
|
||||
content_left = cursor - 9
|
||||
times = sorted({start} | {t for t in index.columns if start < t < end})
|
||||
placements = []
|
||||
@@ -81,15 +88,18 @@ def make_system(index: ScoreIndex, start: Fraction, end: Fraction, fonts: Fonts,
|
||||
for measure_start, measure_end, m in index.measures:
|
||||
if time == measure_start and time > start:
|
||||
previous = next(previous for a, b, previous in index.measures if b == time)
|
||||
leading.extend(barline(previous.get('barlines', {}).get('right', 'regular'), 0, -style.space * (index.state(time)['staff_details']['lines'] - 1), previous['id']))
|
||||
leading.extend(draw_boundary(previous, m, 0, -style.space * (index.state(time)['staff_details']['lines'] - 1), fonts, style))
|
||||
old_state = index.state(time, before=True)
|
||||
fields = tuple(k for k in ('clef', 'key', 'meter', 'staff_details') if old_state[k] != index.state(time)[k])
|
||||
leading.extend(p.moved(12, 0) for p in staff_attributes(index, index.state(time), time, fonts, style.space, m['id'] + ':initial', fields))
|
||||
offset = max((p.box.right for p in leading), default=0) + 12 if previous.get('repeats') or m.get('repeats') else 12
|
||||
leading.extend(p.moved(offset, 0) for p in staff_attributes(index, index.state(time), time, fonts, style.space, m['id'] + ':initial', fields))
|
||||
for ci, change in enumerate(m.get('attributes', [])):
|
||||
if measure_start + fraction(change['onset']) == time and time > start:
|
||||
extra = staff_attributes(index, index.state(time), time, fonts, style.space, m['id'] + f':attributes:{ci}', tuple(change))
|
||||
leading.extend(p.moved(max((p.box.right for p in leading), default=0) + 10, 0) for p in extra)
|
||||
if leading:
|
||||
if time in index.boundaries:
|
||||
boundary_positions[time] = cursor - bounds(leading).left
|
||||
width = bounds(leading).right - bounds(leading).left + 14
|
||||
items.extend(p.moved(cursor - bounds(leading).left, 0) for p in leading)
|
||||
cursor += width
|
||||
@@ -111,12 +121,18 @@ def make_system(index: ScoreIndex, start: Fraction, end: Fraction, fonts: Fonts,
|
||||
items[first_item:last_item] = [p.moved(i * stretch, 0) for p in items[first_item:last_item]]
|
||||
anchors[first_anchor:last_anchor] = [a.moved(i * stretch, 0) for a in anchors[first_anchor:last_anchor]]
|
||||
placements = [(time, x + i * stretch) for i, (time, x) in enumerate(placements)]
|
||||
boundary_positions = {time: x + times.index(time) * stretch for time, x in boundary_positions.items()}
|
||||
width = available
|
||||
right = width - 5
|
||||
boundary_positions[end] = width - 3
|
||||
last_measure = next(m for a, b, m in index.measures if a < end <= b)
|
||||
if end in index.boundaries and last_measure.get('repeats', {}).get('right'):
|
||||
items.extend(draw_boundary(last_measure, None, width - 3, -style.space * (index.state(end, before=True)['staff_details']['lines'] - 1), fonts, style))
|
||||
items = draw_beams(index, anchors, items, start, end, content_left, right, style)
|
||||
items = draw_spans(index, anchors, items, start, end, content_left, right, fonts, style)
|
||||
items = place_text_lanes(items, fonts, style)
|
||||
items = draw_lyric_spans(index, items, anchors, start, end, content_left, right, fonts)
|
||||
items = draw_endings(index, items, start, end, boundary_positions, fonts, style)
|
||||
# Staff lines are interrupted behind TAB numerals, not painted through them.
|
||||
changes = [(0, state['staff_details']['lines'])]
|
||||
for time, x in placements:
|
||||
@@ -135,11 +151,11 @@ def make_system(index: ScoreIndex, start: Fraction, end: Fraction, fonts: Fonts,
|
||||
staff_lines.append(line('staff', (), ((cursor, y), (a, y)), style.space * 0.13))
|
||||
cursor = max(cursor, b)
|
||||
items = staff_lines + items
|
||||
last_measure = next(m for a, b, m in index.measures if a < end <= b)
|
||||
if end in index.boundaries:
|
||||
items.extend(barline(last_measure.get('barlines', {}).get('right', 'regular'), width - 1, -style.space * (index.state(end, before=True)['staff_details']['lines'] - 1), last_measure['id']))
|
||||
if end in index.boundaries and not last_measure.get('repeats', {}).get('right'):
|
||||
items.extend(draw_boundary(last_measure, None, width - (3 if last_measure.get('repeats') else 1), -style.space * (index.state(end, before=True)['staff_details']['lines'] - 1), fonts, style))
|
||||
if start in index.boundaries:
|
||||
items.extend(barline(measure.get('barlines', {}).get('left', 'none'), 0, -style.space * (state['staff_details']['lines'] - 1), measure['id']))
|
||||
if not measure.get('repeats', {}).get('left'):
|
||||
items.extend(barline(measure.get('barlines', {}).get('left', 'none'), 0, -style.space * (state['staff_details']['lines'] - 1), measure['id']))
|
||||
else:
|
||||
items.append(fonts.text(str(measure['number']) + ' (cont.)', 0, min(p.box.top for p in items) - 6, 12, 'continuation', (measure['id'],)))
|
||||
return System(start, end, tuple(items), tuple(anchors), tuple(fragments), bounds(items))
|
||||
|
||||
Reference in New Issue
Block a user