/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.litho.widget;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
class CardClipDrawable extends Drawable {
private final Paint mCornerPaint;
private final Path mCornerPath = new Path();
static final int NONE = 0;
static final int TOP_LEFT = 1 << 0;
static final int TOP_RIGHT = 1 << 1;
static final int BOTTOM_LEFT = 1 << 2;
static final int BOTTOM_RIGHT = 1 << 3;
private int mDisableClipCorners = NONE;
private float mCornerRadius;
private boolean mDirty = true;
CardClipDrawable() {
mCornerPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
}
@Override
public void setAlpha(int alpha) {
mCornerPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mCornerPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
void setDisableClip(int edge) {
if ((mDisableClipCorners & edge) != 0) {
return;
}
mDisableClipCorners |= edge;
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
if (mDirty) {
buildClippingCorners();
mDirty = false;
}
final Rect bounds = getBounds();
if ((mDisableClipCorners & TOP_LEFT) == 0) {
int saved = canvas.save();
canvas.translate(bounds.left, bounds.top);
canvas.drawPath(mCornerPath, mCornerPaint);
canvas.restoreToCount(saved);
}
if ((mDisableClipCorners & BOTTOM_RIGHT) == 0) {
int saved = canvas.save();
canvas.translate(bounds.right, bounds.bottom);
canvas.rotate(180f);
canvas.drawPath(mCornerPath, mCornerPaint);
canvas.restoreToCount(saved);
}
if ((mDisableClipCorners & BOTTOM_LEFT) == 0) {
int saved = canvas.save();
canvas.translate(bounds.left, bounds.bottom);
canvas.rotate(270f);
canvas.drawPath(mCornerPath, mCornerPaint);
canvas.restoreToCount(saved);
}
if ((mDisableClipCorners & TOP_RIGHT) == 0) {
int saved = canvas.save();
canvas.translate(bounds.right, bounds.top);
canvas.rotate(90f);
canvas.drawPath(mCornerPath, mCornerPaint);
canvas.restoreToCount(saved);
}
}
void setClippingColor(int clippingColor) {
if (mCornerPaint.getColor() == clippingColor) {
return;
}
mCornerPaint.setColor(clippingColor);
invalidateSelf();
}
void setCornerRadius(float radius) {
radius = (int) (radius + .5f);
if (mCornerRadius == radius) {
return;
}
mCornerRadius = radius;
mDirty = true;
invalidateSelf();
}
private void buildClippingCorners() {
mCornerPath.reset();
RectF oval = new RectF(0, 0, mCornerRadius * 2, mCornerRadius * 2);
mCornerPath.setFillType(Path.FillType.EVEN_ODD);
mCornerPath.moveTo(0, 0);
mCornerPath.lineTo(0, mCornerRadius);
mCornerPath.arcTo(oval, 180f, 90f, true);
mCornerPath.lineTo(0, 0);
mCornerPath.close();
}
}