@@ -57,7 +57,6 @@ def column(index: generator.engraving.notation.ScoreIndex, time: fractions.Fract
|
||||
items.append(fonts.text(generator.harmony.symbol(item), 0, 0, 18 if index.staff.get('tablature') else 21, 'harmony', (item['id'],)))
|
||||
items.extend(generator.engraving.scales.column(index, time, start, fonts))
|
||||
if time == measure_start:
|
||||
items.append(fonts.text(str(measure['number']), 0, -style.space * (index.state(time)['staff_details']['lines'] + 0.5), 12, 'measure_number', (measure['id'],)))
|
||||
if label := measure.get('section_label'):
|
||||
items.append(fonts.text(label, 0, 0, 16 if index.staff.get('tablature') else 19, 'section', (measure['id'] + ':section',)))
|
||||
return items, anchors, fragments
|
||||
@@ -103,6 +102,10 @@ def make_system(index: generator.engraving.notation.ScoreIndex, start: fractions
|
||||
for owner, ci, change in index.attributes_by_onset.get(time, []):
|
||||
extra = generator.engraving.attributes.staff_attributes(index, index.state(time), time, fonts, style.space, owner['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 time == measure_start:
|
||||
# Anchor labels to the barline, not to the first note's time column.
|
||||
bar_x = cursor - generator.engraving.types.bounds(leading).left if leading else 0
|
||||
items.append(fonts.text(str(m['number']), bar_x, 0, 12, 'measure_number', (m['id'],), True))
|
||||
if leading:
|
||||
width = generator.engraving.types.bounds(leading).right - generator.engraving.types.bounds(leading).left + 14
|
||||
items.extend(p.moved(cursor - generator.engraving.types.bounds(leading).left, 0) for p in leading)
|
||||
@@ -162,7 +165,7 @@ def fit_part_systems(systems, index, available_height, fonts, style):
|
||||
|
||||
def fitting_scale(items):
|
||||
scale = 1
|
||||
for first in range(0, len(items), 2):
|
||||
for first in range(len(items)):
|
||||
pair = items[first:first + 2]
|
||||
height = sum(s.box.bottom - s.box.top for s in pair)
|
||||
scale = min(scale, (available_height - style.system_gap * (len(pair) - 1)) / height)
|
||||
@@ -214,30 +217,36 @@ def part_header(document, fonts, style):
|
||||
result.append(fonts.text(line, style.margin_x, baseline, 12, 'subtitle', ()))
|
||||
return result
|
||||
|
||||
def paginate(systems: list[generator.engraving.types.System], document: dict, fonts: generator.engraving.fonts.Fonts, style: generator.engraving.types.Style, *, index=None) -> tuple[generator.engraving.types.Page, ...]:
|
||||
pages = []
|
||||
def page_views(systems: list[generator.engraving.types.System], document: dict, fonts: generator.engraving.fonts.Fonts, style: generator.engraving.types.Style, *, index=None) -> tuple[tuple[generator.engraving.types.Page, ...], tuple[generator.engraving.types.Page, ...]]:
|
||||
index = index or generator.engraving.notation.ScoreIndex(document)
|
||||
header = part_header(document, fonts, style)
|
||||
top = generator.engraving.types.bounds(header).bottom + style.page_clearance
|
||||
footers = [fonts.text(str(number), style.width / 2, style.height - style.margin_y, 12, 'page_number', (), True) for number in range(1, (len(systems) + 1) // 2 + 1)]
|
||||
footers = [fonts.text(str(number), style.width / 2, style.height - style.margin_y, 12, 'page_number', (), True) for number in range(1, len(systems) + 1)]
|
||||
bottom = min(p.box.top for p in footers) - style.page_clearance
|
||||
if bottom - top <= style.system_gap:
|
||||
raise generator.engraving.types.EngravingError('page header leaves no room for two music systems')
|
||||
fitted = fit_part_systems(systems, index, bottom - top, fonts, style)
|
||||
for first in range(0, len(systems), 2):
|
||||
number = len(pages) + 1
|
||||
pair = fitted[first:first + 2]
|
||||
slack = max(0, bottom - top - sum(s.box.bottom - s.box.top for s in pair) - style.system_gap * (len(pair) - 1))
|
||||
spacing = slack / 3 if len(pair) == 2 else 0
|
||||
cursor = top + spacing
|
||||
placed = []
|
||||
for system in pair:
|
||||
dx, dy = style.margin_x + 1, cursor - system.box.top
|
||||
placed.append(dataclasses.replace(system, primitives=tuple(p.moved(dx, dy) for p in system.primitives), anchors=tuple(a.moved(dx, dy) for a in system.anchors), box=system.box.moved(dx, dy)))
|
||||
cursor = placed[-1].box.bottom + style.system_gap + spacing
|
||||
footer = footers[first // 2]
|
||||
pages.append(generator.engraving.types.Page(number, style.width, style.height, style.supersampling, tuple(placed), tuple(header + [p for s in placed for p in s.primitives] + [footer])))
|
||||
return tuple(pages)
|
||||
|
||||
def place(stride):
|
||||
pages = []
|
||||
for first in range(0, len(fitted), stride):
|
||||
number = len(pages) + 1
|
||||
pair = fitted[first:first + 2]
|
||||
slack = max(0, bottom - top - sum(s.box.bottom - s.box.top for s in pair) - style.system_gap * (len(pair) - 1))
|
||||
spacing = slack / 3 if len(pair) == 2 else 0
|
||||
cursor = top + spacing
|
||||
placed = []
|
||||
for system in pair:
|
||||
dx, dy = style.margin_x + 1, cursor - system.box.top
|
||||
placed.append(dataclasses.replace(system, primitives=tuple(p.moved(dx, dy) for p in system.primitives), anchors=tuple(a.moved(dx, dy) for a in system.anchors), box=system.box.moved(dx, dy)))
|
||||
cursor = placed[-1].box.bottom + style.system_gap + spacing
|
||||
pages.append(generator.engraving.types.Page(number, style.width, style.height, style.supersampling, tuple(placed), tuple(header + [p for s in placed for p in s.primitives] + [footers[number - 1]])))
|
||||
return tuple(pages)
|
||||
|
||||
return place(2), place(1)
|
||||
|
||||
def paginate(systems, document, fonts, style, *, index=None):
|
||||
return page_views(systems, document, fonts, style, index=index)[0]
|
||||
|
||||
def layout_systems(document: dict, style: generator.engraving.types.Style, fonts: generator.engraving.fonts.Fonts, *, index=None) -> tuple[generator.engraving.types.System, ...]:
|
||||
if index is None:
|
||||
|
||||
Reference in New Issue
Block a user