From 0b95651f71651a4713a563c931d1e775d53f047a Mon Sep 17 00:00:00 2001 From: alexey Date: Sat, 19 Dec 2020 01:45:05 +0300 Subject: [PATCH] Custom radius for each corner --- .../RoundedCornersTransformation.java | 217 +++++++++++++----- 1 file changed, 158 insertions(+), 59 deletions(-) diff --git a/transformations/src/main/java/jp/wasabeef/glide/transformations/RoundedCornersTransformation.java b/transformations/src/main/java/jp/wasabeef/glide/transformations/RoundedCornersTransformation.java index c7c64c3..acce846 100755 --- a/transformations/src/main/java/jp/wasabeef/glide/transformations/RoundedCornersTransformation.java +++ b/transformations/src/main/java/jp/wasabeef/glide/transformations/RoundedCornersTransformation.java @@ -35,6 +35,8 @@ public class RoundedCornersTransformation extends BitmapTransformation { private static final int VERSION = 1; private static final String ID = "jp.wasabeef.glide.transformations.RoundedCornersTransformation." + VERSION; + private static final int DRAW_SECTION_OFFSET = 1; + public enum CornerType { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, @@ -43,18 +45,50 @@ public enum CornerType { DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT } - private final int radius; - private final int diameter; + public static class CornerRadius { + public int topLeft; + public int topRight; + public int bottomLeft; + public int bottomRight; + + public CornerRadius(int topLeft, int topRight, int bottomLeft, int bottomRight) { + this.topLeft = topLeft; + this.topRight = topRight; + this.bottomLeft = bottomLeft; + this.bottomRight = bottomRight; + } + + @Override + public String toString() { + return "CornerRadius{" + + "topLeft=" + topLeft + + ", topRight=" + topRight + + ", bottomLeft=" + bottomLeft + + ", bottomRight=" + bottomRight + + '}'; + } + } + + private final CornerRadius radius; private final int margin; private final CornerType cornerType; public RoundedCornersTransformation(int radius, int margin) { + this(new CornerRadius(radius, radius, radius, radius), margin, CornerType.ALL); + } + + public RoundedCornersTransformation(CornerRadius radius, int margin) { this(radius, margin, CornerType.ALL); } - public RoundedCornersTransformation(int radius, int margin, CornerType cornerType) { + public RoundedCornersTransformation(CornerRadius radius, int margin, CornerType cornerType) { this.radius = radius; - this.diameter = this.radius * 2; + this.margin = margin; + this.cornerType = cornerType; + } + + public RoundedCornersTransformation(int radius, int margin, CornerType cornerType) { + this.radius = new CornerRadius(radius, radius, radius, radius); this.margin = margin; this.cornerType = cornerType; } @@ -84,7 +118,7 @@ private void drawRoundRect(Canvas canvas, Paint paint, float width, float height switch (cornerType) { case ALL: - canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint); + drawAllRoundRect(canvas, paint, right, bottom); break; case TOP_LEFT: drawTopLeftRoundRect(canvas, paint, right, bottom); @@ -129,135 +163,200 @@ private void drawRoundRect(Canvas canvas, Paint paint, float width, float height drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom); break; default: - canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius, radius, paint); + canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius.topLeft, radius.topLeft, paint); break; } } + private void drawAllRoundRect(Canvas canvas, Paint paint, float right, float bottom) { + if (radius.topLeft == radius.topRight && + radius.topLeft == radius.bottomLeft && + radius.topLeft == radius.bottomRight) { + drawAllRoundRectEquals(canvas, paint, right, bottom); + } else { + drawAllRoundRectNonEquals(canvas, paint, right, bottom); + } + } + + private void drawAllRoundRectEquals(Canvas canvas, Paint paint, float right, float bottom) { + canvas.drawRoundRect(new RectF(margin, margin, right, bottom), radius.topLeft, radius.topLeft, paint); + } + + private void drawAllRoundRectNonEquals(Canvas canvas, Paint paint, float right, float bottom) { + // top left + canvas.drawRoundRect( + new RectF(margin, margin, margin + radius.topLeft * 2, margin + radius.topLeft * 2), + radius.topLeft, + radius.topLeft, + paint); + canvas.drawRect(new RectF(margin + radius.topLeft, margin, margin + right / 2 + DRAW_SECTION_OFFSET, bottom / 2 + DRAW_SECTION_OFFSET), paint); + + // top right + canvas.drawRoundRect(new RectF(right - radius.topRight * 2, margin, right, margin + radius.topRight * 2), + radius.topRight, + radius.topRight, + paint); + canvas.drawRect(new RectF(margin + right / 2, margin, right - radius.topRight, bottom / 2 + DRAW_SECTION_OFFSET), paint); + + // bottom left + canvas.drawRoundRect(new RectF(margin, bottom - radius.bottomLeft * 2, margin + radius.bottomLeft * 2, bottom), + radius.bottomLeft, + radius.bottomLeft, + paint); + canvas.drawRect(new RectF(margin + radius.bottomLeft, bottom / 2 - DRAW_SECTION_OFFSET, margin + right / 2 + DRAW_SECTION_OFFSET, bottom), paint); + + // bottom right + canvas.drawRoundRect(new RectF(right - radius.bottomRight * 2, bottom - radius.bottomRight * 2, right, bottom), + radius.bottomRight, + radius.bottomRight, + paint); + canvas.drawRect(new RectF(margin + right / 2 - DRAW_SECTION_OFFSET, bottom / 2 - DRAW_SECTION_OFFSET, right - radius.bottomRight, bottom), paint); + + // left vertical + canvas.drawRect(new RectF(margin, margin + radius.topLeft, margin + Math.max(radius.topLeft, radius.bottomLeft), bottom - radius.bottomLeft), paint); + + // right vertical + canvas.drawRect(new RectF(right - Math.max(radius.topRight, radius.bottomRight), margin + radius.topRight, right, bottom - radius.bottomRight), paint); + } + private void drawTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin + radius, margin + radius, bottom), paint); - canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); + int diameter = radius.topLeft * 2; + canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius.topLeft, + radius.topLeft, paint); + canvas.drawRect(new RectF(margin, margin + radius.topLeft, margin + radius.topLeft, bottom), paint); + canvas.drawRect(new RectF(margin + radius.topLeft, margin, right, bottom), paint); } private void drawTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); - canvas.drawRect(new RectF(right - radius, margin + radius, right, bottom), paint); + int diameter = radius.topRight * 2; + canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius.topRight, + radius.topRight, paint); + canvas.drawRect(new RectF(margin, margin, right - radius.topRight, bottom), paint); + canvas.drawRect(new RectF(right - radius.topRight, margin + radius.topRight, right, bottom), paint); } private void drawBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin, margin + diameter, bottom - radius), paint); - canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); + int diameter = radius.bottomLeft * 2; + canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius.bottomLeft, + radius.bottomLeft, paint); + canvas.drawRect(new RectF(margin, margin, margin + diameter, bottom - radius.bottomLeft), paint); + canvas.drawRect(new RectF(margin + radius.bottomLeft, margin, right, bottom), paint); } private void drawBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); - canvas.drawRect(new RectF(right - radius, margin, right, bottom - radius), paint); + int diameter = radius.bottomRight * 2; + canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius.bottomRight, + radius.bottomRight, paint); + canvas.drawRect(new RectF(margin, margin, right - radius.bottomRight, bottom), paint); + canvas.drawRect(new RectF(right - radius.bottomRight, margin, right, bottom - radius.bottomRight), paint); } private void drawTopRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, + int diameter = radius.topLeft * 2; + canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius.topLeft, radius.topLeft, paint); - canvas.drawRect(new RectF(margin, margin + radius, right, bottom), paint); + canvas.drawRect(new RectF(margin, margin + radius.topLeft, right, bottom), paint); } private void drawBottomRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, + int diameter = radius.bottomLeft * 2; + canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius.bottomLeft, radius.bottomLeft, paint); - canvas.drawRect(new RectF(margin, margin, right, bottom - radius), paint); + canvas.drawRect(new RectF(margin, margin, right, bottom - radius.bottomLeft), paint); } private void drawLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, + int diameter = radius.topLeft * 2; + canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius.topLeft, radius.topLeft, paint); - canvas.drawRect(new RectF(margin + radius, margin, right, bottom), paint); + canvas.drawRect(new RectF(margin + radius.topLeft, margin, right, bottom), paint); } private void drawRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); - canvas.drawRect(new RectF(margin, margin, right - radius, bottom), paint); + int diameter = radius.topRight * 2; + canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius.topRight, radius.topRight, paint); + canvas.drawRect(new RectF(margin, margin, right - radius.topRight, bottom), paint); } private void drawOtherTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, + int diameter = radius.topLeft * 2; + canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius.topLeft, radius.topLeft, paint); - canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); - canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint); + canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius.topLeft, radius.topLeft, paint); + canvas.drawRect(new RectF(margin, margin, right - radius.topLeft, bottom - radius.topLeft), paint); } private void drawOtherTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, + int diameter = radius.topRight * 2; + canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius.topRight, radius.topRight, paint); - canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius, radius, + canvas.drawRoundRect(new RectF(margin, bottom - diameter, right, bottom), radius.topRight, radius.topRight, paint); - canvas.drawRect(new RectF(margin + radius, margin, right, bottom - radius), paint); + canvas.drawRect(new RectF(margin + radius.topRight, margin, right, bottom - radius.topRight), paint); } private void drawOtherBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, + int diameter = radius.bottomLeft * 2; + canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius.bottomLeft, radius.bottomLeft, paint); - canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius, radius, paint); - canvas.drawRect(new RectF(margin, margin + radius, right - radius, bottom), paint); + canvas.drawRoundRect(new RectF(right - diameter, margin, right, bottom), radius.bottomLeft, radius.bottomLeft, paint); + canvas.drawRect(new RectF(margin, margin + radius.bottomLeft, right - radius.bottomLeft, bottom), paint); } private void drawOtherBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius, radius, + int diameter = radius.bottomRight * 2; + canvas.drawRoundRect(new RectF(margin, margin, right, margin + diameter), radius.bottomRight, radius.bottomRight, paint); - canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius, radius, + canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, bottom), radius.bottomRight, radius.bottomRight, paint); - canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint); + canvas.drawRect(new RectF(margin + radius.bottomRight, margin + radius.bottomRight, right, bottom), paint); } private void drawDiagonalFromTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(margin, margin, margin + diameter, margin + diameter), radius, - radius, paint); - canvas.drawRoundRect(new RectF(right - diameter, bottom - diameter, right, bottom), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin + radius, right - radius, bottom), paint); - canvas.drawRect(new RectF(margin + radius, margin, right, bottom - radius), paint); + int diameterTopLeft = radius.topLeft * 2; + int diameterBottomRight = radius.bottomRight * 2; + canvas.drawRoundRect(new RectF(margin, margin, margin + diameterTopLeft, margin + diameterTopLeft), radius.topLeft, + radius.topLeft, paint); + canvas.drawRoundRect(new RectF(right - diameterBottomRight, bottom - diameterBottomRight, right, bottom), radius.topRight, + radius.topRight, paint); + canvas.drawRect(new RectF(margin, margin + radius.topLeft, right - radius.bottomRight, bottom), paint); + canvas.drawRect(new RectF(margin + radius.topLeft, margin, right, bottom - radius.topRight), paint); } private void drawDiagonalFromTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) { - canvas.drawRoundRect(new RectF(right - diameter, margin, right, margin + diameter), radius, - radius, paint); - canvas.drawRoundRect(new RectF(margin, bottom - diameter, margin + diameter, bottom), radius, - radius, paint); - canvas.drawRect(new RectF(margin, margin, right - radius, bottom - radius), paint); - canvas.drawRect(new RectF(margin + radius, margin + radius, right, bottom), paint); + int diameterTopRight = radius.topRight * 2; + int diameterBottomLeft = radius.bottomLeft * 2; + canvas.drawRoundRect(new RectF(right - diameterTopRight, margin, right, margin + diameterTopRight), radius.topRight, + radius.topRight, paint); + canvas.drawRoundRect(new RectF(margin, bottom - diameterBottomLeft, margin + diameterBottomLeft, bottom), radius.bottomLeft, + radius.bottomLeft, paint); + canvas.drawRect(new RectF(margin, margin, right - radius.topRight, bottom - radius.bottomLeft), paint); + canvas.drawRect(new RectF(margin + radius.bottomLeft, margin + radius.topRight, right, bottom), paint); } @Override public String toString() { - return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ", diameter=" - + diameter + ", cornerType=" + cornerType.name() + ")"; + return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ", cornerType=" + cornerType.name() + ")"; } @Override public boolean equals(Object o) { return o instanceof RoundedCornersTransformation && ((RoundedCornersTransformation) o).radius == radius && - ((RoundedCornersTransformation) o).diameter == diameter && ((RoundedCornersTransformation) o).margin == margin && ((RoundedCornersTransformation) o).cornerType == cornerType; } @Override public int hashCode() { - return ID.hashCode() + radius * 10000 + diameter * 1000 + margin * 100 + cornerType.ordinal() * 10; + return ID.hashCode() + (radius.topLeft + radius.topRight + radius.bottomLeft + radius.bottomRight) * 10000 + margin * 100 + cornerType.ordinal() * 10; } @Override public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { - messageDigest.update((ID + radius + diameter + margin + cornerType).getBytes(CHARSET)); + messageDigest.update((ID + radius + margin + cornerType).getBytes(CHARSET)); } }