ninepatch

16:39:19.178 INFO  jd.cli.Main - Decompiling ninepatch.jar
package com.android.ninepatch;

import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;

public class GraphicsUtilities
{
  public static BufferedImage loadCompatibleImage(URL resource)
    throws IOException
  {
    BufferedImage image = ImageIO.read(resource);
    return toCompatibleImage(image);
  }
  
  public static BufferedImage loadCompatibleImage(InputStream stream)
    throws IOException
  {
    BufferedImage image = ImageIO.read(stream);
    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, 3);
  }
  
  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 == 2) || (imageType == 1))
    {
      Raster raster = img.getRaster();
      return (int[])raster.getDataElements(x, y, w, h, pixels);
    }
    return img.getRGB(x, y, w, h, pixels, 0, w);
  }
}

/* Location:
 * Qualified Name:     com.android.ninepatch.GraphicsUtilities
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.ninepatch;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

public class NinePatch
{
  public static final String EXTENSION_9PATCH = ".9.png";
  private BufferedImage mImage;
  private NinePatchChunk mChunk;
  
  public BufferedImage getImage()
  {
    return mImage;
  }
  
  public NinePatchChunk getChunk()
  {
    return mChunk;
  }
  
  public static NinePatch load(URL fileUrl, boolean convert)
    throws IOException
  {
    BufferedImage image = null;
    try
    {
      image = GraphicsUtilities.loadCompatibleImage(fileUrl);
    }
    catch (MalformedURLException e)
    {
      return null;
    }
    boolean is9Patch = fileUrl.getPath().toLowerCase(Locale.US).endsWith(".9.png");
    
    return load(image, is9Patch, convert);
  }
  
  public static NinePatch load(InputStream stream, boolean is9Patch, boolean convert)
    throws IOException
  {
    BufferedImage image = null;
    try
    {
      image = GraphicsUtilities.loadCompatibleImage(stream);
    }
    catch (MalformedURLException e)
    {
      return null;
    }
    return load(image, is9Patch, convert);
  }
  
  public static NinePatch load(BufferedImage image, boolean is9Patch, boolean convert)
  {
    if (!is9Patch)
    {
      if (convert) {
        image = convertTo9Patch(image);
      } else {
        return null;
      }
    }
    else {
      ensure9Patch(image);
    }
    return new NinePatch(image);
  }
  
  public int getWidth()
  {
    return mImage.getWidth();
  }
  
  public int getHeight()
  {
    return mImage.getHeight();
  }
  
  public boolean getPadding(int[] padding)
  {
    mChunk.getPadding(padding);
    return true;
  }
  
  public void draw(Graphics2D graphics2D, int x, int y, int scaledWidth, int scaledHeight)
  {
    mChunk.draw(mImage, graphics2D, x, y, scaledWidth, scaledHeight, 0, 0);
  }
  
  private NinePatch(BufferedImage image)
  {
    mChunk = NinePatchChunk.create(image);
    mImage = extractBitmapContent(image);
  }
  
  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 != -16777216)) {
        image.setRGB(i, 0, 0);
      }
      pixel = image.getRGB(i, height - 1);
      if ((pixel != 0) && (pixel != -16777216)) {
        image.setRGB(i, height - 1, 0);
      }
    }
    for (int i = 0; i < height; i++)
    {
      int pixel = image.getRGB(0, i);
      if ((pixel != 0) && (pixel != -16777216)) {
        image.setRGB(0, i, 0);
      }
      pixel = image.getRGB(width - 1, i);
      if ((pixel != 0) && (pixel != -16777216)) {
        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;
  }
  
  private BufferedImage extractBitmapContent(BufferedImage image)
  {
    return image.getSubimage(1, 1, image.getWidth() - 2, image.getHeight() - 2);
  }
}

/* Location:
 * Qualified Name:     com.android.ninepatch.NinePatch
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.ninepatch;

final class NinePatchChunk$DrawingData
{
  private int mRemainderHorizontal;
  private int mRemainderVertical;
  private float mHorizontalPatchesSum;
  private float mVerticalPatchesSum;
}

/* Location:
 * Qualified Name:     com.android.ninepatch.NinePatchChunk.DrawingData
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.ninepatch;

import java.io.Serializable;

class NinePatchChunk$Pair<E>
  implements Serializable
{
  private static final long serialVersionUID = -2204108979541762418L;
  E mFirst;
  E mSecond;
  
  NinePatchChunk$Pair(E first, E second)
  {
    mFirst = first;
    mSecond = second;
  }
  
  public String toString()
  {
    return "Pair[" + mFirst + ", " + mSecond + "]";
  }
}

/* Location:
 * Qualified Name:     com.android.ninepatch.NinePatchChunk.Pair
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.ninepatch;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class NinePatchChunk
  implements Serializable
{
  private static final long serialVersionUID = -7353439224505296217L;
  private static final int[] sPaddingRect = new int[4];
  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;
  
  public static NinePatchChunk create(BufferedImage image)
  {
    NinePatchChunk chunk = new NinePatchChunk();
    chunk.findPatches(image);
    return chunk;
  }
  
  public void draw(BufferedImage image, Graphics2D graphics2D, int x, int y, int scaledWidth, int scaledHeight, int destDensity, int srcDensity)
  {
    boolean scaling = (destDensity != srcDensity) && (destDensity != 0) && (srcDensity != 0);
    if (scaling) {
      try
      {
        graphics2D = (Graphics2D)graphics2D.create();
        
        float densityScale = destDensity / srcDensity;
        
        graphics2D.translate(x, y);
        graphics2D.scale(densityScale, densityScale);
        
        scaledWidth = (int)(scaledWidth / densityScale);
        scaledHeight = (int)(scaledHeight / densityScale);
        x = y = 0;
        
        draw(image, graphics2D, x, y, scaledWidth, scaledHeight);
      }
      finally
      {
        graphics2D.dispose();
      }
    } else {
      draw(image, graphics2D, x, y, scaledWidth, scaledHeight);
    }
  }
  
  private void draw(BufferedImage image, 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)
      {
        g.drawImage(image, x, y, scaledWidth, scaledHeight, null);
      }
      else
      {
        g.translate(x, y);
        x = y = 0;
        
        DrawingData data = computePatches(scaledWidth, scaledHeight);
        
        int fixedIndex = 0;
        int horizontalIndex = 0;
        int verticalIndex = 0;
        int patchIndex = 0;
        
        float vWeightSum = 1.0F;
        float vRemainder = mRemainderVertical;
        
        boolean vStretch = mVerticalStartWithPatch;
        while (y < scaledHeight - 1)
        {
          boolean hStretch = mHorizontalStartWithPatch;
          
          int height = 0;
          float vExtra = 0.0F;
          
          float hWeightSum = 1.0F;
          float hRemainder = mRemainderHorizontal;
          while (x < scaledWidth - 1)
          {
            if (!vStretch)
            {
              Rectangle r;
              if (hStretch)
              {
                Rectangle r = (Rectangle)mHorizontalPatches.get(horizontalIndex++);
                float extra = width / mHorizontalPatchesSum;
                int width = (int)(extra * hRemainder / hWeightSum);
                hWeightSum -= extra;
                hRemainder -= width;
                g.drawImage(image, x, y, x + width, y + height, x, y, x + width, y + height, null);
                
                x += width;
              }
              else
              {
                r = (Rectangle)mFixed.get(fixedIndex++);
                g.drawImage(image, x, y, x + width, y + height, x, y, x + width, y + height, null);
                
                x += width;
              }
              height = height;
            }
            else if (hStretch)
            {
              Rectangle r = (Rectangle)mPatches.get(patchIndex++);
              vExtra = height / mVerticalPatchesSum;
              height = (int)(vExtra * vRemainder / vWeightSum);
              float extra = width / mHorizontalPatchesSum;
              int width = (int)(extra * hRemainder / hWeightSum);
              hWeightSum -= extra;
              hRemainder -= width;
              g.drawImage(image, x, y, x + width, y + height, x, y, x + width, y + height, null);
              
              x += width;
            }
            else
            {
              Rectangle r = (Rectangle)mVerticalPatches.get(verticalIndex++);
              vExtra = height / mVerticalPatchesSum;
              height = (int)(vExtra * vRemainder / vWeightSum);
              g.drawImage(image, x, y, x + width, y + height, x, y, x + width, y + height, null);
              
              x += width;
            }
            hStretch = !hStretch;
          }
          x = 0;
          y += height;
          if (vStretch)
          {
            vWeightSum -= vExtra;
            vRemainder -= height;
          }
          vStretch = !vStretch;
        }
      }
    }
    finally
    {
      g.dispose();
    }
  }
  
  public void getPadding(int[] padding)
  {
    padding[0] = ((Integer)mHorizontalPadding.mFirst).intValue();
    padding[2] = ((Integer)mHorizontalPadding.mSecond).intValue();
    padding[1] = ((Integer)mVerticalPadding.mFirst).intValue();
    padding[3] = ((Integer)mVerticalPadding.mSecond).intValue();
  }
  
  public int[] getPadding()
  {
    getPadding(sPaddingRect);
    return sPaddingRect;
  }
  
  private DrawingData computePatches(int scaledWidth, int scaledHeight)
  {
    DrawingData data = new DrawingData();
    boolean measuredWidth = false;
    boolean endRow = true;
    
    int remainderHorizontal = 0;
    int remainderVertical = 0;
    int start;
    if (!mFixed.isEmpty())
    {
      start = mFixed.get(0)).y;
      for (Rectangle rect : mFixed)
      {
        if (y > start)
        {
          endRow = true;
          measuredWidth = true;
        }
        if (!measuredWidth) {
          remainderHorizontal += width;
        }
        if (endRow)
        {
          remainderVertical += height;
          endRow = false;
          start = y;
        }
      }
    }
    else
    {
      for (Rectangle rect : mVerticalPatches) {
        remainderHorizontal += width;
      }
      for (Rectangle rect : mHorizontalPatches) {
        remainderVertical += height;
      }
    }
    mRemainderHorizontal = (scaledWidth - remainderHorizontal);
    mRemainderVertical = (scaledHeight - remainderVertical);
    
    mHorizontalPatchesSum = 0.0F;
    int start;
    int start;
    if (mHorizontalPatches.size() > 0)
    {
      start = -1;
      for (Rectangle rect : mHorizontalPatches) {
        if (x > start)
        {
          DrawingData.access$216(data, width);
          start = x;
        }
      }
    }
    else
    {
      start = -1;
      for (Rectangle rect : mPatches) {
        if (x > start)
        {
          DrawingData.access$216(data, width);
          start = x;
        }
      }
    }
    mVerticalPatchesSum = 0.0F;
    int start;
    int start;
    if (mVerticalPatches.size() > 0)
    {
      start = -1;
      for (Rectangle rect : mVerticalPatches) {
        if (y > start)
        {
          DrawingData.access$316(data, height);
          start = y;
        }
      }
    }
    else
    {
      start = -1;
      for (Rectangle rect : mPatches) {
        if (y > start)
        {
          DrawingData.access$316(data, height);
          start = y;
        }
      }
    }
    return data;
  }
  
  private void findPatches(BufferedImage image)
  {
    int width = image.getWidth() - 2;
    int height = image.getHeight() - 2;
    
    int[] row = null;
    int[] column = null;
    
    row = GraphicsUtilities.getPixels(image, 1, 0, width, 1, row);
    column = GraphicsUtilities.getPixels(image, 0, 1, 1, height, column);
    
    boolean[] result = new boolean[1];
    Pair<List<Pair<Integer>>> left = getPatches(column, result);
    mVerticalStartWithPatch = result[0];
    
    result = new boolean[1];
    Pair<List<Pair<Integer>>> top = getPatches(row, result);
    mHorizontalStartWithPatch = result[0];
    
    mFixed = getRectangles((List)mFirst, (List)mFirst);
    mPatches = getRectangles((List)mSecond, (List)mSecond);
    if (mFixed.size() > 0)
    {
      mHorizontalPatches = getRectangles((List)mFirst, (List)mSecond);
      mVerticalPatches = getRectangles((List)mSecond, (List)mFirst);
    }
    else if (((List)mFirst).size() > 0)
    {
      mHorizontalPatches = new ArrayList(0);
      mVerticalPatches = getVerticalRectangles(height, (List)mFirst);
    }
    else if (((List)mFirst).size() > 0)
    {
      mHorizontalPatches = getHorizontalRectangles(width, (List)mFirst);
      mVerticalPatches = new ArrayList(0);
    }
    else
    {
      mHorizontalPatches = (mVerticalPatches = new ArrayList(0));
    }
    row = GraphicsUtilities.getPixels(image, 1, height + 1, width, 1, row);
    column = GraphicsUtilities.getPixels(image, width + 1, 1, 1, height, column);
    
    top = getPatches(row, result);
    mHorizontalPadding = getPadding((List)mFirst);
    
    left = getPatches(column, result);
    mVerticalPadding = getPadding((List)mFirst);
  }
  
  private List<Rectangle> getVerticalRectangles(int imageHeight, List<Pair<Integer>> topPairs)
  {
    List<Rectangle> rectangles = new ArrayList();
    for (Pair<Integer> top : topPairs)
    {
      int x = ((Integer)mFirst).intValue();
      int width = ((Integer)mSecond).intValue() - ((Integer)mFirst).intValue();
      
      rectangles.add(new Rectangle(x, 0, width, imageHeight));
    }
    return rectangles;
  }
  
  private List<Rectangle> getHorizontalRectangles(int imageWidth, List<Pair<Integer>> leftPairs)
  {
    List<Rectangle> rectangles = new ArrayList();
    for (Pair<Integer> left : leftPairs)
    {
      int y = ((Integer)mFirst).intValue();
      int height = ((Integer)mSecond).intValue() - ((Integer)mFirst).intValue();
      
      rectangles.add(new Rectangle(0, y, imageWidth, height));
    }
    return rectangles;
  }
  
  private Pair<Integer> getPadding(List<Pair<Integer>> pairs)
  {
    if (pairs.size() == 0) {
      return new Pair(Integer.valueOf(0), Integer.valueOf(0));
    }
    if (pairs.size() == 1)
    {
      if (((Integer)get0mFirst).intValue() == 0) {
        return new Pair(Integer.valueOf(((Integer)get0mSecond).intValue() - ((Integer)get0mFirst).intValue()), Integer.valueOf(0));
      }
      return new Pair(Integer.valueOf(0), Integer.valueOf(((Integer)get0mSecond).intValue() - ((Integer)get0mFirst).intValue()));
    }
    int index = pairs.size() - 1;
    return new Pair(Integer.valueOf(((Integer)get0mSecond).intValue() - ((Integer)get0mFirst).intValue()), Integer.valueOf(((Integer)getmSecond).intValue() - ((Integer)getmFirst).intValue()));
  }
  
  private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs, List<Pair<Integer>> topPairs)
  {
    List<Rectangle> rectangles = new ArrayList();
    for (Pair<Integer> left : leftPairs)
    {
      y = ((Integer)mFirst).intValue();
      height = ((Integer)mSecond).intValue() - ((Integer)mFirst).intValue();
      for (Pair<Integer> top : topPairs)
      {
        int x = ((Integer)mFirst).intValue();
        int width = ((Integer)mSecond).intValue() - ((Integer)mFirst).intValue();
        
        rectangles.add(new Rectangle(x, y, width, height));
      }
    }
    int y;
    int height;
    return rectangles;
  }
  
  private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch)
  {
    int lastIndex = 0;
    int lastPixel = pixels[0];
    boolean first = true;
    
    List<Pair<Integer>> fixed = new ArrayList();
    List<Pair<Integer>> patches = new ArrayList();
    for (int i = 0; i < pixels.length; i++)
    {
      int pixel = pixels[i];
      if (pixel != lastPixel)
      {
        if (lastPixel == -16777216)
        {
          if (first) {
            startWithPatch[0] = true;
          }
          patches.add(new Pair(Integer.valueOf(lastIndex), Integer.valueOf(i)));
        }
        else
        {
          fixed.add(new Pair(Integer.valueOf(lastIndex), Integer.valueOf(i)));
        }
        first = false;
        
        lastIndex = i;
        lastPixel = pixel;
      }
    }
    if (lastPixel == -16777216)
    {
      if (first) {
        startWithPatch[0] = true;
      }
      patches.add(new Pair(Integer.valueOf(lastIndex), Integer.valueOf(pixels.length)));
    }
    else
    {
      fixed.add(new Pair(Integer.valueOf(lastIndex), Integer.valueOf(pixels.length)));
    }
    if (patches.size() == 0)
    {
      patches.add(new Pair(Integer.valueOf(1), Integer.valueOf(pixels.length)));
      startWithPatch[0] = true;
      fixed.clear();
    }
    return new Pair(fixed, patches);
  }
  
  static class Pair<E>
    implements Serializable
  {
    private static final long serialVersionUID = -2204108979541762418L;
    E mFirst;
    E mSecond;
    
    Pair(E first, E second)
    {
      mFirst = first;
      mSecond = second;
    }
    
    public String toString()
    {
      return "Pair[" + mFirst + ", " + mSecond + "]";
    }
  }
  
  static final class DrawingData
  {
    private int mRemainderHorizontal;
    private int mRemainderVertical;
    private float mHorizontalPatchesSum;
    private float mVerticalPatchesSum;
  }
}

/* Location:
 * Qualified Name:     com.android.ninepatch.NinePatchChunk
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
1

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd