transform
Affine 2D transformation matrix class.
The Transform class implements various transformation matrix operations, both on the matrix itself, as well as on 2D coordinates.
Transform instances are effectively immutable: all methods that operate on the transformation itself always return a new instance. This has as the interesting side effect that Transform instances are hashable, ie. they can be used as dictionary keys.
This module exports the following symbols:
- Transform
this is the main class
- Identity
Transform instance set to the identity transformation
- Offset
Convenience function that returns a translating transformation
- Scale
Convenience function that returns a scaling transformation
The DecomposedTransform class implements a transformation with separate translate, rotation, scale, skew, and transformation-center components.
- Example:
>>> t = Transform(2, 0, 0, 3, 0, 0) >>> t.transformPoint((100, 100)) (200, 300) >>> t = Scale(2, 3) >>> t.transformPoint((100, 100)) (200, 300) >>> t.transformPoint((0, 0)) (0, 0) >>> t = Offset(2, 3) >>> t.transformPoint((100, 100)) (102, 103) >>> t.transformPoint((0, 0)) (2, 3) >>> t2 = t.scale(0.5) >>> t2.transformPoint((100, 100)) (52.0, 53.0) >>> import math >>> t3 = t2.rotate(math.pi / 2) >>> t3.transformPoint((0, 0)) (2.0, 3.0) >>> t3.transformPoint((100, 100)) (-48.0, 53.0) >>> t = Identity.scale(0.5).translate(100, 200).skew(0.1, 0.2) >>> t.transformPoints([(0, 0), (1, 1), (100, 100)]) [(50.0, 100.0), (50.550167336042726, 100.60135501775433), (105.01673360427253, 160.13550177543362)] >>>
- class fontTools.misc.transform.Transform(xx: float = 1, xy: float = 0, yx: float = 0, yy: float = 1, dx: float = 0, dy: float = 0)[source]
Bases:
NamedTuple
2x2 transformation matrix plus offset, a.k.a. Affine transform. Transform instances are immutable: all transforming methods, eg. rotate(), return a new Transform instance.
- Example:
>>> t = Transform() >>> t <Transform [1 0 0 1 0 0]> >>> t.scale(2) <Transform [2 0 0 2 0 0]> >>> t.scale(2.5, 5.5) <Transform [2.5 0 0 5.5 0 0]> >>> >>> t.scale(2, 3).transformPoint((100, 100)) (200, 300)
Transform’s constructor takes six arguments, all of which are optional, and can be used as keyword arguments:
>>> Transform(12) <Transform [12 0 0 1 0 0]> >>> Transform(dx=12) <Transform [1 0 0 1 12 0]> >>> Transform(yx=12) <Transform [1 0 12 1 0 0]>
Transform instances also behave like sequences of length 6:
>>> len(Identity) 6 >>> list(Identity) [1, 0, 0, 1, 0, 0] >>> tuple(Identity) (1, 0, 0, 1, 0, 0)
Transform instances are comparable:
>>> t1 = Identity.scale(2, 3).translate(4, 6) >>> t2 = Identity.translate(8, 18).scale(2, 3) >>> t1 == t2 1
But beware of floating point rounding errors:
>>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) >>> t1 <Transform [0.2 0 0 0.3 0.08 0.18]> >>> t2 <Transform [0.2 0 0 0.3 0.08 0.18]> >>> t1 == t2 0
Transform instances are hashable, meaning you can use them as keys in dictionaries:
>>> d = {Scale(12, 13): None} >>> d {<Transform [12 0 0 13 0 0]>: None}
But again, beware of floating point rounding errors:
>>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) >>> t1 <Transform [0.2 0 0 0.3 0.08 0.18]> >>> t2 <Transform [0.2 0 0 0.3 0.08 0.18]> >>> d = {t1: None} >>> d {<Transform [0.2 0 0 0.3 0.08 0.18]>: None} >>> d[t2] Traceback (most recent call last): File "<stdin>", line 1, in ? KeyError: <Transform [0.2 0 0 0.3 0.08 0.18]>
- xx: float
Alias for field number 0
- xy: float
Alias for field number 1
- yx: float
Alias for field number 2
- yy: float
Alias for field number 3
- dx: float
Alias for field number 4
- dy: float
Alias for field number 5
- transformPoint(p)[source]
Transform a point.
- Example:
>>> t = Transform() >>> t = t.scale(2.5, 5.5) >>> t.transformPoint((100, 100)) (250.0, 550.0)
- transformPoints(points)[source]
Transform a list of points.
- Example:
>>> t = Scale(2, 3) >>> t.transformPoints([(0, 0), (0, 100), (100, 100), (100, 0)]) [(0, 0), (0, 300), (200, 300), (200, 0)] >>>
- transformVector(v)[source]
Transform an (dx, dy) vector, treating translation as zero.
- Example:
>>> t = Transform(2, 0, 0, 2, 10, 20) >>> t.transformVector((3, -4)) (6, -8) >>>
- transformVectors(vectors)[source]
Transform a list of (dx, dy) vector, treating translation as zero.
- Example:
>>> t = Transform(2, 0, 0, 2, 10, 20) >>> t.transformVectors([(3, -4), (5, -6)]) [(6, -8), (10, -12)] >>>
- translate(x: float = 0, y: float = 0)[source]
Return a new transformation, translated (offset) by x, y.
- Example:
>>> t = Transform() >>> t.translate(20, 30) <Transform [1 0 0 1 20 30]> >>>
- scale(x: float = 1, y: float | None = None)[source]
Return a new transformation, scaled by x, y. The ‘y’ argument may be None, which implies to use the x value for y as well.
- Example:
>>> t = Transform() >>> t.scale(5) <Transform [5 0 0 5 0 0]> >>> t.scale(5, 6) <Transform [5 0 0 6 0 0]> >>>
- rotate(angle: float)[source]
Return a new transformation, rotated by ‘angle’ (radians).
- Example:
>>> import math >>> t = Transform() >>> t.rotate(math.pi / 2) <Transform [0 1 -1 0 0 0]> >>>
- skew(x: float = 0, y: float = 0)[source]
Return a new transformation, skewed by x and y.
- Example:
>>> import math >>> t = Transform() >>> t.skew(math.pi / 4) <Transform [1 0 1 1 0 0]> >>>
- transform(other)[source]
Return a new transformation, transformed by another transformation.
- Example:
>>> t = Transform(2, 0, 0, 3, 1, 6) >>> t.transform((4, 3, 2, 1, 5, 6)) <Transform [8 9 4 3 11 24]> >>>
- reverseTransform(other)[source]
Return a new transformation, which is the other transformation transformed by self. self.reverseTransform(other) is equivalent to other.transform(self).
- Example:
>>> t = Transform(2, 0, 0, 3, 1, 6) >>> t.reverseTransform((4, 3, 2, 1, 5, 6)) <Transform [8 6 6 3 21 15]> >>> Transform(4, 3, 2, 1, 5, 6).transform((2, 0, 0, 3, 1, 6)) <Transform [8 6 6 3 21 15]> >>>
- inverse()[source]
Return the inverse transformation.
- Example:
>>> t = Identity.translate(2, 3).scale(4, 5) >>> t.transformPoint((10, 20)) (42, 103) >>> it = t.inverse() >>> it.transformPoint((42, 103)) (10.0, 20.0) >>>
- toPS() str [source]
Return a PostScript representation
- Example:
>>> t = Identity.scale(2, 3).translate(4, 5) >>> t.toPS() '[2 0 0 3 8 15]' >>>
- toDecomposed() DecomposedTransform [source]
Decompose into a DecomposedTransform.
- fontTools.misc.transform.Offset(x: float = 0, y: float = 0) Transform [source]
Return the identity transformation offset by x, y.
- Example:
>>> Offset(2, 3) <Transform [1 0 0 1 2 3]> >>>
- fontTools.misc.transform.Scale(x: float, y: float | None = None) Transform [source]
Return the identity transformation scaled by x, y. The ‘y’ argument may be None, which implies to use the x value for y as well.
- Example:
>>> Scale(2, 3) <Transform [2 0 0 3 0 0]> >>>
- class fontTools.misc.transform.DecomposedTransform(translateX: float = 0, translateY: float = 0, rotation: float = 0, scaleX: float = 1, scaleY: float = 1, skewX: float = 0, skewY: float = 0, tCenterX: float = 0, tCenterY: float = 0)[source]
Bases:
object
The DecomposedTransform class implements a transformation with separate translate, rotation, scale, skew, and transformation-center components.
- translateX: float = 0
- translateY: float = 0
- rotation: float = 0
- scaleX: float = 1
- scaleY: float = 1
- skewX: float = 0
- skewY: float = 0
- tCenterX: float = 0
- tCenterY: float = 0
- classmethod fromTransform(transform)[source]
Return a DecomposedTransform() equivalent of this transformation. The returned solution always has skewY = 0, and angle in the (-180, 180].
- Example:
>>> DecomposedTransform.fromTransform(Transform(3, 0, 0, 2, 0, 0)) DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=3.0, scaleY=2.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0) >>> DecomposedTransform.fromTransform(Transform(0, 0, 0, 1, 0, 0)) DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=0.0, scaleY=1.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0) >>> DecomposedTransform.fromTransform(Transform(0, 0, 1, 1, 0, 0)) DecomposedTransform(translateX=0, translateY=0, rotation=-45.0, scaleX=0.0, scaleY=1.4142135623730951, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0)