Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2011 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 com.android.layoutlib.bridge.impl;
     18 
     19 import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
     20 
     21 import com.android.ide.common.rendering.api.DrawableParams;
     22 import com.android.ide.common.rendering.api.HardwareConfig;
     23 import com.android.ide.common.rendering.api.ResourceValue;
     24 import com.android.ide.common.rendering.api.Result;
     25 import com.android.ide.common.rendering.api.Result.Status;
     26 import com.android.layoutlib.bridge.android.BridgeContext;
     27 import com.android.resources.ResourceType;
     28 
     29 import android.graphics.Bitmap;
     30 import android.graphics.Bitmap_Delegate;
     31 import android.graphics.Canvas;
     32 import android.graphics.drawable.Drawable;
     33 import android.view.AttachInfo_Accessor;
     34 import android.view.View.MeasureSpec;
     35 import android.widget.FrameLayout;
     36 
     37 import java.awt.AlphaComposite;
     38 import java.awt.Color;
     39 import java.awt.Graphics2D;
     40 import java.awt.image.BufferedImage;
     41 import java.io.IOException;
     42 
     43 /**
     44  * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
     45  *
     46  * The class only provides a simple {@link #render()} method, but the full life-cycle of the
     47  * action must be respected.
     48  *
     49  * @see RenderAction
     50  *
     51  */
     52 public class RenderDrawable extends RenderAction<DrawableParams> {
     53 
     54     public RenderDrawable(DrawableParams params) {
     55         super(new DrawableParams(params));
     56     }
     57 
     58     public Result render() {
     59         checkLock();
     60         try {
     61             // get the drawable resource value
     62             DrawableParams params = getParams();
     63             HardwareConfig hardwareConfig = params.getHardwareConfig();
     64             ResourceValue drawableResource = params.getDrawable();
     65 
     66             // resolve it
     67             BridgeContext context = getContext();
     68             drawableResource = context.getRenderResources().resolveResValue(drawableResource);
     69 
     70             if (drawableResource == null ||
     71                     drawableResource.getResourceType() != ResourceType.DRAWABLE) {
     72                 return Status.ERROR_NOT_A_DRAWABLE.createResult();
     73             }
     74 
     75             // create a simple FrameLayout
     76             FrameLayout content = new FrameLayout(context);
     77 
     78             // get the actual Drawable object to draw
     79             Drawable d = ResourceHelper.getDrawable(drawableResource, context);
     80             content.setBackground(d);
     81 
     82             // set the AttachInfo on the root view.
     83             AttachInfo_Accessor.setAttachInfo(content);
     84 
     85 
     86             // measure
     87             int w = hardwareConfig.getScreenWidth();
     88             int h = hardwareConfig.getScreenHeight();
     89             int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
     90             int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
     91             content.measure(w_spec, h_spec);
     92 
     93             // now do the layout.
     94             content.layout(0, 0, w, h);
     95 
     96             // preDraw setup
     97             AttachInfo_Accessor.dispatchOnPreDraw(content);
     98 
     99             // draw into a new image
    100             BufferedImage image = getImage(w, h);
    101 
    102             // create an Android bitmap around the BufferedImage
    103             Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
    104                     true /*isMutable*/, hardwareConfig.getDensity());
    105 
    106             // create a Canvas around the Android bitmap
    107             Canvas canvas = new Canvas(bitmap);
    108             canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
    109 
    110             // and draw
    111             content.draw(canvas);
    112 
    113             return Status.SUCCESS.createResult(image);
    114         } catch (IOException e) {
    115             return ERROR_UNKNOWN.createResult(e.getMessage(), e);
    116         }
    117     }
    118 
    119     protected BufferedImage getImage(int w, int h) {
    120         BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    121         Graphics2D gc = image.createGraphics();
    122         gc.setComposite(AlphaComposite.Src);
    123 
    124         gc.setColor(new Color(0x00000000, true));
    125         gc.fillRect(0, 0, w, h);
    126 
    127         // done
    128         gc.dispose();
    129 
    130         return image;
    131     }
    132 
    133 }
    134