File indexing completed on 2025-04-27 04:01:22

0001 import math
0002 from .. import base
0003 from lottie.parsers.sif import api, builder, ast
0004 from lottie import objects
0005 from lottie.nvector import NVector
0006 from lottie.utils.color import Color
0007 
0008 
0009 class TestSifBuilder(base.TestCase):
0010     def test_empty(self):
0011         lot = objects.Animation()
0012         lot.width = 123
0013         lot.height = 456
0014         lot.frame_rate = 69
0015         lot.in_point = 3
0016         lot.out_point = 7
0017         lot.name = "test"
0018         sif = builder.to_sif(lot)
0019         self.assertEqual(sif.width, lot.width)
0020         self.assertEqual(sif.height, lot.height)
0021         self.assertEqual(sif.fps, lot.frame_rate)
0022         self.assertEqual(sif.begin_time, api.FrameTime.frame(3))
0023         self.assertEqual(sif.end_time, api.FrameTime.frame(7))
0024         self.assertEqual(sif.name, lot.name)
0025 
0026     def _visualize_test(self, lot):
0027         from lottie.exporters.core import export_embedded_html
0028         export_embedded_html(lot, "/tmp/testout.html")
0029         sif = builder.to_sif(lot)
0030         with open("/tmp/testout.sif", "w") as sifile:
0031             sif.to_xml().writexml(sifile, "", "  ", "\n")
0032 
0033     def test_star_fill(self):
0034         lot = objects.Animation()
0035         sl = lot.add_layer(objects.ShapeLayer())
0036 
0037         star = sl.add_shape(objects.Star())
0038         star.name = "Star"
0039         star.rotation.value = 20
0040         star.inner_radius.value = 64
0041         star.outer_radius.value = 128
0042         star.position.value = NVector(256, 256)
0043         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0044 
0045         sif = builder.to_sif(lot)
0046         self.assertEqual(len(sif.layers), 1)
0047         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0048 
0049         grp = sif.layers[0]
0050         self.assertEqual(len(grp.layers), 1)
0051         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0052         self.assertTrue(grp.active)
0053 
0054         rgl = grp.layers[0]
0055         self.assertEqual(rgl.desc, "Star")
0056         self.assertEqual(len(rgl.bline.points), 10)
0057         self.assert_nvector_equal(rgl.origin.value, star.position.value)
0058         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1))
0059         self.assertTrue(rgl.active)
0060 
0061         # TODO check points?
0062 
0063     def test_star_hidden_parent(self):
0064         lot = objects.Animation()
0065         sl = lot.add_layer(objects.ShapeLayer())
0066         sl.hidden = True
0067 
0068         star = sl.add_shape(objects.Star())
0069         star.name = "Star"
0070         star.rotation.value = 20
0071         star.inner_radius.value = 64
0072         star.outer_radius.value = 128
0073         star.position.value = NVector(256, 256)
0074         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0075 
0076         sif = builder.to_sif(lot)
0077         self.assertEqual(len(sif.layers), 1)
0078         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0079 
0080         grp = sif.layers[0]
0081         self.assertEqual(len(grp.layers), 1)
0082         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0083         self.assertFalse(grp.active)
0084 
0085         rgl = grp.layers[0]
0086         self.assertEqual(rgl.desc, "Star")
0087         self.assertEqual(len(rgl.bline.points), 10)
0088         self.assert_nvector_equal(rgl.origin.value, star.position.value)
0089         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1))
0090         self.assertTrue(rgl.active)
0091 
0092     def test_star_hidden(self):
0093         lot = objects.Animation()
0094         sl = lot.add_layer(objects.ShapeLayer())
0095 
0096         star = sl.add_shape(objects.Star())
0097         star.hidden = True
0098         star.name = "Star"
0099         star.rotation.value = 20
0100         star.inner_radius.value = 64
0101         star.outer_radius.value = 128
0102         star.position.value = NVector(256, 256)
0103         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0104 
0105         sif = builder.to_sif(lot)
0106         self.assertEqual(len(sif.layers), 1)
0107         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0108 
0109         grp = sif.layers[0]
0110         self.assertEqual(len(grp.layers), 1)
0111         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0112         self.assertTrue(grp.active)
0113 
0114         rgl = grp.layers[0]
0115         self.assertEqual(rgl.desc, "Star")
0116         self.assertEqual(len(rgl.bline.points), 10)
0117         self.assert_nvector_equal(rgl.origin.value, star.position.value)
0118         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1))
0119         self.assertFalse(rgl.active)
0120 
0121     def test_star_outline(self):
0122         lot = objects.Animation()
0123         sl = lot.add_layer(objects.ShapeLayer())
0124 
0125         star = sl.add_shape(objects.Star())
0126         star.name = "Star"
0127         star.rotation.value = 20
0128         star.inner_radius.value = 64
0129         star.outer_radius.value = 128
0130         star.position.value = NVector(256, 256)
0131         sl.add_shape(objects.Stroke(Color(1, 1, 0), 10))
0132 
0133         sif = builder.to_sif(lot)
0134         self.assertEqual(len(sif.layers), 1)
0135         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0136 
0137         grp = sif.layers[0]
0138         self.assertEqual(len(grp.layers), 1)
0139         self.assertIsInstance(grp.layers[0], api.OutlineLayer)
0140         self.assertTrue(grp.active)
0141 
0142         rgl = grp.layers[0]
0143         self.assertEqual(rgl.desc, "Star")
0144         self.assertEqual(len(rgl.bline.points), 10)
0145         self.assert_nvector_equal(rgl.origin.value, star.position.value)
0146         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1))
0147         self.assertTrue(rgl.active)
0148         self.assertTrue(rgl.bline.loop)
0149         self.assertEqual(rgl.width.value, 5)
0150 
0151     def test_star_outfill(self):
0152         lot = objects.Animation()
0153         sl = lot.add_layer(objects.ShapeLayer())
0154 
0155         star = sl.add_shape(objects.Star())
0156         star.name = "Star"
0157         star.rotation.value = 20
0158         star.inner_radius.value = 64
0159         star.outer_radius.value = 128
0160         star.position.value = NVector(256, 256)
0161         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0162         sl.add_shape(objects.Stroke(Color(1, 0, 0), 10))
0163 
0164         sif = builder.to_sif(lot)
0165         self.assertEqual(len(sif.layers), 1)
0166         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0167 
0168         grp = sif.layers[0]
0169         self.assertEqual(len(grp.layers), 2)
0170         self.assertTrue(grp.active)
0171 
0172         rgl = grp.layers[1]
0173         self.assertIsInstance(rgl, api.RegionLayer)
0174         self.assertEqual(rgl.desc, "Star")
0175         self.assertEqual(len(rgl.bline.points), 10)
0176         self.assert_nvector_equal(rgl.origin.value, star.position.value)
0177         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1))
0178         self.assertTrue(rgl.active)
0179         self.assertTrue(rgl.bline.loop)
0180 
0181         out = grp.layers[0]
0182         self.assertIsInstance(out, api.OutlineLayer)
0183         self.assertEqual(out.desc, "Star")
0184         self.assertEqual(len(out.bline.points), 10)
0185         self.assert_nvector_equal(out.origin.value, star.position.value)
0186         self.assert_nvector_equal(out.color.value, sif.make_color(1, 0, 0, 1))
0187         self.assertTrue(out.active)
0188         self.assertTrue(out.bline.loop)
0189 
0190     def test_rect(self):
0191         lot = objects.Animation()
0192         sl = lot.add_layer(objects.ShapeLayer())
0193 
0194         rect = sl.add_shape(objects.Rect())
0195         rect.position.value = NVector(256, 256)
0196         rect.size.value = NVector(128, 256)
0197         sl.add_shape(objects.Fill(Color(1, .25, 0)))
0198 
0199         sif = builder.to_sif(lot)
0200         self.assertEqual(len(sif.layers), 1)
0201         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0202 
0203         grp = sif.layers[0]
0204         self.assertEqual(len(grp.layers), 1)
0205         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0206         self.assertTrue(grp.active)
0207 
0208         rgl = grp.layers[0]
0209         self.assertEqual(len(rgl.bline.points), 4)
0210         self.assert_nvector_equal(rgl.origin.value, rect.position.value)
0211         self.assert_nvector_equal(rgl.color.value, sif.make_color(1, .25, 0))
0212         self.assertTrue(rgl.active)
0213 
0214         self.assert_nvector_equal(rgl.bline.points[0].point.value, NVector(-64, -128))
0215         self.assert_nvector_equal(rgl.bline.points[1].point.value, NVector(+64, -128))
0216         self.assert_nvector_equal(rgl.bline.points[2].point.value, NVector(+64, +128))
0217         self.assert_nvector_equal(rgl.bline.points[3].point.value, NVector(-64, +128))
0218 
0219         self.assert_nvector_equal(rgl.bline.points[0].t1.value, NVector(0, 0))
0220         self.assert_nvector_equal(rgl.bline.points[1].t1.value, NVector(0, 0))
0221         self.assert_nvector_equal(rgl.bline.points[2].t1.value, NVector(0, 0))
0222         self.assert_nvector_equal(rgl.bline.points[3].t1.value, NVector(0, 0))
0223 
0224         self.assert_nvector_equal(rgl.bline.points[0].t2.value, NVector(0, 0))
0225         self.assert_nvector_equal(rgl.bline.points[1].t2.value, NVector(0, 0))
0226         self.assert_nvector_equal(rgl.bline.points[2].t2.value, NVector(0, 0))
0227         self.assert_nvector_equal(rgl.bline.points[3].t2.value, NVector(0, 0))
0228 
0229     def test_circle(self):
0230         lot = objects.Animation()
0231         sl = lot.add_layer(objects.ShapeLayer())
0232 
0233         ellipse = sl.add_shape(objects.Ellipse())
0234         ellipse.position.value = NVector(256, 256)
0235         ellipse.size.value = NVector(512, 512)
0236         sl.add_shape(objects.Fill(Color(.25, .25, .25)))
0237 
0238         sif = builder.to_sif(lot)
0239         self.assertEqual(len(sif.layers), 1)
0240         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0241 
0242         grp = sif.layers[0]
0243         self.assertEqual(len(grp.layers), 1)
0244         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0245         self.assertTrue(grp.active)
0246 
0247         rgl = grp.layers[0]
0248         self.assertEqual(len(rgl.bline.points), 4)
0249         self.assert_nvector_equal(rgl.origin.value, ellipse.position.value)
0250         self.assert_nvector_equal(rgl.color.value, sif.make_color(.25, .25, .25))
0251         self.assertTrue(rgl.active)
0252 
0253         self.assert_nvector_equal(rgl.bline.points[0].point.value, NVector(0, 256))
0254         self.assert_nvector_equal(rgl.bline.points[1].point.value, NVector(-256, 0))
0255         self.assert_nvector_equal(rgl.bline.points[2].point.value, NVector(0, -256))
0256         self.assert_nvector_equal(rgl.bline.points[3].point.value, NVector(256, 0))
0257 
0258         self.assertNotAlmostEqual(rgl.bline.points[0].t1.value.x, 0)
0259         self.assertAlmostEqual(rgl.bline.points[0].t1.value.y, 0)
0260 
0261         self.assertNotAlmostEqual(rgl.bline.points[1].t1.value.y, 0)
0262         self.assertAlmostEqual(rgl.bline.points[1].t1.value.x, 0)
0263 
0264         self.assertNotAlmostEqual(rgl.bline.points[2].t1.value.x, 0)
0265         self.assertAlmostEqual(rgl.bline.points[2].t1.value.y, 0)
0266 
0267         self.assertNotAlmostEqual(rgl.bline.points[3].t1.value.y, 0)
0268         self.assertAlmostEqual(rgl.bline.points[3].t1.value.x, 0)
0269 
0270         for i in range(4):
0271             self.assert_nvector_equal(rgl.bline.points[i].t1.value,  rgl.bline.points[i].t2.value)
0272 
0273     def test_bezier(self):
0274         lot = objects.Animation()
0275         sl = lot.add_layer(objects.ShapeLayer())
0276 
0277         shape = sl.add_shape(objects.Path())
0278         sl.add_shape(objects.Fill(Color(0, .25, 1)))
0279         shape.shape.value.closed = True
0280         shape.shape.value.add_point(NVector(256, 0))
0281         shape.shape.value.add_point(NVector(256+128, 256), NVector(0, 0), NVector(64, 128))
0282         shape.shape.value.add_smooth_point(NVector(256, 512), NVector(128, 0))
0283         shape.shape.value.add_point(NVector(256-128, 256), NVector(-64, 128), NVector(0, 0))
0284 
0285         sif = builder.to_sif(lot)
0286         self.assertEqual(len(sif.layers), 1)
0287         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0288 
0289         grp = sif.layers[0]
0290         self.assertEqual(len(grp.layers), 1)
0291         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0292         self.assertTrue(grp.active)
0293 
0294         rgl = grp.layers[0]
0295         self.assertEqual(len(rgl.bline.points), 4)
0296         self.assert_nvector_equal(rgl.color.value, sif.make_color(0, .25, 1))
0297         self.assertTrue(rgl.active)
0298         self.assertTrue(rgl.bline.loop)
0299 
0300         for i in range(len(rgl.bline.points)):
0301             sp = rgl.bline.points[i]
0302             lp = shape.shape.value.vertices[i] - NVector(256, 256)
0303             self.assert_nvector_equal(
0304                 sp.point.value, lp,
0305                 msg="Point %s mismatch %s != %s" % (i, sp.point.value, lp)
0306             )
0307 
0308             lt1 = shape.shape.value.in_tangents[i] * -3
0309             self.assert_nvector_equal(
0310                 sp.t1.value, lt1,
0311                 msg="In Tangent %s mismatch %s != %s" % (i, sp.t1.value, lt1)
0312             )
0313 
0314             lt2 = shape.shape.value.out_tangents[i] * 3
0315             self.assert_nvector_equal(
0316                 sp.t2.value, lt2,
0317                 msg="Out Tangent %s mismatch %s != %s" % (i, sp.t2.value, lt2)
0318             )
0319 
0320     def test_group_opacity(self):
0321         lot = objects.Animation()
0322 
0323         ref_sl = lot.add_layer(objects.ShapeLayer())
0324         ref_rect = ref_sl.add_shape(objects.Rect())
0325         ref_rect.position.value = NVector(128, 128)
0326         ref_rect.size.value = NVector(256, 256)
0327         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0328         ref_sl.transform.opacity.value = 80
0329 
0330         sif = builder.to_sif(lot)
0331         self.assertEqual(len(sif.layers), 1)
0332         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0333         self.assertAlmostEqual(sif.layers[0].amount.value, 0.8)
0334 
0335     def test_group_translate(self):
0336         lot = objects.Animation()
0337 
0338         ref_sl = lot.add_layer(objects.ShapeLayer())
0339         ref_rect = ref_sl.add_shape(objects.Rect())
0340         ref_rect.position.value = NVector(128, 128)
0341         ref_rect.size.value = NVector(256, 256)
0342         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0343         ref_sl.transform.opacity.value = 80
0344 
0345         sl = lot.add_layer(objects.ShapeLayer())
0346         rect = sl.add_shape(objects.Rect())
0347         rect.position.value = NVector(128, 128)
0348         rect.size.value = NVector(256, 256)
0349         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0350 
0351         sl.transform.position.value = NVector(128, 128)
0352 
0353         sif = builder.to_sif(lot)
0354         self.assertEqual(len(sif.layers), 2)
0355         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0356         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0357         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0358         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0359 
0360         self.assert_nvector_equal(sif.layers[0].transformation.offset.value, NVector(128, 128))
0361         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0362 
0363     def test_group_translate_anchor(self):
0364         lot = objects.Animation()
0365 
0366         ref_sl = lot.add_layer(objects.ShapeLayer())
0367         ref_rect = ref_sl.add_shape(objects.Rect())
0368         ref_rect.position.value = NVector(128, 128)
0369         ref_rect.size.value = NVector(256, 256)
0370         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0371         ref_sl.transform.opacity.value = 80
0372 
0373         sl = lot.add_layer(objects.ShapeLayer())
0374         rect = sl.add_shape(objects.Rect())
0375         rect.position.value = NVector(128, 128)
0376         rect.size.value = NVector(256, 256)
0377         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0378 
0379         sl.transform.position.value = NVector(128, 128)
0380         sl.transform.anchor_point.value = NVector(128, 128)
0381 
0382         sif = builder.to_sif(lot)
0383         self.assertEqual(len(sif.layers), 2)
0384         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0385         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0386         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0387         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0388 
0389         self.assert_nvector_equal(sif.layers[0].transformation.offset.value, NVector(128, 128))
0390         self.assert_nvector_equal(sif.layers[0].origin.value, NVector(128, 128))
0391 
0392         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0393         self.assert_nvector_equal(sif.layers[1].origin.value, NVector(0, 0))
0394 
0395     def test_group_rotate(self):
0396         lot = objects.Animation()
0397 
0398         ref_sl = lot.add_layer(objects.ShapeLayer())
0399         ref_rect = ref_sl.add_shape(objects.Rect())
0400         ref_rect.position.value = NVector(128, 128)
0401         ref_rect.size.value = NVector(256, 256)
0402         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0403         ref_sl.transform.opacity.value = 80
0404 
0405         sl = lot.add_layer(objects.ShapeLayer())
0406         rect = sl.add_shape(objects.Rect())
0407         rect.position.value = NVector(128, 128)
0408         rect.size.value = NVector(256, 256)
0409         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0410 
0411         sl.transform.rotation.value = 20
0412 
0413         sif = builder.to_sif(lot)
0414         self.assertEqual(len(sif.layers), 2)
0415         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0416         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0417         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0418         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0419 
0420         self.assertAlmostEqual(sif.layers[0].transformation.angle.value, 20)
0421         self.assertAlmostEqual(sif.layers[1].transformation.angle.value, 0)
0422 
0423     def test_group_rotate_anchor(self):
0424         lot = objects.Animation()
0425 
0426         ref_sl = lot.add_layer(objects.ShapeLayer())
0427         ref_rect = ref_sl.add_shape(objects.Rect())
0428         ref_rect.position.value = NVector(128, 128)
0429         ref_rect.size.value = NVector(256, 256)
0430         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0431         ref_sl.transform.opacity.value = 80
0432 
0433         sl = lot.add_layer(objects.ShapeLayer())
0434         rect = sl.add_shape(objects.Rect())
0435         rect.position.value = NVector(128, 128)
0436         rect.size.value = NVector(256, 256)
0437         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0438 
0439         sl.transform.rotation.value = 20
0440         sl.transform.position.value = NVector(128, 128)
0441         sl.transform.anchor_point.value = NVector(128, 128)
0442 
0443         sif = builder.to_sif(lot)
0444         self.assertEqual(len(sif.layers), 2)
0445         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0446         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0447         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0448         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0449 
0450         self.assertAlmostEqual(sif.layers[0].transformation.angle.value, 20)
0451         self.assertAlmostEqual(sif.layers[1].transformation.angle.value, 0)
0452 
0453         self.assert_nvector_equal(sif.layers[0].transformation.offset.value, NVector(128, 128))
0454         self.assert_nvector_equal(sif.layers[0].origin.value, NVector(128, 128))
0455 
0456         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0457         self.assert_nvector_equal(sif.layers[1].origin.value, NVector(0, 0))
0458 
0459     def test_group_scale(self):
0460         lot = objects.Animation()
0461 
0462         ref_sl = lot.add_layer(objects.ShapeLayer())
0463         ref_rect = ref_sl.add_shape(objects.Rect())
0464         ref_rect.position.value = NVector(128, 128)
0465         ref_rect.size.value = NVector(256, 256)
0466         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0467         ref_sl.transform.opacity.value = 80
0468 
0469         sl = lot.add_layer(objects.ShapeLayer())
0470         rect = sl.add_shape(objects.Rect())
0471         rect.position.value = NVector(128, 128)
0472         rect.size.value = NVector(256, 256)
0473         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0474 
0475         sl.transform.scale.value = NVector(180, 50)
0476         sl.transform.position.value = NVector(256, 256)
0477         sl.transform.anchor_point.value = NVector(128, 128)
0478 
0479         sif = builder.to_sif(lot)
0480         self.assertEqual(len(sif.layers), 2)
0481         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0482         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0483         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0484         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0485 
0486         self.assert_nvector_equal(sif.layers[0].transformation.offset.value, NVector(256, 256))
0487         self.assert_nvector_equal(sif.layers[0].origin.value, NVector(128, 128))
0488         self.assert_nvector_equal(sif.layers[0].transformation.scale.value, NVector(1.8, .5))
0489 
0490         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0491         self.assert_nvector_equal(sif.layers[1].origin.value, NVector(0, 0))
0492         self.assert_nvector_equal(sif.layers[1].transformation.scale.value, NVector(1, 1))
0493 
0494     def test_animated_vector(self):
0495         lot = objects.Animation()
0496 
0497         ref_sl = lot.add_layer(objects.ShapeLayer())
0498         ref_rect = ref_sl.add_shape(objects.Rect())
0499         ref_rect.position.value = NVector(128, 128)
0500         ref_rect.size.value = NVector(256, 256)
0501         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0502         ref_sl.transform.opacity.value = 80
0503 
0504         sl = lot.add_layer(objects.ShapeLayer())
0505         rect = sl.add_shape(objects.Rect())
0506         rect.position.value = NVector(128, 128)
0507         rect.size.value = NVector(256, 256)
0508         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0509 
0510         sl.transform.position.add_keyframe(0, NVector(0, 0))
0511         sl.transform.position.add_keyframe(30, NVector(256, 256))
0512         sl.transform.position.add_keyframe(60, NVector(0, 0))
0513 
0514         sif = builder.to_sif(lot)
0515         self.assertEqual(len(sif.layers), 2)
0516         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0517         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0518         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0519         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0520 
0521         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0522 
0523         off = sif.layers[0].transformation.offset
0524 
0525         self.assert_nvector_equal(off.keyframes[0].value, NVector(0, 0))
0526         self.assert_nvector_equal(off.keyframes[1].value, NVector(256, 256))
0527         self.assert_nvector_equal(off.keyframes[2].value, NVector(0, 0))
0528 
0529         self.assertEqual(off.keyframes[0].time, api.FrameTime.frame(0))
0530         self.assertEqual(off.keyframes[1].time, api.FrameTime.frame(30))
0531         self.assertEqual(off.keyframes[2].time, api.FrameTime.frame(60))
0532 
0533         self.assertEqual(off.keyframes[0].before, api.Interpolation.Linear)
0534         self.assertEqual(off.keyframes[1].before, api.Interpolation.Linear)
0535         self.assertEqual(off.keyframes[2].before, api.Interpolation.Linear)
0536 
0537         self.assertEqual(off.keyframes[0].after, api.Interpolation.Linear)
0538         self.assertEqual(off.keyframes[1].after, api.Interpolation.Linear)
0539         self.assertEqual(off.keyframes[2].after, api.Interpolation.Linear)
0540 
0541     def test_animated_vector_ease(self):
0542         lot = objects.Animation()
0543 
0544         ref_sl = lot.add_layer(objects.ShapeLayer())
0545         ref_rect = ref_sl.add_shape(objects.Rect())
0546         ref_rect.position.value = NVector(128, 128)
0547         ref_rect.size.value = NVector(256, 256)
0548         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0549         ref_sl.transform.opacity.value = 80
0550 
0551         sl = lot.add_layer(objects.ShapeLayer())
0552         rect = sl.add_shape(objects.Rect())
0553         rect.position.value = NVector(128, 128)
0554         rect.size.value = NVector(256, 256)
0555         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0556 
0557         sl.transform.position.add_keyframe(0, NVector(0, 0), objects.easing.Sigmoid())
0558         sl.transform.position.add_keyframe(30, NVector(256, 256), objects.easing.Sigmoid())
0559         sl.transform.position.add_keyframe(60, NVector(0, 0), objects.easing.Sigmoid())
0560 
0561         sif = builder.to_sif(lot)
0562         self.assertEqual(len(sif.layers), 2)
0563         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0564         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0565         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0566         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0567 
0568         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0569 
0570         off = sif.layers[0].transformation.offset
0571 
0572         self.assert_nvector_equal(off.keyframes[0].value, NVector(0, 0))
0573         self.assert_nvector_equal(off.keyframes[1].value, NVector(256, 256))
0574         self.assert_nvector_equal(off.keyframes[2].value, NVector(0, 0))
0575 
0576         self.assertEqual(off.keyframes[0].time, api.FrameTime.frame(0))
0577         self.assertEqual(off.keyframes[1].time, api.FrameTime.frame(30))
0578         self.assertEqual(off.keyframes[2].time, api.FrameTime.frame(60))
0579 
0580         #self.assertEqual(off.keyframes[0].before, api.Interpolation.Ease)
0581         self.assertEqual(off.keyframes[1].before, api.Interpolation.Ease)
0582         self.assertEqual(off.keyframes[2].before, api.Interpolation.Ease)
0583 
0584         self.assertEqual(off.keyframes[0].after, api.Interpolation.Ease)
0585         self.assertEqual(off.keyframes[1].after, api.Interpolation.Ease)
0586         #self.assertEqual(off.keyframes[2].after, api.Interpolation.Ease)
0587 
0588     def test_animated_vector_jump(self):
0589         lot = objects.Animation()
0590 
0591         ref_sl = lot.add_layer(objects.ShapeLayer())
0592         ref_rect = ref_sl.add_shape(objects.Rect())
0593         ref_rect.position.value = NVector(128, 128)
0594         ref_rect.size.value = NVector(256, 256)
0595         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0596         ref_sl.transform.opacity.value = 80
0597 
0598         sl = lot.add_layer(objects.ShapeLayer())
0599         rect = sl.add_shape(objects.Rect())
0600         rect.position.value = NVector(128, 128)
0601         rect.size.value = NVector(256, 256)
0602         sl.add_shape(objects.Fill(Color(1, 1, 0)))
0603 
0604         sl.transform.position.add_keyframe(0, NVector(0, 0), objects.easing.Jump())
0605         sl.transform.position.add_keyframe(30, NVector(256, 256), objects.easing.Jump())
0606         sl.transform.position.add_keyframe(60, NVector(0, 0), objects.easing.Jump())
0607 
0608         sif = builder.to_sif(lot)
0609         self.assertEqual(len(sif.layers), 2)
0610         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0611         self.assertIsInstance(sif.layers[1], api.GroupLayer)
0612         self.assertAlmostEqual(sif.layers[0].amount.value, 1)
0613         self.assertAlmostEqual(sif.layers[1].amount.value, 0.8)
0614 
0615         self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0))
0616 
0617         off = sif.layers[0].transformation.offset
0618 
0619         self.assert_nvector_equal(off.keyframes[0].value, NVector(0, 0))
0620         self.assert_nvector_equal(off.keyframes[1].value, NVector(256, 256))
0621         self.assert_nvector_equal(off.keyframes[2].value, NVector(0, 0))
0622 
0623         self.assertEqual(off.keyframes[0].time, api.FrameTime.frame(0))
0624         self.assertEqual(off.keyframes[1].time, api.FrameTime.frame(30))
0625         self.assertEqual(off.keyframes[2].time, api.FrameTime.frame(60))
0626 
0627         self.assertEqual(off.keyframes[1].before, api.Interpolation.Constant)
0628         self.assertEqual(off.keyframes[2].before, api.Interpolation.Constant)
0629 
0630         self.assertEqual(off.keyframes[0].after, api.Interpolation.Constant)
0631         self.assertEqual(off.keyframes[1].after, api.Interpolation.Constant)
0632 
0633     def test_animated_real(self):
0634         lot = objects.Animation()
0635 
0636         ref_sl = lot.add_layer(objects.ShapeLayer())
0637         ref_rect = ref_sl.add_shape(objects.Rect())
0638         ref_rect.position.value = NVector(128, 128)
0639         ref_rect.size.value = NVector(256, 256)
0640         ref_sl.add_shape(objects.Fill(Color(1, 0, 0)))
0641 
0642         ref_sl.transform.opacity.add_keyframe(0, 100)
0643         ref_sl.transform.opacity.add_keyframe(30, 0)
0644         ref_sl.transform.opacity.add_keyframe(60, 100)
0645 
0646         sif = builder.to_sif(lot)
0647         self.assertEqual(len(sif.layers), 1)
0648         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0649 
0650         amount = sif.layers[0].amount
0651 
0652         self.assertAlmostEqual(amount.keyframes[0].value, 1)
0653         self.assertAlmostEqual(amount.keyframes[1].value, 0)
0654         self.assertAlmostEqual(amount.keyframes[2].value, 1)
0655 
0656         self.assertEqual(amount.keyframes[0].time, api.FrameTime.frame(0))
0657         self.assertEqual(amount.keyframes[1].time, api.FrameTime.frame(30))
0658         self.assertEqual(amount.keyframes[2].time, api.FrameTime.frame(60))
0659 
0660     def test_animated_fill(self):
0661         lot = objects.Animation()
0662 
0663         ref_sl = lot.add_layer(objects.ShapeLayer())
0664         ref_rect = ref_sl.add_shape(objects.Rect())
0665         ref_rect.position.value = NVector(128, 128)
0666         ref_rect.size.value = NVector(256, 256)
0667         fill = ref_sl.add_shape(objects.Fill())
0668 
0669         fill.opacity.add_keyframe(0, 100)
0670         fill.opacity.add_keyframe(30, 50)
0671         fill.opacity.add_keyframe(60, 100)
0672         fill.color.add_keyframe(0, NVector(1, 0, 0))
0673         fill.color.add_keyframe(30, NVector(0, 1, 0))
0674         fill.color.add_keyframe(60, NVector(1, 0, 0))
0675 
0676         sif = builder.to_sif(lot)
0677         self.assertEqual(len(sif.layers), 1)
0678         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0679 
0680         amount = sif.layers[0].layers[0].amount
0681 
0682         self.assertAlmostEqual(amount.keyframes[0].value, 1)
0683         self.assertAlmostEqual(amount.keyframes[1].value, 0.5)
0684         self.assertAlmostEqual(amount.keyframes[2].value, 1)
0685 
0686         self.assertEqual(amount.keyframes[0].time, api.FrameTime.frame(0))
0687         self.assertEqual(amount.keyframes[1].time, api.FrameTime.frame(30))
0688         self.assertEqual(amount.keyframes[2].time, api.FrameTime.frame(60))
0689 
0690         color = sif.layers[0].layers[0].color
0691 
0692         self.assert_nvector_equal(color.keyframes[0].value, sif.make_color(1, 0, 0))
0693         self.assert_nvector_equal(color.keyframes[1].value, sif.make_color(0, 1, 0))
0694         self.assert_nvector_equal(color.keyframes[2].value, sif.make_color(1, 0, 0))
0695 
0696         self.assertEqual(color.keyframes[0].time, api.FrameTime.frame(0))
0697         self.assertEqual(color.keyframes[1].time, api.FrameTime.frame(30))
0698         self.assertEqual(color.keyframes[2].time, api.FrameTime.frame(60))
0699 
0700     def test_animated_bezier(self):
0701         lot = objects.Animation()
0702         sl = lot.add_layer(objects.ShapeLayer())
0703 
0704         shape = sl.add_shape(objects.Path())
0705         sl.add_shape(objects.Fill(Color(0, .25, 1)))
0706 
0707         bez = objects.Bezier()
0708         bez.closed = True
0709         bez.add_point(NVector(256, 0))
0710         bez.add_point(NVector(256+128, 256), NVector(0, 0), NVector(64, 128))
0711         bez.add_smooth_point(NVector(256, 512), NVector(128, 0))
0712         bez.add_point(NVector(256-128, 256), NVector(-64, 128), NVector(0, 0))
0713 
0714         new_bez = bez.clone()
0715         new_bez.vertices[2] = NVector(256, 256+128)
0716         new_bez.in_tangents[2] = NVector(64, 64)
0717         new_bez.out_tangents[2] = NVector(-64, 64)
0718 
0719         shape.shape.add_keyframe(0, bez)
0720         shape.shape.add_keyframe(30, new_bez)
0721         shape.shape.add_keyframe(60, bez)
0722 
0723         sif = builder.to_sif(lot)
0724         self.assertEqual(len(sif.layers), 1)
0725         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0726 
0727         grp = sif.layers[0]
0728         self.assertEqual(len(grp.layers), 1)
0729         self.assertIsInstance(grp.layers[0], api.RegionLayer)
0730         self.assertTrue(grp.active)
0731 
0732         rgl = grp.layers[0]
0733         self.assertEqual(len(rgl.bline.points), 4)
0734         self.assert_nvector_equal(rgl.color.value, sif.make_color(0, .25, 1))
0735         self.assertTrue(rgl.active)
0736         self.assertTrue(rgl.bline.loop)
0737 
0738         for i in range(4):
0739             sp = rgl.bline.points[i]
0740             lp = bez.vertices[i] - NVector(256, 256)
0741             lt1 = bez.in_tangents[i] * -3
0742             lt2 = bez.out_tangents[i] * 3
0743 
0744             new_lp = new_bez.vertices[i] - NVector(256, 256)
0745             new_lt1 = new_bez.in_tangents[i] * -3
0746             new_lt2 = new_bez.out_tangents[i] * 3
0747 
0748             self.assertEqual(sp.point.keyframes[0].time, api.FrameTime.frame(0))
0749             self.assert_nvector_equal(sp.point.keyframes[0].value, lp)
0750             self.assert_nvector_equal(sp.t1.keyframes[0].value, lt1)
0751             self.assert_nvector_equal(sp.t2.keyframes[0].value, lt2)
0752 
0753             self.assertEqual(sp.point.keyframes[1].time, api.FrameTime.frame(30))
0754             self.assert_nvector_equal(sp.point.keyframes[1].value, new_lp)
0755             self.assert_nvector_equal(sp.t1.keyframes[1].value, new_lt1)
0756             self.assert_nvector_equal(sp.t2.keyframes[1].value, new_lt2)
0757 
0758             self.assertEqual(sp.point.keyframes[2].time, api.FrameTime.frame(60))
0759             self.assert_nvector_equal(sp.point.keyframes[2].value, lp)
0760             self.assert_nvector_equal(sp.t1.keyframes[2].value, lt1)
0761             self.assert_nvector_equal(sp.t2.keyframes[2].value, lt2)
0762 
0763     def test_shape_group(self):
0764         lot = objects.Animation()
0765         sl = lot.add_layer(objects.ShapeLayer())
0766 
0767         gr1 = sl.add_shape(objects.Group())
0768         gr1.name = "Group Shape 1"
0769 
0770         rect = gr1.add_shape(objects.Rect())
0771         rect.position.value = NVector(128, 256)
0772         rect.size.value = NVector(128, 256)
0773         gr1.add_shape(objects.Fill(Color(1, .25, 0)))
0774 
0775         gr2 = sl.add_shape(objects.Group())
0776         gr2.name = "Group Shape 2"
0777         rect = gr2.add_shape(objects.Rect())
0778         rect.position.value = NVector(256+128, 256)
0779         rect.size.value = NVector(128, 256)
0780         gr2.add_shape(objects.Fill(Color(.25, 0, 1)))
0781 
0782         sif = builder.to_sif(lot)
0783         self.assertEqual(len(sif.layers), 1)
0784         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0785 
0786         grp = sif.layers[0]
0787         self.assertEqual(len(grp.layers), 2)
0788         sg1 = grp.layers[1]
0789         sg2 = grp.layers[0]
0790         self.assertIsInstance(sg1, api.GroupLayer)
0791         self.assertIsInstance(sg2, api.GroupLayer)
0792         self.assertEqual(sg1.desc, "Group Shape 1")
0793         self.assertEqual(sg2.desc, "Group Shape 2")
0794         self.assertEqual(len(sg1.layers), 1)
0795         self.assertEqual(len(sg2.layers), 1)
0796         self.assertIsInstance(sg1.layers[0], api.RegionLayer)
0797         self.assertIsInstance(sg2.layers[0], api.RegionLayer)
0798         self.assert_nvector_equal(sg1.layers[0].color.value, sif.make_color(1, .25, 0))
0799         self.assert_nvector_equal(sg2.layers[0].color.value, sif.make_color(.25, 0, 1))
0800 
0801     def test_repeater(self):
0802         lot = objects.Animation()
0803         sl = lot.add_layer(objects.ShapeLayer())
0804 
0805         group = sl.add_shape(objects.Group())
0806 
0807         star = group.add_shape(objects.Star())
0808         star.inner_radius.value = 16
0809         star.outer_radius.value = 32
0810         star.position.value = NVector(256, 40)
0811 
0812         group.add_shape(objects.Fill(Color(1, 1, 0)))
0813         group.add_shape(objects.Stroke(Color(0, 0, 0), 3))
0814         group.name = "Star"
0815 
0816         rep = sl.add_shape(objects.Repeater(4))
0817         rep.name = "Repeater"
0818         rep.transform.position.value = NVector(20, 80)
0819         rep.transform.end_opacity.value = 20
0820 
0821         sif = builder.to_sif(lot)
0822         self.assertEqual(len(sif.layers), 1)
0823         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0824         self.assertEqual(len(sif.layers[0].layers), 1)
0825         self.assertIsInstance(sif.layers[0].layers[0], api.GroupLayer)
0826         self.assertEqual(sif.layers[0].layers[0].desc, "Repeater")
0827         self.assertEqual(len(sif.layers[0].layers[0].layers), 2)
0828 
0829         duplicate_lay = sif.layers[0].layers[0].layers[1]
0830         self.assertIsInstance(duplicate_lay, api.DuplicateLayer)
0831         self.assertEqual(duplicate_lay.desc, "Repeater")
0832         duplicate = sif.get_object(duplicate_lay.index.id)
0833         self.assertIsInstance(duplicate, api.Duplicate)
0834         self.assertEqual(duplicate.from_.value, 3)
0835         self.assertEqual(duplicate.to.value, 0)
0836         self.assertEqual(duplicate.step.value, -1)
0837 
0838         dup_trans = sif.layers[0].layers[0].layers[0]
0839         self.assertIsInstance(dup_trans, api.GroupLayer)
0840         self.assertEqual(dup_trans.desc, "Transformation for Repeater")
0841         dup_origin = sif.get_object(dup_trans.origin.id)
0842         self.assert_nvector_equal(dup_origin.value.value, NVector(0, 0))
0843         trans = dup_trans.transformation
0844         self.assertIsInstance(trans.offset, ast.SifAdd)
0845         self.assertEqual(trans.offset.rhs.value.id, dup_origin.id)
0846         self.assertIsInstance(trans.offset.lhs, ast.SifScale)
0847         self.assert_nvector_equal(trans.offset.lhs.link.value, NVector(20, 80))
0848         self.assertEqual(trans.offset.lhs.scalar.value.id, duplicate.id)
0849         self.assertIsInstance(trans.angle, ast.SifScale)
0850         self.assertEqual(trans.angle.link.value, 0)
0851         self.assertEqual(trans.angle.scalar.value.id, duplicate.id)
0852         self.assertIsInstance(dup_trans.amount, ast.SifSubtract)
0853         self.assertEqual(dup_trans.amount.lhs.value, 1)
0854         self.assertIsInstance(dup_trans.amount.rhs, ast.SifScale)
0855         self.assertAlmostEqual(dup_trans.amount.rhs.link.value, 0.266666666)
0856         self.assertEqual(dup_trans.amount.rhs.scalar.value.id, duplicate.id)
0857         self.assertEqual(len(dup_trans.layers), 1)
0858         self.assertEqual(dup_trans.layers[0].desc, "Star")
0859 
0860     def test_repeater_rot(self):
0861         lot = objects.Animation()
0862         sl = lot.add_layer(objects.ShapeLayer())
0863 
0864         group = sl.add_shape(objects.Group())
0865 
0866         star = group.add_shape(objects.Star())
0867         star.inner_radius.value = 16
0868         star.outer_radius.value = 32
0869         star.position.value = NVector(256, 40)
0870 
0871         group.add_shape(objects.Fill(Color(1, 1, 0)))
0872         group.name = "Star"
0873 
0874         rep = sl.add_shape(objects.Repeater(12))
0875         rep.name = "Repeater"
0876         rep.transform.anchor_point.value = NVector(256, 256)
0877         rep.transform.rotation.value = 30
0878 
0879         sif = builder.to_sif(lot)
0880         self.assertEqual(len(sif.layers), 1)
0881         self.assertIsInstance(sif.layers[0], api.GroupLayer)
0882         self.assertEqual(len(sif.layers[0].layers), 1)
0883         self.assertIsInstance(sif.layers[0].layers[0], api.GroupLayer)
0884         self.assertEqual(sif.layers[0].layers[0].desc, "Repeater")
0885         self.assertEqual(len(sif.layers[0].layers[0].layers), 2)
0886 
0887         duplicate_lay = sif.layers[0].layers[0].layers[1]
0888         self.assertIsInstance(duplicate_lay, api.DuplicateLayer)
0889         self.assertEqual(duplicate_lay.desc, "Repeater")
0890         duplicate = sif.get_object(duplicate_lay.index.id)
0891         self.assertIsInstance(duplicate, api.Duplicate)
0892         self.assertEqual(duplicate.from_.value, 11)
0893         self.assertEqual(duplicate.to.value, 0)
0894         self.assertEqual(duplicate.step.value, -1)
0895 
0896         dup_trans = sif.layers[0].layers[0].layers[0]
0897         self.assertIsInstance(dup_trans, api.GroupLayer)
0898         self.assertEqual(dup_trans.desc, "Transformation for Repeater")
0899         dup_origin = sif.get_object(dup_trans.origin.id)
0900         self.assert_nvector_equal(dup_origin.value.value, NVector(256, 256))
0901         trans = dup_trans.transformation
0902         self.assertIsInstance(trans.offset, ast.SifAdd)
0903         self.assertEqual(trans.offset.rhs.value.id, dup_origin.id)
0904         self.assertIsInstance(trans.offset.lhs, ast.SifScale)
0905         self.assert_nvector_equal(trans.offset.lhs.link.value, NVector(0, 0))
0906         self.assertEqual(trans.offset.lhs.scalar.value.id, duplicate.id)
0907         self.assertIsInstance(trans.angle, ast.SifScale)
0908         self.assertEqual(trans.angle.link.value, 30)
0909         self.assertEqual(trans.angle.scalar.value.id, duplicate.id)
0910         self.assertIsInstance(dup_trans.amount, ast.SifSubtract)
0911         self.assertEqual(dup_trans.amount.lhs.value, 1)
0912         self.assertIsInstance(dup_trans.amount.rhs, ast.SifScale)
0913         self.assertAlmostEqual(dup_trans.amount.rhs.link.value, 0.)
0914         self.assertEqual(dup_trans.amount.rhs.scalar.value.id, duplicate.id)
0915         self.assertEqual(len(dup_trans.layers), 1)
0916         self.assertEqual(dup_trans.layers[0].desc, "Star")