aboutsummaryrefslogtreecommitdiffstats
path: root/assetstudio
diff options
context:
space:
mode:
Diffstat (limited to 'assetstudio')
-rw-r--r--assetstudio/.classpath4
-rw-r--r--assetstudio/src/com/android/assetstudiolib/ActionBarIconGenerator.java92
-rw-r--r--assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java160
-rw-r--r--assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java165
-rw-r--r--assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java100
-rw-r--r--assetstudio/src/com/android/assetstudiolib/NotificationIconGenerator.java175
-rw-r--r--assetstudio/src/com/android/assetstudiolib/TabIconGenerator.java188
-rw-r--r--assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java45
-rw-r--r--assetstudio/src/com/android/assetstudiolib/Util.java2
-rw-r--r--assetstudio/src/images/notification_stencil/circle/hdpi.pngbin0 -> 1260 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/circle/ldpi.pngbin0 -> 751 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/circle/mdpi.pngbin0 -> 925 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/circle/xhdpi.pngbin0 -> 2596 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/square/hdpi.pngbin0 -> 519 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/square/ldpi.pngbin0 -> 395 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/square/mdpi.pngbin0 -> 491 bytes
-rw-r--r--assetstudio/src/images/notification_stencil/square/xhdpi.pngbin0 -> 1534 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/ActionBarIconGeneratorTest.java41
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/GeneratorTest.java225
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/LauncherIconGeneratorTest.java48
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/MenuIconGeneratorTest.java31
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/NotificationIconGeneratorTest.java41
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/TabIconGeneratorTest.java31
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_dark.pngbin0 -> 1293 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_light.pngbin0 -> 646 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_dark.pngbin0 -> 548 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_light.pngbin0 -> 337 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_dark.pngbin0 -> 813 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_light.pngbin0 -> 481 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_dark.pngbin0 -> 1975 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_light.pngbin0 -> 859 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/blue_glossy_square-web.pngbin0 -> 65994 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/red_fancy_circle-web.pngbin0 -> 80075 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/blue_glossy_square.pngbin0 -> 4931 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/red_fancy_circle.pngbin0 -> 4686 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/blue_glossy_square.pngbin0 -> 2018 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/red_fancy_circle.pngbin0 -> 1876 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/blue_glossy_square.pngbin0 -> 3061 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/red_fancy_circle.pngbin0 -> 2731 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/blue_glossy_square.pngbin0 -> 6746 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/red_fancy_circle.pngbin0 -> 6903 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-hdpi/ic_menu_1.pngbin0 -> 1888 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-ldpi/ic_menu_1.pngbin0 -> 879 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-mdpi/ic_menu_1.pngbin0 -> 1186 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-xhdpi/ic_menu_1.pngbin0 -> 2525 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_circle.pngbin0 -> 550 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_square.pngbin0 -> 550 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_circle.pngbin0 -> 619 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_square.pngbin0 -> 619 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_circle.pngbin0 -> 1406 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_square.pngbin0 -> 1066 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_circle.pngbin0 -> 301 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_square.pngbin0 -> 301 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_circle.pngbin0 -> 343 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_square.pngbin0 -> 343 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_circle.pngbin0 -> 647 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_square.pngbin0 -> 503 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_circle.pngbin0 -> 399 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_square.pngbin0 -> 399 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_circle.pngbin0 -> 412 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_square.pngbin0 -> 412 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_circle.pngbin0 -> 881 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_square.pngbin0 -> 687 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_circle.pngbin0 -> 731 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_square.pngbin0 -> 731 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_circle.pngbin0 -> 735 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_square.pngbin0 -> 735 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_circle.pngbin0 -> 1958 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_square.pngbin0 -> 1506 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_selected.pngbin0 -> 1577 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_unselected.pngbin0 -> 724 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_selected.pngbin0 -> 1667 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_unselected.pngbin0 -> 1560 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_selected.pngbin0 -> 704 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_unselected.pngbin0 -> 403 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_selected.pngbin0 -> 725 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_unselected.pngbin0 -> 719 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_selected.pngbin0 -> 940 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_unselected.pngbin0 -> 501 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_selected.pngbin0 -> 1003 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_unselected.pngbin0 -> 968 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_selected.pngbin0 -> 2270 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_unselected.pngbin0 -> 978 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_selected.pngbin0 -> 2289 bytes
-rw-r--r--assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_unselected.pngbin0 -> 2159 bytes
85 files changed, 1221 insertions, 127 deletions
diff --git a/assetstudio/.classpath b/assetstudio/.classpath
index ee79d9631..53a77a144 100644
--- a/assetstudio/.classpath
+++ b/assetstudio/.classpath
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="tests/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="output" path="bin"/>
<classpathentry combineaccessrules="false" kind="src" path="/common"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+ <classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/assetstudio/src/com/android/assetstudiolib/ActionBarIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/ActionBarIconGenerator.java
new file mode 100644
index 000000000..b54aad56c
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/ActionBarIconGenerator.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.Util.Effect;
+import com.android.assetstudiolib.Util.FillEffect;
+import com.android.assetstudiolib.Util.ShadowEffect;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+/**
+ * Generate icons for the action bar
+ */
+public class ActionBarIconGenerator extends GraphicGenerator {
+
+ /** Creates a new {@link ActionBarIconGenerator} */
+ public ActionBarIconGenerator() {
+ }
+
+ @Override
+ public BufferedImage generate(GraphicGeneratorContext context, Options options) {
+ Rectangle iconSizeHdpi = new Rectangle(0, 0, 48, 48);
+ Rectangle targetRectHdpi = new Rectangle(6, 6, 36, 36);
+ final float scaleFactor = GraphicGenerator.getHdpiScaleFactor(options.density);
+ Rectangle imageRect = Util.scaleRectangle(iconSizeHdpi, scaleFactor);
+ Rectangle targetRect = Util.scaleRectangle(targetRectHdpi, scaleFactor);
+ BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
+ Graphics2D g = (Graphics2D) outImage.getGraphics();
+
+ BufferedImage tempImage = Util.newArgbBufferedImage(
+ imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
+ Util.drawCenterInside(g2, options.sourceImage, targetRect);
+
+ ActionBarOptions actionBarOptions = (ActionBarOptions) options;
+ if (actionBarOptions.theme == Theme.HOLO_LIGHT) {
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(new Color(0x898989)),
+ });
+ } else {
+ assert actionBarOptions.theme == Theme.HOLO_DARK;
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ // TODO: should be white @ 60% opacity, but
+ // the fill then blends with the drop shadow
+ new FillEffect(new Color(0x909090)),
+ new ShadowEffect(
+ 0,
+ 0,
+ 3 * scaleFactor,
+ Color.BLACK,
+ 0.85,
+ false),
+ });
+ }
+
+ g.dispose();
+ g2.dispose();
+
+ return outImage;
+ }
+
+ /** Options specific to generating action bar icons */
+ public static class ActionBarOptions extends GraphicGenerator.Options {
+ /** The theme to generate icons for */
+ public Theme theme = Theme.HOLO_LIGHT;
+ }
+
+ /** The themes to generate action bar icons for */
+ public enum Theme {
+ /** Theme.Holo - a dark (and default) version of the Honeycomb theme */
+ HOLO_DARK,
+
+ /** Theme.HoloLight - a light version of the Honeycomb theme */
+ HOLO_LIGHT;
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java
index 902b21dba..dea6eeb1f 100644
--- a/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java
+++ b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java
@@ -26,9 +26,13 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -38,15 +42,165 @@ import javax.imageio.ImageIO;
/**
* The base Generator class.
*/
-public class GraphicGenerator {
+public abstract class GraphicGenerator {
/**
* Options used for all generators.
*/
public static class Options {
+ /** Source image to use as a basis for the icon */
+ public BufferedImage sourceImage;
+ /** The density to generate the icon with */
+ public Density density = Density.XHIGH;
}
- public static float getScaleFactor(Density density) {
- return density.getDpiValue() / (float) Density.DEFAULT_DENSITY;
+ /** Shapes that can be used for icon backgrounds */
+ public static enum Shape {
+ /** Circular background */
+ CIRCLE("circle"),
+ /** Square background */
+ SQUARE("square");
+
+ /** Id, used in filenames to identify associated stencils */
+ public final String id;
+
+ Shape(String id) {
+ this.id = id;
+ }
+ }
+
+ /** Foreground effects styles */
+ public static enum Style {
+ /** No effects */
+ SIMPLE("fore1"),
+ /** "Fancy" effects */
+ FANCY("fore2"),
+ /** A glossy look */
+ GLOSSY("fore3");
+
+ /** Id, used in filenames to identify associated stencils */
+ public final String id;
+
+ Style(String id) {
+ this.id = id;
+ }
+ }
+
+ /**
+ * Generate a single icon using the given options
+ *
+ * @param context render context to use for looking up resources etc
+ * @param options options controlling the appearance of the icon
+ * @return a {@link BufferedImage} with the generated icon
+ */
+ public abstract BufferedImage generate(GraphicGeneratorContext context, Options options);
+
+ /**
+ * Computes the target filename (relative to the Android project folder)
+ * where an icon rendered with the given options should be stored. This is
+ * also used as the map keys in the result map used by
+ * {@link #generate(String, Map, GraphicGeneratorContext, Options, String)}.
+ *
+ * @param options the options object used by the generator for the current
+ * image
+ * @param name the base name to use when creating the path
+ * @return a path relative to the res/ folder where the image should be
+ * stored (will always use / as a path separator, not \ on Windows)
+ */
+ protected String getIconPath(Options options, String name) {
+ return getIconFolder(options) + '/' + getIconName(options, name);
+ }
+
+ /**
+ * Gets name of the file itself. It is sometimes modified by options, for
+ * example in unselected tabs we change foo.png to foo-unselected.png
+ */
+ protected String getIconName(Options options, String name) {
+ return name + ".png"; //$NON-NLS-1$
+ }
+
+ /**
+ * Gets name of the folder to contain the resource. It usually includes the
+ * density, but is also sometimes modified by options. For example, in some
+ * notification icons we add in -v9 or -v11.
+ */
+ protected String getIconFolder(Options options) {
+ return "res/drawable-" + options.density.getResourceValue(); //$NON-NLS-1$
+ }
+
+ /**
+ * Generates a full set of icons into the given map. The values in the map
+ * will be the generated images, and each value is keyed by the
+ * corresponding relative path of the image, which is determined by the
+ * {@link #getIconPath(Options, String)} method.
+ *
+ * @param category the current category to place images into (if null the
+ * density name will be used)
+ * @param categoryMap the map to put images into, should not be null. The
+ * map is a map from a category name, to a map from file path to
+ * image.
+ * @param context a generator context which for example can load resources
+ * @param options options to apply to this generator
+ * @param name the base name of the icons to generate
+ */
+ public void generate(String category, Map<String, Map<String, BufferedImage>> categoryMap,
+ GraphicGeneratorContext context, Options options, String name) {
+ Density[] densityValues = Density.values();
+ // Sort density values into ascending order
+ Arrays.sort(densityValues, new Comparator<Density>() {
+ public int compare(Density d1, Density d2) {
+ return d1.getDpiValue() - d2.getDpiValue();
+ }
+ });
+
+ for (Density density : densityValues) {
+ if (!density.isValidValueForDevice()) {
+ continue;
+ }
+ if (density == Density.TV) {
+ // Not yet supported -- missing stencil image
+ continue;
+ }
+ options.density = density;
+ BufferedImage image = generate(context, options);
+ if (image != null) {
+ String mapCategory = category;
+ if (mapCategory == null) {
+ mapCategory = options.density.getResourceValue();
+ }
+ Map<String, BufferedImage> imageMap = categoryMap.get(mapCategory);
+ if (imageMap == null) {
+ imageMap = new LinkedHashMap<String, BufferedImage>();
+ categoryMap.put(mapCategory, imageMap);
+ }
+ imageMap.put(getIconPath(options, name), image);
+ }
+ }
+ }
+
+ /**
+ * Returns the scale factor to apply for a given HDPI density to compute the
+ * absolute pixel count to use to draw an icon of the given target density
+ *
+ * @param density the density
+ * @return a factor to multiple hdpi distances with to compute the target density
+ */
+ public static float getHdpiScaleFactor(Density density) {
+ // We used to do this:
+ //return density.getDpiValue() / (float) Density.DEFAULT_DENSITY;
+ // However, the HTML5 version of the AssetStudio would end up with different
+ // sizes for the assets, because it uses this table:
+ // studio.util.getMultBaseHdpi = function(density) {
+ // switch (density) {
+ // case 'xhdpi': return 1.333333;
+ // case 'hdpi': return 1.0;
+ // case 'mdpi': return 0.666667;
+ // case 'ldpi': return 0.5;
+ // }
+ // return 1.0;
+ // };
+ // This corresponds to dividing the dpi value not by Density.MEDIUM but
+ // Density.HIGH:
+ return density.getDpiValue() / (float) Density.HIGH.getDpiValue();
}
/**
diff --git a/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java
index b6715a484..66cb6ae66 100644
--- a/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java
+++ b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java
@@ -16,93 +16,136 @@
package com.android.assetstudiolib;
-import com.android.resources.Density;
-
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
+import java.util.HashMap;
+import java.util.Map;
/**
* A {@link GraphicGenerator} that generates Android "launcher" icons.
*/
public class LauncherIconGenerator extends GraphicGenerator {
- private static final Rectangle BASE_IMAGE_RECT = new Rectangle(0, 0, 48, 48);
- private static final Rectangle BASE_TARGET_RECT = new Rectangle(4, 4, 40, 40);
-
- private Options mOptions;
- private BufferedImage mBackImage;
- private BufferedImage mMaskImage;
- private BufferedImage mForeImage;
-
- public LauncherIconGenerator(GraphicGeneratorContext context, Options options) {
- mOptions = options;
- mBackImage = context.loadImageResource("/images/launcher_stencil/"
- + options.shape.id + "/" + options.density.getResourceValue() + "/back.png");
- mForeImage = context.loadImageResource("/images/launcher_stencil/"
- + options.shape.id + "/" + options.density.getResourceValue() + "/"
- + options.style.id + ".png");
- mMaskImage = context.loadImageResource("/images/launcher_stencil/"
- + options.shape.id + "/" + options.density.getResourceValue() + "/mask.png");
- }
-
- public BufferedImage generate() {
- final float scaleFactor = GraphicGenerator.getScaleFactor(mOptions.density);
- Rectangle imageRect = Util.scaleRectangle(BASE_IMAGE_RECT, scaleFactor);
- Rectangle targetRect = Util.scaleRectangle(BASE_TARGET_RECT, scaleFactor);
+ private static final Rectangle IMAGE_SIZE_HDPI = new Rectangle(0, 0, 72, 72);
+ /* TODO: Adapt from html version:
+ 'square-web-targetRect': { x: 57, y: 57, w: 398, h: 398 },
+ 'circle-web-targetRect': { x: 42, y: 42, w: 428, h: 428 },
+ 'square-xhdpi-targetRect': { x: 11, y: 11, w: 74, h: 74 },
+ 'circle-xhdpi-targetRect': { x: 8, y: 8, w: 80, h: 80 },
+ 'square-hdpi-targetRect': { x: 8, y: 8, w: 56, h: 56 },
+ 'circle-hdpi-targetRect': { x: 6, y: 6, w: 60, h: 60 }, <====
+ 'square-mdpi-targetRect': { x: 5, y: 5, w: 38, h: 38 },
+ 'circle-mdpi-targetRect': { x: 4, y: 4, w: 40, h: 40 },
+ 'square-ldpi-targetRect': { x: 4, y: 4, w: 28, h: 28 },
+ 'circle-ldpi-targetRect': { x: 3, y: 3, w: 30, h: 30 }
+ */
+ private static final Rectangle TARGET_RECT_HDPI = new Rectangle(6, 6, 60, 60);
+
+ @Override
+ public BufferedImage generate(GraphicGeneratorContext context, Options options) {
+ LauncherOptions launcherOptions = (LauncherOptions) options;
+
+ String density;
+ if (launcherOptions.isWebGraphic) {
+ density = "web";
+ } else {
+ density = launcherOptions.density.getResourceValue();
+ }
+ String shape = launcherOptions.shape.id;
+ BufferedImage mBackImage = context.loadImageResource("/images/launcher_stencil/"
+ + shape + "/" + density + "/back.png");
+ BufferedImage mForeImage = context.loadImageResource("/images/launcher_stencil/"
+ + shape + "/" + density + "/" + launcherOptions.style.id + ".png");
+ BufferedImage mMaskImage = context.loadImageResource("/images/launcher_stencil/"
+ + shape + "/" + density + "/mask.png");
+
+ float scaleFactor = GraphicGenerator.getHdpiScaleFactor(launcherOptions.density);
+ if (launcherOptions.isWebGraphic) {
+ // Target size for the web graphic is 512
+ scaleFactor = 512 / (float) IMAGE_SIZE_HDPI.height;
+ }
+ Rectangle imageRect = Util.scaleRectangle(IMAGE_SIZE_HDPI, scaleFactor);
+ Rectangle targetRect = Util.scaleRectangle(TARGET_RECT_HDPI, scaleFactor);
BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
Graphics2D g = (Graphics2D) outImage.getGraphics();
g.drawImage(mBackImage, 0, 0, null);
- {
- BufferedImage tempImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
- Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
- g2.drawImage(mMaskImage, 0, 0, null);
- g2.setComposite(AlphaComposite.SrcAtop);
- g2.setPaint(new Color(mOptions.backgroundColor));
- g2.fillRect(0, 0, imageRect.width, imageRect.height);
-
- if (mOptions.crop) {
- Util.drawCenterCrop(g2, mOptions.sourceImage, targetRect);
- } else {
- Util.drawCenterInside(g2, mOptions.sourceImage, targetRect);
- }
-
- g.drawImage(tempImage, 0, 0, null);
+ BufferedImage tempImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
+ g2.drawImage(mMaskImage, 0, 0, null);
+ g2.setComposite(AlphaComposite.SrcAtop);
+ g2.setPaint(new Color(launcherOptions.backgroundColor));
+ g2.fillRect(0, 0, imageRect.width, imageRect.height);
+
+ if (launcherOptions.crop) {
+ Util.drawCenterCrop(g2, launcherOptions.sourceImage, targetRect);
+ } else {
+ Util.drawCenterInside(g2, launcherOptions.sourceImage, targetRect);
}
+ g.drawImage(tempImage, 0, 0, null);
g.drawImage(mForeImage, 0, 0, null);
+
+ g.dispose();
+ g2.dispose();
+
return outImage;
}
- public static class Options {
- public BufferedImage sourceImage;
- public int backgroundColor = 0;
- public boolean crop = true;
- public Shape shape = Shape.SQUARE;
- public Style style = Style.SIMPLE;
- public Density density = Density.XHIGH;
+ @Override
+ public void generate(String category, Map<String, Map<String, BufferedImage>> categoryMap,
+ GraphicGeneratorContext context, Options options, String name) {
+ LauncherOptions launcherOptions = (LauncherOptions) options;
+ boolean generateWebImage = launcherOptions.isWebGraphic;
+ launcherOptions.isWebGraphic = false;
+ super.generate(category, categoryMap, context, options, name);
+
+ if (generateWebImage) {
+ launcherOptions.isWebGraphic = true;
+ BufferedImage image = generate(context, options);
+ if (image != null) {
+ Map<String, BufferedImage> imageMap = new HashMap<String, BufferedImage>();
+ categoryMap.put("Web", imageMap);
+ imageMap.put(getIconPath(options, name), image);
+ }
+ }
+ }
- public static enum Shape {
- CIRCLE("circle"), SQUARE("square");
+ @Override
+ protected String getIconPath(Options options, String name) {
+ if (((LauncherOptions) options).isWebGraphic) {
+ return name + "-web.png"; // Store at the root of the project
+ }
- public String id;
+ return super.getIconPath(options, name);
+ }
- Shape(String id) {
- this.id = id;
- }
- }
+ /** Options specific to generating launcher icons */
+ public static class LauncherOptions extends GraphicGenerator.Options {
+ /** Background color, as an RRGGBB packed integer */
+ public int backgroundColor = 0;
- public static enum Style {
- SIMPLE("fore1"), FANCY("fore2"), GLOSSY("fore3");
+ /** Whether the image should be cropped or not */
+ public boolean crop = true;
- public String id;
+ /** The shape to use for the background */
+ public Shape shape = Shape.SQUARE;
- Style(String id) {
- this.id = id;
- }
- }
+ /** The effects to apply to the foreground */
+ public Style style = Style.SIMPLE;
+
+ /**
+ * Whether a web graphic should be generated (will ignore normal density
+ * setting). The {@link #generate(GraphicGeneratorContext, Options)}
+ * method will use this to decide whether to generate a normal density
+ * icon or a high res web image. The
+ * {@link GraphicGenerator#generate(String, Map, GraphicGeneratorContext, Options, String)}
+ * method will use this flag to determine whether it should include a
+ * web graphic in its iteration.
+ */
+ public boolean isWebGraphic;
}
}
diff --git a/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java
index 07b7a6b2d..8fdbddff5 100644
--- a/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java
+++ b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java
@@ -16,7 +16,9 @@
package com.android.assetstudiolib;
-import com.android.resources.Density;
+import com.android.assetstudiolib.Util.Effect;
+import com.android.assetstudiolib.Util.FillEffect;
+import com.android.assetstudiolib.Util.ShadowEffect;
import java.awt.Color;
import java.awt.GradientPaint;
@@ -28,65 +30,59 @@ import java.awt.image.BufferedImage;
* A {@link GraphicGenerator} that generates Android "menu" icons.
*/
public class MenuIconGenerator extends GraphicGenerator {
- private static final Rectangle BASE_IMAGE_RECT = new Rectangle(0, 0, 48, 48);
- private static final Rectangle BASE_TARGET_RECT = new Rectangle(8, 8, 32, 32);
-
- private Options mOptions;
-
- public MenuIconGenerator(GraphicGeneratorContext context, Options options) {
- mOptions = options;
+ /** Creates a menu icon generator */
+ public MenuIconGenerator() {
}
- public BufferedImage generate() {
- final float scaleFactor = GraphicGenerator.getScaleFactor(mOptions.density);
- Rectangle imageRect = Util.scaleRectangle(BASE_IMAGE_RECT, scaleFactor);
- Rectangle targetRect = Util.scaleRectangle(BASE_TARGET_RECT, scaleFactor);
+ @Override
+ public BufferedImage generate(GraphicGeneratorContext context, Options options) {
+ Rectangle imageSizeHdpi = new Rectangle(0, 0, 72, 72);
+ Rectangle targetRectHdpi = new Rectangle(12, 12, 48, 48);
+ float scaleFactor = GraphicGenerator.getHdpiScaleFactor(options.density);
+ Rectangle imageRect = Util.scaleRectangle(imageSizeHdpi, scaleFactor);
+ Rectangle targetRect = Util.scaleRectangle(targetRectHdpi, scaleFactor);
BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
Graphics2D g = (Graphics2D) outImage.getGraphics();
- {
- BufferedImage tempImage = Util.newArgbBufferedImage(
- imageRect.width, imageRect.height);
- Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
- Util.drawCenterInside(g2, mOptions.sourceImage, targetRect);
+ BufferedImage tempImage = Util.newArgbBufferedImage(
+ imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
+ Util.drawCenterInside(g2, options.sourceImage, targetRect);
- Util.drawEffects(g, tempImage, 0, 0, new Util.Effect[]{
- new Util.FillEffect(
- new GradientPaint(
- 0, 0,
- new Color(0xa3a3a3),
- 0, imageRect.height,
- new Color(0x787878))),
- new Util.ShadowEffect(
- 0,
- 3 * scaleFactor,
- 3 * scaleFactor,
- Color.black,
- 0.2,
- true),
- new Util.ShadowEffect(
- 0,
- 1,
- 0,
- Color.black,
- 0.35,
- true),
- new Util.ShadowEffect(
- 0,
- -1,
- 0,
- Color.white,
- 0.35,
- true),
- });
- }
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(
+ new GradientPaint(
+ 0, 0,
+ new Color(0xa3a3a3),
+ 0, imageRect.height,
+ new Color(0x787878))),
+ new ShadowEffect(
+ 0,
+ 3 * scaleFactor,
+ 3 * scaleFactor,
+ Color.BLACK,
+ 0.2,
+ true),
+ new ShadowEffect(
+ 0,
+ 1,
+ 0,
+ Color.BLACK,
+ 0.35,
+ true),
+ new ShadowEffect(
+ 0,
+ -1,
+ 0,
+ Color.WHITE,
+ 0.35,
+ true),
+ });
- return outImage;
- }
+ g.dispose();
+ g2.dispose();
- public static class Options {
- public BufferedImage sourceImage;
- public Density density = Density.XHIGH;
+ return outImage;
}
}
diff --git a/assetstudio/src/com/android/assetstudiolib/NotificationIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/NotificationIconGenerator.java
new file mode 100644
index 000000000..1237a89e6
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/NotificationIconGenerator.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.Util.Effect;
+import com.android.assetstudiolib.Util.FillEffect;
+import com.android.assetstudiolib.Util.ShadowEffect;
+
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.util.Map;
+
+/**
+ * Generate icons for the notifications bar
+ */
+public class NotificationIconGenerator extends GraphicGenerator {
+ /** Creates a new {@link NotificationIconGenerator} */
+ public NotificationIconGenerator() {
+ }
+
+ @Override
+ public BufferedImage generate(GraphicGeneratorContext context, Options options) {
+ Rectangle iconSizeHdpi;
+ Rectangle targetRectHdpi;
+ NotificationOptions notificationOptions = (NotificationOptions) options;
+ if (notificationOptions.version == Version.OLDER) {
+ iconSizeHdpi = new Rectangle(0, 0, 38, 38);
+ targetRectHdpi = new Rectangle(6, 6, 26, 26);
+ } else if (notificationOptions.version == Version.V11) {
+ iconSizeHdpi = new Rectangle(0, 0, 48, 48);
+ targetRectHdpi = new Rectangle(6, 6, 36, 36);
+ } else {
+ assert notificationOptions.version == Version.V9;
+ iconSizeHdpi = new Rectangle(0, 0, 24, 38);
+ targetRectHdpi = new Rectangle(0, 7, 24, 24);
+ }
+
+ final float scaleFactor = GraphicGenerator.getHdpiScaleFactor(options.density);
+ Rectangle imageRect = Util.scaleRectangle(iconSizeHdpi, scaleFactor);
+ Rectangle targetRect = Util.scaleRectangle(targetRectHdpi, scaleFactor);
+
+ BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
+ Graphics2D g = (Graphics2D) outImage.getGraphics();
+
+ BufferedImage tempImage = Util.newArgbBufferedImage(
+ imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
+
+ if (notificationOptions.version == Version.OLDER) {
+ BufferedImage mBackImage = context.loadImageResource(
+ "/images/notification_stencil/"
+ + notificationOptions.shape.id + '/' +
+ notificationOptions.density.getResourceValue()
+ + ".png");
+ g.drawImage(mBackImage, 0, 0, null);
+ BufferedImage top = options.sourceImage;
+ BufferedImage filled = Util.filledImage(top, Color.WHITE);
+ Util.drawCenterInside(g, filled, targetRect);
+ } else if (notificationOptions.version == Version.V11) {
+ Util.drawCenterInside(g2, options.sourceImage, targetRect);
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(
+ Color.WHITE),
+ });
+ } else {
+ assert notificationOptions.version == Version.V9;
+ Util.drawCenterInside(g2, options.sourceImage, targetRect);
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(
+ new GradientPaint(
+ 0, 0,
+ new Color(0x919191),
+ 0, imageRect.height,
+ new Color(0x828282))),
+ new ShadowEffect(
+ 0,
+ 1,
+ 0,
+ Color.WHITE,
+ 0.10,
+ true),
+ });
+ }
+
+ g.dispose();
+ g2.dispose();
+
+ return outImage;
+ }
+
+ @Override
+ public void generate(String category, Map<String, Map<String, BufferedImage>> categoryMap,
+ GraphicGeneratorContext context, Options options, String name) {
+ for (Version version : Version.values()) {
+ ((NotificationOptions) options).version = version;
+ super.generate(version.getDisplayName(), categoryMap, context, options, name);
+ }
+ }
+
+ @Override
+ protected String getIconFolder(Options options) {
+ String folder = super.getIconFolder(options);
+ Version version = ((NotificationOptions) options).version;
+ if (version == Version.V11) {
+ return folder + "-v11"; //$NON-NLS-1$
+ } else if (version == Version.V9) {
+ return folder + "-v9"; //$NON-NLS-1$
+ } else {
+ return folder;
+ }
+ }
+
+ /**
+ * Options specific to generating notification icons
+ */
+ public static class NotificationOptions extends GraphicGenerator.Options {
+ /**
+ * The shape to use for graphics behind the icon (for {@link Version#OLDER} only)
+ */
+ public Shape shape = Shape.SQUARE;
+
+ /**
+ * The version of the icon to generate - different styles are used for different
+ * versions of Android
+ */
+ public Version version = Version.V9;
+ }
+
+ /**
+ * The version of the icon to generate - different styles are used for different
+ * versions of Android
+ */
+ public enum Version {
+ /** Icon style used for -v9 and -v10 */
+ V9("V9"),
+
+ /** Icon style used for -v11 (Honeycomb) and later */
+ V11("V11"),
+
+ /** Icon style used for versions older than v9 */
+ OLDER("Other");
+
+ private final String mDisplayName;
+
+ Version(String displayName) {
+ mDisplayName = displayName;
+ }
+
+ /**
+ * Returns the display name for this version, typically shown as a
+ * category
+ *
+ * @return the display name, never null
+ */
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/TabIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/TabIconGenerator.java
new file mode 100644
index 000000000..506aebd4e
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/TabIconGenerator.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.Util.Effect;
+import com.android.assetstudiolib.Util.FillEffect;
+import com.android.assetstudiolib.Util.ShadowEffect;
+
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.util.Map;
+
+
+/**
+ * Generate icons for tabs
+ */
+public class TabIconGenerator extends GraphicGenerator {
+ /** Creates a new {@link TabIconGenerator} */
+ public TabIconGenerator() {
+ }
+
+ @Override
+ public BufferedImage generate(GraphicGeneratorContext context, Options options) {
+ Rectangle iconSizeHdpi = new Rectangle(0, 0, 48, 48);
+ Rectangle targetRectHdpi = new Rectangle(3, 3, 42, 42);
+ final float scaleFactor = GraphicGenerator.getHdpiScaleFactor(options.density);
+ Rectangle imageRect = Util.scaleRectangle(iconSizeHdpi, scaleFactor);
+ Rectangle targetRect = Util.scaleRectangle(targetRectHdpi, scaleFactor);
+ BufferedImage outImage = Util.newArgbBufferedImage(imageRect.width, imageRect.height);
+ Graphics2D g = (Graphics2D) outImage.getGraphics();
+
+ BufferedImage tempImage = Util.newArgbBufferedImage(
+ imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) tempImage.getGraphics();
+ Util.drawCenterInside(g2, options.sourceImage, targetRect);
+
+ TabOptions tabOptions = (TabOptions) options;
+ if (tabOptions.selected) {
+ if (tabOptions.oldStyle) {
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(
+ new GradientPaint(
+ 0, 0,
+ new Color(0xa3a3a3),
+ 0, imageRect.height,
+ new Color(0x787878))),
+ new ShadowEffect(
+ 0,
+ 3 * scaleFactor,
+ 3 * scaleFactor,
+ Color.BLACK,
+ 0.2,
+ true),
+ new ShadowEffect(
+ 0,
+ 1,
+ 0,
+ Color.BLACK,
+ 0.35,
+ true),
+ new ShadowEffect(
+ 0,
+ -1,
+ 0,
+ Color.WHITE,
+ 0.35,
+ true),
+ });
+ } else {
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(Color.WHITE),
+ new ShadowEffect(
+ 0,
+ 0,
+ 5 * scaleFactor,
+ Color.BLACK,
+ 0.25,
+ false),
+ });
+ }
+ } else {
+ // Unselected
+ if (tabOptions.oldStyle) {
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(
+ new GradientPaint(
+ 0, 0.25f * imageRect.height,
+ new Color(0xf9f9f9),
+ 0, imageRect.height,
+ new Color(0xdfdfdf))),
+ new ShadowEffect(
+ 0,
+ 3 * scaleFactor,
+ 3 * scaleFactor,
+ Color.BLACK,
+ 0.1,
+ true),
+ new ShadowEffect(
+ 0,
+ 1,
+ 0,
+ Color.BLACK,
+ 0.35,
+ true),
+ new ShadowEffect(
+ 0,
+ -1,
+ 0,
+ Color.WHITE,
+ 0.35,
+ true),
+ });
+ } else {
+ Util.drawEffects(g, tempImage, 0, 0, new Effect[] {
+ new FillEffect(new Color(0x808080)),
+ });
+ }
+ }
+
+ g.dispose();
+ g2.dispose();
+
+ return outImage;
+ }
+
+ @Override
+ public void generate(String category, Map<String, Map<String, BufferedImage>> categoryMap,
+ GraphicGeneratorContext context, Options options, String name) {
+ TabOptions tabOptions = (TabOptions) options;
+ // Generate all permutations of tabOptions.selected and tabOptions.oldStyle
+ tabOptions.selected = true;
+ tabOptions.oldStyle = false;
+ super.generate("Selected (v5+)", categoryMap, context, options, name);
+ tabOptions.oldStyle = true;
+ super.generate("Selected", categoryMap, context, options, name);
+ tabOptions.selected = false;
+ tabOptions.oldStyle = false;
+ super.generate("Unselected (v5+)", categoryMap, context, options, name);
+ tabOptions.oldStyle = true;
+ super.generate("Unselected", categoryMap, context, options, name);
+ }
+
+ @Override
+ protected String getIconFolder(Options options) {
+ String folder = super.getIconFolder(options);
+
+ TabOptions tabOptions = (TabOptions) options;
+ if (tabOptions.oldStyle) {
+ return folder;
+ } else {
+ return folder + "-v5"; //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ protected String getIconName(Options options, String name) {
+ TabOptions tabOptions = (TabOptions) options;
+ if (tabOptions.selected) {
+ return name + "_selected.png"; //$NON-NLS-1$
+ } else {
+ return name + "_unselected.png"; //$NON-NLS-1$
+ }
+ }
+
+ /** Options specific to generating tab icons */
+ public static class TabOptions extends GraphicGenerator.Options {
+ /** Generate icon in the style used prior to v5 */
+ public boolean oldStyle;
+ /** Generate "selected" icon if true, and "unselected" icon if false */
+ public boolean selected = true;
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java b/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java
index a10370107..e08a2340d 100644
--- a/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java
+++ b/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java
@@ -16,14 +16,14 @@
package com.android.assetstudiolib;
+import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
+import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
-import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.util.Hashtable;
-import java.util.Map;
/**
* A set of utility classes for rendering text to a {@link BufferedImage}, suitable for use as a
@@ -31,13 +31,18 @@ import java.util.Map;
*/
public class TextRenderUtil {
/**
- * Renders the given string with the provided {@link Options} to a {@link BufferedImage}.
+ * Renders the given string with the provided {@link Options} to a
+ * {@link BufferedImage}.
*
- * @param text The text to render.
+ * @param text The text to render.
+ * @param paddingPercentage If nonzero, a percentage of the width or height
+ * (whichever is smaller) to add as padding around the text
* @param options The optional parameters for rendering the text.
- * @return An image, suitable for use as an input to a {@link GraphicGenerator}.
+ * @return An image, suitable for use as an input to a
+ * {@link GraphicGenerator}.
*/
- public static BufferedImage renderTextImage(String text, Options options) {
+ public static BufferedImage renderTextImage(String text, int paddingPercentage,
+ Options options) {
if (options == null) {
options = new Options();
}
@@ -59,13 +64,32 @@ public class TextRenderUtil {
FontRenderContext frc = tempG.getFontRenderContext();
- Rectangle2D bounds = font.getStringBounds(text, frc);
+ TextLayout layout = new TextLayout(text, font, frc);
+ Rectangle2D bounds = layout.getBounds();
+
+ // The padding is a percentage relative to the overall minimum of the width or height
+ if (paddingPercentage != 0) {
+ double minDimension = Math.min(bounds.getWidth(), bounds.getHeight());
+ double delta = minDimension * paddingPercentage / 100;
+ bounds.setRect(bounds.getMinX() - delta, bounds.getMinY() - delta,
+ bounds.getWidth() + 2 * delta, bounds.getHeight() + 2 * delta);
+ }
BufferedImage image = Util.newArgbBufferedImage(
Math.max(1, (int) bounds.getWidth()), Math.max(1, (int) bounds.getHeight()));
Graphics2D g = (Graphics2D) image.getGraphics();
+ g.setColor(new Color(options.foregroundColor, true));
g.setFont(font);
- g.drawString(text, 0, (float) -bounds.getY());
+
+ g.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(
+ RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ g.drawString(text, (float) -bounds.getX(), (float) -bounds.getY());
+
+ g.dispose();
+ tempG.dispose();
return image;
}
@@ -79,6 +103,9 @@ public class TextRenderUtil {
// TODO: Instead, a graphic generator should use a different source image for each density.
private static final int DEFAULT_FONT_SIZE = 512;
+ /** Foreground color to render text with, as an AARRGGBB packed integer */
+ public int foregroundColor = 0xFFFFFFFF;
+
/**
* The optional {@link Font} to use. If null, a {@link Font} object will be generated using
* the other options.
diff --git a/assetstudio/src/com/android/assetstudiolib/Util.java b/assetstudio/src/com/android/assetstudiolib/Util.java
index 1a6b00e59..927ca30a4 100644
--- a/assetstudio/src/com/android/assetstudiolib/Util.java
+++ b/assetstudio/src/com/android/assetstudiolib/Util.java
@@ -84,7 +84,7 @@ public class Util {
}
/**
- * Applies a gaussion blur of the given radius to the given {@link BufferedImage} using a kernel
+ * Applies a gaussian blur of the given radius to the given {@link BufferedImage} using a kernel
* convolution.
*
* @param source The source image.
diff --git a/assetstudio/src/images/notification_stencil/circle/hdpi.png b/assetstudio/src/images/notification_stencil/circle/hdpi.png
new file mode 100644
index 000000000..4d2871043
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/circle/hdpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/circle/ldpi.png b/assetstudio/src/images/notification_stencil/circle/ldpi.png
new file mode 100644
index 000000000..5c9a9f79e
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/circle/ldpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/circle/mdpi.png b/assetstudio/src/images/notification_stencil/circle/mdpi.png
new file mode 100644
index 000000000..1f064a213
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/circle/mdpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/circle/xhdpi.png b/assetstudio/src/images/notification_stencil/circle/xhdpi.png
new file mode 100644
index 000000000..f6a57c1be
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/circle/xhdpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/square/hdpi.png b/assetstudio/src/images/notification_stencil/square/hdpi.png
new file mode 100644
index 000000000..f755f4f3f
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/square/hdpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/square/ldpi.png b/assetstudio/src/images/notification_stencil/square/ldpi.png
new file mode 100644
index 000000000..23846bd79
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/square/ldpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/square/mdpi.png b/assetstudio/src/images/notification_stencil/square/mdpi.png
new file mode 100644
index 000000000..5f80247d2
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/square/mdpi.png
Binary files differ
diff --git a/assetstudio/src/images/notification_stencil/square/xhdpi.png b/assetstudio/src/images/notification_stencil/square/xhdpi.png
new file mode 100644
index 000000000..7c27d8224
--- /dev/null
+++ b/assetstudio/src/images/notification_stencil/square/xhdpi.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/ActionBarIconGeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/ActionBarIconGeneratorTest.java
new file mode 100644
index 000000000..ed5ea04ab
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/ActionBarIconGeneratorTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.ActionBarIconGenerator.ActionBarOptions;
+import com.android.assetstudiolib.ActionBarIconGenerator.Theme;
+
+import java.io.IOException;
+
+@SuppressWarnings("javadoc")
+public class ActionBarIconGeneratorTest extends GeneratorTest {
+ private void checkGraphic(String baseName, Theme theme) throws IOException {
+ ActionBarOptions options = new ActionBarOptions();
+ options.theme = theme;
+
+ ActionBarIconGenerator generator = new ActionBarIconGenerator();
+ checkGraphic(4, "actions", baseName, generator, options);
+ }
+
+ public void testDark() throws Exception {
+ checkGraphic("ic_action_dark", Theme.HOLO_DARK);
+ }
+
+ public void testLight() throws Exception {
+ checkGraphic("ic_action_light", Theme.HOLO_LIGHT);
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/GeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/GeneratorTest.java
new file mode 100644
index 000000000..59812bffe
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/GeneratorTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+import junit.framework.TestCase;
+
+/**
+ * Shared test infrastructure for code generator
+ */
+public abstract class GeneratorTest extends TestCase implements GraphicGeneratorContext {
+ private static final String TEST_DATA_REL_PATH =
+ "assetstudio/tests/src/com/android/assetstudiolib/testdata";
+
+ protected void checkGraphic(int expectedFileCount, String folderName, String baseName,
+ GraphicGenerator generator, GraphicGenerator.Options options)
+ throws IOException {
+ Map<String, Map<String, BufferedImage>> categoryMap =
+ new HashMap<String, Map<String, BufferedImage>>();
+ options.sourceImage = GraphicGenerator.getClipartImage("android.png");
+ generator.generate(null, categoryMap, this, options, baseName);
+
+ File targetDir = getTargetDir();
+
+ List<String> errors = new ArrayList<String>();
+ int fileCount = 0;
+ for (Map<String, BufferedImage> previews : categoryMap.values()) {
+ for (Map.Entry<String, BufferedImage> entry : previews.entrySet()) {
+ String relativePath = entry.getKey();
+ BufferedImage image = entry.getValue();
+
+ String path = "testdata" + File.separator + folderName + File.separator
+ + relativePath;
+ InputStream is = GeneratorTest.class.getResourceAsStream(path);
+ if (is == null) {
+ if (targetDir == null) {
+ fail("Did not find " + path
+ + ". Set ADT_SDK_SOURCE_PATH to have it created automatically");
+ }
+ File fileName = new File(targetDir, folderName + File.separator
+ + relativePath);
+ assertFalse(fileName.exists());
+ if (!fileName.getParentFile().exists()) {
+ boolean mkdir = fileName.getParentFile().mkdirs();
+ assertTrue(fileName.getParent(), mkdir);
+ }
+
+ ImageIO.write(image, "PNG", fileName);
+ errors.add("File did not exist, created " + fileName.getPath());
+ } else {
+ BufferedImage goldenImage = ImageIO.read(is);
+ assertImageSimilar(relativePath, goldenImage, image, 5.0f);
+ }
+ }
+
+ fileCount += previews.values().size();
+ }
+ if (errors.size() > 0) {
+ fail(errors.toString());
+ }
+
+ assertEquals("Wrong number of generated files", expectedFileCount, fileCount);
+ }
+
+ private void assertImageSimilar(String imageName, BufferedImage goldenImage,
+ BufferedImage image, float maxPercentDifferent) throws IOException {
+ assertTrue("Widths differ too much for " + imageName, Math.abs(goldenImage.getWidth()
+ - image.getWidth()) < 2);
+ assertTrue("Widths differ too much for " + imageName, Math.abs(goldenImage.getHeight()
+ - image.getHeight()) < 2);
+
+ assertEquals(BufferedImage.TYPE_INT_ARGB, image.getType());
+
+ if (goldenImage.getType() != BufferedImage.TYPE_INT_ARGB) {
+ BufferedImage temp = new BufferedImage(goldenImage.getWidth(), goldenImage.getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+ temp.getGraphics().drawImage(goldenImage, 0, 0, null);
+ goldenImage = temp;
+ }
+ assertEquals(BufferedImage.TYPE_INT_ARGB, goldenImage.getType());
+
+ int imageWidth = Math.min(goldenImage.getWidth(), image.getWidth());
+ int imageHeight = Math.min(goldenImage.getHeight(), image.getHeight());
+
+ // Blur the images to account for the scenarios where there are pixel
+ // differences
+ // in where a sharp edge occurs
+ // goldenImage = blur(goldenImage, 6);
+ // image = blur(image, 6);
+
+ int width = 3 * imageWidth;
+ int height = imageHeight;
+ BufferedImage deltaImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics g = deltaImage.getGraphics();
+
+ // Compute delta map
+ long delta = 0;
+ for (int y = 0; y < imageHeight; y++) {
+ for (int x = 0; x < imageWidth; x++) {
+ int goldenRgb = goldenImage.getRGB(x, y);
+ int rgb = image.getRGB(x, y);
+ if (goldenRgb == rgb) {
+ deltaImage.setRGB(imageWidth + x, y, 0x00808080);
+ continue;
+ }
+
+ // If the pixels have no opacity, don't delta colors at all
+ if (((goldenRgb & 0xFF000000) == 0) && (rgb & 0xFF000000) == 0) {
+ deltaImage.setRGB(imageWidth + x, y, 0x00808080);
+ continue;
+ }
+
+ int deltaR = ((rgb & 0xFF0000) >>> 16) - ((goldenRgb & 0xFF0000) >>> 16);
+ int newR = 128 + deltaR & 0xFF;
+ int deltaG = ((rgb & 0x00FF00) >>> 8) - ((goldenRgb & 0x00FF00) >>> 8);
+ int newG = 128 + deltaG & 0xFF;
+ int deltaB = (rgb & 0x0000FF) - (goldenRgb & 0x0000FF);
+ int newB = 128 + deltaB & 0xFF;
+
+ int avgAlpha = ((((goldenRgb & 0xFF000000) >>> 24)
+ + ((rgb & 0xFF000000) >>> 24)) / 2) << 24;
+
+ int newRGB = avgAlpha | newR << 16 | newG << 8 | newB;
+ deltaImage.setRGB(imageWidth + x, y, newRGB);
+
+ delta += Math.abs(deltaR);
+ delta += Math.abs(deltaG);
+ delta += Math.abs(deltaB);
+ }
+ }
+
+ // 3 different colors, 256 color levels
+ long total = imageHeight * imageWidth * 3L * 256L;
+ float percentDifference = (float) (delta * 100 / (double) total);
+
+ if (percentDifference > maxPercentDifferent) {
+ // Expected on the left
+ // Golden on the right
+ g.drawImage(goldenImage, 0, 0, null);
+ g.drawImage(image, 2 * imageWidth, 0, null);
+
+ // Labels
+ if (imageWidth > 80) {
+ g.setColor(Color.RED);
+ g.drawString("Expected", 10, 20);
+ g.drawString("Actual", 2 * imageWidth + 10, 20);
+ }
+
+ File output = new File(getTempDir(), "delta-"
+ + imageName.replace(File.separatorChar, '_'));
+ if (output.exists()) {
+ output.delete();
+ }
+ ImageIO.write(deltaImage, "PNG", output);
+ String message = String.format("Images differ (by %.1f%%) - see details in %s",
+ percentDifference, output);
+ System.out.println(message);
+ fail(message);
+ }
+
+ g.dispose();
+ }
+
+ protected File getTempDir() {
+ if (System.getProperty("os.name").equals("Mac OS X")) {
+ return new File("/tmp"); //$NON-NLS-1$
+ }
+
+ return new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
+ }
+
+ public BufferedImage loadImageResource(String path) {
+ try {
+ return GraphicGenerator.getStencilImage(path);
+ } catch (IOException e) {
+ fail(e.toString());
+ }
+
+ return null;
+ }
+
+ /** Get the location to write missing golden files to */
+ protected File getTargetDir() {
+ // Set $ADT_SDK_SOURCE_PATH to point to your git "sdk" directory
+ String sdk = System.getenv("ADT_SDK_SOURCE_PATH");
+ if (sdk != null) {
+ File sdkPath = new File(sdk);
+ if (sdkPath.exists()) {
+ File testData = new File(sdkPath, TEST_DATA_REL_PATH.replace('/',
+ File.separatorChar));
+ if (testData.exists()) {
+ return testData;
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/LauncherIconGeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/LauncherIconGeneratorTest.java
new file mode 100644
index 000000000..4d6680cc3
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/LauncherIconGeneratorTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.LauncherIconGenerator.LauncherOptions;
+
+import java.io.IOException;
+
+@SuppressWarnings("javadoc")
+public class LauncherIconGeneratorTest extends GeneratorTest {
+ private void checkGraphic(String baseName,
+ GraphicGenerator.Shape shape, GraphicGenerator.Style style,
+ boolean crop, int background, boolean isWebGraphic) throws IOException {
+ LauncherOptions options = new LauncherOptions();
+ options.shape = shape;
+ options.crop = crop;
+ options.style = style;
+ options.backgroundColor = background;
+ options.isWebGraphic = isWebGraphic;
+
+ LauncherIconGenerator generator = new LauncherIconGenerator();
+ checkGraphic(4 + (isWebGraphic ? 1 : 0), "launcher", baseName, generator, options);
+ }
+
+ public void testLauncher_fancyCircle() throws Exception {
+ checkGraphic("red_fancy_circle", GraphicGenerator.Shape.CIRCLE,
+ GraphicGenerator.Style.FANCY, true, 0xFF0000, true);
+ }
+
+ public void testLauncher_glossySquare() throws Exception {
+ checkGraphic("blue_glossy_square", GraphicGenerator.Shape.SQUARE,
+ GraphicGenerator.Style.GLOSSY, true, 0x0040FF, true);
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/MenuIconGeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/MenuIconGeneratorTest.java
new file mode 100644
index 000000000..700be4b32
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/MenuIconGeneratorTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import java.io.IOException;
+
+@SuppressWarnings("javadoc")
+public class MenuIconGeneratorTest extends GeneratorTest {
+ private void checkGraphic(String baseName) throws IOException {
+ MenuIconGenerator generator = new MenuIconGenerator();
+ checkGraphic(4, "menus", baseName, generator, new GraphicGenerator.Options());
+ }
+
+ public void testMenu() throws Exception {
+ checkGraphic("ic_menu_1");
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/NotificationIconGeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/NotificationIconGeneratorTest.java
new file mode 100644
index 000000000..7ac56345d
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/NotificationIconGeneratorTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import com.android.assetstudiolib.NotificationIconGenerator.NotificationOptions;
+
+import java.io.IOException;
+
+@SuppressWarnings("javadoc")
+public class NotificationIconGeneratorTest extends GeneratorTest {
+ private void checkGraphic(String baseName,
+ GraphicGenerator.Shape shape) throws IOException {
+ NotificationOptions options = new NotificationOptions();
+ options.shape = shape;
+
+ NotificationIconGenerator generator = new NotificationIconGenerator();
+ checkGraphic(12, "notification", baseName, generator, options);
+ }
+
+ public void testNotification1() throws Exception {
+ checkGraphic("ic_stat_circle", GraphicGenerator.Shape.CIRCLE);
+ }
+
+ public void testNotification2() throws Exception {
+ checkGraphic("ic_stat_square", GraphicGenerator.Shape.SQUARE);
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/TabIconGeneratorTest.java b/assetstudio/tests/src/com/android/assetstudiolib/TabIconGeneratorTest.java
new file mode 100644
index 000000000..4fb48017f
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/TabIconGeneratorTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.assetstudiolib;
+
+import java.io.IOException;
+
+@SuppressWarnings("javadoc")
+public class TabIconGeneratorTest extends GeneratorTest {
+ private void checkGraphic(String baseName) throws IOException {
+ TabIconGenerator generator = new TabIconGenerator();
+ checkGraphic(16, "tabs", baseName, generator, new TabIconGenerator.TabOptions());
+ }
+
+ public void testTabs1() throws Exception {
+ checkGraphic("ic_tab_1");
+ }
+}
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_dark.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_dark.png
new file mode 100644
index 000000000..ac9fcf9d2
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_dark.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_light.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_light.png
new file mode 100644
index 000000000..15da7b942
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-hdpi/ic_action_light.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_dark.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_dark.png
new file mode 100644
index 000000000..e9ea176ae
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_dark.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_light.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_light.png
new file mode 100644
index 000000000..1dca5d260
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-ldpi/ic_action_light.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_dark.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_dark.png
new file mode 100644
index 000000000..82ec17f61
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_dark.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_light.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_light.png
new file mode 100644
index 000000000..a9ecda298
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-mdpi/ic_action_light.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_dark.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_dark.png
new file mode 100644
index 000000000..cd6b55516
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_dark.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_light.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_light.png
new file mode 100644
index 000000000..cdc2cfd1f
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/actions/res/drawable-xhdpi/ic_action_light.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/blue_glossy_square-web.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/blue_glossy_square-web.png
new file mode 100644
index 000000000..d8b82948d
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/blue_glossy_square-web.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/red_fancy_circle-web.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/red_fancy_circle-web.png
new file mode 100644
index 000000000..e9bd6fe2a
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/red_fancy_circle-web.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/blue_glossy_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/blue_glossy_square.png
new file mode 100644
index 000000000..f549138d2
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/blue_glossy_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/red_fancy_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/red_fancy_circle.png
new file mode 100644
index 000000000..b068fb587
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-hdpi/red_fancy_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/blue_glossy_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/blue_glossy_square.png
new file mode 100644
index 000000000..fcc7c1ce9
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/blue_glossy_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/red_fancy_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/red_fancy_circle.png
new file mode 100644
index 000000000..b85b2b55e
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-ldpi/red_fancy_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/blue_glossy_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/blue_glossy_square.png
new file mode 100644
index 000000000..29da2c363
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/blue_glossy_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/red_fancy_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/red_fancy_circle.png
new file mode 100644
index 000000000..54ea5edbe
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-mdpi/red_fancy_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/blue_glossy_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/blue_glossy_square.png
new file mode 100644
index 000000000..3377ddc2a
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/blue_glossy_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/red_fancy_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/red_fancy_circle.png
new file mode 100644
index 000000000..896da29aa
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/launcher/res/drawable-xhdpi/red_fancy_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-hdpi/ic_menu_1.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-hdpi/ic_menu_1.png
new file mode 100644
index 000000000..0d6d67f29
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-hdpi/ic_menu_1.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-ldpi/ic_menu_1.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-ldpi/ic_menu_1.png
new file mode 100644
index 000000000..85655edcb
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-ldpi/ic_menu_1.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-mdpi/ic_menu_1.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-mdpi/ic_menu_1.png
new file mode 100644
index 000000000..de6819968
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-mdpi/ic_menu_1.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-xhdpi/ic_menu_1.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-xhdpi/ic_menu_1.png
new file mode 100644
index 000000000..dca9a757c
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/menus/res/drawable-xhdpi/ic_menu_1.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_circle.png
new file mode 100644
index 000000000..daad50380
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_square.png
new file mode 100644
index 000000000..daad50380
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v11/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_circle.png
new file mode 100644
index 000000000..bdd859839
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_square.png
new file mode 100644
index 000000000..bdd859839
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi-v9/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_circle.png
new file mode 100644
index 000000000..d2ea9f5b3
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_square.png
new file mode 100644
index 000000000..a1c92854c
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-hdpi/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_circle.png
new file mode 100644
index 000000000..228ab6035
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_square.png
new file mode 100644
index 000000000..228ab6035
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v11/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_circle.png
new file mode 100644
index 000000000..ea4b10566
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_square.png
new file mode 100644
index 000000000..ea4b10566
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi-v9/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_circle.png
new file mode 100644
index 000000000..c315dff56
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_square.png
new file mode 100644
index 000000000..8592c1fc6
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-ldpi/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_circle.png
new file mode 100644
index 000000000..7749b11aa
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_square.png
new file mode 100644
index 000000000..7749b11aa
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v11/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_circle.png
new file mode 100644
index 000000000..1956c8e3b
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_square.png
new file mode 100644
index 000000000..1956c8e3b
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi-v9/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_circle.png
new file mode 100644
index 000000000..c63fc8ff8
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_square.png
new file mode 100644
index 000000000..40b27afcb
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-mdpi/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_circle.png
new file mode 100644
index 000000000..3dbfa96e8
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_square.png
new file mode 100644
index 000000000..3dbfa96e8
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v11/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_circle.png
new file mode 100644
index 000000000..8d52ab714
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_square.png
new file mode 100644
index 000000000..8d52ab714
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi-v9/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_circle.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_circle.png
new file mode 100644
index 000000000..d05fbff06
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_circle.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_square.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_square.png
new file mode 100644
index 000000000..c7159ec64
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/notification/res/drawable-xhdpi/ic_stat_square.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_selected.png
new file mode 100644
index 000000000..e8e7e713a
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_unselected.png
new file mode 100644
index 000000000..8d1ea96fd
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi-v5/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_selected.png
new file mode 100644
index 000000000..5a49be91f
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_unselected.png
new file mode 100644
index 000000000..d957240e7
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-hdpi/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_selected.png
new file mode 100644
index 000000000..0550dd2c4
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_unselected.png
new file mode 100644
index 000000000..82f44121e
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi-v5/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_selected.png
new file mode 100644
index 000000000..81302e9f5
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_unselected.png
new file mode 100644
index 000000000..00568c773
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-ldpi/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_selected.png
new file mode 100644
index 000000000..646490fca
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_unselected.png
new file mode 100644
index 000000000..c11de02c4
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi-v5/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_selected.png
new file mode 100644
index 000000000..7c603b75a
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_unselected.png
new file mode 100644
index 000000000..521bf60d3
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-mdpi/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_selected.png
new file mode 100644
index 000000000..448454be1
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_unselected.png
new file mode 100644
index 000000000..52852ee27
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi-v5/ic_tab_1_unselected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_selected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_selected.png
new file mode 100644
index 000000000..317fc5af3
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_selected.png
Binary files differ
diff --git a/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_unselected.png b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_unselected.png
new file mode 100644
index 000000000..7a0ffc68a
--- /dev/null
+++ b/assetstudio/tests/src/com/android/assetstudiolib/testdata/tabs/res/drawable-xhdpi/ic_tab_1_unselected.png
Binary files differ