forked from jdaly101/kassia
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathscore.py
69 lines (54 loc) · 2.36 KB
/
score.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from typing import List
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Flowable
from drop_cap import Dropcap
from syllable_line import SyllableLine
class Score(Flowable):
def __init__(self, syl_lines: List[SyllableLine] = None,
dropcap: Dropcap = None,
available_width: float = 0):
super().__init__()
self.dropcap: Dropcap = dropcap
self.syl_lines: List[SyllableLine] = syl_lines
self.width: float = self._calc_width(available_width)
self.height: float = self._calc_height()
def _calc_width(self, available_width: float) -> float:
width: float = available_width
if len(self.syl_lines) == 1:
width = self.syl_lines[0].width + getattr(self.dropcap, 'width', 0) + getattr(self.dropcap, 'x_padding', 0)
return width
def _calc_height(self):
height: float = sum(line.height for line in self.syl_lines)
return height
def wrap(self, *args):
return self.width, self.height
def draw(self):
canvas: Canvas = self.canv
canvas.saveState()
canvas.translate(0, self.height - self.syl_lines[0].height)
iter_lines = iter(self.syl_lines)
if self.dropcap:
canvas.saveState()
self.dropcap.draw(canvas)
canvas.translate(self.dropcap.width + self.dropcap.x_padding, 0)
self.syl_lines[0].draw(canvas)
canvas.restoreState()
canvas.translate(0, -self.syl_lines[0].height)
next(iter_lines)
for line in iter_lines:
line.draw(canvas)
canvas.translate(0, -line.height)
canvas.restoreState()
def split(self, avail_width, avail_height):
# If no actual lines, or there's not enough space for even the first line, force new page
# We shouldn't have to check if the first line can fit (ReportLab Flowable code should handle
# that), but RL throws errors if we don't manually check for it here.
if len(self.syl_lines) <= 0 or avail_height < self.syl_lines[0].height:
return []
if avail_height >= self.height:
return [self]
if self.dropcap:
first_line = Score([self.syl_lines.pop(0)], self.dropcap, avail_width)
return [first_line, *self.syl_lines]
else:
return self.syl_lines