content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you 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 org.apache.weex.utils;
  
  import android.graphics.Bitmap;
  import android.graphics.BitmapShader;
  import android.graphics.Canvas;
  import android.graphics.Matrix;
  import android.graphics.Paint;
  import android.graphics.RectF;
  import android.graphics.Shader;
  import android.graphics.drawable.BitmapDrawable;
  import android.graphics.drawable.Drawable;
  import android.graphics.drawable.PaintDrawable;
  import android.graphics.drawable.shapes.Shape;
  import android.os.Build;
  import android.support.annotation.NonNull;
  import android.support.annotation.Nullable;
  import android.widget.ImageView;
  
  public class ImageDrawable extends PaintDrawable {
  
    public static Drawable createImageDrawable(@Nullable Drawable original,
                                               @NonNull ImageView.ScaleType scaleType,
                                               @Nullable float[] borderRadius,
                                               int vWidth,
                                               int vHeight,
                                               boolean gif) {
      Bitmap bm;
      if (!gif && vWidth > 0 && vHeight > 0) {
        if (original instanceof BitmapDrawable &&
                (bm = ((BitmapDrawable) original).getBitmap()) != null) {
          ImageDrawable imageDrawable;
          imageDrawable = new ImageDrawable();
          // fix android 9 image antialiasing
          imageDrawable.getPaint().setFilterBitmap(true);
          imageDrawable.bitmapWidth = bm.getWidth();
          imageDrawable.bitmapHeight = bm.getHeight();
          BitmapShader bitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
          updateShaderAndSize(scaleType, vWidth, vHeight, imageDrawable, bitmapShader);
          imageDrawable.getPaint().setShader(bitmapShader);
          return imageDrawable;
        } else if (original instanceof ImageDrawable) {
          ImageDrawable imageDrawable = (ImageDrawable) original;
          if (imageDrawable.getPaint() != null &&
                  imageDrawable.getPaint().getShader() instanceof BitmapShader) {
            BitmapShader bitmapShader = (BitmapShader) imageDrawable.getPaint().getShader();
            updateShaderAndSize(scaleType, vWidth, vHeight, imageDrawable, bitmapShader);
            return imageDrawable;
          }
        }
      }
      return original;
    }
  
    private static void updateShaderAndSize(@NonNull ImageView.ScaleType scaleType, int vWidth, int vHeight, ImageDrawable imageDrawable, BitmapShader bitmapShader) {
      Matrix matrix = createShaderMatrix(scaleType, vWidth, vHeight,
              imageDrawable.bitmapWidth,
              imageDrawable.bitmapHeight);
      int intrinsicWidth = vWidth, intrinsicHeight = vHeight;
      if (scaleType == ImageView.ScaleType.FIT_CENTER) {
        RectF bitmapRect = new RectF(0, 0, imageDrawable.bitmapWidth, imageDrawable.bitmapHeight), contentRect = new RectF();
        matrix.mapRect(contentRect, bitmapRect);
        intrinsicWidth = (int) contentRect.width();
        intrinsicHeight = (int) contentRect.height();
        matrix = createShaderMatrix(scaleType, intrinsicWidth, intrinsicHeight, imageDrawable
                .bitmapWidth, imageDrawable.bitmapHeight);
      }
      imageDrawable.setIntrinsicWidth(intrinsicWidth);
      imageDrawable.setIntrinsicHeight(intrinsicHeight);
      bitmapShader.setLocalMatrix(matrix);
    }
  
    @NonNull
    private static Matrix createShaderMatrix(@NonNull ImageView.ScaleType scaleType, int vWidth,
                                             int vHeight, int bmWidth, int bmHeight) {
      float scale, translateX = 0, translateY = 0;
  
      if (bmWidth * vHeight > bmHeight * vWidth) {
        scale = vHeight / (float) bmHeight;
        translateX = (vWidth - bmWidth * scale) * 0.5f;
      } else {
        scale = vWidth / (float) bmWidth;
        translateY = (vHeight - bmHeight * scale) * 0.5f;
      }
  
      Matrix mMatrix = new Matrix();
      if (scaleType == ImageView.ScaleType.FIT_XY) {
        mMatrix.setScale(vWidth / (float) bmWidth, vHeight / (float) bmHeight);
      } else if (scaleType == ImageView.ScaleType.FIT_CENTER) {
        RectF src = new RectF(0, 0, bmWidth, bmHeight);
        RectF dist = new RectF(0, 0, vWidth, vHeight);
        mMatrix.setRectToRect(src, dist, Matrix.ScaleToFit.CENTER);
      } else if (scaleType == ImageView.ScaleType.CENTER_CROP) {
        mMatrix.setScale(scale, scale);
        mMatrix.postTranslate(translateX + 0.5f, translateY + 0.5f);
      }
      return mMatrix;
    }
  
    private float[] radii;
    private int bitmapHeight;
    private int bitmapWidth;
  
    private ImageDrawable() {
  
    }
  
    @Override
    public void setCornerRadii(float[] radii) {
      this.radii = radii;
      super.setCornerRadii(radii);
    }
  
    @Override
    protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
      if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
        // fix api 21 PaintDrawable crash
        paint.setAntiAlias(false);
      }
      super.onDraw(shape, canvas, paint);
    }
  
    public
    @Nullable
    float[] getCornerRadii() {
      return this.radii;
    }
  
    public int getBitmapHeight() {
      return bitmapHeight;
    }
  
    public int getBitmapWidth() {
      return bitmapWidth;
    }
  
  }
  