Fix RCTImageView always clipping to bounds even if overflow is visible

Summary: Previously, RCTImageView/DrawCommand would always clip for specific scale types (such as CENTER_CROP), but this is incorrect if we want to allow overflow: visible on RCTImageView (which iOS allows). This patch tweaks the clipping condition from paddingLeft/paddingTop < 0 (i.e. image wants to draw outside of its bounds) to actual image rect being outside of clip rect. Previously, that would mean exact same thing, but now that clip rect is aware of overflow: visible, it matters, allowing RCTImage to not clip when we want it to draw outside of the boundaries.

Reviewed By: ahmedre

Differential Revision: D2873350
This commit is contained in:
Denis Koroskin 2016-01-29 15:04:00 -08:00 committed by Ahmed El-Helw
parent 674e74a963
commit 88ebce0512
2 changed files with 26 additions and 9 deletions

View File

@ -137,6 +137,22 @@ import android.graphics.Canvas;
return mBottom;
}
public final float getClipLeft() {
return mClipLeft;
}
public final float getClipTop() {
return mClipTop;
}
public final float getClipRight() {
return mClipRight;
}
public final float getClipBottom() {
return mClipBottom;
}
protected abstract void onDraw(Canvas canvas);
protected boolean shouldClip() {

View File

@ -44,7 +44,8 @@ import com.facebook.react.views.image.ReactImageView;
private @Nullable FlatViewGroup.InvalidateCallback mCallback;
private @Nullable Path mPathForRoundedBitmap;
private @Nullable BitmapShader mBitmapShader;
private boolean mForceClip;
private float mHorizontalPadding;
private float mVerticalPadding;
private int mReactTag;
// variables used for fading the image in
@ -149,7 +150,10 @@ import com.facebook.react.views.image.ReactImageView;
@Override
protected boolean shouldClip() {
return mForceClip || super.shouldClip();
return getLeft() + mHorizontalPadding < getClipLeft() ||
getTop() + mVerticalPadding < getClipTop() ||
getRight() - mHorizontalPadding > getClipRight() ||
getBottom() - mVerticalPadding < getClipBottom();
}
@Override
@ -211,11 +215,10 @@ import com.facebook.react.views.image.ReactImageView;
float imageWidth = (float) bitmap.getWidth();
float imageHeight = (float) bitmap.getHeight();
mForceClip = false;
if (mScaleType == ScaleType.FIT_XY) {
mTransform.setScale(containerWidth / imageWidth, containerHeight / imageHeight);
mTransform.postTranslate(left, top);
mHorizontalPadding = mVerticalPadding = 0;
return;
}
@ -231,13 +234,11 @@ import com.facebook.react.views.image.ReactImageView;
scale = Math.max(containerWidth / imageWidth, containerHeight / imageHeight);
}
float paddingLeft = (containerWidth - imageWidth * scale) / 2;
float paddingTop = (containerHeight - imageHeight * scale) / 2;
mForceClip = paddingLeft < 0 || paddingTop < 0;
mHorizontalPadding = (containerWidth - imageWidth * scale) / 2;
mVerticalPadding = (containerHeight - imageHeight * scale) / 2;
mTransform.setScale(scale, scale);
mTransform.postTranslate(left + paddingLeft, top + paddingTop);
mTransform.postTranslate(left + mHorizontalPadding, top + mVerticalPadding);
if (mBitmapShader != null) {
mBitmapShader.setLocalMatrix(mTransform);