OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.ui.resources.statics; |
| 6 |
| 7 import android.graphics.Bitmap; |
| 8 import android.graphics.NinePatch; |
| 9 import android.graphics.Rect; |
| 10 |
| 11 import java.nio.BufferUnderflowException; |
| 12 import java.nio.ByteBuffer; |
| 13 import java.nio.ByteOrder; |
| 14 |
| 15 /** |
| 16 * A helper class to decode and expose relevant 9-patch data from a Bitmap. |
| 17 */ |
| 18 class NinePatchData { |
| 19 private final int mWidth; |
| 20 private final int mHeight; |
| 21 private final Rect mPadding; |
| 22 private final int[] mDivX; |
| 23 private final int[] mDivY; |
| 24 |
| 25 private Rect mAperture; |
| 26 |
| 27 /** |
| 28 * Creates a {@link NinePatchData} that stores 9-patch metadata. |
| 29 * @param width The width of the underlying bitmap. |
| 30 * @param height The height of the underlying bitmap. |
| 31 * @param padding The padding of the 9-patch for the content area. This pad
ding is a set of |
| 32 * insets (left = left padding, top = top padding, right = ri
ght padding, |
| 33 * bottom = bottom padding). |
| 34 * @param divX A run-length encoded list of stretch regions along the x d
imension. The |
| 35 * regions will go from 0 -> divX[0] - 1, divX[0] -> divX[1]
- 1, etc.. |
| 36 * @param divY A run-length encoded list of stretch regions along the y d
imension. The |
| 37 * regions will go from 0 -> divY[0] - 1, divY[0] -> divY[1]
- 1, etc.. |
| 38 */ |
| 39 private NinePatchData(int width, int height, Rect padding, int[] divX, int[]
divY) { |
| 40 mWidth = width; |
| 41 mHeight = height; |
| 42 mPadding = new Rect( |
| 43 padding.left, padding.top, mWidth - padding.right, mHeight - pad
ding.bottom); |
| 44 |
| 45 mDivX = new int[divX.length]; |
| 46 mDivY = new int[divY.length]; |
| 47 |
| 48 System.arraycopy(divX, 0, mDivX, 0, divX.length); |
| 49 System.arraycopy(divY, 0, mDivY, 0, divY.length); |
| 50 |
| 51 mAperture = new Rect(mDivX[0], mDivY[0], mDivX[1], mDivY[1]); |
| 52 } |
| 53 |
| 54 /** |
| 55 * @return The padded content area of this 9-patch. |
| 56 */ |
| 57 public Rect getPadding() { |
| 58 return mPadding; |
| 59 } |
| 60 |
| 61 /** |
| 62 * This class only exposes one 9-patch stretch region. |
| 63 * @return The aperture of this 9-patch. This specifies the center of the 9
-patch, with the |
| 64 * surrounding areas being stretchable. |
| 65 */ |
| 66 public Rect getAperture() { |
| 67 return mAperture; |
| 68 } |
| 69 |
| 70 /** |
| 71 * Attempts to decode 9-patch data from a {@link Bitmap}. |
| 72 * @param bitmap The {@link Bitmap} to check. |
| 73 * @return An instance of {@link NinePatchData} representing the 9-pat
ch information |
| 74 * encoded in {@code bitmap} or {@code null} if the {@link Bit
map} wasn't a |
| 75 * 9-patch. |
| 76 */ |
| 77 public static NinePatchData create(Bitmap bitmap) { |
| 78 if (bitmap == null) return null; |
| 79 |
| 80 try { |
| 81 byte[] chunk = bitmap.getNinePatchChunk(); |
| 82 if (chunk == null || !NinePatch.isNinePatchChunk(chunk)) return null
; |
| 83 |
| 84 ByteBuffer buffer = ByteBuffer.wrap(chunk).order(ByteOrder.nativeOrd
er()); |
| 85 |
| 86 // int8_t wasDeserialized |
| 87 if (buffer.get() == 0) return null; |
| 88 |
| 89 // int8_t numXDivs |
| 90 int numDivX = buffer.get(); |
| 91 if (numDivX == 0 || (numDivX & 0x01) != 0) return null; |
| 92 |
| 93 // int8_t numYDivs |
| 94 int numDivY = buffer.get(); |
| 95 if (numDivY == 0 || (numDivY & 0x01) != 0) return null; |
| 96 |
| 97 // int8_t numColors |
| 98 buffer.get(); |
| 99 |
| 100 // uint32_t xDivsOffset |
| 101 buffer.getInt(); |
| 102 |
| 103 // uint32_t yDivsOffset |
| 104 buffer.getInt(); |
| 105 |
| 106 Rect padding = new Rect(); |
| 107 |
| 108 // uint32_t paddingLeft |
| 109 padding.left = buffer.getInt(); |
| 110 |
| 111 // uint32_t paddingRight |
| 112 padding.right = buffer.getInt(); |
| 113 |
| 114 // uint32_t paddingTop |
| 115 padding.top = buffer.getInt(); |
| 116 |
| 117 // uint32_t paddingBottom |
| 118 padding.bottom = buffer.getInt(); |
| 119 |
| 120 // uint32_t colorsOffset |
| 121 buffer.getInt(); |
| 122 |
| 123 // uint32_t uint32_t uint32_t ... |
| 124 int[] divX = new int[numDivX]; |
| 125 for (int i = 0; i < numDivX; i++) divX[i] = buffer.getInt(); |
| 126 |
| 127 // uint32_t uint32_t uint32_t ... |
| 128 int[] divY = new int[numDivY]; |
| 129 for (int i = 0; i < numDivY; i++) divY[i] = buffer.getInt(); |
| 130 |
| 131 return new NinePatchData(bitmap.getWidth(), bitmap.getHeight(), padd
ing, divX, divY); |
| 132 } catch (BufferUnderflowException ex) { |
| 133 return null; |
| 134 } |
| 135 } |
| 136 } |
OLD | NEW |