ADD week 5
This commit is contained in:
		| @@ -0,0 +1,249 @@ | ||||
| package com.google.android.material.shape; | ||||
|  | ||||
| import android.graphics.Matrix; | ||||
| import android.graphics.Path; | ||||
| import android.graphics.PointF; | ||||
| import android.graphics.RectF; | ||||
|  | ||||
| /* loaded from: classes.dex */ | ||||
| public class ShapeAppearancePathProvider { | ||||
|     private final ShapePath[] cornerPaths = new ShapePath[4]; | ||||
|     private final Matrix[] cornerTransforms = new Matrix[4]; | ||||
|     private final Matrix[] edgeTransforms = new Matrix[4]; | ||||
|     private final PointF pointF = new PointF(); | ||||
|     private final Path overlappedEdgePath = new Path(); | ||||
|     private final Path boundsPath = new Path(); | ||||
|     private final ShapePath shapePath = new ShapePath(); | ||||
|     private final float[] scratch = new float[2]; | ||||
|     private final float[] scratch2 = new float[2]; | ||||
|     private final Path edgePath = new Path(); | ||||
|     private final Path cornerPath = new Path(); | ||||
|     private boolean edgeIntersectionCheckEnabled = true; | ||||
|  | ||||
|     public interface PathListener { | ||||
|         void onCornerPathCreated(ShapePath shapePath, Matrix matrix, int i); | ||||
|  | ||||
|         void onEdgePathCreated(ShapePath shapePath, Matrix matrix, int i); | ||||
|     } | ||||
|  | ||||
|     void setEdgeIntersectionCheckEnable(boolean z) { | ||||
|         this.edgeIntersectionCheckEnabled = z; | ||||
|     } | ||||
|  | ||||
|     private static class Lazy { | ||||
|         static final ShapeAppearancePathProvider INSTANCE = new ShapeAppearancePathProvider(); | ||||
|  | ||||
|         private Lazy() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public ShapeAppearancePathProvider() { | ||||
|         for (int i = 0; i < 4; i++) { | ||||
|             this.cornerPaths[i] = new ShapePath(); | ||||
|             this.cornerTransforms[i] = new Matrix(); | ||||
|             this.edgeTransforms[i] = new Matrix(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static ShapeAppearancePathProvider getInstance() { | ||||
|         return Lazy.INSTANCE; | ||||
|     } | ||||
|  | ||||
|     public void calculatePath(ShapeAppearanceModel shapeAppearanceModel, float f, RectF rectF, Path path) { | ||||
|         calculatePath(shapeAppearanceModel, f, rectF, null, path); | ||||
|     } | ||||
|  | ||||
|     public void calculatePath(ShapeAppearanceModel shapeAppearanceModel, float f, RectF rectF, PathListener pathListener, Path path) { | ||||
|         path.rewind(); | ||||
|         this.overlappedEdgePath.rewind(); | ||||
|         this.boundsPath.rewind(); | ||||
|         this.boundsPath.addRect(rectF, Path.Direction.CW); | ||||
|         ShapeAppearancePathSpec shapeAppearancePathSpec = new ShapeAppearancePathSpec(shapeAppearanceModel, f, rectF, pathListener, path); | ||||
|         for (int i = 0; i < 4; i++) { | ||||
|             setCornerPathAndTransform(shapeAppearancePathSpec, i); | ||||
|             setEdgePathAndTransform(i); | ||||
|         } | ||||
|         for (int i2 = 0; i2 < 4; i2++) { | ||||
|             appendCornerPath(shapeAppearancePathSpec, i2); | ||||
|             appendEdgePath(shapeAppearancePathSpec, i2); | ||||
|         } | ||||
|         path.close(); | ||||
|         this.overlappedEdgePath.close(); | ||||
|         if (this.overlappedEdgePath.isEmpty()) { | ||||
|             return; | ||||
|         } | ||||
|         path.op(this.overlappedEdgePath, Path.Op.UNION); | ||||
|     } | ||||
|  | ||||
|     private void setCornerPathAndTransform(ShapeAppearancePathSpec shapeAppearancePathSpec, int i) { | ||||
|         getCornerTreatmentForIndex(i, shapeAppearancePathSpec.shapeAppearanceModel).getCornerPath(this.cornerPaths[i], 90.0f, shapeAppearancePathSpec.interpolation, shapeAppearancePathSpec.bounds, getCornerSizeForIndex(i, shapeAppearancePathSpec.shapeAppearanceModel)); | ||||
|         float angleOfEdge = angleOfEdge(i); | ||||
|         this.cornerTransforms[i].reset(); | ||||
|         getCoordinatesOfCorner(i, shapeAppearancePathSpec.bounds, this.pointF); | ||||
|         this.cornerTransforms[i].setTranslate(this.pointF.x, this.pointF.y); | ||||
|         this.cornerTransforms[i].preRotate(angleOfEdge); | ||||
|     } | ||||
|  | ||||
|     private void setEdgePathAndTransform(int i) { | ||||
|         this.scratch[0] = this.cornerPaths[i].getEndX(); | ||||
|         this.scratch[1] = this.cornerPaths[i].getEndY(); | ||||
|         this.cornerTransforms[i].mapPoints(this.scratch); | ||||
|         float angleOfEdge = angleOfEdge(i); | ||||
|         this.edgeTransforms[i].reset(); | ||||
|         Matrix matrix = this.edgeTransforms[i]; | ||||
|         float[] fArr = this.scratch; | ||||
|         matrix.setTranslate(fArr[0], fArr[1]); | ||||
|         this.edgeTransforms[i].preRotate(angleOfEdge); | ||||
|     } | ||||
|  | ||||
|     private void appendCornerPath(ShapeAppearancePathSpec shapeAppearancePathSpec, int i) { | ||||
|         this.scratch[0] = this.cornerPaths[i].getStartX(); | ||||
|         this.scratch[1] = this.cornerPaths[i].getStartY(); | ||||
|         this.cornerTransforms[i].mapPoints(this.scratch); | ||||
|         if (i == 0) { | ||||
|             Path path = shapeAppearancePathSpec.path; | ||||
|             float[] fArr = this.scratch; | ||||
|             path.moveTo(fArr[0], fArr[1]); | ||||
|         } else { | ||||
|             Path path2 = shapeAppearancePathSpec.path; | ||||
|             float[] fArr2 = this.scratch; | ||||
|             path2.lineTo(fArr2[0], fArr2[1]); | ||||
|         } | ||||
|         this.cornerPaths[i].applyToPath(this.cornerTransforms[i], shapeAppearancePathSpec.path); | ||||
|         if (shapeAppearancePathSpec.pathListener != null) { | ||||
|             shapeAppearancePathSpec.pathListener.onCornerPathCreated(this.cornerPaths[i], this.cornerTransforms[i], i); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void appendEdgePath(ShapeAppearancePathSpec shapeAppearancePathSpec, int i) { | ||||
|         int i2 = (i + 1) % 4; | ||||
|         this.scratch[0] = this.cornerPaths[i].getEndX(); | ||||
|         this.scratch[1] = this.cornerPaths[i].getEndY(); | ||||
|         this.cornerTransforms[i].mapPoints(this.scratch); | ||||
|         this.scratch2[0] = this.cornerPaths[i2].getStartX(); | ||||
|         this.scratch2[1] = this.cornerPaths[i2].getStartY(); | ||||
|         this.cornerTransforms[i2].mapPoints(this.scratch2); | ||||
|         float f = this.scratch[0]; | ||||
|         float[] fArr = this.scratch2; | ||||
|         float max = Math.max(((float) Math.hypot(f - fArr[0], r1[1] - fArr[1])) - 0.001f, 0.0f); | ||||
|         float edgeCenterForIndex = getEdgeCenterForIndex(shapeAppearancePathSpec.bounds, i); | ||||
|         this.shapePath.reset(0.0f, 0.0f); | ||||
|         EdgeTreatment edgeTreatmentForIndex = getEdgeTreatmentForIndex(i, shapeAppearancePathSpec.shapeAppearanceModel); | ||||
|         edgeTreatmentForIndex.getEdgePath(max, edgeCenterForIndex, shapeAppearancePathSpec.interpolation, this.shapePath); | ||||
|         this.edgePath.reset(); | ||||
|         this.shapePath.applyToPath(this.edgeTransforms[i], this.edgePath); | ||||
|         if (this.edgeIntersectionCheckEnabled && (edgeTreatmentForIndex.forceIntersection() || pathOverlapsCorner(this.edgePath, i) || pathOverlapsCorner(this.edgePath, i2))) { | ||||
|             Path path = this.edgePath; | ||||
|             path.op(path, this.boundsPath, Path.Op.DIFFERENCE); | ||||
|             this.scratch[0] = this.shapePath.getStartX(); | ||||
|             this.scratch[1] = this.shapePath.getStartY(); | ||||
|             this.edgeTransforms[i].mapPoints(this.scratch); | ||||
|             Path path2 = this.overlappedEdgePath; | ||||
|             float[] fArr2 = this.scratch; | ||||
|             path2.moveTo(fArr2[0], fArr2[1]); | ||||
|             this.shapePath.applyToPath(this.edgeTransforms[i], this.overlappedEdgePath); | ||||
|         } else { | ||||
|             this.shapePath.applyToPath(this.edgeTransforms[i], shapeAppearancePathSpec.path); | ||||
|         } | ||||
|         if (shapeAppearancePathSpec.pathListener != null) { | ||||
|             shapeAppearancePathSpec.pathListener.onEdgePathCreated(this.shapePath, this.edgeTransforms[i], i); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private boolean pathOverlapsCorner(Path path, int i) { | ||||
|         this.cornerPath.reset(); | ||||
|         this.cornerPaths[i].applyToPath(this.cornerTransforms[i], this.cornerPath); | ||||
|         RectF rectF = new RectF(); | ||||
|         path.computeBounds(rectF, true); | ||||
|         this.cornerPath.computeBounds(rectF, true); | ||||
|         path.op(this.cornerPath, Path.Op.INTERSECT); | ||||
|         path.computeBounds(rectF, true); | ||||
|         if (rectF.isEmpty()) { | ||||
|             return rectF.width() > 1.0f && rectF.height() > 1.0f; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     private float getEdgeCenterForIndex(RectF rectF, int i) { | ||||
|         this.scratch[0] = this.cornerPaths[i].endX; | ||||
|         this.scratch[1] = this.cornerPaths[i].endY; | ||||
|         this.cornerTransforms[i].mapPoints(this.scratch); | ||||
|         if (i == 1 || i == 3) { | ||||
|             return Math.abs(rectF.centerX() - this.scratch[0]); | ||||
|         } | ||||
|         return Math.abs(rectF.centerY() - this.scratch[1]); | ||||
|     } | ||||
|  | ||||
|     private CornerTreatment getCornerTreatmentForIndex(int i, ShapeAppearanceModel shapeAppearanceModel) { | ||||
|         if (i == 1) { | ||||
|             return shapeAppearanceModel.getBottomRightCorner(); | ||||
|         } | ||||
|         if (i == 2) { | ||||
|             return shapeAppearanceModel.getBottomLeftCorner(); | ||||
|         } | ||||
|         if (i == 3) { | ||||
|             return shapeAppearanceModel.getTopLeftCorner(); | ||||
|         } | ||||
|         return shapeAppearanceModel.getTopRightCorner(); | ||||
|     } | ||||
|  | ||||
|     private CornerSize getCornerSizeForIndex(int i, ShapeAppearanceModel shapeAppearanceModel) { | ||||
|         if (i == 1) { | ||||
|             return shapeAppearanceModel.getBottomRightCornerSize(); | ||||
|         } | ||||
|         if (i == 2) { | ||||
|             return shapeAppearanceModel.getBottomLeftCornerSize(); | ||||
|         } | ||||
|         if (i == 3) { | ||||
|             return shapeAppearanceModel.getTopLeftCornerSize(); | ||||
|         } | ||||
|         return shapeAppearanceModel.getTopRightCornerSize(); | ||||
|     } | ||||
|  | ||||
|     private EdgeTreatment getEdgeTreatmentForIndex(int i, ShapeAppearanceModel shapeAppearanceModel) { | ||||
|         if (i == 1) { | ||||
|             return shapeAppearanceModel.getBottomEdge(); | ||||
|         } | ||||
|         if (i == 2) { | ||||
|             return shapeAppearanceModel.getLeftEdge(); | ||||
|         } | ||||
|         if (i == 3) { | ||||
|             return shapeAppearanceModel.getTopEdge(); | ||||
|         } | ||||
|         return shapeAppearanceModel.getRightEdge(); | ||||
|     } | ||||
|  | ||||
|     private void getCoordinatesOfCorner(int i, RectF rectF, PointF pointF) { | ||||
|         if (i == 1) { | ||||
|             pointF.set(rectF.right, rectF.bottom); | ||||
|             return; | ||||
|         } | ||||
|         if (i == 2) { | ||||
|             pointF.set(rectF.left, rectF.bottom); | ||||
|         } else if (i == 3) { | ||||
|             pointF.set(rectF.left, rectF.top); | ||||
|         } else { | ||||
|             pointF.set(rectF.right, rectF.top); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private float angleOfEdge(int i) { | ||||
|         return ((i + 1) % 4) * 90; | ||||
|     } | ||||
|  | ||||
|     static final class ShapeAppearancePathSpec { | ||||
|         public final RectF bounds; | ||||
|         public final float interpolation; | ||||
|         public final Path path; | ||||
|         public final PathListener pathListener; | ||||
|         public final ShapeAppearanceModel shapeAppearanceModel; | ||||
|  | ||||
|         ShapeAppearancePathSpec(ShapeAppearanceModel shapeAppearanceModel, float f, RectF rectF, PathListener pathListener, Path path) { | ||||
|             this.pathListener = pathListener; | ||||
|             this.shapeAppearanceModel = shapeAppearanceModel; | ||||
|             this.interpolation = f; | ||||
|             this.bounds = rectF; | ||||
|             this.path = path; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user