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