1*e1fe3e4aSElliott Hughesfrom fontTools.misc.transform import ( 2*e1fe3e4aSElliott Hughes Transform, 3*e1fe3e4aSElliott Hughes Identity, 4*e1fe3e4aSElliott Hughes Offset, 5*e1fe3e4aSElliott Hughes Scale, 6*e1fe3e4aSElliott Hughes DecomposedTransform, 7*e1fe3e4aSElliott Hughes) 8*e1fe3e4aSElliott Hughesimport math 9*e1fe3e4aSElliott Hughesimport pytest 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughes 12*e1fe3e4aSElliott Hughesclass TransformTest(object): 13*e1fe3e4aSElliott Hughes def test_examples(self): 14*e1fe3e4aSElliott Hughes t = Transform() 15*e1fe3e4aSElliott Hughes assert repr(t) == "<Transform [1 0 0 1 0 0]>" 16*e1fe3e4aSElliott Hughes assert t.scale(2) == Transform(2, 0, 0, 2, 0, 0) 17*e1fe3e4aSElliott Hughes assert t.scale(2.5, 5.5) == Transform(2.5, 0, 0, 5.5, 0, 0) 18*e1fe3e4aSElliott Hughes assert t.scale(2, 3).transformPoint((100, 100)) == (200, 300) 19*e1fe3e4aSElliott Hughes 20*e1fe3e4aSElliott Hughes def test__init__(self): 21*e1fe3e4aSElliott Hughes assert Transform(12) == Transform(12, 0, 0, 1, 0, 0) 22*e1fe3e4aSElliott Hughes assert Transform(dx=12) == Transform(1, 0, 0, 1, 12, 0) 23*e1fe3e4aSElliott Hughes assert Transform(yx=12) == Transform(1, 0, 12, 1, 0, 0) 24*e1fe3e4aSElliott Hughes 25*e1fe3e4aSElliott Hughes def test_transformPoints(self): 26*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, 0, 0) 27*e1fe3e4aSElliott Hughes assert t.transformPoints([(0, 0), (0, 100), (100, 100), (100, 0)]) == [ 28*e1fe3e4aSElliott Hughes (0, 0), 29*e1fe3e4aSElliott Hughes (0, 300), 30*e1fe3e4aSElliott Hughes (200, 300), 31*e1fe3e4aSElliott Hughes (200, 0), 32*e1fe3e4aSElliott Hughes ] 33*e1fe3e4aSElliott Hughes 34*e1fe3e4aSElliott Hughes def test_transformVector(self): 35*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, -10, 30) 36*e1fe3e4aSElliott Hughes assert t.transformVector((-4, 5)) == (-8, 15) 37*e1fe3e4aSElliott Hughes 38*e1fe3e4aSElliott Hughes def test_transformVectors(self): 39*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, -10, 30) 40*e1fe3e4aSElliott Hughes assert t.transformVectors([(-4, 5), (-6, 7)]) == [(-8, 15), (-12, 21)] 41*e1fe3e4aSElliott Hughes 42*e1fe3e4aSElliott Hughes def test_translate(self): 43*e1fe3e4aSElliott Hughes t = Transform() 44*e1fe3e4aSElliott Hughes assert t.translate(20, 30) == Transform(1, 0, 0, 1, 20, 30) 45*e1fe3e4aSElliott Hughes 46*e1fe3e4aSElliott Hughes def test_scale(self): 47*e1fe3e4aSElliott Hughes t = Transform() 48*e1fe3e4aSElliott Hughes assert t.scale(5) == Transform(5, 0, 0, 5, 0, 0) 49*e1fe3e4aSElliott Hughes assert t.scale(5, 6) == Transform(5, 0, 0, 6, 0, 0) 50*e1fe3e4aSElliott Hughes 51*e1fe3e4aSElliott Hughes def test_rotate(self): 52*e1fe3e4aSElliott Hughes t = Transform() 53*e1fe3e4aSElliott Hughes assert t.rotate(math.pi / 2) == Transform(0, 1, -1, 0, 0, 0) 54*e1fe3e4aSElliott Hughes t = Transform() 55*e1fe3e4aSElliott Hughes assert t.rotate(-math.pi / 2) == Transform(0, -1, 1, 0, 0, 0) 56*e1fe3e4aSElliott Hughes t = Transform() 57*e1fe3e4aSElliott Hughes assert tuple(t.rotate(math.radians(30))) == pytest.approx( 58*e1fe3e4aSElliott Hughes tuple(Transform(0.866025, 0.5, -0.5, 0.866025, 0, 0)) 59*e1fe3e4aSElliott Hughes ) 60*e1fe3e4aSElliott Hughes 61*e1fe3e4aSElliott Hughes def test_skew(self): 62*e1fe3e4aSElliott Hughes t = Transform().skew(math.pi / 4) 63*e1fe3e4aSElliott Hughes assert tuple(t) == pytest.approx(tuple(Transform(1, 0, 1, 1, 0, 0))) 64*e1fe3e4aSElliott Hughes 65*e1fe3e4aSElliott Hughes def test_transform(self): 66*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, 1, 6) 67*e1fe3e4aSElliott Hughes assert t.transform((4, 3, 2, 1, 5, 6)) == Transform(8, 9, 4, 3, 11, 24) 68*e1fe3e4aSElliott Hughes 69*e1fe3e4aSElliott Hughes def test_reverseTransform(self): 70*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, 1, 6) 71*e1fe3e4aSElliott Hughes reverse_t = t.reverseTransform((4, 3, 2, 1, 5, 6)) 72*e1fe3e4aSElliott Hughes assert reverse_t == Transform(8, 6, 6, 3, 21, 15) 73*e1fe3e4aSElliott Hughes t = Transform(4, 3, 2, 1, 5, 6) 74*e1fe3e4aSElliott Hughes reverse_t = t.transform((2, 0, 0, 3, 1, 6)) 75*e1fe3e4aSElliott Hughes assert reverse_t == Transform(8, 6, 6, 3, 21, 15) 76*e1fe3e4aSElliott Hughes 77*e1fe3e4aSElliott Hughes def test_inverse(self): 78*e1fe3e4aSElliott Hughes t = Transform().translate(2, 3).scale(4, 5) 79*e1fe3e4aSElliott Hughes assert t.transformPoint((10, 20)) == (42, 103) 80*e1fe3e4aSElliott Hughes it = t.inverse() 81*e1fe3e4aSElliott Hughes assert it.transformPoint((42, 103)) == (10.0, 20.0) 82*e1fe3e4aSElliott Hughes assert Transform().inverse() == Transform() 83*e1fe3e4aSElliott Hughes 84*e1fe3e4aSElliott Hughes def test_toPS(self): 85*e1fe3e4aSElliott Hughes t = Transform().scale(2, 3).translate(4, 5) 86*e1fe3e4aSElliott Hughes assert t.toPS() == "[2 0 0 3 8 15]" 87*e1fe3e4aSElliott Hughes 88*e1fe3e4aSElliott Hughes def test__ne__(self): 89*e1fe3e4aSElliott Hughes assert Transform() != Transform(2, 0, 0, 2, 0, 0) 90*e1fe3e4aSElliott Hughes 91*e1fe3e4aSElliott Hughes def test__hash__(self): 92*e1fe3e4aSElliott Hughes t = Transform(12, 0, 0, 13, 0, 0) 93*e1fe3e4aSElliott Hughes d = {t: None} 94*e1fe3e4aSElliott Hughes assert t in d.keys() 95*e1fe3e4aSElliott Hughes 96*e1fe3e4aSElliott Hughes def test__bool__(self): 97*e1fe3e4aSElliott Hughes assert not bool(Transform()) 98*e1fe3e4aSElliott Hughes assert Transform(2, 0, 0, 2, 0, 0) 99*e1fe3e4aSElliott Hughes assert Transform(1, 0, 0, 1, 1, 0) 100*e1fe3e4aSElliott Hughes 101*e1fe3e4aSElliott Hughes def test__repr__(self): 102*e1fe3e4aSElliott Hughes assert repr(Transform(1, 2, 3, 4, 5, 6)) == "<Transform [1 2 3 4 5 6]>" 103*e1fe3e4aSElliott Hughes 104*e1fe3e4aSElliott Hughes def test_Identity(self): 105*e1fe3e4aSElliott Hughes assert isinstance(Identity, Transform) 106*e1fe3e4aSElliott Hughes assert Identity == Transform(1, 0, 0, 1, 0, 0) 107*e1fe3e4aSElliott Hughes 108*e1fe3e4aSElliott Hughes def test_Offset(self): 109*e1fe3e4aSElliott Hughes assert Offset() == Transform(1, 0, 0, 1, 0, 0) 110*e1fe3e4aSElliott Hughes assert Offset(1) == Transform(1, 0, 0, 1, 1, 0) 111*e1fe3e4aSElliott Hughes assert Offset(1, 2) == Transform(1, 0, 0, 1, 1, 2) 112*e1fe3e4aSElliott Hughes 113*e1fe3e4aSElliott Hughes def test_Scale(self): 114*e1fe3e4aSElliott Hughes assert Scale(1) == Transform(1, 0, 0, 1, 0, 0) 115*e1fe3e4aSElliott Hughes assert Scale(2) == Transform(2, 0, 0, 2, 0, 0) 116*e1fe3e4aSElliott Hughes assert Scale(1, 2) == Transform(1, 0, 0, 2, 0, 0) 117*e1fe3e4aSElliott Hughes 118*e1fe3e4aSElliott Hughes def test_decompose(self): 119*e1fe3e4aSElliott Hughes t = Transform(2, 0, 0, 3, 5, 7) 120*e1fe3e4aSElliott Hughes d = t.toDecomposed() 121*e1fe3e4aSElliott Hughes assert d.scaleX == 2 122*e1fe3e4aSElliott Hughes assert d.scaleY == 3 123*e1fe3e4aSElliott Hughes assert d.translateX == 5 124*e1fe3e4aSElliott Hughes assert d.translateY == 7 125*e1fe3e4aSElliott Hughes 126*e1fe3e4aSElliott Hughes def test_decompose(self): 127*e1fe3e4aSElliott Hughes t = Transform(-1, 0, 0, 1, 0, 0) 128*e1fe3e4aSElliott Hughes d = t.toDecomposed() 129*e1fe3e4aSElliott Hughes assert d.scaleX == -1 130*e1fe3e4aSElliott Hughes assert d.scaleY == 1 131*e1fe3e4aSElliott Hughes assert d.rotation == 0 132*e1fe3e4aSElliott Hughes 133*e1fe3e4aSElliott Hughes t = Transform(1, 0, 0, -1, 0, 0) 134*e1fe3e4aSElliott Hughes d = t.toDecomposed() 135*e1fe3e4aSElliott Hughes assert d.scaleX == 1 136*e1fe3e4aSElliott Hughes assert d.scaleY == -1 137*e1fe3e4aSElliott Hughes assert d.rotation == 0 138*e1fe3e4aSElliott Hughes 139*e1fe3e4aSElliott Hughes 140*e1fe3e4aSElliott Hughesclass DecomposedTransformTest(object): 141*e1fe3e4aSElliott Hughes def test_identity(self): 142*e1fe3e4aSElliott Hughes t = DecomposedTransform() 143*e1fe3e4aSElliott Hughes assert ( 144*e1fe3e4aSElliott Hughes repr(t) 145*e1fe3e4aSElliott Hughes == "DecomposedTransform(translateX=0, translateY=0, rotation=0, scaleX=1, scaleY=1, skewX=0, skewY=0, tCenterX=0, tCenterY=0)" 146*e1fe3e4aSElliott Hughes ) 147*e1fe3e4aSElliott Hughes assert t == DecomposedTransform(scaleX=1.0) 148*e1fe3e4aSElliott Hughes 149*e1fe3e4aSElliott Hughes def test_scale(self): 150*e1fe3e4aSElliott Hughes t = DecomposedTransform(scaleX=2, scaleY=3) 151*e1fe3e4aSElliott Hughes assert t.scaleX == 2 152*e1fe3e4aSElliott Hughes assert t.scaleY == 3 153*e1fe3e4aSElliott Hughes 154*e1fe3e4aSElliott Hughes def test_toTransform(self): 155*e1fe3e4aSElliott Hughes t = DecomposedTransform(scaleX=2, scaleY=3) 156*e1fe3e4aSElliott Hughes assert t.toTransform() == (2, 0, 0, 3, 0, 0) 157*e1fe3e4aSElliott Hughes 158*e1fe3e4aSElliott Hughes @pytest.mark.parametrize( 159*e1fe3e4aSElliott Hughes "decomposed", 160*e1fe3e4aSElliott Hughes [ 161*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=1, scaleY=0), 162*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=0, scaleY=1), 163*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=1, scaleY=0, rotation=30), 164*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=0, scaleY=1, rotation=30), 165*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=1, scaleY=1), 166*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, scaleY=1), 167*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=1, scaleY=-1), 168*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, scaleY=-1), 169*e1fe3e4aSElliott Hughes DecomposedTransform(rotation=90), 170*e1fe3e4aSElliott Hughes DecomposedTransform(rotation=-90), 171*e1fe3e4aSElliott Hughes DecomposedTransform(skewX=45), 172*e1fe3e4aSElliott Hughes DecomposedTransform(skewY=45), 173*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewX=45), 174*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewY=45), 175*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewX=45), 176*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewY=45), 177*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewX=45, rotation=30), 178*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewY=45, rotation=30), 179*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewX=45, rotation=30), 180*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewY=45, rotation=30), 181*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewX=45, rotation=-30), 182*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-1, skewY=45, rotation=-30), 183*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewX=45, rotation=-30), 184*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-1, skewY=45, rotation=-30), 185*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-2, skewX=45, rotation=30), 186*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-2, skewY=45, rotation=30), 187*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-2, skewX=45, rotation=30), 188*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-2, skewY=45, rotation=30), 189*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-2, skewX=45, rotation=-30), 190*e1fe3e4aSElliott Hughes DecomposedTransform(scaleX=-2, skewY=45, rotation=-30), 191*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-2, skewX=45, rotation=-30), 192*e1fe3e4aSElliott Hughes DecomposedTransform(scaleY=-2, skewY=45, rotation=-30), 193*e1fe3e4aSElliott Hughes ], 194*e1fe3e4aSElliott Hughes ) 195*e1fe3e4aSElliott Hughes def test_roundtrip(lst, decomposed): 196*e1fe3e4aSElliott Hughes assert decomposed.toTransform().toDecomposed().toTransform() == pytest.approx( 197*e1fe3e4aSElliott Hughes tuple(decomposed.toTransform()) 198*e1fe3e4aSElliott Hughes ), decomposed 199