Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37ecda0e authored by Diego Perez's avatar Diego Perez Committed by Android (Google) Code Review
Browse files

Merge "Fix BitmapShader to work with adaptive icons"

parents 9f7958c1 f4291b03
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.layoutlib.bridge.impl.PorterDuffUtility;
import com.android.ninepatch.NinePatchChunk;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.annotation.Nullable;
import android.text.TextUtils;

import java.awt.*;
@@ -31,6 +32,8 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;

public class BaseCanvas_Delegate {
    // ---- delegate manager ----
@@ -646,9 +649,15 @@ public class BaseCanvas_Delegate {
        forceSrcMode[0] = false;

        // if the bitmap config is alpha_8, then we erase all color value from it
        // before drawing it.
        // before drawing it or apply the texture from the shader if present.
        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
            fixAlpha8Bitmap(image);
            Shader_Delegate shader = paint.getShader();
            java.awt.Paint javaPaint = null;
            if (shader instanceof BitmapShader_Delegate) {
                javaPaint = shader.getJavaPaint();
            }

            fixAlpha8Bitmap(image, javaPaint);
        } else if (!bitmap.hasAlpha()) {
            // hasAlpha is merely a rendering hint. There can in fact be alpha values
            // in the bitmap but it should be ignored at drawing time.
@@ -672,16 +681,37 @@ public class BaseCanvas_Delegate {
        return image;
    }

    private static void fixAlpha8Bitmap(final BufferedImage image) {
    /**
     * This method will apply the correct color to the passed "only alpha" image. Colors on the
     * passed image will be destroyed.
     * If the passed javaPaint is null, the color will be set to 0. If a paint is passed, it will
     * be used to obtain the color that will be applied.
     * <p/>
     * This will destroy the passed image color channel.
     */
    private static void fixAlpha8Bitmap(final BufferedImage image,
            @Nullable java.awt.Paint javaPaint) {
        int w = image.getWidth();
        int h = image.getHeight();

        DataBuffer texture = null;
        if (javaPaint != null) {
            PaintContext context = javaPaint.createContext(ColorModel.getRGBdefault(), null, null,
                    new AffineTransform(), null);
            texture = context.getRaster(0, 0, w, h).getDataBuffer();
        }

        int[] argb = new int[w * h];
        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());

        final int length = argb.length;
        for (int i = 0; i < length; i++) {
            argb[i] &= 0xFF000000;
            if (texture != null) {
                argb[i] |= texture.getElem(i) & 0x00FFFFFF;
            }
        }

        image.setRGB(0, 0, w, h, argb, 0, w);
    }

+0 −59
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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 android.graphics.drawable;

import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable.LayerState;

/**
 * Delegate used to provide new implementation of a select few methods of {@link
 * AdaptiveIconDrawable}
 * <p>
 * Through the layoutlib_create tool, the original  methods of AdaptiveIconDrawable have been
 * replaced by calls to methods of the same name in this delegate class.
 */
@SuppressWarnings("unused")
public class AdaptiveIconDrawable_Delegate {
    @LayoutlibDelegate
    /*package*/ static void draw(AdaptiveIconDrawable thisDrawable, Canvas canvas) {
        // This is a workaround for the broken BitmapShader in layoutlib. This new draw methods
        // avoids the use of the shader.

        for (int i = 0; i < LayerState.N_CHILDREN; i++) {
            if (thisDrawable.mLayerState.mChildren[i] == null) {
                continue;
            }
            final Drawable dr = thisDrawable.mLayerState.mChildren[i].mDrawable;
            if (dr != null) {
                dr.draw(canvas);
            }
        }

        if (thisDrawable.mMaskBitmap != null) {
            Rect bounds = thisDrawable.getBounds();
            Paint paint = new Paint();
            paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
            canvas.drawBitmap(thisDrawable.mMaskBitmap, bounds.left, bounds.top, paint);
        }
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -163,7 +163,6 @@ public final class CreateInfo implements ICreateInfo {
        "android.content.res.TypedArray#obtain",
        "android.graphics.BitmapFactory#finishDecode",
        "android.graphics.BitmapFactory#setDensityFromOptions",
        "android.graphics.drawable.AdaptiveIconDrawable#draw",
        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw",
        "android.graphics.drawable.GradientDrawable#buildRing",
@@ -333,8 +332,6 @@ public final class CreateInfo implements ICreateInfo {
     * needed when access from the delegate classes is needed.
     */
    private final static String[] PROMOTED_FIELDS = new String[] {
        "android.graphics.drawable.AdaptiveIconDrawable#mMaskBitmap",
        "android.graphics.drawable.AdaptiveIconDrawable#mPaint",
        "android.graphics.drawable.VectorDrawable#mVectorState",
        "android.view.Choreographer#mLastFrameTimeNanos",
        "android.graphics.FontFamily#mBuilderPtr"