RenderDrawable.java revision fd18f573280bbbcc549b35b548580a562bd960e2
1fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet/* 2fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Copyright (C) 2011 The Android Open Source Project 3fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 4fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License"); 5fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * you may not use this file except in compliance with the License. 6fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * You may obtain a copy of the License at 7fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 8fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * http://www.apache.org/licenses/LICENSE-2.0 9fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 10fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Unless required by applicable law or agreed to in writing, software 11fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS, 12fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * See the License for the specific language governing permissions and 14fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * limitations under the License. 15fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet */ 16fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 17fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetpackage com.android.layoutlib.bridge.impl; 18fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 19fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; 20fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 21fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.ide.common.rendering.api.DrawableParams; 22fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.ide.common.rendering.api.ResourceValue; 23fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.ide.common.rendering.api.Result; 24fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status; 25fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeContext; 26fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeWindow; 27fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.layoutlib.bridge.android.BridgeWindowSession; 28fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.resources.ResourceType; 29fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 30fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.graphics.Bitmap; 31fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.graphics.Bitmap_Delegate; 32fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.graphics.Canvas; 33fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.graphics.drawable.Drawable; 34fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.os.Handler; 35fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.view.View; 36fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.view.View.AttachInfo; 37fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.view.View.MeasureSpec; 38fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport android.widget.FrameLayout; 39fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 40fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport java.awt.AlphaComposite; 41fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport java.awt.Color; 42fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport java.awt.Graphics2D; 43fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport java.awt.image.BufferedImage; 44fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport java.io.IOException; 45fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 46fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet/** 47fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}. 48fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 49fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * The class only provides a simple {@link #render()} method, but the full life-cycle of the 50fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * action must be respected. 51fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 52fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * @see RenderAction 53fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet * 54fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet */ 55fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetpublic class RenderDrawable extends RenderAction<DrawableParams> { 56fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 57fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet public RenderDrawable(DrawableParams params) { 58fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet super(new DrawableParams(params)); 59fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } 60fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 61fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet public Result render() { 62fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet checkLock(); 63fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet try { 64fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // get the drawable resource value 65fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet DrawableParams params = getParams(); 66fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet ResourceValue drawableResource = params.getDrawable(); 67fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 68fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // resolve it 69fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet BridgeContext context = getContext(); 70fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet drawableResource = context.getRenderResources().resolveResValue(drawableResource); 71fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 72fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet if (drawableResource == null || 73fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet drawableResource.getResourceType() != ResourceType.DRAWABLE) { 74fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet return Status.ERROR_NOT_A_DRAWABLE.createResult(); 75fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } 76fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 77fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // create a simple FrameLayout 78fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet FrameLayout content = new FrameLayout(context); 79fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 80fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // get the actual Drawable object to draw 81fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet Drawable d = ResourceHelper.getDrawable(drawableResource, context); 82fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.setBackgroundDrawable(d); 83fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 84fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // set the AttachInfo on the root view. 85fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(), 86fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet new Handler(), null); 87fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet info.mHasWindowFocus = true; 88fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet info.mWindowVisibility = View.VISIBLE; 89fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet info.mInTouchMode = false; // this is so that we can display selections. 90fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet info.mHardwareAccelerated = false; 91fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.dispatchAttachedToWindow(info, 0); 92fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 93fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 94fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // measure 95fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet int w = params.getScreenWidth(); 96fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet int h = params.getScreenHeight(); 97fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY); 98fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY); 99fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.measure(w_spec, h_spec); 100fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 101fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // now do the layout. 102fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.layout(0, 0, w, h); 103fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 104fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // preDraw setup 105fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.mAttachInfo.mTreeObserver.dispatchOnPreDraw(); 106fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 107fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // draw into a new image 108fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet BufferedImage image = getImage(w, h); 109fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 110fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // create an Android bitmap around the BufferedImage 111fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet Bitmap bitmap = Bitmap_Delegate.createBitmap(image, 112fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet true /*isMutable*/, params.getDensity()); 113fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 114fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // create a Canvas around the Android bitmap 115fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet Canvas canvas = new Canvas(bitmap); 116fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet canvas.setDensity(params.getDensity().getDpiValue()); 117fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 118fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // and draw 119fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet content.draw(canvas); 120fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 121fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet return Status.SUCCESS.createResult(image); 122fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } catch (IOException e) { 123fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet return ERROR_UNKNOWN.createResult(e.getMessage(), e); 124fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } 125fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } 126fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 127fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet protected BufferedImage getImage(int w, int h) { 128fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 129fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet Graphics2D gc = image.createGraphics(); 130fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet gc.setComposite(AlphaComposite.Src); 131fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 132fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet gc.setColor(new Color(0x00000000, true)); 133fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet gc.fillRect(0, 0, w, h); 134fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 135fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet // done 136fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet gc.dispose(); 137fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 138fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet return image; 139fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet } 140fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet 141fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet} 142