Skip to content

Commit b5c3fec

Browse files
cketchamymarian
authored andcommitted
Add warning to ShapePath when an operation is being used in a situation where a compatibility shadow would normally be drawn
PiperOrigin-RevId: 295847026
1 parent d716ba4 commit b5c3fec

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/java/com/google/android/material/shape/MaterialShapeDrawable.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import androidx.core.graphics.drawable.TintAwareDrawable;
5757
import androidx.core.util.ObjectsCompat;
5858
import android.util.AttributeSet;
59+
import android.util.Log;
5960
import com.google.android.material.color.MaterialColors;
6061
import com.google.android.material.elevation.ElevationOverlayProvider;
6162
import com.google.android.material.shadow.ShadowRenderer;
@@ -64,13 +65,16 @@
6465
import com.google.android.material.shape.ShapePath.ShadowCompatOperation;
6566
import java.lang.annotation.Retention;
6667
import java.lang.annotation.RetentionPolicy;
68+
import java.util.BitSet;
6769

6870
/**
6971
* Base drawable class for Material Shapes that handles shadows, elevation, scale and color for a
7072
* generated path.
7173
*/
7274
public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable, Shapeable {
7375

76+
private static final String TAG = MaterialShapeDrawable.class.getSimpleName();
77+
7478
private static final float SHADOW_RADIUS_MULTIPLIER = .75f;
7579

7680
private static final float SHADOW_OFFSET_MULTIPLIER = .25f;
@@ -108,6 +112,7 @@ public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable
108112
// Inter-method state.
109113
private final ShadowCompatOperation[] cornerShadowOperation = new ShadowCompatOperation[4];
110114
private final ShadowCompatOperation[] edgeShadowOperation = new ShadowCompatOperation[4];
115+
private final BitSet containsIncompatibleShadowOp = new BitSet(8);
111116
private boolean pathDirty;
112117

113118
// Pre-allocated objects that are re-used several times during path computation and rendering.
@@ -204,11 +209,13 @@ private MaterialShapeDrawable(@NonNull MaterialShapeDrawableState drawableState)
204209
@Override
205210
public void onCornerPathCreated(
206211
@NonNull ShapePath cornerPath, Matrix transform, int count) {
212+
containsIncompatibleShadowOp.set(count, cornerPath.containsIncompatibleShadowOp());
207213
cornerShadowOperation[count] = cornerPath.createShadowCompatOperation(transform);
208214
}
209215

210216
@Override
211217
public void onEdgePathCreated(@NonNull ShapePath edgePath, Matrix transform, int count) {
218+
containsIncompatibleShadowOp.set(count + 4, edgePath.containsIncompatibleShadowOp());
212219
edgeShadowOperation[count] = edgePath.createShadowCompatOperation(transform);
213220
}
214221
};
@@ -1067,6 +1074,12 @@ private void prepareCanvasForShadow(@NonNull Canvas canvas) {
10671074
* completely covered by the shape.
10681075
*/
10691076
private void drawCompatShadow(@NonNull Canvas canvas) {
1077+
if (containsIncompatibleShadowOp.cardinality() > 0) {
1078+
Log.w(
1079+
TAG,
1080+
"Compatibility shadow requested but can't be drawn for all operations in this shape.");
1081+
}
1082+
10701083
if (drawableState.shadowCompatOffset != 0) {
10711084
canvas.drawPath(path, shadowRenderer.getShadowPaint());
10721085
}

lib/java/com/google/android/material/shape/ShapePath.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public class ShapePath {
8989

9090
private final List<PathOperation> operations = new ArrayList<>();
9191
private final List<ShadowCompatOperation> shadowCompatOperations = new ArrayList<>();
92+
private boolean containsIncompatibleShadowOp;
9293

9394
public ShapePath() {
9495
reset(0, 0);
@@ -116,6 +117,7 @@ public void reset(float startX, float startY, float shadowStartAngle, float shad
116117
setEndShadowAngle((shadowStartAngle + shadowSweepAngle) % 360);
117118
this.operations.clear();
118119
this.shadowCompatOperations.clear();
120+
this.containsIncompatibleShadowOp = false;
119121
}
120122

121123
/**
@@ -162,6 +164,8 @@ public void quadToPoint(float controlX, float controlY, float toX, float toY) {
162164
operation.setEndY(toY);
163165
operations.add(operation);
164166

167+
containsIncompatibleShadowOp = true;
168+
165169
setEndX(toX);
166170
setEndY(toY);
167171
}
@@ -186,6 +190,8 @@ public void cubicToPoint(
186190
new PathCubicOperation(controlX1, controlY1, controlX2, controlY2, toX, toY);
187191
operations.add(operation);
188192

193+
containsIncompatibleShadowOp = true;
194+
189195
setEndX(toX);
190196
setEndY(toY);
191197
}
@@ -270,6 +276,14 @@ private void addShadowCompatOperation(
270276
setCurrentShadowAngle(endShadowAngle);
271277
}
272278

279+
/**
280+
* Hint to let {@link MaterialShapeDrawable} know that it won't be rendering the shadow correctly
281+
* if it's drawing the compat shadow.
282+
*/
283+
boolean containsIncompatibleShadowOp() {
284+
return containsIncompatibleShadowOp;
285+
}
286+
273287
/**
274288
* Create an {@link ArcShadowOperation} to fill in a shadow between the currently drawn shadow and
275289
* the next shadow angle, if there would be a gap.

0 commit comments

Comments
 (0)