Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Unified Diff: ui/android/java/src/org/chromium/ui/resources/sprites/CrushedSpriteResource.java

Issue 1337703002: [Contextual Search] Add support for crushed sprites and animate the search provider icon (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add TODO's for other planned tests Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/android/java/src/org/chromium/ui/resources/sprites/CrushedSpriteResource.java
diff --git a/ui/android/java/src/org/chromium/ui/resources/sprites/CrushedSpriteResource.java b/ui/android/java/src/org/chromium/ui/resources/sprites/CrushedSpriteResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5b3061bd20f4f59bb72fc8b7131da06732857fe
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/resources/sprites/CrushedSpriteResource.java
@@ -0,0 +1,242 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.ui.resources.sprites;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Rect;
+import android.util.JsonReader;
+
+import org.chromium.ui.resources.Resource;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+/**
+ * A {@link Resource} that provides an unscaled {@link Bitmap} and corresponding metadata for a
+ * crushed sprite. A crushed sprite animation is run by drawing rectangles from a bitmap to a
+ * canvas. Each frame in the animation draws its rectangles on top of the previous frame.
+ *
+ * TODO(twellington): Add an Instrumentation test for this class.
+ */
+public class CrushedSpriteResource implements Resource {
+ private static final Rect EMPTY_RECT = new Rect();
+
+ private Bitmap mBitmap;
+ private final Rect mBitmapSize = new Rect();
+ private int mSpriteSize;
+ private int[][] mRectangles;
+
+ /**
+ * @param bitmapResId The id of the bitmap resource.
+ * @param metadataResId The id of the raw resource containing JSON metadata.
+ * @param resources A {@link Resources} instance to load assets from.
+ */
+ public CrushedSpriteResource(int bitmapResId, int metadataResId, Resources resources) {
David Trainor- moved to gerrit 2015/10/15 21:04:57 Add trace events around the bitmap and json loadin
Theresa 2015/10/24 00:06:45 Done.
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScaled = false;
+ mBitmap = BitmapFactory.decodeResource(resources, bitmapResId, opts);
+
+ if (mBitmap != null) {
+ mBitmapSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ try {
+ parseMetadata(metadataResId, opts.inDensity, resources);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Convenience method for use in reloading an unscaled {@link Bitmap} without recreating the
+ * entire resource.
+ * @param bitmapResId The id of the bitmap resource for this crushed sprite.
+ * @param resources A {@link Resources} instance to load assets from.
+ */
+ public static Bitmap loadBitmap(int bitmapResId, Resources resources) {
David Trainor- moved to gerrit 2015/10/15 21:04:57 If we still need this, can the constructor use thi
Theresa 2015/10/24 00:06:45 Done.
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScaled = false;
+ return BitmapFactory.decodeResource(resources, bitmapResId, opts);
+ }
+
+ @Override
+ public Bitmap getBitmap() {
+ return mBitmap;
+ }
+
+ @Override
+ public Rect getBitmapSize() {
+ return mBitmapSize;
+ }
+
+ @Override
+ public Rect getPadding() {
+ return EMPTY_RECT;
+ }
+
+ @Override
+ public Rect getAperture() {
+ return EMPTY_RECT;
+ }
+
+ /**
+ * @return The unscaled size of an individual sprite in px.
+ */
+ public int getSpriteSize() {
+ return mSpriteSize;
+ }
+
+ /**
+ * Each sprite frame is represented by a set of rectangles. Most frames consist of small
+ * rectangles representing the change from the previous frame. Each rectangle is represented
+ * using six consecutive values that specify the values to be used when creating the destination
+ * and source rectangles that get painted:
+ * 0: destination x 1: destination y 2: source x 3: source y 4: width 5: height
+ *
+ * @return The unscaled rectangles that need to be painted for each sprite frame in px.
+ */
+ public int[][] getFrameRectangles() {
+ return mRectangles.clone();
+ }
+
+ /**
+ * Parses the raw JSON resource specified by {@code metadataResId}. The JSON is expected to be
+ * in this format:
+ * {
+ * "version": <version number>,
+ * "densities":
+ * [
+ * {
+ * "density": <density number>,
+ * "size": <unscaled sprite size>,
+ * "rectangles": [
+ * [<list of ints for frame 0>],
+ * [<list of ints for frame 1>],
+ * ......
+ * ]
+ * },
+ * {
+ * "density": <density number>,
+ * "size": <unscaled sprite size>,
+ * "rectangles": [
+ * [<list of ints for frame 0>],
+ * [<list of ints for frame 1>],
+ * ......
+ * ]
+ * },
+ * ......
+ * ]
+ * }
+ *
+ * @param metadataResId The id of the raw resource containing JSON to parse.
+ * @param bitmapDensity The density of the unscaled {@link Bitmap} that was loaded.
+ * @param resources A {@link Resources} instance to load assets from.
+ * @throws IOException
+ */
+ private void parseMetadata(int metadataResId, int bitmapDensity, Resources resources)
+ throws IOException {
+ InputStream inputStream = resources.openRawResource(metadataResId);
+ JsonReader reader = new JsonReader(new InputStreamReader(inputStream));
+ try {
+ reader.beginObject(); // Start reading top-level object.
+
+ // Consume version.
+ String name = reader.nextName();
+ assert name.equals("version");
+ reader.nextDouble();
+
+ // Parse array of densities.
+ name = reader.nextName();
+ assert name.equals("densities");
+ reader.beginArray(); // Start reading array of densities.
+ while (reader.hasNext()) {
+ reader.beginObject(); // Start reading object for this density.
+ boolean foundDensity = parseMetadataForDensity(reader, bitmapDensity);
+ reader.endObject(); // Stop reading object for this density.
+
+ if (foundDensity) break;
+ }
+ } finally {
+ reader.close();
+ inputStream.close();
+ }
+ }
+
+ /**
+ * Reads a JSON object for a specific density and populates variables if the density matches
+ * {@code bitmapDensity}.
+ *
+ * @param reader The JsonReader reading the JSON metadata.
+ * @param bitmapDensity The density of the unscaled {@link Bitmap} that was loaded.
+ * @return True if the JSON object being parsed corresponds to bitmapDensity.
+ * @throws IOException
+ */
+ private boolean parseMetadataForDensity(JsonReader reader, int bitmapDensity)
+ throws IOException {
+ String name = reader.nextName();
+ assert name.equals("density");
+ int density = reader.nextInt();
+
+ // If this is metadata for a density other than bitmapDensity, skip parsing the rest of the
+ // object.
+ if (density != bitmapDensity) {
+ reader.skipValue(); // Skip size name.
+ reader.skipValue(); // Skip size value.
+ reader.skipValue(); // Skip rectangles name.
+ reader.skipValue(); // Skip rectangles array.
+ return false;
+ }
+
+ name = reader.nextName();
+ assert name.equals("size");
+ mSpriteSize = reader.nextInt();
+
+ name = reader.nextName();
+ assert name.equals("rectangles");
+
+ parseFrameRectangles(reader);
+
+ return true;
+ }
+
+
+ /**
+ * Parses the 2D JSONArray of frame rectangles and populates {@code mRectangles}.
+ * @param reader The JsonReader reading the JSON metadata.
+ * @throws IOException
+ */
+ private void parseFrameRectangles(JsonReader reader) throws IOException {
+ ArrayList<ArrayList<Integer>> allFrameRectangles = new ArrayList<ArrayList<Integer>>();
+ int frameCount = 0;
+
+ reader.beginArray(); // Start reading 2D rectangles array.
+ while (reader.hasNext()) {
+ ArrayList<Integer> frameRectangles = new ArrayList<Integer>();
+ reader.beginArray(); // Start reading frame array.
+ while (reader.hasNext()) {
+ frameRectangles.add(reader.nextInt());
+ }
+ reader.endArray(); // Stop reading frame array.
+ allFrameRectangles.add(frameRectangles);
+ frameCount++;
+ }
+ reader.endArray(); // Stop reading 2D rectangles array.
+
+ // Convert 2D ArrayList to int[][].
+ mRectangles = new int[frameCount][];
+ for (int i = 0; i < frameCount; i++) {
+ ArrayList<Integer> frameRectangles = allFrameRectangles.get(i);
+ int[] frameRectanglesArray = new int[frameRectangles.size()];
+ for (int j = 0; j < frameRectangles.size(); j++) {
+ frameRectanglesArray[j] = frameRectangles.get(j);
+ }
+ mRectangles[i] = frameRectanglesArray;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698