| Index: ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java
|
| diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..13b8179bd640c2cb77f73c289c399d14b5fabf75
|
| --- /dev/null
|
| +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java
|
| @@ -0,0 +1,164 @@
|
| +// Copyright 2014 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.dynamics;
|
| +
|
| +import android.graphics.Bitmap;
|
| +import android.graphics.Canvas;
|
| +import android.graphics.Rect;
|
| +import android.view.View;
|
| +import android.view.View.OnLayoutChangeListener;
|
| +
|
| +import org.chromium.base.TraceEvent;
|
| +
|
| +/**
|
| + * An adapter that exposes a {@link View} as a {@link DynamicResource}. In order to properly use
|
| + * this adapter {@link ViewResourceAdapter#invalidate(Rect)} must be called when parts of the
|
| + * {@link View} are invalidated. For {@link ViewGroup}s the easiest way to do this is to override
|
| + * {@link View#invalidateChildInParent(int[], Rect)}.
|
| + */
|
| +public class ViewResourceAdapter implements DynamicResource, OnLayoutChangeListener {
|
| + private final View mView;
|
| + private final Rect mDirtyRect = new Rect();
|
| + private final Rect mContentPadding = new Rect();
|
| + private final Rect mContentAperture = new Rect();
|
| +
|
| + private Bitmap mBitmap;
|
| + private Rect mBitmapSize = new Rect();
|
| +
|
| + /**
|
| + * Builds a {@link ViewResourceAdapter} instance around {@code view}.
|
| + * @param view The {@link View} to expose as a {@link Resource}.
|
| + */
|
| + public ViewResourceAdapter(View view) {
|
| + mView = view;
|
| + mView.addOnLayoutChangeListener(this);
|
| + }
|
| +
|
| + /**
|
| + * If this resource is not dirty ({@link #isDirty()} returned {@code false}), this will return
|
| + * the last {@link Bitmap} built from the {@link View}. Otherwise it will recapture a
|
| + * {@link Bitmap} of the {@link View}.
|
| + * @see {@link DynamicResource#getBitmap()}.
|
| + * @return A {@link Bitmap} representing the {@link View}.
|
| + */
|
| + @Override
|
| + public Bitmap getBitmap() {
|
| + if (!isDirty()) return mBitmap;
|
| + TraceEvent.begin("ViewResourceAdapter:getBitmap");
|
| + validateBitmap();
|
| +
|
| + Canvas canvas = new Canvas(mBitmap);
|
| +
|
| + onCaptureStart(canvas, mDirtyRect.isEmpty() ? null : mDirtyRect);
|
| +
|
| + if (!mDirtyRect.isEmpty()) canvas.clipRect(mDirtyRect);
|
| + mView.draw(canvas);
|
| +
|
| + onCaptureEnd();
|
| +
|
| + mDirtyRect.setEmpty();
|
| + TraceEvent.end("ViewResourceAdapter:getBitmap");
|
| + return mBitmap;
|
| + }
|
| +
|
| + @Override
|
| + public Rect getBitmapSize() {
|
| + return mBitmapSize;
|
| + }
|
| +
|
| + @Override
|
| + public Rect getPadding() {
|
| + computeContentPadding(mContentPadding);
|
| +
|
| + return mContentPadding;
|
| + }
|
| +
|
| + @Override
|
| + public Rect getAperture() {
|
| + computeContentAperture(mContentAperture);
|
| +
|
| + return mContentAperture;
|
| + }
|
| +
|
| + @Override
|
| + public boolean isDirty() {
|
| + if (mBitmap == null) mDirtyRect.set(0, 0, mView.getWidth(), mView.getHeight());
|
| +
|
| + return !mDirtyRect.isEmpty();
|
| + }
|
| +
|
| + @Override
|
| + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
| + int oldTop, int oldRight, int oldBottom) {
|
| + final int width = right - left;
|
| + final int height = bottom - top;
|
| + final int oldWidth = oldRight - oldLeft;
|
| + final int oldHeight = oldBottom - oldTop;
|
| +
|
| + if (width != oldWidth || height != oldHeight) mDirtyRect.set(0, 0, width, height);
|
| + }
|
| +
|
| + /**
|
| + * Invalidates a particular region of the {@link View} that needs to be repainted.
|
| + * @param dirtyRect The region to invalidate, or {@code null} if the entire {@code Bitmap}
|
| + * should be redrawn.
|
| + */
|
| + public void invalidate(Rect dirtyRect) {
|
| + if (dirtyRect == null) {
|
| + mDirtyRect.set(0, 0, mView.getWidth(), mView.getHeight());
|
| + } else {
|
| + mDirtyRect.union(dirtyRect);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Called before {@link View#draw(Canvas)} is called.
|
| + * @param canvas The {@link Canvas} that will be drawn to.
|
| + * @param dirtyRect The dirty {@link Rect} or {@code null} if the entire area is being redrawn.
|
| + */
|
| + protected void onCaptureStart(Canvas canvas, Rect dirtyRect) {
|
| + }
|
| +
|
| + /**
|
| + * Called after {@link View#draw(Canvas)}.
|
| + */
|
| + protected void onCaptureEnd() {
|
| + }
|
| +
|
| + /**
|
| + * Gives overriding classes the chance to specify a different content padding.
|
| + * @param outContentPadding The resulting content padding.
|
| + */
|
| + protected void computeContentPadding(Rect outContentPadding) {
|
| + outContentPadding.set(0, 0, mView.getWidth(), mView.getHeight());
|
| + }
|
| +
|
| + /**
|
| + * Gives overriding classes the chance to specify a different content aperture.
|
| + * @param outContentAperture The resulting content aperture.
|
| + */
|
| + protected void computeContentAperture(Rect outContentAperture) {
|
| + outContentAperture.set(0, 0, mView.getWidth(), mView.getHeight());
|
| + }
|
| +
|
| + private void validateBitmap() {
|
| + if (mBitmap != null
|
| + && (mBitmap.getWidth() != mView.getWidth()
|
| + || mBitmap.getHeight() != mView.getHeight())) {
|
| + mBitmap.recycle();
|
| + mBitmap = null;
|
| + }
|
| +
|
| + if (mView.getWidth() == 0 || mView.getHeight() == 0) return;
|
| +
|
| + if (mBitmap == null) {
|
| + mBitmap = Bitmap.createBitmap(
|
| + mView.getWidth(), mView.getHeight(), Bitmap.Config.ARGB_8888);
|
| + mBitmap.setHasAlpha(true);
|
| + mDirtyRect.set(0, 0, mView.getWidth(), mView.getHeight());
|
| + mBitmapSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
|
| + }
|
| + }
|
| +}
|
|
|