aboutsummaryrefslogtreecommitdiffstats
path: root/assetstudio
diff options
context:
space:
mode:
Diffstat (limited to 'assetstudio')
-rw-r--r--assetstudio/.classpath7
-rw-r--r--assetstudio/.gitignore2
-rw-r--r--assetstudio/.project17
-rw-r--r--assetstudio/.settings/org.eclipse.jdt.core.prefs71
-rw-r--r--assetstudio/Android.mk30
-rw-r--r--assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java52
-rw-r--r--assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java33
-rw-r--r--assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java108
-rw-r--r--assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java92
-rw-r--r--assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java110
-rw-r--r--assetstudio/src/com/android/assetstudiolib/Util.java440
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/hdpi/back.pngbin0 -> 1885 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.pngbin0 -> 666 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.pngbin0 -> 2922 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.pngbin0 -> 4690 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/hdpi/mask.pngbin0 -> 992 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/ldpi/back.pngbin0 -> 745 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.pngbin0 -> 376 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.pngbin0 -> 1370 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.pngbin0 -> 2432 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/ldpi/mask.pngbin0 -> 435 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/mdpi/back.pngbin0 -> 1162 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.pngbin0 -> 457 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.pngbin0 -> 1720 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.pngbin0 -> 2926 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/mdpi/mask.pngbin0 -> 610 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/web/back.pngbin0 -> 29806 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/web/fore1.pngbin0 -> 30292 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/web/fore2.pngbin0 -> 59463 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/web/fore3.pngbin0 -> 61713 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/web/mask.pngbin0 -> 8447 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/xhdpi/back.pngbin0 -> 3451 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.pngbin0 -> 1746 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.pngbin0 -> 5054 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.pngbin0 -> 6239 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.pngbin0 -> 2142 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/hdpi/back.pngbin0 -> 713 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/hdpi/fore1.pngbin0 -> 331 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/hdpi/fore2.pngbin0 -> 1477 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/hdpi/fore3.pngbin0 -> 3592 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/hdpi/mask.pngbin0 -> 370 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/ldpi/back.pngbin0 -> 295 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/ldpi/fore1.pngbin0 -> 212 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/ldpi/fore2.pngbin0 -> 693 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/ldpi/fore3.pngbin0 -> 2061 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/ldpi/mask.pngbin0 -> 205 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/mdpi/back.pngbin0 -> 455 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/mdpi/fore1.pngbin0 -> 239 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/mdpi/fore2.pngbin0 -> 1010 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/mdpi/fore3.pngbin0 -> 2510 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/mdpi/mask.pngbin0 -> 250 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/web/back.pngbin0 -> 10984 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/web/fore1.pngbin0 -> 8562 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/web/fore2.pngbin0 -> 26230 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/web/fore3.pngbin0 -> 42175 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/web/mask.pngbin0 -> 3786 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/xhdpi/back.pngbin0 -> 1956 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.pngbin0 -> 1289 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.pngbin0 -> 2932 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.pngbin0 -> 4649 bytes
-rw-r--r--assetstudio/src/images/launcher_stencil/square/xhdpi/mask.pngbin0 -> 1396 bytes
61 files changed, 962 insertions, 0 deletions
diff --git a/assetstudio/.classpath b/assetstudio/.classpath
new file mode 100644
index 0000000..ee79d96
--- /dev/null
+++ b/assetstudio/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/common"/>
+</classpath>
diff --git a/assetstudio/.gitignore b/assetstudio/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/assetstudio/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/assetstudio/.project b/assetstudio/.project
new file mode 100644
index 0000000..f9aa2ce
--- /dev/null
+++ b/assetstudio/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>assetstudio</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/assetstudio/.settings/org.eclipse.jdt.core.prefs b/assetstudio/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e755df2
--- /dev/null
+++ b/assetstudio/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,71 @@
+#Thu Jun 09 12:26:44 PDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/assetstudio/Android.mk b/assetstudio/Android.mk
new file mode 100644
index 0000000..a48c3a0
--- /dev/null
+++ b/assetstudio/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_JAVA_RESOURCE_DIRS := src
+
+# TODO: Replace common with the batik stuff
+LOCAL_JAVA_LIBRARIES := \
+ common
+
+LOCAL_MODULE := assetstudio
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java
new file mode 100644
index 0000000..e53f0ab
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.resources.Density;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+/**
+ * The base Generator class.
+ */
+public class GraphicGenerator {
+ /**
+ * Options used for all generators.
+ */
+ public static class Options {
+ }
+
+ public static float getScaleFactor(Density density) {
+ return density.getDpiValue() / (float) Density.DEFAULT_DENSITY;
+ }
+
+ /**
+ * Returns one of the built in stencil images, or null
+ *
+ * @param relativePath stencil path such as "launcher-stencil/square/web/back.png"
+ * @return the image, or null
+ * @throws IOException if an unexpected I/O error occurs
+ */
+ public static BufferedImage getStencilImage(String relativePath) throws IOException {
+ InputStream is = GraphicGenerator.class.getResourceAsStream(relativePath);
+ return ImageIO.read(is);
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java b/assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java
new file mode 100644
index 0000000..e0b00a6
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.image.BufferedImage;
+
+/**
+ * The context used during graphic generation.
+ */
+public interface GraphicGeneratorContext {
+ /**
+ * Loads the given image resource, as requested by the graphic generator.
+ *
+ * @param path The path to the resource, relative to the general "resources" path, as defined by
+ * the context implementor.
+ * @return The loaded image resource, or null if there was an error.
+ */
+ public BufferedImage loadImageResource(String path);
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java
new file mode 100644
index 0000000..b6715a4
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.resources.Density;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+/**
+ * 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);
+
+ 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);
+ }
+
+ g.drawImage(mForeImage, 0, 0, null);
+ 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;
+
+ public static enum Shape {
+ CIRCLE("circle"), SQUARE("square");
+
+ public String id;
+
+ Shape(String id) {
+ this.id = id;
+ }
+ }
+
+ public static enum Style {
+ SIMPLE("fore1"), FANCY("fore2"), GLOSSY("fore3");
+
+ public String id;
+
+ Style(String id) {
+ this.id = id;
+ }
+ }
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java
new file mode 100644
index 0000000..07b7a6b
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.resources.Density;
+
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+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;
+ }
+
+ 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);
+
+ 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);
+
+ 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),
+ });
+ }
+
+ return outImage;
+ }
+
+ public static class Options {
+ public BufferedImage sourceImage;
+ public Density density = Density.XHIGH;
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java b/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java
new file mode 100644
index 0000000..a103701
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/TextRenderUtil.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Font;
+import java.awt.Graphics2D;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextAttribute;
+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
+ * source image to {@link GraphicGenerator} objects.
+ */
+public class TextRenderUtil {
+ /**
+ * Renders the given string with the provided {@link Options} to a {@link BufferedImage}.
+ *
+ * @param text The text to render.
+ * @param options The optional parameters for rendering the text.
+ * @return An image, suitable for use as an input to a {@link GraphicGenerator}.
+ */
+ public static BufferedImage renderTextImage(String text, Options options) {
+ if (options == null) {
+ options = new Options();
+ }
+
+ BufferedImage tempImage = Util.newArgbBufferedImage(1, 1);
+ if (text == null || text.equals("")) {
+ return tempImage;
+ }
+
+ Graphics2D tempG = (Graphics2D) tempImage.getGraphics();
+
+ Font font = options.font;
+ if (font == null) {
+ font = new Font(options.fontName, options.fontStyle, options.fontSize);
+ // Map<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>();
+ // map.put(TextAttribute.TRACKING, 0.3);
+ // font = font.deriveFont(map);
+ }
+
+ FontRenderContext frc = tempG.getFontRenderContext();
+
+ Rectangle2D bounds = font.getStringBounds(text, frc);
+
+ BufferedImage image = Util.newArgbBufferedImage(
+ Math.max(1, (int) bounds.getWidth()), Math.max(1, (int) bounds.getHeight()));
+ Graphics2D g = (Graphics2D) image.getGraphics();
+ g.setFont(font);
+ g.drawString(text, 0, (float) -bounds.getY());
+
+ return image;
+ }
+
+ /**
+ * The parameters for text rendering. There are no required values so a <code>new
+ * Options()</code> object is considered valid.
+ */
+ public static class Options {
+ // We use a large default font size to reduce the need to scale generated images up.
+ // TODO: Instead, a graphic generator should use a different source image for each density.
+ private static final int DEFAULT_FONT_SIZE = 512;
+
+ /**
+ * The optional {@link Font} to use. If null, a {@link Font} object will be generated using
+ * the other options.
+ */
+ public Font font = null;
+
+ /**
+ * The optional font name. Defaults to {@link Font#SERIF}.
+ *
+ * @see Font#Font(String, int, int)
+ */
+ public String fontName = Font.SERIF;
+
+ /**
+ * The optional font styling (bold and/or italic). Defaults to no styling.
+ *
+ * @see Font#Font(String, int, int)
+ */
+ public int fontStyle = 0;
+
+ /**
+ * The optional font size, in points. Defaults to a very large font size, to prevent
+ * up-scaling rendered text.
+ *
+ * @see Font#Font(String, int, int)
+ */
+ public int fontSize = DEFAULT_FONT_SIZE;
+ }
+}
diff --git a/assetstudio/src/com/android/assetstudiolib/Util.java b/assetstudio/src/com/android/assetstudiolib/Util.java
new file mode 100644
index 0000000..1a6b00e
--- /dev/null
+++ b/assetstudio/src/com/android/assetstudiolib/Util.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+import java.awt.image.Raster;
+import java.awt.image.RescaleOp;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A set of utility classes for manipulating {@link BufferedImage} objects and drawing them to
+ * {@link Graphics2D} canvases.
+ */
+public class Util {
+ /**
+ * Scales the given rectangle by the given scale factor.
+ *
+ * @param rect The rectangle to scale.
+ * @param scaleFactor The factor to scale by.
+ * @return The scaled rectangle.
+ */
+ public static Rectangle scaleRectangle(Rectangle rect, float scaleFactor) {
+ return new Rectangle(
+ (int) (rect.x * scaleFactor),
+ (int) (rect.y * scaleFactor),
+ (int) (rect.width * scaleFactor),
+ (int) (rect.height * scaleFactor));
+ }
+
+ /**
+ * Creates a new ARGB {@link BufferedImage} of the given width and height.
+ *
+ * @param width The width of the new image.
+ * @param height The height of the new image.
+ * @return The newly created image.
+ */
+ public static BufferedImage newArgbBufferedImage(int width, int height) {
+ return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ /**
+ * Smoothly scales the given {@link BufferedImage} to the given width and height using the
+ * {@link Image#SCALE_SMOOTH} algorithm (generally bicubic resampling or bilinear filtering).
+ *
+ * @param source The source image.
+ * @param width The destination width to scale to.
+ * @param height The destination height to scale to.
+ * @return A new, scaled image.
+ */
+ public static BufferedImage scaledImage(BufferedImage source, int width, int height) {
+ Image scaledImage = source.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+ BufferedImage scaledBufImage = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics g = scaledBufImage.createGraphics();
+ g.drawImage(scaledImage, 0, 0, null);
+ g.dispose();
+ return scaledBufImage;
+ }
+
+ /**
+ * Applies a gaussion blur of the given radius to the given {@link BufferedImage} using a kernel
+ * convolution.
+ *
+ * @param source The source image.
+ * @param radius The blur radius, in pixels.
+ * @return A new, blurred image, or the source image if no blur is performed.
+ */
+ public static BufferedImage blurredImage(BufferedImage source, double radius) {
+ if (radius == 0) {
+ return source;
+ }
+
+ final int r = (int) Math.ceil(radius);
+ final int rows = r * 2 + 1;
+ final float[] kernelData = new float[rows * rows];
+
+ final double sigma = radius / 3;
+ final double sigma22 = 2 * sigma * sigma;
+ final double sqrtPiSigma22 = Math.sqrt(Math.PI * sigma22);
+ final double radius2 = radius * radius;
+
+ double total = 0;
+ int index = 0;
+ double distance2;
+
+ int x, y;
+ for (y = -r; y <= r; y++) {
+ for (x = -r; x <= r; x++) {
+ distance2 = 1.0 * x * x + 1.0 * y * y;
+ if (distance2 > radius2) {
+ kernelData[index] = 0;
+ } else {
+ kernelData[index] = (float) (Math.exp(-distance2 / sigma22) / sqrtPiSigma22);
+ }
+ total += kernelData[index];
+ ++index;
+ }
+ }
+
+ for (index = 0; index < kernelData.length; index++) {
+ kernelData[index] /= total;
+ }
+
+ // We first pad the image so the kernel can operate at the edges.
+ BufferedImage paddedSource = paddedImage(source, r);
+ BufferedImage blurredPaddedImage = operatedImage(paddedSource, new ConvolveOp(
+ new Kernel(rows, rows, kernelData), ConvolveOp.EDGE_ZERO_FILL, null));
+ return blurredPaddedImage.getSubimage(r, r, source.getWidth(), source.getHeight());
+ }
+
+ /**
+ * Inverts the alpha channel of the given {@link BufferedImage}. RGB data for the inverted area
+ * are undefined, so it's generally best to fill the resulting image with a color.
+ *
+ * @param source The source image.
+ * @return A new image with an alpha channel inverted from the original.
+ */
+ public static BufferedImage invertedAlphaImage(BufferedImage source) {
+ final float[] scaleFactors = new float[]{1, 1, 1, -1};
+ final float[] offsets = new float[]{0, 0, 0, 255};
+
+ return operatedImage(source, new RescaleOp(scaleFactors, offsets, null));
+ }
+
+ /**
+ * Applies a {@link BufferedImageOp} on the given {@link BufferedImage}.
+ *
+ * @param source The source image.
+ * @param op The operation to perform.
+ * @return A new image with the operation performed.
+ */
+ public static BufferedImage operatedImage(BufferedImage source, BufferedImageOp op) {
+ BufferedImage newImage = newArgbBufferedImage(source.getWidth(), source.getHeight());
+ Graphics2D g = (Graphics2D) newImage.getGraphics();
+ g.drawImage(source, op, 0, 0);
+ return newImage;
+ }
+
+ /**
+ * Fills the given {@link BufferedImage} with a {@link Paint}, preserving its alpha channel.
+ *
+ * @param source The source image.
+ * @param paint The paint to fill with.
+ * @return A new, painted/filled image.
+ */
+ public static BufferedImage filledImage(BufferedImage source, Paint paint) {
+ BufferedImage newImage = newArgbBufferedImage(source.getWidth(), source.getHeight());
+ Graphics2D g = (Graphics2D) newImage.getGraphics();
+ g.drawImage(source, 0, 0, null);
+ g.setComposite(AlphaComposite.SrcAtop);
+ g.setPaint(paint);
+ g.fillRect(0, 0, source.getWidth(), source.getHeight());
+ return newImage;
+ }
+
+ /**
+ * Pads the given {@link BufferedImage} on all sides by the given padding amount.
+ *
+ * @param source The source image.
+ * @param padding The amount to pad on all sides, in pixels.
+ * @return A new, padded image, or the source image if no padding is performed.
+ */
+ public static BufferedImage paddedImage(BufferedImage source, int padding) {
+ if (padding == 0) {
+ return source;
+ }
+
+ BufferedImage newImage = newArgbBufferedImage(
+ source.getWidth() + padding * 2, source.getHeight() + padding * 2);
+ Graphics2D g = (Graphics2D) newImage.getGraphics();
+ g.drawImage(source, padding, padding, null);
+ return newImage;
+ }
+
+ /**
+ * Trims the transparent pixels from the given {@link BufferedImage} (returns a sub-image).
+ *
+ * @param source The source image.
+ * @return A new, trimmed image, or the source image if no trim is performed.
+ */
+ public static BufferedImage trimmedImage(BufferedImage source) {
+ final int minAlpha = 1;
+ final int srcWidth = source.getWidth();
+ final int srcHeight = source.getHeight();
+ Raster raster = source.getRaster();
+ int l = srcWidth, t = srcHeight, r = 0, b = 0;
+
+ int alpha, x, y;
+ int[] pixel = new int[4];
+ for (y = 0; y < srcHeight; y++) {
+ for (x = 0; x < srcWidth; x++) {
+ raster.getPixel(x, y, pixel);
+ alpha = pixel[3];
+ if (alpha >= minAlpha) {
+ l = Math.min(x, l);
+ t = Math.min(y, t);
+ r = Math.max(x, r);
+ b = Math.max(y, b);
+ }
+ }
+ }
+
+ if (l > r || t > b) {
+ // No pixels, couldn't trim
+ return source;
+ }
+
+ return source.getSubimage(l, t, r - l + 1, b - t + 1);
+ }
+
+ /**
+ * Draws the given {@link BufferedImage} to the canvas, at the given coordinates, with the given
+ * {@link Effect}s applied. Note that drawn effects may be outside the bounds of the source
+ * image.
+ *
+ * @param g The destination canvas.
+ * @param source The source image.
+ * @param x The x offset at which to draw the image.
+ * @param y The y offset at which to draw the image.
+ * @param effects The list of effects to apply.
+ */
+ public static void drawEffects(Graphics2D g, BufferedImage source, int x, int y,
+ Effect[] effects) {
+ List<ShadowEffect> shadowEffects = new ArrayList<ShadowEffect>();
+ List<FillEffect> fillEffects = new ArrayList<FillEffect>();
+
+ for (Effect effect : effects) {
+ if (effect instanceof ShadowEffect) {
+ shadowEffects.add((ShadowEffect) effect);
+ } else if (effect instanceof FillEffect) {
+ fillEffects.add((FillEffect) effect);
+ }
+ }
+
+ Composite oldComposite = g.getComposite();
+ for (ShadowEffect effect : shadowEffects) {
+ if (effect.inner) {
+ continue;
+ }
+
+ // Outer shadow
+ g.setComposite(AlphaComposite.getInstance(
+ AlphaComposite.SRC_OVER, (float) effect.opacity));
+ g.drawImage(
+ filledImage(
+ blurredImage(source, effect.radius),
+ effect.color),
+ (int) effect.xOffset, (int) effect.yOffset, null);
+ }
+ g.setComposite(oldComposite);
+
+ // Inner shadow & fill effects.
+ final Rectangle imageRect = new Rectangle(0, 0, source.getWidth(), source.getHeight());
+ BufferedImage out = newArgbBufferedImage(imageRect.width, imageRect.height);
+ Graphics2D g2 = (Graphics2D) out.getGraphics();
+
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
+ g2.drawImage(source, 0, 0, null);
+ g2.setComposite(AlphaComposite.SrcAtop);
+
+ // Gradient fill
+ for (FillEffect effect : fillEffects) {
+ g2.setPaint(effect.paint);
+ g2.fillRect(0, 0, imageRect.width, imageRect.height);
+ }
+
+ // Inner shadows
+ for (ShadowEffect effect : shadowEffects) {
+ if (!effect.inner) {
+ continue;
+ }
+
+ BufferedImage innerShadowImage = newArgbBufferedImage(
+ imageRect.width, imageRect.height);
+ Graphics2D g3 = (Graphics2D) innerShadowImage.getGraphics();
+ g3.drawImage(source, (int) effect.xOffset, (int) effect.yOffset, null);
+ g2.setComposite(AlphaComposite.getInstance(
+ AlphaComposite.SRC_ATOP, (float) effect.opacity));
+ g2.drawImage(
+ filledImage(
+ blurredImage(invertedAlphaImage(innerShadowImage), effect.radius),
+ effect.color),
+ 0, 0, null);
+ }
+
+ g.drawImage(out, x, y, null);
+ }
+
+ /**
+ * Draws the given {@link BufferedImage} to the canvas, centered, wholly contained within the
+ * bounds defined by the destination rectangle, and with preserved aspect ratio.
+ *
+ * @param g The destination canvas.
+ * @param source The source image.
+ * @param dstRect The destination rectangle in the destination canvas into which to draw the
+ * image.
+ */
+ public static void drawCenterInside(Graphics2D g, BufferedImage source, Rectangle dstRect) {
+ final int srcWidth = source.getWidth();
+ final int srcHeight = source.getHeight();
+ if (srcWidth * 1.0 / srcHeight > dstRect.width * 1.0 / dstRect.height) {
+ final int scaledWidth = Math.max(1, dstRect.width);
+ final int scaledHeight = Math.max(1, dstRect.width * srcHeight / srcWidth);
+ Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
+ g.drawImage(scaledImage,
+ dstRect.x,
+ dstRect.y + (dstRect.height - scaledHeight) / 2,
+ dstRect.x + dstRect.width,
+ dstRect.y + (dstRect.height - scaledHeight) / 2 + scaledHeight,
+ 0,
+ 0,
+ 0 + scaledWidth,
+ 0 + scaledHeight,
+ null);
+ } else {
+ final int scaledWidth = Math.max(1, dstRect.height * srcWidth / srcHeight);
+ final int scaledHeight = Math.max(1, dstRect.height);
+ Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
+ g.drawImage(scaledImage,
+ dstRect.x + (dstRect.width - scaledWidth) / 2,
+ dstRect.y,
+ dstRect.x + (dstRect.width - scaledWidth) / 2 + scaledWidth,
+ dstRect.y + dstRect.height,
+ 0,
+ 0,
+ 0 + scaledWidth,
+ 0 + scaledHeight,
+ null);
+ }
+ }
+
+ /**
+ * Draws the given {@link BufferedImage} to the canvas, centered and cropped to fill the
+ * bounds defined by the destination rectangle, and with preserved aspect ratio.
+ *
+ * @param g The destination canvas.
+ * @param source The source image.
+ * @param dstRect The destination rectangle in the destination canvas into which to draw the
+ * image.
+ */
+ public static void drawCenterCrop(Graphics2D g, BufferedImage source, Rectangle dstRect) {
+ final int srcWidth = source.getWidth();
+ final int srcHeight = source.getHeight();
+ if (srcWidth * 1.0 / srcHeight > dstRect.width * 1.0 / dstRect.height) {
+ final int scaledWidth = dstRect.height * srcWidth / srcHeight;
+ final int scaledHeight = dstRect.height;
+ Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
+ g.drawImage(scaledImage,
+ dstRect.x,
+ dstRect.y,
+ dstRect.x + dstRect.width,
+ dstRect.y + dstRect.height,
+ 0 + (scaledWidth - dstRect.width) / 2,
+ 0,
+ 0 + (scaledWidth - dstRect.width) / 2 + dstRect.width,
+ 0 + dstRect.height,
+ null);
+ } else {
+ final int scaledWidth = dstRect.width;
+ final int scaledHeight = dstRect.width * srcHeight / srcWidth;
+ Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
+ g.drawImage(scaledImage,
+ dstRect.x,
+ dstRect.y,
+ dstRect.x + dstRect.width,
+ dstRect.y + dstRect.height,
+ 0,
+ 0 + (scaledHeight - dstRect.height) / 2,
+ 0 + dstRect.width,
+ 0 + (scaledHeight - dstRect.height) / 2 + dstRect.height,
+ null);
+ }
+ }
+
+ /**
+ * An effect to apply in
+ * {@link Util#drawEffects(java.awt.Graphics2D, java.awt.image.BufferedImage, int, int, Util.Effect[])}
+ */
+ public static abstract class Effect {
+ }
+
+ /**
+ * An inner or outer shadow.
+ */
+ public static class ShadowEffect extends Effect {
+ public double xOffset;
+ public double yOffset;
+ public double radius;
+ public Color color;
+ public double opacity;
+ public boolean inner;
+
+ public ShadowEffect(double xOffset, double yOffset, double radius, Color color,
+ double opacity, boolean inner) {
+ this.xOffset = xOffset;
+ this.yOffset = yOffset;
+ this.radius = radius;
+ this.color = color;
+ this.opacity = opacity;
+ this.inner = inner;
+ }
+ }
+
+ /**
+ * A fill, defined by a paint.
+ */
+ public static class FillEffect extends Effect {
+ public Paint paint;
+
+ public FillEffect(Paint paint) {
+ this.paint = paint;
+ }
+ }
+}
diff --git a/assetstudio/src/images/launcher_stencil/circle/hdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/back.png
new file mode 100644
index 0000000..8e3dbc1
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png
new file mode 100644
index 0000000..79d75c0
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png
new file mode 100644
index 0000000..594257a
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png
new file mode 100644
index 0000000..65fb48b
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png
new file mode 100644
index 0000000..99e787a
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/ldpi/back.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/back.png
new file mode 100644
index 0000000..d9a9fcc
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png
new file mode 100644
index 0000000..ecc3bc5
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png
new file mode 100644
index 0000000..c86b59c
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png
new file mode 100644
index 0000000..1ae4d31
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png
new file mode 100644
index 0000000..e537ad0
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/mdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/back.png
new file mode 100644
index 0000000..e165038
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png
new file mode 100644
index 0000000..c42af13
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png
new file mode 100644
index 0000000..0c06821
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png
new file mode 100644
index 0000000..01fe418
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png
new file mode 100644
index 0000000..19f18bf
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/web/back.png b/assetstudio/src/images/launcher_stencil/circle/web/back.png
new file mode 100644
index 0000000..191c677
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/web/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/web/fore1.png b/assetstudio/src/images/launcher_stencil/circle/web/fore1.png
new file mode 100644
index 0000000..7ea8096
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/web/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/web/fore2.png b/assetstudio/src/images/launcher_stencil/circle/web/fore2.png
new file mode 100644
index 0000000..5a76240
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/web/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/web/fore3.png b/assetstudio/src/images/launcher_stencil/circle/web/fore3.png
new file mode 100644
index 0000000..1794bff
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/web/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/web/mask.png b/assetstudio/src/images/launcher_stencil/circle/web/mask.png
new file mode 100644
index 0000000..8316d80
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/web/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png
new file mode 100644
index 0000000..e655af6
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png
new file mode 100644
index 0000000..639ccba
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png
new file mode 100644
index 0000000..b922452
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png
new file mode 100644
index 0000000..5f1c15e
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png
new file mode 100644
index 0000000..6dc3bc7
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/hdpi/back.png b/assetstudio/src/images/launcher_stencil/square/hdpi/back.png
new file mode 100644
index 0000000..3e58211
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/hdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png
new file mode 100644
index 0000000..e76d493
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png
new file mode 100644
index 0000000..ab28d8d
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png
new file mode 100644
index 0000000..59f5e8f
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/hdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/hdpi/mask.png
new file mode 100644
index 0000000..9c56fe6
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/hdpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/ldpi/back.png b/assetstudio/src/images/launcher_stencil/square/ldpi/back.png
new file mode 100644
index 0000000..1a68be3
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/ldpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png
new file mode 100644
index 0000000..c46e1c2
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png
new file mode 100644
index 0000000..3bc8315
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png
new file mode 100644
index 0000000..0bfa4f7
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/ldpi/mask.png b/assetstudio/src/images/launcher_stencil/square/ldpi/mask.png
new file mode 100644
index 0000000..04d6d1a
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/ldpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/mdpi/back.png b/assetstudio/src/images/launcher_stencil/square/mdpi/back.png
new file mode 100644
index 0000000..f49e513
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/mdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png
new file mode 100644
index 0000000..2837d41
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png
new file mode 100644
index 0000000..566941f
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png
new file mode 100644
index 0000000..9bcfc5e
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/mdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/mdpi/mask.png
new file mode 100644
index 0000000..90e5cd0
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/mdpi/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/web/back.png b/assetstudio/src/images/launcher_stencil/square/web/back.png
new file mode 100644
index 0000000..2f008b7
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/web/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/web/fore1.png b/assetstudio/src/images/launcher_stencil/square/web/fore1.png
new file mode 100644
index 0000000..527ac47
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/web/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/web/fore2.png b/assetstudio/src/images/launcher_stencil/square/web/fore2.png
new file mode 100644
index 0000000..5e557f8
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/web/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/web/fore3.png b/assetstudio/src/images/launcher_stencil/square/web/fore3.png
new file mode 100644
index 0000000..58d85af
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/web/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/web/mask.png b/assetstudio/src/images/launcher_stencil/square/web/mask.png
new file mode 100644
index 0000000..2c80196
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/web/mask.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/xhdpi/back.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/back.png
new file mode 100644
index 0000000..84caac0
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/back.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png
new file mode 100644
index 0000000..2d237e1
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png
new file mode 100644
index 0000000..cce5e0e
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png
new file mode 100644
index 0000000..3b91aa4
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png
Binary files differ
diff --git a/assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png
new file mode 100644
index 0000000..9e0bbdc
--- /dev/null
+++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png
Binary files differ