1ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamspackage com.xtremelabs.robolectric.shadows;
2ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
3ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamsimport android.graphics.Bitmap;
4b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williamsimport com.xtremelabs.robolectric.Robolectric;
5f64d95f87eb9715622e3f77eb0b369d60270054cChristian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implementation;
6f64d95f87eb9715622e3f77eb0b369d60270054cChristian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implements;
7f64d95f87eb9715622e3f77eb0b369d60270054cChristian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.RealObject;
8ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
9ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamsimport java.io.IOException;
10ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamsimport java.io.OutputStream;
11ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
12b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williamsimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
13b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
14ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams@SuppressWarnings({"UnusedDeclaration"})
15ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams@Implements(Bitmap.class)
16ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamspublic class ShadowBitmap {
17ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    @RealObject private Bitmap realBitmap;
18ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
19b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    private int width;
20b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    private int height;
21c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    private Bitmap.Config config;
22c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    private boolean mutable;
23b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    private String description = "";
24dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams    private int loadedFromResourceId = -1;
2514534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    private boolean recycled = false;
26b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
27ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    @Implementation
28ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    public boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream) {
29ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        try {
30b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams            stream.write((description + " compressed as " + format + " with quality " + quality).getBytes());
31ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        } catch (IOException e) {
32ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams            throw new RuntimeException(e);
33ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        }
34ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
35ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        return true;
36ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    }
37b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
38b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Implementation
392b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams    public static Bitmap createBitmap(int width, int height, Bitmap.Config config) {
402b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        Bitmap scaledBitmap = Robolectric.newInstanceOf(Bitmap.class);
412b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        ShadowBitmap shadowBitmap = shadowOf(scaledBitmap);
422b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        shadowBitmap.appendDescription("Bitmap (" + width + " x " + height + ")");
432b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        shadowBitmap.setWidth(width);
442b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        shadowBitmap.setHeight(height);
45c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles        shadowBitmap.setConfig(config);
462b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams        return scaledBitmap;
472b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams    }
48c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
49c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    @Implementation
50c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public static Bitmap createBitmap(Bitmap bitmap) {
51c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles        ShadowBitmap shadowBitmap = shadowOf(bitmap);
52c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles        shadowBitmap.appendDescription(" created from Bitmap object");
53c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles        return bitmap;
54c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
552b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams
562b1c0603c5d232bfe77ba6eb22f3cf30bb913869Josh Lauer & Christian Williams    @Implementation
57b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) {
58b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        Bitmap scaledBitmap = Robolectric.newInstanceOf(Bitmap.class);
59b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        ShadowBitmap shadowBitmap = shadowOf(scaledBitmap);
60b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        shadowBitmap.appendDescription(shadowOf(src).getDescription());
6122ae0c422c4f1bb6878f624fbf2531eea4da0187Christian Williams & Phil Goodwin        shadowBitmap.appendDescription(" scaled to " + dstWidth + " x " + dstHeight);
6222ae0c422c4f1bb6878f624fbf2531eea4da0187Christian Williams & Phil Goodwin        if (filter) {
6322ae0c422c4f1bb6878f624fbf2531eea4da0187Christian Williams & Phil Goodwin            shadowBitmap.appendDescription(" with filter " + filter);
6422ae0c422c4f1bb6878f624fbf2531eea4da0187Christian Williams & Phil Goodwin        }
65b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        shadowBitmap.setWidth(dstWidth);
66b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        shadowBitmap.setHeight(dstHeight);
67b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return scaledBitmap;
68b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
6914534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi
7014534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    @Implementation
7114534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    public void recycle() {
7214534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    	recycled = true;
7314534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    }
74b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
7514534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    @Implementation
7614534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    public final boolean isRecycled() {
7714534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    	return recycled;
7814534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi    }
7914534b6218c4eeaec49059f8d9bed1da5da6dfeaMichael Portuesi
80c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    @Implementation
81c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public Bitmap copy(Bitmap.Config config, boolean isMutable) {
82c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	ShadowBitmap shadowBitmap = shadowOf(realBitmap);
83c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	shadowBitmap.setConfig(config);
84c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	shadowBitmap.setMutable(isMutable);
85c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles		return realBitmap;
86c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
87c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
88c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    @Implementation
89c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public final Bitmap.Config getConfig() {
90c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles		return config;
91c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
92c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
93c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public void setConfig(Bitmap.Config config) {
94c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	this.config = config;
95c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
96c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
97c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    @Implementation
98c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public final boolean isMutable() {
99c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	return mutable;
100c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
101c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
102c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public void setMutable(boolean mutable) {
103c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	this.mutable = mutable;
104c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
105c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
106b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public void appendDescription(String s) {
107b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        description += s;
108b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
109b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
110580676cf93d673bf5ad0328f261f6980cfec6f61Josh Lauer & Christian Williams    public void setDescription(String s) {
111580676cf93d673bf5ad0328f261f6980cfec6f61Josh Lauer & Christian Williams        description = s;
112580676cf93d673bf5ad0328f261f6980cfec6f61Josh Lauer & Christian Williams    }
113580676cf93d673bf5ad0328f261f6980cfec6f61Josh Lauer & Christian Williams
114b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public String getDescription() {
115b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return description;
116b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
117b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
118b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public static Bitmap create(String name) {
119b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        Bitmap bitmap = Robolectric.newInstanceOf(Bitmap.class);
120b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        shadowOf(bitmap).appendDescription(name);
121b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return bitmap;
122b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
123b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
124dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams    public void setLoadedFromResourceId(int loadedFromResourceId) {
125dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams        this.loadedFromResourceId = loadedFromResourceId;
126dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams    }
127dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams
128dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams    public int getLoadedFromResourceId() {
129dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams        if (loadedFromResourceId == -1) {
130dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams            throw new IllegalStateException("not loaded from a resource");
131dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams        }
132dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams        return loadedFromResourceId;
133dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams    }
134dc2eb2cd17a7fa2777e6e4f5a7566d90b2413cb4Josh Lauer & Christian Williams
135b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public void setWidth(int width) {
136b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        this.width = width;
137b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
138b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
139b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Implementation
140b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public int getWidth() {
141b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return width;
142b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
143b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
144b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public void setHeight(int height) {
145b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        this.height = height;
146b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
147b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
148b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Implementation
149b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public int getHeight() {
150b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return height;
151b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
152b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
153b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Override @Implementation
154b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public boolean equals(Object o) {
155b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        if (this == o) return true;
156b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        if (o == null || getClass() != ShadowBitmap.class) return false;
157b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
158b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        ShadowBitmap that = shadowOf((Bitmap) o);
159b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
160b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        if (height != that.height) return false;
161b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        if (width != that.width) return false;
162b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        if (description != null ? !description.equals(that.description) : that.description != null) return false;
163b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
164b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return true;
165b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
166b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
167b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Override @Implementation
168b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public int hashCode() {
169b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        int result = width;
170b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        result = 31 * result + height;
171b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        result = 31 * result + (description != null ? description.hashCode() : 0);
172b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return result;
173b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
174b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams
175b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    @Override @Implementation
176b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    public String toString() {
177b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams        return "ShadowBitmap{" +
178b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams                "description='" + description + '\'' +
179b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams                ", width=" + width +
180b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams                ", height=" + height +
181b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams                '}';
182b01474a3329222965d31068f5c33e59c6e6aa6a4Josh Lauer & Christian Williams    }
183c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
184c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    public Bitmap getRealBitmap() {
185c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    	return realBitmap;
186c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles    }
187c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
188c3f77896cb2eb511d6aee0b27d010c4def7730a9Zoodles
189ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams}
190