diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:16 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:16 -0800 |
commit | 82ea7a177797b844b252effea5c7c7c5d63ea4ac (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /ninepatch | |
parent | c9432be76d50a527da232d518f633add2f76242b (diff) | |
download | sdk-82ea7a177797b844b252effea5c7c7c5d63ea4ac.zip sdk-82ea7a177797b844b252effea5c7c7c5d63ea4ac.tar.gz sdk-82ea7a177797b844b252effea5c7c7c5d63ea4ac.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'ninepatch')
-rw-r--r-- | ninepatch/Android.mk | 23 | ||||
-rw-r--r-- | ninepatch/src/com/android/ninepatch/GraphicsUtilities.java | 96 | ||||
-rw-r--r-- | ninepatch/src/com/android/ninepatch/NinePatch.java | 474 |
3 files changed, 0 insertions, 593 deletions
diff --git a/ninepatch/Android.mk b/ninepatch/Android.mk deleted file mode 100644 index 42e0205..0000000 --- a/ninepatch/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2008 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_MODULE := ninepatch - -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java b/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java deleted file mode 100644 index 7a823ec..0000000 --- a/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2008 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.ninepatch; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.awt.image.Raster; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsEnvironment; -import java.awt.Graphics; -import java.awt.Transparency; -import java.net.URL; -import java.io.IOException; - -public class GraphicsUtilities { - public static BufferedImage loadCompatibleImage(URL resource) throws IOException { - BufferedImage image = ImageIO.read(resource); - return toCompatibleImage(image); - } - - public static BufferedImage createCompatibleImage(int width, int height) { - return getGraphicsConfiguration().createCompatibleImage(width, height); - } - - public static BufferedImage toCompatibleImage(BufferedImage image) { - if (isHeadless()) { - return image; - } - - if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) { - return image; - } - - BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage( - image.getWidth(), image.getHeight(), image.getTransparency()); - Graphics g = compatibleImage.getGraphics(); - g.drawImage(image, 0, 0, null); - g.dispose(); - - return compatibleImage; - } - - public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) { - return getGraphicsConfiguration().createCompatibleImage(width, height, - image.getTransparency()); - } - - private static GraphicsConfiguration getGraphicsConfiguration() { - GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); - return environment.getDefaultScreenDevice().getDefaultConfiguration(); - } - - private static boolean isHeadless() { - return GraphicsEnvironment.isHeadless(); - } - - public static BufferedImage createTranslucentCompatibleImage(int width, int height) { - return getGraphicsConfiguration().createCompatibleImage(width, height, - Transparency.TRANSLUCENT); - } - - public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) { - if (w == 0 || h == 0) { - return new int[0]; - } - - if (pixels == null) { - pixels = new int[w * h]; - } else if (pixels.length < w * h) { - throw new IllegalArgumentException("Pixels array must have a length >= w * h"); - } - - int imageType = img.getType(); - if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) { - Raster raster = img.getRaster(); - return (int[]) raster.getDataElements(x, y, w, h, pixels); - } - - // Unmanages the image - return img.getRGB(x, y, w, h, pixels, 0, w); - } -} diff --git a/ninepatch/src/com/android/ninepatch/NinePatch.java b/ninepatch/src/com/android/ninepatch/NinePatch.java deleted file mode 100644 index 39e05c6..0000000 --- a/ninepatch/src/com/android/ninepatch/NinePatch.java +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) 2008 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.ninepatch; - -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a 9-Patch bitmap. - */ -public class NinePatch { - public static final String EXTENSION_9PATCH = ".9.png"; - - private BufferedImage mImage; - - private int mMinWidth; - private int mMinHeight; - - private int[] row; - private int[] column; - - private boolean mVerticalStartWithPatch; - private boolean mHorizontalStartWithPatch; - - private List<Rectangle> mFixed; - private List<Rectangle> mPatches; - private List<Rectangle> mHorizontalPatches; - private List<Rectangle> mVerticalPatches; - - private Pair<Integer> mHorizontalPadding; - private Pair<Integer> mVerticalPadding; - - private float mHorizontalPatchesSum; - private float mVerticalPatchesSum; - - private int mRemainderHorizontal; - - private int mRemainderVertical; - - private final URL mFileUrl; - - /** - * Loads a 9 patch or regular bitmap. - * @param fileUrl the URL of the file to load. - * @param convert if <code>true</code>, non 9-patch bitmpa will be converted into a 9 patch. - * If <code>false</code> and the bitmap is not a 9 patch, the method will return - * <code>null</code>. - * @return a {@link NinePatch} or <code>null</code>. - * @throws IOException - */ - public static NinePatch load(URL fileUrl, boolean convert) throws IOException { - BufferedImage image = null; - try { - image = GraphicsUtilities.loadCompatibleImage(fileUrl); - } catch (MalformedURLException e) { - // really this shouldn't be happening since we're not creating the URL manually. - return null; - } - - boolean is9Patch = fileUrl.getPath().toLowerCase().endsWith(EXTENSION_9PATCH); - - if (is9Patch == false) { - if (convert) { - image = convertTo9Patch(image); - } else { - return null; - } - } else { - ensure9Patch(image); - } - - - return new NinePatch(fileUrl, image); - } - - public int getWidth() { - return mImage.getWidth() - 2; - } - - public int getHeight() { - return mImage.getHeight() - 2; - } - - /** - * - * @param padding array of left, top, right, bottom padding - * @return - */ - public boolean getPadding(int[] padding) { - padding[0] = mHorizontalPadding.mFirst; // left - padding[2] = mHorizontalPadding.mSecond; // right - padding[1] = mVerticalPadding.mFirst; // top - padding[3] = mVerticalPadding.mSecond; // bottom - return true; - } - - - public void draw(Graphics2D graphics2D, int x, int y, int scaledWidth, int scaledHeight) { - if (scaledWidth <= 1 || scaledHeight <= 1) { - return; - } - - Graphics2D g = (Graphics2D)graphics2D.create(); - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR); - - - try { - if (mPatches.size() == 0 || mHorizontalPatches.size() == 0 || - mVerticalPatches.size() == 0) { - g.drawImage(mImage, x, y, scaledWidth, scaledHeight, null); - return; - } - - g.translate(x, y); - x = y = 0; - - computePatches(scaledWidth, scaledHeight); - - int fixedIndex = 0; - int horizontalIndex = 0; - int verticalIndex = 0; - int patchIndex = 0; - - boolean hStretch; - boolean vStretch; - - float vWeightSum = 1.0f; - float vRemainder = mRemainderVertical; - - vStretch = mVerticalStartWithPatch; - while (y < scaledHeight - 1) { - hStretch = mHorizontalStartWithPatch; - - int height = 0; - float vExtra = 0.0f; - - float hWeightSum = 1.0f; - float hRemainder = mRemainderHorizontal; - - while (x < scaledWidth - 1) { - Rectangle r; - if (!vStretch) { - if (hStretch) { - r = mHorizontalPatches.get(horizontalIndex++); - float extra = r.width / mHorizontalPatchesSum; - int width = (int) (extra * hRemainder / hWeightSum); - hWeightSum -= extra; - hRemainder -= width; - g.drawImage(mImage, x, y, x + width, y + r.height, r.x, r.y, - r.x + r.width, r.y + r.height, null); - x += width; - } else { - r = mFixed.get(fixedIndex++); - g.drawImage(mImage, x, y, x + r.width, y + r.height, r.x, r.y, - r.x + r.width, r.y + r.height, null); - x += r.width; - } - height = r.height; - } else { - if (hStretch) { - r = mPatches.get(patchIndex++); - vExtra = r.height / mVerticalPatchesSum; - height = (int) (vExtra * vRemainder / vWeightSum); - float extra = r.width / mHorizontalPatchesSum; - int width = (int) (extra * hRemainder / hWeightSum); - hWeightSum -= extra; - hRemainder -= width; - g.drawImage(mImage, x, y, x + width, y + height, r.x, r.y, - r.x + r.width, r.y + r.height, null); - x += width; - } else { - r = mVerticalPatches.get(verticalIndex++); - vExtra = r.height / mVerticalPatchesSum; - height = (int) (vExtra * vRemainder / vWeightSum); - g.drawImage(mImage, x, y, x + r.width, y + height, r.x, r.y, - r.x + r.width, r.y + r.height, null); - x += r.width; - } - - } - hStretch = !hStretch; - } - x = 0; - y += height; - if (vStretch) { - vWeightSum -= vExtra; - vRemainder -= height; - } - vStretch = !vStretch; - } - - } finally { - g.dispose(); - } - } - - void computePatches(int scaledWidth, int scaledHeight) { - boolean measuredWidth = false; - boolean endRow = true; - - int remainderHorizontal = 0; - int remainderVertical = 0; - - if (mFixed.size() > 0) { - int start = mFixed.get(0).y; - for (Rectangle rect : mFixed) { - if (rect.y > start) { - endRow = true; - measuredWidth = true; - } - if (!measuredWidth) { - remainderHorizontal += rect.width; - } - if (endRow) { - remainderVertical += rect.height; - endRow = false; - start = rect.y; - } - } - } - - mRemainderHorizontal = scaledWidth - remainderHorizontal; - - mRemainderVertical = scaledHeight - remainderVertical; - - mHorizontalPatchesSum = 0; - if (mHorizontalPatches.size() > 0) { - int start = -1; - for (Rectangle rect : mHorizontalPatches) { - if (rect.x > start) { - mHorizontalPatchesSum += rect.width; - start = rect.x; - } - } - } - - mVerticalPatchesSum = 0; - if (mVerticalPatches.size() > 0) { - int start = -1; - for (Rectangle rect : mVerticalPatches) { - if (rect.y > start) { - mVerticalPatchesSum += rect.height; - start = rect.y; - } - } - } - } - - - private NinePatch(URL fileUrl, BufferedImage image) { - mFileUrl = fileUrl; - mImage = image; - - findPatches(); - } - - private void findPatches() { - int width = mImage.getWidth(); - int height = mImage.getHeight(); - - row = GraphicsUtilities.getPixels(mImage, 0, 0, width, 1, row); - column = GraphicsUtilities.getPixels(mImage, 0, 0, 1, height, column); - - boolean[] result = new boolean[1]; - Pair<List<Pair<Integer>>> left = getPatches(column, result); - mVerticalStartWithPatch = result[0]; - - // compute the min size, based on the list of fixed sections, which is stored in - // Pair.mFirst - mMinHeight = 0; - List<Pair<Integer>> fixedSections = left.mFirst; - for (Pair<Integer> section : fixedSections) { - mMinHeight += section.mSecond - section.mFirst; - } - - result = new boolean[1]; - Pair<List<Pair<Integer>>> top = getPatches(row, result); - mHorizontalStartWithPatch = result[0]; - - // compute the min size, based on the list of fixed sections, which is stored in - // Pair.mFirst - - mMinWidth = 0; - fixedSections = top.mFirst; - for (Pair<Integer> section : fixedSections) { - mMinWidth += section.mSecond - section.mFirst; - } - - mFixed = getRectangles(left.mFirst, top.mFirst); - mPatches = getRectangles(left.mSecond, top.mSecond); - - if (mFixed.size() > 0) { - mHorizontalPatches = getRectangles(left.mFirst, top.mSecond); - mVerticalPatches = getRectangles(left.mSecond, top.mFirst); - } else { - mHorizontalPatches = mVerticalPatches = new ArrayList<Rectangle>(0); - } - - row = GraphicsUtilities.getPixels(mImage, 0, height - 1, width, 1, row); - column = GraphicsUtilities.getPixels(mImage, width - 1, 0, 1, height, column); - - top = getPatches(row, result); - mHorizontalPadding = getPadding(top.mFirst); - - left = getPatches(column, result); - mVerticalPadding = getPadding(left.mFirst); - - mHorizontalPatchesSum = 0; - if (mHorizontalPatches.size() > 0) { - int start = -1; - for (Rectangle rect : mHorizontalPatches) { - if (rect.x > start) { - mHorizontalPatchesSum += rect.width; - start = rect.x; - } - } - } - - mVerticalPatchesSum = 0; - if (mVerticalPatches.size() > 0) { - int start = -1; - for (Rectangle rect : mVerticalPatches) { - if (rect.y > start) { - mVerticalPatchesSum += rect.height; - start = rect.y; - } - } - } - - } - - private Pair<Integer> getPadding(List<Pair<Integer>> pairs) { - if (pairs.size() == 0) { - return new Pair<Integer>(0, 0); - } else if (pairs.size() == 1) { - if (pairs.get(0).mFirst == 1) { - return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst, 0); - } else { - return new Pair<Integer>(0, pairs.get(0).mSecond - pairs.get(0).mFirst); - } - } else { - int index = pairs.size() - 1; - return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst, - pairs.get(index).mSecond - pairs.get(index).mFirst); - } - } - - private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs, - List<Pair<Integer>> topPairs) { - List<Rectangle> rectangles = new ArrayList<Rectangle>(); - for (Pair<Integer> left : leftPairs) { - int y = left.mFirst; - int height = left.mSecond - left.mFirst; - for (Pair<Integer> top: topPairs) { - int x = top.mFirst; - int width = top.mSecond - top.mFirst; - - rectangles.add(new Rectangle(x, y, width, height)); - } - } - return rectangles; - } - - private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) { - int lastIndex = 1; - int lastPixel = pixels[1]; - boolean first = true; - - List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>(); - List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>(); - - for (int i = 1; i < pixels.length - 1; i++) { - int pixel = pixels[i]; - if (pixel != lastPixel) { - if (lastPixel == 0xFF000000) { - if (first) startWithPatch[0] = true; - patches.add(new Pair<Integer>(lastIndex, i)); - } else { - fixed.add(new Pair<Integer>(lastIndex, i)); - } - first = false; - - lastIndex = i; - lastPixel = pixel; - } - } - if (lastPixel == 0xFF000000) { - if (first) startWithPatch[0] = true; - patches.add(new Pair<Integer>(lastIndex, pixels.length - 1)); - } else { - fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1)); - } - - if (patches.size() == 0) { - patches.add(new Pair<Integer>(1, pixels.length - 1)); - startWithPatch[0] = true; - fixed.clear(); - } - return new Pair<List<Pair<Integer>>>(fixed, patches); - } - - private static void ensure9Patch(BufferedImage image) { - int width = image.getWidth(); - int height = image.getHeight(); - for (int i = 0; i < width; i++) { - int pixel = image.getRGB(i, 0); - if (pixel != 0 && pixel != 0xFF000000) { - image.setRGB(i, 0, 0); - } - pixel = image.getRGB(i, height - 1); - if (pixel != 0 && pixel != 0xFF000000) { - image.setRGB(i, height - 1, 0); - } - } - for (int i = 0; i < height; i++) { - int pixel = image.getRGB(0, i); - if (pixel != 0 && pixel != 0xFF000000) { - image.setRGB(0, i, 0); - } - pixel = image.getRGB(width - 1, i); - if (pixel != 0 && pixel != 0xFF000000) { - image.setRGB(width - 1, i, 0); - } - } - } - - private static BufferedImage convertTo9Patch(BufferedImage image) { - BufferedImage buffer = GraphicsUtilities.createTranslucentCompatibleImage( - image.getWidth() + 2, image.getHeight() + 2); - - Graphics2D g2 = buffer.createGraphics(); - g2.drawImage(image, 1, 1, null); - g2.dispose(); - - return buffer; - } - - static class Pair<E> { - E mFirst; - E mSecond; - - Pair(E first, E second) { - mFirst = first; - mSecond = second; - } - - @Override - public String toString() { - return "Pair[" + mFirst + ", " + mSecond + "]"; - } - } -} |