Add functions to draw text
This commit is contained in:
parent
783d8b3868
commit
59f7311ede
55
lib/plot.py
55
lib/plot.py
|
@ -2,6 +2,7 @@
|
|||
|
||||
import cairo
|
||||
import numpy as np
|
||||
from HersheyFonts import HersheyFonts
|
||||
|
||||
|
||||
class Paper:
|
||||
|
@ -135,6 +136,17 @@ A6_PORTRAIT = Paper(105, 148, 8)
|
|||
A6_LANDSCAPE = Paper(148, 105, 8)
|
||||
|
||||
|
||||
def _measure_text(hf, text):
|
||||
points = np.array([point for stroke in hf.strokes_for_text(text)
|
||||
for point in stroke])
|
||||
return {
|
||||
'x': points[:, 0].min(),
|
||||
'y': points[:, 1].min(),
|
||||
'width': points[:, 0].max() - points[:, 0].min(),
|
||||
'height': points[:, 1].max() - points[:, 1].min(),
|
||||
}
|
||||
|
||||
|
||||
class Plotter:
|
||||
|
||||
def __init__(self, paper, line_width=0, colour=[0, 0, 0, 1]):
|
||||
|
@ -174,6 +186,49 @@ class Plotter:
|
|||
self.line_to(self.paper.top_left())
|
||||
self.line_to(self.paper.bottom_left())
|
||||
|
||||
def draw_text(self, text, position, font='futural', height=10, x_scale=1,
|
||||
fit_width=None, fixed_height=True, spacing=None,
|
||||
v_align='baseline', h_align='left'):
|
||||
x, y = position
|
||||
hf = HersheyFonts()
|
||||
hf.load_default_font(font)
|
||||
hf.normalize_rendering(height)
|
||||
hf.render_options['scaley'] *= -1
|
||||
hf.render_options['scalex'] *= x_scale
|
||||
if spacing is not None:
|
||||
hf.render_options['spacing'] = spacing
|
||||
|
||||
hf.render_options['yofs'] -= hf.render_options['base_line']
|
||||
|
||||
metrics = _measure_text(hf, text)
|
||||
|
||||
if fit_width is not None:
|
||||
hf.render_options['scalex'] *= fit_width / metrics['width']
|
||||
hf.render_options['spacing'] *= fit_width / metrics['width']
|
||||
metrics['x'] *= fit_width / metrics['width']
|
||||
if not fixed_height:
|
||||
hf.render_options['scaley'] *= fit_width / metrics['width']
|
||||
metrics['y'] *= fit_width / text_width
|
||||
metrics['height'] *= fit_width / metrics['width']
|
||||
metrics['width'] = fit_width
|
||||
|
||||
if h_align == 'centre':
|
||||
x -= metrics['width'] / 2
|
||||
elif h_align == 'right':
|
||||
x -= metrics['width']
|
||||
|
||||
x -= metrics['x']
|
||||
|
||||
if v_align == 'bottom':
|
||||
y -= metrics['y'] + metrics['height']
|
||||
elif v_align == 'top':
|
||||
y -= metrics['y']
|
||||
|
||||
for s in hf.strokes_for_text(text):
|
||||
self.move_to((s[0][0] + x, s[0][1] + y))
|
||||
for p in s[1:]:
|
||||
self.line_to((p[0] + x, p[1] + y))
|
||||
|
||||
|
||||
class SVGPlotter(Plotter):
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ executing==1.2.0
|
|||
fastjsonschema==2.16.2
|
||||
fonttools==4.38.0
|
||||
fqdn==1.5.1
|
||||
Hershey-Fonts==2.1.0
|
||||
idna==3.4
|
||||
ipykernel==6.19.2
|
||||
ipython==8.7.0
|
||||
|
|
Loading…
Reference in a new issue