@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import aggdraw
|
||||
from fontTools.pens.basePen import BasePen
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from generator.engraving.fonts import Fonts
|
||||
from generator.engraving.types import Page
|
||||
|
||||
class OutlinePen(BasePen):
|
||||
def __init__(self, glyphs, scale: float, x: float, y: float):
|
||||
super().__init__(glyphs)
|
||||
self.path = aggdraw.Path()
|
||||
self.scale, self.x, self.y = scale, x, y
|
||||
def point(self, point):
|
||||
return self.x + point[0] * self.scale, self.y - point[1] * self.scale
|
||||
def _moveTo(self, point):
|
||||
self.path.moveto(*self.point(point))
|
||||
def _lineTo(self, point):
|
||||
self.path.lineto(*self.point(point))
|
||||
def _curveToOne(self, first, second, last):
|
||||
self.path.curveto(*self.point(first), *self.point(second), *self.point(last))
|
||||
def _closePath(self):
|
||||
self.path.close()
|
||||
def _endPath(self):
|
||||
pass
|
||||
|
||||
def rasterize_page(page: Page, fonts: Fonts) -> Image.Image:
|
||||
scale = page.supersampling
|
||||
image = Image.new('RGB', (page.width * scale, page.height * scale), 'white')
|
||||
context = aggdraw.Draw(image)
|
||||
for item in page.primitives:
|
||||
points = [(x * scale, y * scale) for x, y in item.points]
|
||||
if item.kind == 'text':
|
||||
continue
|
||||
if item.kind == 'glyph':
|
||||
pen = OutlinePen(fonts.glyphs, item.size * scale / fonts.units, *points[0])
|
||||
fonts.outline(item.value).replay(pen)
|
||||
path = pen.path
|
||||
else:
|
||||
path = aggdraw.Path()
|
||||
path.moveto(*points[0])
|
||||
if item.kind == 'curve':
|
||||
path.curveto(*points[1], *points[2], *points[3])
|
||||
else:
|
||||
for point in points[1:]:
|
||||
path.lineto(*point)
|
||||
if item.kind == 'polygon':
|
||||
path.close()
|
||||
if item.kind in ('glyph', 'polygon'):
|
||||
context.path(path, None, aggdraw.Brush('black'))
|
||||
else:
|
||||
context.path(path, aggdraw.Pen('black', item.thickness * scale))
|
||||
context.flush()
|
||||
drawing = ImageDraw.Draw(image)
|
||||
for item in page.primitives:
|
||||
if item.kind == 'text':
|
||||
drawing.text(tuple(v * scale for v in item.points[0]), item.value, font=fonts.text_font(item.size * scale), anchor='ls', fill='black')
|
||||
return image.resize((page.width, page.height), Image.Resampling.LANCZOS)
|
||||
Reference in New Issue
Block a user