Home | History | Annotate | Download | only in shadow
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.view.shadow;
     18 
     19 import com.android.ide.common.rendering.api.LayoutLog;
     20 import com.android.layoutlib.bridge.Bridge;
     21 
     22 import android.graphics.Bitmap;
     23 import android.view.math.Math3DHelper;
     24 
     25 /**
     26  * Generates ambient shadow bitmap
     27  */
     28 class AmbientShadowBitmapGenerator {
     29 
     30     private final AmbientShadowConfig mShadowConfig;
     31     private final TriangleBuffer mTriangleBuffer;
     32     private final AmbientShadowVertexCalculator mCalculator;
     33 
     34     private float mTranslateX;
     35     private float mTranslateY;
     36 
     37     private boolean mValid;
     38 
     39     public AmbientShadowBitmapGenerator(AmbientShadowConfig shadowConfig) {
     40         mShadowConfig = shadowConfig;
     41 
     42         mTriangleBuffer = new TriangleBuffer();
     43         mTriangleBuffer.setSize(mShadowConfig.getWidth(), mShadowConfig.getHeight(), 0);
     44 
     45         mCalculator = new AmbientShadowVertexCalculator(mShadowConfig);
     46     }
     47 
     48     /**
     49      * Populate vertices and fill the triangle buffers. To be called before {@link #getBitmap()}
     50      */
     51     public void populateShadow() {
     52         try {
     53             mValid = mCalculator.generateVertex(mShadowConfig.getPolygon());
     54             if (!mValid) {
     55                 Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Arithmetic error while " +
     56                                 "drawing ambient shadow", null, null);
     57                 return;
     58             }
     59 
     60             float[] shadowBounds = Math3DHelper.flatBound(mCalculator.getVertex(), 2);
     61             if (shadowBounds[0] < 0) {
     62                 // translate to right by the offset amount.
     63                 mTranslateX = shadowBounds[0] * -1;
     64             } else if (shadowBounds[2] > mShadowConfig.getWidth()) {
     65                 // translate to left by the offset amount.
     66                 mTranslateX = shadowBounds[2] - mShadowConfig.getWidth();
     67             }
     68 
     69             if (shadowBounds[1] < 0) {
     70                 mTranslateY = shadowBounds[1] * -1;
     71             } else if (shadowBounds[3] > mShadowConfig.getHeight()) {
     72                 mTranslateY = shadowBounds[3] - mShadowConfig.getHeight();
     73             }
     74 
     75             Math3DHelper.translate(mCalculator.getVertex(), mTranslateX, mTranslateY, 2);
     76 
     77             mTriangleBuffer.drawTriangles(mCalculator.getIndex(), mCalculator.getVertex(),
     78                     mCalculator.getColor(), mShadowConfig.getShadowStrength());
     79         } catch (IndexOutOfBoundsException|ArithmeticException mathError) {
     80             Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Arithmetic error while drawing " +
     81                             "ambient shadow",
     82                     mathError);
     83         } catch (Exception ex) {
     84             Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Error while drawing shadow",
     85                     ex);
     86         }
     87     }
     88 
     89     public boolean isValid() {
     90         return mValid;
     91     }
     92 
     93     public Bitmap getBitmap() {
     94         return mTriangleBuffer.getImage();
     95     }
     96 
     97     public float getTranslateX() {
     98         return mTranslateX;
     99     }
    100 
    101     public float getTranslateY() {
    102         return mTranslateY;
    103     }
    104 }
    105