Add support for reversed polystar paths (#2003)

Fixes #1863
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
index 8fcceca..cfa9523 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
@@ -33,6 +33,7 @@
   private final LottieDrawable lottieDrawable;
   private final PolystarShape.Type type;
   private final boolean hidden;
+  private final boolean isReversed;
   private final BaseKeyframeAnimation<?, Float> pointsAnimation;
   private final BaseKeyframeAnimation<?, PointF> positionAnimation;
   private final BaseKeyframeAnimation<?, Float> rotationAnimation;
@@ -51,6 +52,7 @@
     name = polystarShape.getName();
     type = polystarShape.getType();
     hidden = polystarShape.isHidden();
+    isReversed = polystarShape.isReversed();
     pointsAnimation = polystarShape.getPoints().createAnimation();
     positionAnimation = polystarShape.getPosition().createAnimation();
     rotationAnimation = polystarShape.getRotation().createAnimation();
@@ -148,6 +150,9 @@
     currentAngle = Math.toRadians(currentAngle);
     // adjust current angle for partial points
     float anglePerPoint = (float) (2 * Math.PI / points);
+    if (isReversed) {
+      anglePerPoint *= -1;
+    }
     float halfAnglePerPoint = anglePerPoint / 2.0f;
     float partialPointAmount = points - (int) points;
     if (partialPointAmount != 0) {
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java b/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
index 1ebab06..e7d805a 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
@@ -40,12 +40,13 @@
   private final AnimatableFloatValue innerRoundedness;
   private final AnimatableFloatValue outerRoundedness;
   private final boolean hidden;
+  private final boolean isReversed;
 
   public PolystarShape(String name, Type type, AnimatableFloatValue points,
       AnimatableValue<PointF, PointF> position,
       AnimatableFloatValue rotation, AnimatableFloatValue innerRadius,
       AnimatableFloatValue outerRadius, AnimatableFloatValue innerRoundedness,
-      AnimatableFloatValue outerRoundedness, boolean hidden) {
+      AnimatableFloatValue outerRoundedness, boolean hidden, boolean isReversed) {
     this.name = name;
     this.type = type;
     this.points = points;
@@ -56,6 +57,7 @@
     this.innerRoundedness = innerRoundedness;
     this.outerRoundedness = outerRoundedness;
     this.hidden = hidden;
+    this.isReversed = isReversed;
   }
 
   public String getName() {
@@ -98,6 +100,10 @@
     return hidden;
   }
 
+  public boolean isReversed() {
+    return isReversed;
+  }
+
   @Override public Content toContent(LottieDrawable drawable, BaseLayer layer) {
     return new PolystarContent(drawable, layer, this);
   }
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
index 16b0674..1b19853 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
@@ -81,7 +81,7 @@
         model = ShapeTrimPathParser.parse(reader, composition);
         break;
       case "sr":
-        model = PolystarShapeParser.parse(reader, composition);
+        model = PolystarShapeParser.parse(reader, composition, d);
         break;
       case "mm":
         model = MergePathsParser.parse(reader);
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
index 1865be6..afa31f6 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
@@ -21,14 +21,15 @@
       "os",
       "ir",
       "is",
-      "hd"
+      "hd",
+      "d"
   );
 
   private PolystarShapeParser() {
   }
 
   static PolystarShape parse(
-      JsonReader reader, LottieComposition composition) throws IOException {
+      JsonReader reader, LottieComposition composition, int d) throws IOException {
     String name = null;
     PolystarShape.Type type = null;
     AnimatableFloatValue points = null;
@@ -39,6 +40,7 @@
     AnimatableFloatValue innerRadius = null;
     AnimatableFloatValue innerRoundedness = null;
     boolean hidden = false;
+    boolean reversed = d == 3;
 
     while (reader.hasNext()) {
       switch (reader.selectName(NAMES)) {
@@ -72,6 +74,10 @@
         case 9:
           hidden = reader.nextBoolean();
           break;
+        case 10:
+          // "d" is 2 for normal and 3 for reversed.
+          reversed = reader.nextInt() == 3;
+          break;
         default:
           reader.skipName();
           reader.skipValue();
@@ -80,6 +86,6 @@
 
     return new PolystarShape(
         name, type, points, position, rotation, innerRadius, outerRadius,
-        innerRoundedness, outerRoundedness, hidden);
+        innerRoundedness, outerRoundedness, hidden, reversed);
   }
 }
diff --git a/snapshot-tests/src/main/assets/Tests/ReversedStar.json b/snapshot-tests/src/main/assets/Tests/ReversedStar.json
new file mode 100644
index 0000000..593308c
--- /dev/null
+++ b/snapshot-tests/src/main/assets/Tests/ReversedStar.json
@@ -0,0 +1 @@
+{"v":"5.8.2","fr":24,"ip":0,"op":94,"w":150,"h":150,"nm":"Anim_load","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"LF03","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-19,"ix":10},"p":{"a":0,"k":[75,76.005,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.986,19.986,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":3,"pt":{"a":0,"k":14,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":91.612,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":113.225,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[0.937254905701,0.89411765337,0.850980401039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-1.979,-0.604],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":-0.127,"s":[100]},{"t":32,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":36,"s":[100]},{"t":68,"s":[0]}],"ix":2},"o":{"a":0,"k":-43,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":94,"st":18,"bm":0}],"markers":[]}
\ No newline at end of file