From dff21b8eb4c6fe305367f39790ba11f157f3ede7 Mon Sep 17 00:00:00 2001 From: Allen Chen Date: Tue, 23 Jul 2024 17:51:03 -0700 Subject: [PATCH] Support range selector in glyph rendering path Also adds support for ranges specified as a percentage. Note that the provided sample has easing values included, which we don't support yet. --- .../AnimatableTextRangeSelector.java | 7 +- .../lottie/model/content/TextRangeUnits.java | 6 + .../airbnb/lottie/model/layer/TextLayer.java | 38 +- .../AnimatableTextPropertiesParser.java | 17 +- .../assets/Tests/text_range_test_glyphs.json | 1840 +++++++++++++++++ 5 files changed, 1892 insertions(+), 16 deletions(-) create mode 100644 lottie/src/main/java/com/airbnb/lottie/model/content/TextRangeUnits.java create mode 100644 snapshot-tests/src/main/assets/Tests/text_range_test_glyphs.json diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextRangeSelector.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextRangeSelector.java index fe8ace28b8..413008ba4e 100644 --- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextRangeSelector.java +++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextRangeSelector.java @@ -1,6 +1,7 @@ package com.airbnb.lottie.model.animatable; import androidx.annotation.Nullable; +import com.airbnb.lottie.model.content.TextRangeUnits; /** * Defines an animated range of text that should have an [AnimatableTextProperties] applied to it. @@ -9,14 +10,16 @@ public class AnimatableTextRangeSelector { @Nullable public final AnimatableIntegerValue start; @Nullable public final AnimatableIntegerValue end; @Nullable public final AnimatableIntegerValue offset; + public final TextRangeUnits units; public AnimatableTextRangeSelector( @Nullable AnimatableIntegerValue start, @Nullable AnimatableIntegerValue end, - @Nullable AnimatableIntegerValue offset - ) { + @Nullable AnimatableIntegerValue offset, + TextRangeUnits units) { this.start = start; this.end = end; this.offset = offset; + this.units = units; } } diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/TextRangeUnits.java b/lottie/src/main/java/com/airbnb/lottie/model/content/TextRangeUnits.java new file mode 100644 index 0000000000..6e4f0c8644 --- /dev/null +++ b/lottie/src/main/java/com/airbnb/lottie/model/content/TextRangeUnits.java @@ -0,0 +1,6 @@ +package com.airbnb.lottie.model.content; + +public enum TextRangeUnits { + PERCENT, + INDEX +} diff --git a/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java b/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java index e33d42661e..309950cec8 100644 --- a/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java +++ b/lottie/src/main/java/com/airbnb/lottie/model/layer/TextLayer.java @@ -25,6 +25,7 @@ import com.airbnb.lottie.model.FontCharacter; import com.airbnb.lottie.model.animatable.AnimatableTextProperties; import com.airbnb.lottie.model.content.ShapeGroup; +import com.airbnb.lottie.model.content.TextRangeUnits; import com.airbnb.lottie.utils.Utils; import com.airbnb.lottie.value.LottieValueCallback; @@ -56,6 +57,7 @@ public class TextLayer extends BaseLayer { private final TextKeyframeAnimation textAnimation; private final LottieDrawable lottieDrawable; private final LottieComposition composition; + private TextRangeUnits textRangeUnits = TextRangeUnits.INDEX; @Nullable private BaseKeyframeAnimation colorAnimation; @Nullable @@ -142,6 +144,10 @@ public class TextLayer extends BaseLayer { textRangeOffsetAnimation.addUpdateListener(this); addAnimation(textRangeOffsetAnimation); } + + if (textProperties != null && textProperties.rangeSelector != null) { + textRangeUnits = textProperties.rangeSelector.units; + } } @Override @@ -164,7 +170,7 @@ void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) { configurePaint(documentData, parentAlpha, 0); if (lottieDrawable.useTextGlyphs()) { - drawTextWithGlyphs(documentData, parentMatrix, font, canvas); + drawTextWithGlyphs(documentData, parentMatrix, font, canvas, parentAlpha); } else { drawTextWithFont(documentData, font, canvas, parentAlpha); } @@ -216,26 +222,31 @@ private void configurePaint(DocumentData documentData, int parentAlpha, int inde } private boolean isIndexInRangeSelection(int indexInDocument) { + int textLength = textAnimation.getValue().text.length(); if (textRangeStartAnimation != null && textRangeEndAnimation != null) { // After effects supports reversed text ranges where the start index is greater than the end index. // For the purposes of determining if the given index is inside of the range, we take the start as the smaller value. - int rangeStartIndex = Math.min(textRangeStartAnimation.getValue(), textRangeEndAnimation.getValue()); - int rangeEndIndex = Math.max(textRangeStartAnimation.getValue(), textRangeEndAnimation.getValue()); + int rangeStart = Math.min(textRangeStartAnimation.getValue(), textRangeEndAnimation.getValue()); + int rangeEnd = Math.max(textRangeStartAnimation.getValue(), textRangeEndAnimation.getValue()); if (textRangeOffsetAnimation != null) { int offset = textRangeOffsetAnimation.getValue(); - rangeStartIndex += offset; - rangeEndIndex += offset; + rangeStart += offset; + rangeEnd += offset; } - return indexInDocument >= rangeStartIndex && indexInDocument < rangeEndIndex; + if (textRangeUnits == TextRangeUnits.INDEX) { + return indexInDocument >= rangeStart && indexInDocument < rangeEnd; + } else { + float currentIndexAsPercent = indexInDocument / (float) textLength * 100; + return currentIndexAsPercent >= rangeStart && currentIndexAsPercent < rangeEnd; + } } - return true; } private void drawTextWithGlyphs( - DocumentData documentData, Matrix parentMatrix, Font font, Canvas canvas) { + DocumentData documentData, Matrix parentMatrix, Font font, Canvas canvas, int parentAlpha) { float textSize; if (textSizeCallbackAnimation != null) { textSize = textSizeCallbackAnimation.getValue(); @@ -269,7 +280,7 @@ private void drawTextWithGlyphs( canvas.save(); if (offsetCanvas(canvas, documentData, lineIndex, line.width)) { - drawGlyphTextLine(line.text, documentData, font, canvas, parentScale, fontScale, tracking); + drawGlyphTextLine(line.text, documentData, font, canvas, parentScale, fontScale, tracking, parentAlpha); } canvas.restore(); @@ -278,7 +289,7 @@ private void drawTextWithGlyphs( } private void drawGlyphTextLine(String text, DocumentData documentData, - Font font, Canvas canvas, float parentScale, float fontScale, float tracking) { + Font font, Canvas canvas, float parentScale, float fontScale, float tracking, int parentAlpha) { for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); int characterHash = FontCharacter.hashFor(c, font.getFamily(), font.getStyle()); @@ -287,7 +298,7 @@ private void drawGlyphTextLine(String text, DocumentData documentData, // Something is wrong. Potentially, they didn't export the text as a glyph. continue; } - drawCharacterAsGlyph(character, fontScale, documentData, canvas); + drawCharacterAsGlyph(character, fontScale, documentData, canvas, i, parentAlpha); float tx = (float) character.getWidth() * fontScale * Utils.dpScale() + tracking; canvas.translate(tx, 0); } @@ -506,7 +517,10 @@ private void drawCharacterAsGlyph( FontCharacter character, float fontScale, DocumentData documentData, - Canvas canvas) { + Canvas canvas, + int indexInDocument, + int parentAlpha) { + configurePaint(documentData, parentAlpha, indexInDocument); List contentGroups = getContentsForCharacter(character); for (int j = 0; j < contentGroups.size(); j++) { Path path = contentGroups.get(j).getPath(); diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableTextPropertiesParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableTextPropertiesParser.java index d989ae991d..c76ad86825 100644 --- a/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableTextPropertiesParser.java +++ b/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableTextPropertiesParser.java @@ -8,6 +8,8 @@ import com.airbnb.lottie.model.animatable.AnimatableTextProperties; import com.airbnb.lottie.model.animatable.AnimatableTextRangeSelector; import com.airbnb.lottie.model.animatable.AnimatableTextStyle; +import com.airbnb.lottie.model.content.LBlendMode; +import com.airbnb.lottie.model.content.TextRangeUnits; import com.airbnb.lottie.parser.moshi.JsonReader; import com.airbnb.lottie.value.Keyframe; @@ -21,7 +23,8 @@ public class AnimatableTextPropertiesParser { private static final JsonReader.Options ANIMATABLE_RANGE_PROPERTIES_NAMES = JsonReader.Options.of( "s", // start "e", // end - "o" // offset + "o", // offset + "r" // text range units (percent or index) ); private static final JsonReader.Options ANIMATABLE_PROPERTIES_NAMES = JsonReader.Options.of( "fc", @@ -63,6 +66,7 @@ private static AnimatableTextRangeSelector parseAnimatableTextRangeSelector(Json AnimatableIntegerValue start = null; AnimatableIntegerValue end = null; AnimatableIntegerValue offset = null; + TextRangeUnits units = null; reader.beginObject(); while (reader.hasNext()) { @@ -76,6 +80,15 @@ private static AnimatableTextRangeSelector parseAnimatableTextRangeSelector(Json case 2: // offset offset = AnimatableValueParser.parseInteger(reader, composition); break; + case 3: // text range units (percent or index) + int textRangeUnits = reader.nextInt(); + if (textRangeUnits != 1 && textRangeUnits != 2) { + composition.addWarning("Unsupported text range units: " + textRangeUnits); + units = TextRangeUnits.INDEX; + break; + } + units = textRangeUnits == 1 ? TextRangeUnits.PERCENT : TextRangeUnits.INDEX; + break; default: reader.skipName(); reader.skipValue(); @@ -88,7 +101,7 @@ private static AnimatableTextRangeSelector parseAnimatableTextRangeSelector(Json start = new AnimatableIntegerValue(Collections.singletonList(new Keyframe<>(0))); } - return new AnimatableTextRangeSelector(start, end, offset); + return new AnimatableTextRangeSelector(start, end, offset, units); } private static AnimatableTextStyle parseAnimatableTextStyle( diff --git a/snapshot-tests/src/main/assets/Tests/text_range_test_glyphs.json b/snapshot-tests/src/main/assets/Tests/text_range_test_glyphs.json new file mode 100644 index 0000000000..cdddb20a28 --- /dev/null +++ b/snapshot-tests/src/main/assets/Tests/text_range_test_glyphs.json @@ -0,0 +1,1840 @@ +{ + "v": "5.12.2", + "fr": 29.9700012207031, + "ip": 0, + "op": 120.0000048877, + "w": 400, + "h": 400, + "nm": "Comp 1", + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fName": "Helvetica", + "fFamily": "Helvetica", + "fStyle": "Regular", + "ascent": 71.8994140625 + } + ] + }, + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 5, + "nm": "Hello World", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 42, + 168, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "t": { + "d": { + "k": [ + { + "s": { + "s": 36, + "f": "Helvetica", + "t": "Hello World", + "ca": 0, + "j": 0, + "tr": 0, + "lh": 43.2000007629395, + "ls": 0, + "fc": [ + 0.132, + 0.132, + 0.132 + ] + }, + "t": 0 + } + ] + }, + "p": {}, + "m": { + "g": 1, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 2 + } + }, + "a": [ + { + "nm": "Animator 1", + "s": { + "t": 0, + "xe": { + "a": 0, + "k": 0, + "ix": 7 + }, + "ne": { + "a": 0, + "k": 0, + "ix": 8 + }, + "a": { + "a": 0, + "k": 100, + "ix": 4 + }, + "b": 1, + "rn": 0, + "sh": 1, + "sm": { + "a": 0, + "k": 100, + "ix": 6 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 119.000004846969, + "s": [ + 100 + ] + } + ], + "ix": 1 + }, + "e": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 119.000004846969, + "s": [ + 0 + ] + } + ], + "ix": 2 + }, + "r": 1 + }, + "a": { + "o": { + "a": 0, + "k": 0, + "ix": 9 + } + } + } + ] + }, + "ip": 0, + "op": 120.0000048877, + "st": 0, + "ct": 1, + "bm": 0 + } + ], + "markers": [], + "props": {}, + "chars": [ + { + "ch": "H", + "size": 36, + "style": "Regular", + "w": 72.22, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 7.861, + 0 + ], + [ + 17.676, + 0 + ], + [ + 17.676, + -33.545 + ], + [ + 54.541, + -33.545 + ], + [ + 54.541, + 0 + ], + [ + 64.355, + 0 + ], + [ + 64.355, + -71.729 + ], + [ + 54.541, + -71.729 + ], + [ + 54.541, + -42.09 + ], + [ + 17.676, + -42.09 + ], + [ + 17.676, + -71.729 + ], + [ + 7.861, + -71.729 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "H", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "H", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": "e", + "size": 36, + "style": "Regular", + "w": 55.62, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 3.688, + 0 + ], + [ + 4.529, + -5.241 + ], + [ + 0, + -8.398 + ], + [ + -4.497, + -4.736 + ], + [ + -6.47, + 0 + ], + [ + -2.1, + 0.52 + ], + [ + -2.65, + 2.605 + ], + [ + -1.286, + 2.361 + ], + [ + -0.228, + 1.921 + ], + [ + 0, + 0 + ], + [ + 1.518, + -1.765 + ], + [ + 4.554, + 0 + ], + [ + 2.325, + 3.215 + ], + [ + 0.162, + 5.321 + ], + [ + 0, + 0 + ], + [ + 0.517, + 2.409 + ], + [ + 1.747, + 2.637 + ], + [ + 3.461, + 1.742 + ] + ], + "o": [ + [ + -7.312, + 0 + ], + [ + -4.53, + 5.241 + ], + [ + 0, + 8.529 + ], + [ + 4.497, + 4.736 + ], + [ + 2.649, + 0 + ], + [ + 3.909, + -0.912 + ], + [ + 1.582, + -1.497 + ], + [ + 1.286, + -2.36 + ], + [ + 0, + 0 + ], + [ + -0.633, + 2.322 + ], + [ + -2.713, + 3.041 + ], + [ + -4.877, + 0 + ], + [ + -2.325, + -3.215 + ], + [ + 0, + 0 + ], + [ + 0, + -5.273 + ], + [ + -0.583, + -3.516 + ], + [ + -1.812, + -2.766 + ], + [ + -3.462, + -1.741 + ] + ], + "v": [ + [ + 28.022, + -53.467 + ], + [ + 10.261, + -45.605 + ], + [ + 3.467, + -25.146 + ], + [ + 10.211, + -5.249 + ], + [ + 26.661, + 1.855 + ], + [ + 33.784, + 1.074 + ], + [ + 43.622, + -4.199 + ], + [ + 47.925, + -9.985 + ], + [ + 50.195, + -16.406 + ], + [ + 41.553, + -16.406 + ], + [ + 38.326, + -10.275 + ], + [ + 27.425, + -5.713 + ], + [ + 16.621, + -10.535 + ], + [ + 12.891, + -23.34 + ], + [ + 50.928, + -23.34 + ], + [ + 50.151, + -34.863 + ], + [ + 46.657, + -44.092 + ], + [ + 38.747, + -50.854 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "e", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + -2.711, + 2.914 + ], + [ + -4.002, + 0 + ], + [ + -2.389, + -4.231 + ], + [ + -0.356, + -3.809 + ] + ], + "o": [ + [ + 0.161, + -4.492 + ], + [ + 2.711, + -2.913 + ], + [ + 5.584, + 0 + ], + [ + 1.291, + 2.279 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 13.086, + -30.322 + ], + [ + 17.395, + -41.431 + ], + [ + 27.466, + -45.801 + ], + [ + 39.425, + -39.453 + ], + [ + 41.895, + -30.322 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "e", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "e", + "np": 5, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": "l", + "size": 36, + "style": "Regular", + "w": 22.22, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 6.689, + 0 + ], + [ + 15.479, + 0 + ], + [ + 15.479, + -71.729 + ], + [ + 6.689, + -71.729 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "l", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "l", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": "o", + "size": 36, + "style": "Regular", + "w": 55.62, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 5.761, + 0 + ], + [ + 2.414, + 3.706 + ], + [ + 0, + 5.56 + ], + [ + -2.414, + 4.097 + ], + [ + -5.312, + 0 + ], + [ + -2.446, + -4.812 + ], + [ + 0, + -4.877 + ], + [ + 2.141, + -4.405 + ] + ], + "o": [ + [ + -5.247, + 0 + ], + [ + -2.414, + -3.706 + ], + [ + 0, + -5.787 + ], + [ + 2.414, + -4.097 + ], + [ + 5.987, + 0 + ], + [ + 1.545, + 3.056 + ], + [ + 0, + 5.397 + ], + [ + -2.141, + 4.405 + ] + ], + "v": [ + [ + 27.026, + -5.713 + ], + [ + 15.535, + -11.272 + ], + [ + 11.914, + -25.172 + ], + [ + 15.535, + -39.997 + ], + [ + 27.122, + -46.143 + ], + [ + 39.772, + -38.924 + ], + [ + 42.09, + -27.025 + ], + [ + 38.879, + -12.321 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "o", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 6.691, + 0 + ], + [ + 4.428, + -5.203 + ], + [ + 0, + -8.781 + ], + [ + -4.202, + -4.862 + ], + [ + -7.144, + 0 + ], + [ + -4.073, + 5.496 + ], + [ + 0, + 8.424 + ], + [ + 4.622, + 4.488 + ] + ], + "o": [ + [ + -7.467, + 0 + ], + [ + -4.428, + 5.204 + ], + [ + 0, + 8.196 + ], + [ + 4.202, + 4.862 + ], + [ + 8.566, + 0 + ], + [ + 4.073, + -5.496 + ], + [ + 0, + -8.716 + ], + [ + -4.623, + -4.488 + ] + ], + "v": [ + [ + 27.366, + -53.809 + ], + [ + 9.523, + -46.003 + ], + [ + 2.881, + -25.025 + ], + [ + 9.184, + -5.437 + ], + [ + 26.202, + 1.855 + ], + [ + 45.16, + -6.389 + ], + [ + 51.27, + -27.27 + ], + [ + 44.336, + -47.076 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "o", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "o", + "np": 5, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": " ", + "size": 36, + "style": "Regular", + "w": 27.78, + "data": {}, + "fFamily": "Helvetica" + }, + { + "ch": "W", + "size": 36, + "style": "Regular", + "w": 94.38, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 1.831, + -71.729 + ], + [ + 20.581, + 0 + ], + [ + 30.786, + 0 + ], + [ + 47.437, + -59.473 + ], + [ + 63.989, + 0 + ], + [ + 74.194, + 0 + ], + [ + 93.042, + -71.729 + ], + [ + 82.39, + -71.729 + ], + [ + 68.867, + -13.343 + ], + [ + 52.617, + -71.729 + ], + [ + 42.114, + -71.729 + ], + [ + 25.9, + -13.453 + ], + [ + 12.379, + -71.729 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "W", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "W", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": "r", + "size": 36, + "style": "Regular", + "w": 33.3, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -2.377, + 2.849 + ], + [ + -4.427, + 0 + ], + [ + -0.439, + -0.032 + ], + [ + -0.521, + -0.098 + ], + [ + 0, + 0 + ], + [ + 0.391, + 0.033 + ], + [ + 0.163, + 0 + ], + [ + 2.669, + -2.522 + ], + [ + 0.684, + -1.758 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -3.711 + ], + [ + 2.376, + -2.848 + ], + [ + 0.52, + 0 + ], + [ + 0.439, + 0.033 + ], + [ + 0, + 0 + ], + [ + -0.945, + -0.098 + ], + [ + -0.391, + -0.032 + ], + [ + -3.484, + 0 + ], + [ + -2.67, + 2.523 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 6.689, + 0 + ], + [ + 15.479, + 0 + ], + [ + 15.479, + -30.078 + ], + [ + 19.043, + -39.917 + ], + [ + 29.248, + -44.189 + ], + [ + 30.688, + -44.141 + ], + [ + 32.129, + -43.945 + ], + [ + 32.129, + -53.223 + ], + [ + 30.127, + -53.418 + ], + [ + 29.297, + -53.467 + ], + [ + 20.068, + -49.683 + ], + [ + 15.039, + -43.262 + ], + [ + 15.039, + -52.295 + ], + [ + 6.689, + -52.295 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "r", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "r", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + }, + { + "ch": "d", + "size": 36, + "style": "Regular", + "w": 55.62, + "data": { + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 5.599 + ], + [ + -2.737, + 3.386 + ], + [ + -4.405, + 0 + ], + [ + -2.689, + -3.174 + ], + [ + 0, + -6.608 + ], + [ + 2.607, + -3.499 + ], + [ + 4.048, + 0 + ], + [ + 2.364, + 3.777 + ] + ], + "o": [ + [ + 0, + -6.575 + ], + [ + 2.737, + -3.385 + ], + [ + 3.951, + 0 + ], + [ + 2.688, + 3.174 + ], + [ + 0, + 6.543 + ], + [ + -2.608, + 3.5 + ], + [ + -5.215, + 0 + ], + [ + -2.364, + -3.776 + ] + ], + "v": [ + [ + 12.012, + -25.537 + ], + [ + 16.116, + -40.479 + ], + [ + 26.829, + -45.557 + ], + [ + 36.788, + -40.796 + ], + [ + 40.82, + -26.123 + ], + [ + 36.909, + -11.06 + ], + [ + 26.926, + -5.811 + ], + [ + 15.558, + -11.475 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "d", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 3.989, + 0 + ], + [ + 3.875, + -5.582 + ], + [ + 0, + -7.617 + ], + [ + -4.248, + -4.899 + ], + [ + -5.804, + 0 + ], + [ + -2.789, + 1.432 + ], + [ + -2.043, + 3.223 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.556, + 0.977 + ] + ], + "o": [ + [ + -7.199, + 0 + ], + [ + -3.875, + 5.583 + ], + [ + 0, + 8.138 + ], + [ + 4.248, + 4.9 + ], + [ + 3.6, + 0 + ], + [ + 2.789, + -1.432 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.978, + -2.441 + ], + [ + -2.692, + -1.692 + ] + ], + "v": [ + [ + 25.157, + -53.223 + ], + [ + 8.546, + -44.849 + ], + [ + 2.734, + -25.049 + ], + [ + 9.106, + -5.493 + ], + [ + 24.185, + 1.855 + ], + [ + 33.768, + -0.293 + ], + [ + 41.016, + -7.275 + ], + [ + 41.016, + 0 + ], + [ + 48.926, + 0 + ], + [ + 48.926, + -71.973 + ], + [ + 40.479, + -71.973 + ], + [ + 40.479, + -45.557 + ], + [ + 35.177, + -50.684 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "d", + "mn": "ADBE Vector Shape - Group", + "hd": false + } + ], + "nm": "d", + "np": 5, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ] + }, + "fFamily": "Helvetica" + } + ] +}