Skip to content

Instantly share code, notes, and snippets.

@LettError
Created October 12, 2021 10:10
Show Gist options
  • Save LettError/7bbf52eeadfee6cb16e1afa2b9af802a to your computer and use it in GitHub Desktop.
Save LettError/7bbf52eeadfee6cb16e1afa2b9af802a to your computer and use it in GitHub Desktop.
Horizontal scaling while preserving the italic angle. (by "unskewing" the geometry to "upright", then scaling, then "reskewing" back to the italic angle)
from fontTools.pens.transformPen import TransformPen
from fontTools.pens.pointPen import AbstractPointPen
from fontTools.misc.transform import Transform
import math
from defcon.objects.glyph import Glyph
class TransformPen2(TransformPen):
# because we don't want to change the transform matrix of the actual components
def addComponent(self, glyphName, transformation):
self._outPen.addComponent(glyphName, transformation)
class CenterPen(AbstractPointPen):
def __init__(self):
self.points = []
def beginPath(self):
pass
def endPath(self):
"""End the current sub path."""
pass
def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
"""Add a point to the current sub path."""
if segmentType == None: return
self.points.append(pt)
def addComponent(self, baseGlyphName, transformation):
"""Add a sub glyph."""
pass
def getCenter(self):
if not self.points:
return 0,0
dx = sum([x for x, y in self.points])/len(self.points)
dy = sum([y for x, y in self.points])/len(self.points)
return dx, dy
def italicScale(factor, src, dst, angle):
# apply a horizontal scale while preserving the angle
cp = CenterPen()
src.drawPoints(cp)
dx, dy = cp.getCenter()
# destinationGlyph pen
s = dst.getPen()
# deskew
m = Transform()
m = m.translate(-dx, -dy)
m = m.skew(-math.radians(angle))
m = m.scale(factor, 1)
m = m.skew(math.radians(angle))
m = m.translate((1/factor)*dx, dy)
tp = TransformPen2(s,m)
src.draw(tp)
src.width *= factor
f = CurrentFont()
g = CurrentGlyph()
# horizontal scale factor
factor = 0.56
background = g.getLayer('background')
background.clear()
foreground = g.getLayer("foreground")
italicScale(factor, foreground, background, f.info.italicAngle)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment