blob: 5256b583f8d3eb44f06795c4c5fa671d4d141ac2 [file] [log] [blame]
Xavier Ducrohet779c9062011-02-04 16:40:49 -08001/*
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 android.graphics;
18
19import com.android.layoutlib.bridge.Bridge;
Xavier Ducrohet779c9062011-02-04 16:40:49 -080020import com.android.layoutlib.bridge.impl.DelegateManager;
21import com.android.ninepatch.NinePatchChunk;
22import com.android.resources.Density;
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -080023import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
Xavier Ducrohet779c9062011-02-04 16:40:49 -080024
Xavier Ducrohetd2f664d2011-07-29 17:41:39 -070025import android.content.res.BridgeResources.NinePatchInputStream;
Xavier Ducrohet779c9062011-02-04 16:40:49 -080026import android.graphics.BitmapFactory.Options;
27
28import java.io.FileDescriptor;
29import java.io.IOException;
30import java.io.InputStream;
31
32/**
33 * Delegate implementing the native methods of android.graphics.BitmapFactory
34 *
35 * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
36 * replaced by calls to methods of the same name in this delegate class.
37 *
38 * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
39 * around to map int to instance of the delegate.
40 *
41 */
42/*package*/ class BitmapFactory_Delegate {
43
Xavier Ducrohet13bdc332011-02-06 10:58:16 -080044 // ------ Java delegates ------
45
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -080046 @LayoutlibDelegate
Xavier Ducrohet13bdc332011-02-06 10:58:16 -080047 /*package*/ static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
48 if (bm == null || opts == null) {
49 return bm;
50 }
51
52 final int density = opts.inDensity;
53 if (density == 0) {
54 return bm;
55 }
56
57 bm.setDensity(density);
58 final int targetDensity = opts.inTargetDensity;
59 if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
60 return bm;
61 }
62
63 byte[] np = bm.getNinePatchChunk();
64 final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
65 // DELEGATE CHANGE: never scale 9-patch
66 if (opts.inScaled && isNinePatch == false) {
67 float scale = targetDensity / (float)density;
68 // TODO: This is very inefficient and should be done in native by Skia
69 final Bitmap oldBitmap = bm;
70 bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
71 (int) (bm.getHeight() * scale + 0.5f), true);
72 oldBitmap.recycle();
73
74 if (isNinePatch) {
75 np = nativeScaleNinePatch(np, scale, outPadding);
76 bm.setNinePatchChunk(np);
77 }
78 bm.setDensity(targetDensity);
79 }
80
81 return bm;
82 }
83
84
Xavier Ducrohet779c9062011-02-04 16:40:49 -080085 // ------ Native Delegates ------
86
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -080087 @LayoutlibDelegate
Xavier Ducrohet22f700a2012-03-23 16:07:23 -070088 /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
89 Rect padding, Options opts) {
90 return nativeDecodeStream(is, storage, padding, opts, false, 1.f);
Xavier Ducrohet779c9062011-02-04 16:40:49 -080091 }
92
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -080093 @LayoutlibDelegate
Xavier Ducrohet22f700a2012-03-23 16:07:23 -070094 /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
95 Rect padding, Options opts, boolean applyScale, float scale) {
Xavier Ducrohet779c9062011-02-04 16:40:49 -080096 Bitmap bm = null;
97
Xavier Ducrohet22f700a2012-03-23 16:07:23 -070098 //TODO support rescaling
99
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800100 Density density = Density.MEDIUM;
101 if (opts != null) {
102 density = Density.getEnum(opts.inDensity);
103 }
104
105 try {
106 if (is instanceof NinePatchInputStream) {
107 NinePatchInputStream npis = (NinePatchInputStream) is;
108 npis.disableFakeMarkSupport();
109
110 // load the bitmap as a nine patch
111 com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
112 npis, true /*is9Patch*/, false /*convert*/);
113
114 // get the bitmap and chunk objects.
115 bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), true /*isMutable*/,
116 density);
117 NinePatchChunk chunk = ninePatch.getChunk();
118
119 // put the chunk in the bitmap
120 bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
121
122 // read the padding
123 int[] paddingarray = chunk.getPadding();
124 padding.left = paddingarray[0];
125 padding.top = paddingarray[1];
126 padding.right = paddingarray[2];
127 padding.bottom = paddingarray[3];
128 } else {
129 // load the bitmap directly.
130 bm = Bitmap_Delegate.createBitmap(is, true, density);
131 }
132 } catch (IOException e) {
133 Bridge.getLog().error(null,"Failed to load image" , e, null);
134 }
135
136 return bm;
137 }
138
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -0800139 @LayoutlibDelegate
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800140 /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
141 Rect padding, Options opts) {
142 opts.inBitmap = null;
143 return null;
144 }
145
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -0800146 @LayoutlibDelegate
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800147 /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts) {
148 opts.inBitmap = null;
149 return null;
150 }
151
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -0800152 @LayoutlibDelegate
Xavier Ducrohet22f700a2012-03-23 16:07:23 -0700153 /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
154 boolean applyScale, float scale) {
155 opts.inBitmap = null;
156 return null;
157 }
158
159 @LayoutlibDelegate
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800160 /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
161 int length, Options opts) {
162 opts.inBitmap = null;
163 return null;
164 }
165
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -0800166 @LayoutlibDelegate
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800167 /*package*/ static byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad) {
Xavier Ducrohet13bdc332011-02-06 10:58:16 -0800168 // don't scale for now. This should not be called anyway since we re-implement
169 // BitmapFactory.finishDecode();
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800170 return chunk;
171 }
172
Xavier Ducrohet9a4fe292011-02-09 17:17:49 -0800173 @LayoutlibDelegate
Xavier Ducrohet779c9062011-02-04 16:40:49 -0800174 /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
175 return true;
176 }
177}