Skip to content

Commit

Permalink
feat(android): capInsets and tintColor support for each image types
Browse files Browse the repository at this point in the history
  • Loading branch information
iPel committed Aug 28, 2023
1 parent 638ed17 commit b93e54c
Show file tree
Hide file tree
Showing 6 changed files with 373 additions and 66 deletions.
10 changes: 10 additions & 0 deletions framework/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,13 @@ task dealAfterAssembleRelease() {
}
}
}

project.afterEvaluate {
project.android.libraryVariants.all { variant ->
def variantName = variant.name.capitalize()
def taskMergeClasses = project.tasks.named("mergeClasses${variantName}")
project.tasks.named("bundleLibCompileToJar${variantName}").configure {
dependsOn(taskMergeClasses)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.Px;

import androidx.core.graphics.Insets;
import com.tencent.mtt.hippy.utils.PixelUtil;
import com.tencent.renderer.component.drawable.BackgroundDrawable;
import com.tencent.renderer.component.drawable.BackgroundDrawable.BorderArc;
Expand Down Expand Up @@ -79,7 +80,8 @@ public Component(RenderNode node) {
}

public int getHostId() {
return (mHostRef.get() != null) ? mHostRef.get().getId() : -1;
final RenderNode host = mHostRef.get();
return (host != null) ? host.getId() : -1;
}

protected boolean checkComponentFlag(int flag) {
Expand Down Expand Up @@ -129,14 +131,16 @@ public void onDraw(@NonNull Canvas canvas, int left, int top, int right, int bot
}

protected void invalidate() {
if (mHostRef.get() != null) {
mHostRef.get().invalidate();
final RenderNode host = mHostRef.get();
if (host != null) {
host.invalidate();
}
}

protected void postInvalidateDelayed(long delayMilliseconds) {
if (mHostRef.get() != null) {
mHostRef.get().postInvalidateDelayed(delayMilliseconds);
final RenderNode host = mHostRef.get();
if (host != null) {
host.postInvalidateDelayed(delayMilliseconds);
}
}

Expand Down Expand Up @@ -343,8 +347,9 @@ public int getZIndex() {

public void setZIndex(int zIndex) {
mZIndex = zIndex;
if (mHostRef.get() != null) {
mHostRef.get().onZIndexChanged();
final RenderNode host = mHostRef.get();
if (host != null) {
host.onZIndexChanged();
}
}

Expand Down Expand Up @@ -463,4 +468,8 @@ public void setShadowRadius(@Px float radius) {
public void setShadowColor(@ColorInt int color) {
ensureBackgroundDrawable().setShadowColor(color);
}

public void setNinePatchCoordinate(Insets insets) {
ensureContentDrawable().setNinePatchCoordinate(insets);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@
* limitations under the License.
*/

/* Tencent is pleased to support the open source community by making Hippy available.
* Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.tencent.renderer.component.drawable;

import android.graphics.Bitmap;
Expand All @@ -50,15 +34,18 @@
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

import android.graphics.drawable.NinePatchDrawable;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;

import androidx.core.graphics.Insets;
import com.tencent.renderer.component.image.ImageDataSupplier;

public class ContentDrawable extends Drawable {

private static final Runnable NO_OP = () -> {};
private int mTintColor;
private int mImagePositionX;
private int mImagePositionY;
Expand All @@ -74,6 +61,14 @@ public class ContentDrawable extends Drawable {
private GifMovieState mGifMovieState;
@Nullable
private BackgroundHolder mBackgroundHolder;
@Nullable
private Insets mNinePatchInsets;
@Nullable
private NinePatchDrawable mNinePatchDrawable;
@Nullable
private PorterDuffColorFilter mColorFilter;
@Nullable
private Shader mShader;

public enum ScaleType {
FIT_XY,
Expand Down Expand Up @@ -129,10 +124,14 @@ public void setColorFilter(ColorFilter colorFilter) {
public void clear() {
mGifMovieState = null;
mImageHolder = null;
mNinePatchDrawable = null;
mShader = null;
}

public void setImageData(@NonNull ImageDataSupplier imageHolder) {
mImageHolder = imageHolder;
mNinePatchDrawable = null;
mShader = null;
}

private void updateContentRegionIfNeeded() {
Expand All @@ -159,20 +158,14 @@ public void draw(@NonNull Canvas canvas) {
} else {
canvas.clipRect(mContentRegion);
}
if (mColorFilter == null && mTintColor != Color.TRANSPARENT) {
mColorFilter = new PorterDuffColorFilter(mTintColor, mTintColorBlendMode);
}
if (mImageHolder.getDrawable() != null) {
mImageHolder.getDrawable().draw(canvas);
drawDrawable(canvas, mImageHolder.getDrawable());
} else if (mImageHolder.isAnimated()) {
drawGif(canvas, mImageHolder.getGifMovie());
} else {
if (mPaint == null) {
mPaint = new Paint();
} else {
mPaint.reset();
}
mPaint.setAntiAlias(true);
if (mTintColor != Color.TRANSPARENT) {
mPaint.setColorFilter(new PorterDuffColorFilter(mTintColor, mTintColorBlendMode));
}
Bitmap bitmap = mImageHolder.getBitmap();
if (bitmap != null) {
drawBitmap(canvas, bitmap);
Expand All @@ -181,6 +174,28 @@ public void draw(@NonNull Canvas canvas) {
canvas.restore();
}

private void drawDrawable(@NonNull Canvas canvas, Drawable drawable) {
final boolean clearColorFilter;
if (drawable.getColorFilter() == null && mColorFilter != null) {
clearColorFilter = true;
drawable.setColorFilter(mColorFilter);
} else {
clearColorFilter = false;
}
if (mNinePatchInsets != null && !mNinePatchInsets.equals(Insets.NONE)
&& !(drawable instanceof NinePatchDrawable)
&& drawable.getIntrinsicWidth() > 0
&& drawable.getIntrinsicHeight() > 0
) {
NinePatchHelper.drawDrawable(canvas, drawable, mContentRegion, mNinePatchInsets);
} else {
drawable.draw(canvas);
}
if (clearColorFilter) {
drawable.setColorFilter(null);
}
}

private void updateBitmapMatrix(@NonNull Bitmap bitmap) {
final RectF dst = new RectF(mContentRegion);
final float bitmapWidth = bitmap.getWidth();
Expand Down Expand Up @@ -231,15 +246,41 @@ private void updateBitmapMatrix(@NonNull Bitmap bitmap) {
}

private void drawBitmap(@NonNull Canvas canvas, @NonNull Bitmap bitmap) {
assert mPaint != null;
updateBitmapMatrix(bitmap);
if (mScaleType == ScaleType.REPEAT) {
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
mPaint.setShader(bitmapShader);
if (mNinePatchInsets != null && !mNinePatchInsets.equals(Insets.NONE)) {
if (mNinePatchDrawable == null) {
mNinePatchDrawable = NinePatchHelper.createNinePatchDrawable(bitmap, mNinePatchInsets);
if (mColorFilter != null) {
mNinePatchDrawable.setColorFilter(mColorFilter);
}
}
mNinePatchDrawable.setBounds((int) mContentRegion.left, (int) mContentRegion.top,
(int) mContentRegion.right, (int) mContentRegion.bottom);
mNinePatchDrawable.draw(canvas);
} else {
Paint paint = getPaint();
updateBitmapMatrix(bitmap);
if (mScaleType == ScaleType.REPEAT) {
if (mShader == null) {
mShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
}
paint.setShader(mShader);
}
paint.setFilterBitmap(true);
canvas.drawBitmap(bitmap, mBitmapMatrix, paint);
}
}

private Paint getPaint() {
if (mPaint == null) {
mPaint = new Paint();
} else {
mPaint.reset();
}
mPaint.setFilterBitmap(true);
canvas.drawBitmap(bitmap, mBitmapMatrix, mPaint);
mPaint.setAntiAlias(true);
if (mColorFilter != null) {
mPaint.setColorFilter(mColorFilter);
}
return mPaint;
}

private void drawGif(@NonNull Canvas canvas, @Nullable Movie movie) {
Expand All @@ -265,20 +306,21 @@ private void drawGif(@NonNull Canvas canvas, @Nullable Movie movie) {
int progress =
mGifMovieState.progress > Integer.MAX_VALUE ? 0 : (int) mGifMovieState.progress;
movie.setTime(progress);
canvas.save();
canvas.scale(mGifMovieState.scaleX, mGifMovieState.scaleY);
movie.draw(canvas, mGifMovieState.startX, mGifMovieState.startY + 1.0f);
canvas.restore();
scheduleSelf(new Runnable() {
@Override
public void run() {

}
}, 40);
Paint paint = getPaint();
if (mNinePatchInsets != null && !mNinePatchInsets.equals(Insets.NONE)) {
NinePatchHelper.drawGif(canvas, movie, paint, mContentRegion, mNinePatchInsets);
} else {
canvas.save();
canvas.scale(mGifMovieState.scaleX, mGifMovieState.scaleY);
movie.draw(canvas, mGifMovieState.startX, mGifMovieState.startY + 1.0f, paint);
canvas.restore();
}
scheduleSelf(NO_OP, 40);
}

public void setScaleType(ScaleType scaleType) {
mScaleType = scaleType;
mShader = null;
}

public void setImagePositionX(@Px int positionX) {
Expand All @@ -291,10 +333,17 @@ public void setImagePositionY(@Px int positionY) {

public void setTintColor(@ColorInt int tintColor) {
mTintColor = tintColor;
mColorFilter = null;
}

public void setTintColorBlendMode(int tintColorBlendMode) {
mTintColorBlendMode = convertToPorterDuffMode(tintColorBlendMode);
mColorFilter = null;
}

public void setNinePatchCoordinate(Insets insets) {
mNinePatchInsets = insets;
mNinePatchDrawable = null;
}

private Mode convertToPorterDuffMode(int val) {
Expand Down
Loading

0 comments on commit b93e54c

Please sign in to comment.