Generation
This commit is contained in:
@@ -53,14 +53,14 @@ def column(index: generator.engraving.notation.ScoreIndex, time: fractions.Fract
|
||||
measure_start, _, measure = index.measure_at(time)
|
||||
for owner, _, item in index.harmonies_by_onset.get(time, []):
|
||||
if owner is measure:
|
||||
items.append(fonts.text(generator.harmony.symbol(item), 0, 0, 21, 'harmony', (item['id'],)))
|
||||
items.append(fonts.text(generator.harmony.symbol(item), 0, 0, 18 if index.staff.get('tablature') else 21, 'harmony', (item['id'],)))
|
||||
for owner, i, value in index.tempos_by_onset.get(time, []):
|
||||
if owner is measure:
|
||||
items.extend(generator.engraving.attributes.tempo(value, fonts, 0, 0, style.space, measure['id'] + f':tempo:{i}'))
|
||||
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, 19, 'section', (measure['id'] + ':section',)))
|
||||
items.append(fonts.text(label, 0, 0, 16 if index.staff.get('tablature') else 19, 'section', (measure['id'] + ':section',)))
|
||||
return items, anchors, fragments
|
||||
|
||||
def column_metrics(index, time, start, end, fonts, style, columns):
|
||||
@@ -157,14 +157,12 @@ def make_system(index: generator.engraving.notation.ScoreIndex, start: fractions
|
||||
|
||||
def paginate(systems: list[generator.engraving.types.System], document: dict, fonts: generator.engraving.fonts.Fonts, style: generator.engraving.types.Style) -> tuple[generator.engraving.types.Page, ...]:
|
||||
pages = []
|
||||
placed = []
|
||||
header = []
|
||||
cursor = style.margin_y
|
||||
first = True
|
||||
guitar = document['staves'][0].get('tablature', False)
|
||||
header_gap = 14 if guitar else 24
|
||||
|
||||
def page_header(number):
|
||||
title = document['metadata']['title']
|
||||
size = 26 if number == 1 else 17
|
||||
size = (20 if number == 1 else 16) if guitar else (26 if number == 1 else 17)
|
||||
item = fonts.text(title, style.margin_x, style.margin_y + size, size, 'title', ())
|
||||
while item.box.right > style.width - style.margin_x and size > 12:
|
||||
size -= 1
|
||||
@@ -175,32 +173,23 @@ def paginate(systems: list[generator.engraving.types.System], document: dict, fo
|
||||
if number == 1:
|
||||
subtitle = ' - '.join(str(value) for value in (document['metadata'].get('composer'), document['staves'][0].get('name')) if value)
|
||||
if subtitle:
|
||||
result.append(fonts.text(subtitle, style.margin_x, item.box.bottom + 22, 16, 'subtitle', ()))
|
||||
result.append(fonts.text(subtitle, style.margin_x, item.box.bottom + (15 if guitar else 22), 12 if guitar else 16, 'subtitle', ()))
|
||||
return result
|
||||
|
||||
for system in systems:
|
||||
height = system.box.bottom - system.box.top
|
||||
if first:
|
||||
header = page_header(len(pages) + 1)
|
||||
cursor = generator.engraving.types.bounds(header).bottom + 24
|
||||
first = False
|
||||
if cursor + height > style.height - style.margin_y - 18:
|
||||
if not placed:
|
||||
raise generator.engraving.types.EngravingError(f'at musical offset {system.start}: simultaneous notation needs {height:.1f}px vertically; fixed-size page cannot fit it')
|
||||
number = len(pages) + 1
|
||||
footer = fonts.text(str(number), style.width / 2, style.height - style.margin_y, 12, 'page-number', (), True)
|
||||
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])))
|
||||
placed = []
|
||||
header = page_header(len(pages) + 1)
|
||||
cursor = generator.engraving.types.bounds(header).bottom + 24
|
||||
if cursor + height > style.height - style.margin_y - 18:
|
||||
raise generator.engraving.types.EngravingError(f'at musical offset {system.start}: simultaneous notation is too tall for a page')
|
||||
dx, dy = style.margin_x + 1, cursor - system.box.top
|
||||
moved = 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))
|
||||
placed.append(moved)
|
||||
cursor += height + style.system_gap
|
||||
if placed:
|
||||
for first in range(0, len(systems), 2):
|
||||
number = len(pages) + 1
|
||||
header = page_header(number)
|
||||
top = generator.engraving.types.bounds(header).bottom + header_gap
|
||||
row_height = (style.height - style.margin_y - 24 - top - style.system_gap) / 2
|
||||
if row_height <= 0:
|
||||
raise generator.engraving.types.EngravingError('page header leaves no room for two music systems')
|
||||
pair = systems[first:first + 2]
|
||||
scale = min(1, row_height / max(s.box.bottom - s.box.top for s in pair))
|
||||
placed = []
|
||||
for row, system in enumerate(pair):
|
||||
system = system.scaled(scale)
|
||||
dx, dy = style.margin_x + 1, top + row * (row_height + style.system_gap) - 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)))
|
||||
footer = fonts.text(str(number), style.width / 2, style.height - style.margin_y, 12, 'page-number', (), True)
|
||||
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)
|
||||
@@ -240,6 +229,7 @@ def layout_systems(document: dict, style: generator.engraving.types.Style, fonts
|
||||
return tuple(systems)
|
||||
|
||||
def layout_score(document: dict, style: generator.engraving.types.Style, fonts: generator.engraving.fonts.Fonts) -> generator.engraving.types.LayoutDocument:
|
||||
style = generator.engraving.types.score_style(document, style)
|
||||
systems = layout_systems(document, style, fonts)
|
||||
layout = generator.engraving.types.LayoutDocument(paginate(systems, document, fonts, style), style, fonts.fingerprint(style))
|
||||
generator.engraving.audit.audit_layout(document, layout, fonts)
|
||||
|
||||
Reference in New Issue
Block a user