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 cairo
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from HersheyFonts import HersheyFonts
|
||||||
|
|
||||||
|
|
||||||
class Paper:
|
class Paper:
|
||||||
|
@ -135,6 +136,17 @@ A6_PORTRAIT = Paper(105, 148, 8)
|
||||||
A6_LANDSCAPE = Paper(148, 105, 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:
|
class Plotter:
|
||||||
|
|
||||||
def __init__(self, paper, line_width=0, colour=[0, 0, 0, 1]):
|
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.top_left())
|
||||||
self.line_to(self.paper.bottom_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):
|
class SVGPlotter(Plotter):
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ executing==1.2.0
|
||||||
fastjsonschema==2.16.2
|
fastjsonschema==2.16.2
|
||||||
fonttools==4.38.0
|
fonttools==4.38.0
|
||||||
fqdn==1.5.1
|
fqdn==1.5.1
|
||||||
|
Hershey-Fonts==2.1.0
|
||||||
idna==3.4
|
idna==3.4
|
||||||
ipykernel==6.19.2
|
ipykernel==6.19.2
|
||||||
ipython==8.7.0
|
ipython==8.7.0
|
||||||
|
|
Loading…
Reference in a new issue