1df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata/*
2df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Copyright (C) 2015 The Android Open Source Project
3df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
4df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Licensed under the Apache License, Version 2.0 (the "License");
5df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * you may not use this file except in compliance with the License.
6df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * You may obtain a copy of the License at
7df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
8df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *      http://www.apache.org/licenses/LICENSE-2.0
9df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
10df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Unless required by applicable law or agreed to in writing, software
11df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * distributed under the License is distributed on an "AS IS" BASIS,
12df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * See the License for the specific language governing permissions and
14df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * limitations under the License.
15df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */
16df64e524a2bad079e6b0aa2d22c287f2c62aed82susnatapackage android.support.v17.leanback.graphics;
17df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
18c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viveretteimport android.support.annotation.RequiresApi;
19df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Bitmap;
20df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Canvas;
21df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.ColorFilter;
223d9017263a760990ba79d5ebf3d1b6587e0bd311susnataimport android.graphics.Paint;
23df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.PixelFormat;
24df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Rect;
253d9017263a760990ba79d5ebf3d1b6587e0bd311susnataimport android.graphics.drawable.Drawable;
26e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.os.Build;
2700f780c9e3cca0b2e364c61e936147e09877c43fDake Guimport android.support.annotation.NonNull;
28e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.util.IntProperty;
29e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Guimport android.util.Property;
30df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
31df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata/**
323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Subclass of {@link Drawable} that can be used to draw a bitmap into a region. Bitmap
33df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * will be scaled to fit the full width of the region and will be aligned to the top left corner.
34df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Any region outside the bounds will be clipped during {@link #draw(Canvas)} call. Top
35e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * position of the bitmap can be controlled by {@link #setVerticalOffset(int)} call or
36e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * {@link #PROPERTY_VERTICAL_OFFSET}.
37df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */
383d9017263a760990ba79d5ebf3d1b6587e0bd311susnatapublic class FitWidthBitmapDrawable extends Drawable {
39df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
4000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    static class BitmapState extends Drawable.ConstantState {
4100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        Paint mPaint;
4200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        Bitmap mBitmap;
4300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        Rect mSource;
4400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final Rect mDefaultSource = new Rect();
4500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        int mOffset;
4600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
4700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        BitmapState() {
4800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mPaint = new Paint();
4900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
5000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
5100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        BitmapState(BitmapState other) {
5200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mBitmap = other.mBitmap;
5300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mPaint = new Paint(other.mPaint);
5400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mSource = other.mSource != null ? new Rect(other.mSource) : null;
5500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mDefaultSource.set(other.mDefaultSource);
5600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mOffset = other.mOffset;
5700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
5800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
5900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @NonNull
6000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @Override
6100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        public Drawable newDrawable() {
6200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return new FitWidthBitmapDrawable(this);
6300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
6400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
6500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @Override
6600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        public int getChangingConfigurations() {
6700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return 0;
6800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
6900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
7000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
7100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    final Rect mDest = new Rect();
7200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    BitmapState mBitmapState;
7300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    boolean mMutated = false;
7400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
75935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata    public FitWidthBitmapDrawable() {
7600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState = new BitmapState();
7700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
7800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
7900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    FitWidthBitmapDrawable(BitmapState state) {
8000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState = state;
8100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
8200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
8300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    @Override
8400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public ConstantState getConstantState() {
8500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mBitmapState;
8600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
8700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
8800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    @Override
8900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public Drawable mutate() {
9000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        if (!mMutated && super.mutate() == this) {
9100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mBitmapState = new BitmapState(mBitmapState);
9200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mMutated = true;
9300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
9400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return this;
95df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
96df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
97df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
98df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Sets the bitmap.
99df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
100df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setBitmap(Bitmap bitmap) {
10100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState.mBitmap = bitmap;
102935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata        if (bitmap != null) {
10300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mBitmapState.mDefaultSource.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
104935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata        } else {
10500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mBitmapState.mDefaultSource.set(0, 0, 0, 0);
106935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata        }
10700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState.mSource = null;
108df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
109df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
110df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
111df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Returns the bitmap.
112df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
113df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public Bitmap getBitmap() {
11400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mBitmapState.mBitmap;
115df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
116df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
117df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
118df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Sets the {@link Rect} used for extracting the bitmap.
119df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
120df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setSource(Rect source) {
12100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState.mSource = source;
122df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
123df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
124df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
125df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Returns the {@link Rect} used for extracting the bitmap.
126df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
127df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public Rect getSource() {
12800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mBitmapState.mSource;
129df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
130df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
131df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
132df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Sets the vertical offset which will be used for drawing the bitmap. The bitmap drawing
133df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * will start the provided vertical offset.
134e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu     * @see #PROPERTY_VERTICAL_OFFSET
135df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
136df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setVerticalOffset(int offset) {
13700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState.mOffset = offset;
138df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        invalidateSelf();
139df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
140df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
1413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    /**
1423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Returns the current vertical offset.
143e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu     * @see #PROPERTY_VERTICAL_OFFSET
1443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     */
1453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public int getVerticalOffset() {
14600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mBitmapState.mOffset;
1473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
1483d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
149df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
150df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void draw(Canvas canvas) {
15100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        if (mBitmapState.mBitmap != null) {
152935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            Rect bounds = getBounds();
153935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            mDest.left = 0;
15400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mDest.top = mBitmapState.mOffset;
155935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            mDest.right = bounds.width();
156935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata
157935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            Rect source = validateSource();
158935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            float scale = (float) bounds.width() / source.width();
159935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            mDest.bottom = mDest.top + (int) (source.height() * scale);
160935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            int i = canvas.save();
161935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            canvas.clipRect(bounds);
16200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            canvas.drawBitmap(mBitmapState.mBitmap, source, mDest, mBitmapState.mPaint);
163935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata            canvas.restoreToCount(i);
164935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata        }
165df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
166df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
167df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
168df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setAlpha(int alpha) {
16900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final int oldAlpha = mBitmapState.mPaint.getAlpha();
170df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        if (alpha != oldAlpha) {
17100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mBitmapState.mPaint.setAlpha(alpha);
172df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata            invalidateSelf();
173df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        }
174df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
175df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
17600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    /**
17700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu     * @return Alpha value between 0(inclusive) and 255(inclusive)
17800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu     */
179e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas    @Override
18000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public int getAlpha() {
18100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mBitmapState.mPaint.getAlpha();
18200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
18300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
184df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
185df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setColorFilter(ColorFilter colorFilter) {
18600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mBitmapState.mPaint.setColorFilter(colorFilter);
187df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        invalidateSelf();
188df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
189df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
190df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
191df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public int getOpacity() {
19200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final Bitmap bitmap = mBitmapState.mBitmap;
19300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return (bitmap == null || bitmap.hasAlpha() || mBitmapState.mPaint.getAlpha() < 255)
19400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
195df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
196df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
197935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata    private Rect validateSource() {
19800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        if (mBitmapState.mSource == null) {
19900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return mBitmapState.mDefaultSource;
200935b033edfd9d03129fce6a5b7a1d3a327b74f91susnata        } else {
20100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return mBitmapState.mSource;
202df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        }
203df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
204e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu
205e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    /**
206e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu     * Property for {@link #setVerticalOffset(int)} and {@link #getVerticalOffset()}.
207e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu     */
208e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    public static final Property<FitWidthBitmapDrawable, Integer> PROPERTY_VERTICAL_OFFSET;
209e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu
210e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    static {
211e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu        if (Build.VERSION.SDK_INT >= 24) {
212e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            // use IntProperty
213e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            PROPERTY_VERTICAL_OFFSET = getVerticalOffsetIntProperty();
214e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu        } else {
215e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            // use Property
216e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            PROPERTY_VERTICAL_OFFSET = new Property<FitWidthBitmapDrawable, Integer>(Integer.class,
217e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                    "verticalOffset") {
218e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas                @Override
219e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                public void set(FitWidthBitmapDrawable object, Integer value) {
220e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                    object.setVerticalOffset(value);
221e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                }
222e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu
223e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas                @Override
224e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                public Integer get(FitWidthBitmapDrawable object) {
225e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                    return object.getVerticalOffset();
226e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                }
227e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            };
228e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu        }
229e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    }
230e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu
231c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette    @RequiresApi(24)
232e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    static IntProperty<FitWidthBitmapDrawable> getVerticalOffsetIntProperty() {
233e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu        return new IntProperty<FitWidthBitmapDrawable>("verticalOffset") {
234e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas            @Override
235e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            public void setValue(FitWidthBitmapDrawable fitWidthBitmapDrawable, int value) {
236e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                fitWidthBitmapDrawable.setVerticalOffset(value);
237e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            }
238e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu
239e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            @Override
240e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            public Integer get(FitWidthBitmapDrawable fitWidthBitmapDrawable) {
241e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu                return fitWidthBitmapDrawable.getVerticalOffset();
242e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu            }
243e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu        };
244e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu    }
245df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata}
246