149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler/*
249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * Copyright (C) 2017 The Android Open Source Project
349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler *
449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * except in compliance with the License. You may obtain a copy of the License at
649ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler *
749ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler *      http://www.apache.org/licenses/LICENSE-2.0
849ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler *
949ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * Unless required by applicable law or agreed to in writing, software distributed under the
1049ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * KIND, either express or implied. See the License for the specific language governing
1249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler * permissions and limitations under the License.
1349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler */
1449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler
1549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerpackage com.android.egg.octo;
1649ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler
1749ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport android.graphics.Canvas;
1849ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport android.graphics.Paint;
1949ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport android.graphics.Path;
2049ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport android.graphics.PathMeasure;
2149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport android.os.Debug;
2249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler
2349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerimport java.util.Arrays;
2449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler
2549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandlerpublic class TaperedPathStroke {
2649ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    static float sMinStepPx = 4f;
2749ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    static PathMeasure pm = new PathMeasure();
2849ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    static float[] pos = {0,0};
2949ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    static float[] tan = {0,0};
3049ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    static float lerp(float t, float a, float b) {
3149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        return a + t*(b-a);
3249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    }
3349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    public static void setMinStep(float px) {
3449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        sMinStepPx = px;
3549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    }
3649ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler
3749ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    // it's the variable-width brush algorithm from the Markers app, basically
3849ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    public static void drawPath(Canvas c, Path p, float r1, float r2, Paint pt) {
3949ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        pm.setPath(p,false);
4049ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        final float len = pm.getLength();
4149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        float t=0;
4249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        boolean last=false;
4349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        while (true) {
4449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            if (t>=len) {
4549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler                t=len;
4649ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler                last=true;
4749ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            }
4849ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            pm.getPosTan(t, pos, tan);
4949ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            float r = len > 0 ? lerp(t/len, r1, r2) : r1;
5049ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            c.drawCircle(pos[0], pos[1], r, pt);
5149ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            t += Math.max(r*0.25f, sMinStepPx); // walk forward 1/4 radius, not too small though
5249ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler            if (last) break;
5349ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler        }
5449ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler    }
5549ddb0de55020320a4f08bd7060cb531a84fb536Dan Sandler}
56