1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageView.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimator.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSystemEventTypes.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageView::SkImageView()
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    fMatrix        = nullptr;
20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fScaleType    = kMatrix_ScaleType;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    fData.fAnim    = nullptr;        // handles initializing the other union values
23d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fDataIsAnim    = true;
24d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
25d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fUriIsValid    = false;    // an empty string is not valid
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkImageView::~SkImageView()
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fMatrix)
31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        sk_free(fMatrix);
32d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->freeData();
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::getUri(SkString* uri) const
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
38d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (uri)
39d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *uri = fUri;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::setUri(const char uri[])
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
44d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (!fUri.equals(uri))
45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
46d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fUri.set(uri);
47d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->onUriChange();
48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::setUri(const SkString& uri)
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fUri != uri)
54d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fUri = uri;
56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->onUriChange();
57d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::setScaleType(ScaleType st)
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT((unsigned)st <= kFitEnd_ScaleType);
63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
64d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((ScaleType)fScaleType != st)
65d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fScaleType = SkToU8(st);
67d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fUriIsValid)
682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            this->inval(nullptr);
69d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageView::getImageMatrix(SkMatrix* matrix) const
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fMatrix)
75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
76d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkASSERT(!fMatrix->isIdentity());
77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (matrix)
78d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            *matrix = *fMatrix;
79d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return true;
80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
81d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else
82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
83d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (matrix)
84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            matrix->reset();
85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return false;
86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::setImageMatrix(const SkMatrix* matrix)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    bool changed = false;
92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
93d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (matrix && !matrix->isIdentity())
94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        if (fMatrix == nullptr)
96d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
97d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *fMatrix = *matrix;
98d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        changed = true;
99d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else    // set us to identity
101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
102d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fMatrix)
103d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkASSERT(!fMatrix->isIdentity());
105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            sk_free(fMatrix);
1062880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            fMatrix = nullptr;
107d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            changed = true;
108d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
109d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
110d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
111d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // only redraw if we changed our matrix and we're not in scaleToFit mode
112d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
1132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        this->inval(nullptr);
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////////////////
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageView::onEvent(const SkEvent& evt)
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
120d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (evt.isType(SK_EventType_Inval))
121d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
122d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fUriIsValid)
1232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            this->inval(nullptr);
124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return true;
125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
126d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return this->INHERITED::onEvent(evt);
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
131d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(st != SkImageView::kMatrix_ScaleType);
132d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);
133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
135d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
137d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
138d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return (SkMatrix::ScaleToFit)(st - 1);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::onDraw(SkCanvas* canvas)
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
144d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkRect    src;
145d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (!this->getDataBounds(&src))
146d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
147d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
148d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return;        // nothing to draw
149d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
150d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
151d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkAutoCanvasRestore    restore(canvas, true);
152d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkMatrix            matrix;
153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
154d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (this->getScaleType() == kMatrix_ScaleType)
155d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        (void)this->getImageMatrix(&matrix);
156d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else
157d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
158d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkRect    dst;
159d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        dst.set(0, 0, this->width(), this->height());
160d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
161d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    canvas->concat(matrix);
163d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
164d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkPaint    paint;
165d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
166d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    paint.setAntiAlias(true);
167d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
168d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDataIsAnim)
169d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
170d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkMSec    now = SkTime::GetMSecs();
171d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
172d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
176d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (diff == SkAnimator::kDifferent)
1772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            this->inval(nullptr);
178d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        else if (diff == SkAnimator::kPartiallyDifferent)
179d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
180d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkRect    bounds;
181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fData.fAnim->getInvalBounds(&bounds);
182d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            matrix.mapRect(&bounds);    // get the bounds into view coordinates
183d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            this->inval(&bounds);
184d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
185d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
186d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else
187d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
192d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->INHERITED::onInflate(dom, node);
193d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
194d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    const char* src = dom.findAttr(node, "src");
195d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (src)
196d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setUri(src);
197d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
198d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    int    index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
199d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (index >= 0)
200d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setScaleType((ScaleType)index);
201d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
202d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // need inflate syntax/reader for matrix
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkImageView::onUriChange()
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
209d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (this->freeData())
2102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        this->inval(nullptr);
211d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fUriIsValid = true;        // give ensureUriIsLoaded() a shot at the new uri
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageView::freeData()
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
216d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fData.fAnim)    // test is valid for all union values
217d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
218d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fDataIsAnim)
219d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            delete fData.fAnim;
220d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        else
221d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            delete fData.fBitmap;
222d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        fData.fAnim = nullptr;    // valid for all union values
224d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return true;
225d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
226d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return false;
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageView::getDataBounds(SkRect* bounds)
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(bounds);
232d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
233d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (this->ensureUriIsLoaded())
234d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
235d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkScalar width, height;
236d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
237d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fDataIsAnim)
238d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
239d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
240d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
241d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            {
242d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                // cons up fake bounds
243d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                width = this->width();
244d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                height = this->height();
245d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            }
246d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
247d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        else
248d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
249d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            width = SkIntToScalar(fData.fBitmap->width());
250d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            height = SkIntToScalar(fData.fBitmap->height());
251d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
252d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        bounds->set(0, 0, width, height);
253d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return true;
254d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
255d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return false;
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkImageView::ensureUriIsLoaded()
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
260d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fData.fAnim)    // test is valid for all union values
261d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
262d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkASSERT(fUriIsValid);
263d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return true;
264d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
265d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (!fUriIsValid)
266d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return false;
267d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
268d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // try to load the url
269d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fUri.endsWith(".xml"))    // assume it is screenplay
270d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
271d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkAnimator* anim = new SkAnimator;
272d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
273d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (!anim->decodeURI(fUri.c_str()))
274d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
275d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            delete anim;
276d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fUriIsValid = false;
277d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            return false;
278d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
279d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        anim->setHostEventSink(this);
280d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
281d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fData.fAnim = anim;
282d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fDataIsAnim = true;
283d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
284d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else    // assume it is an image format
285d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    #if 0
287d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkBitmap* bitmap = new SkBitmap;
288d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
289d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
290d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        {
291d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            delete bitmap;
292d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            fUriIsValid = false;
293d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            return false;
294d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
295d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fData.fBitmap = bitmap;
296d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fDataIsAnim = false;
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    #else
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false;
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    #endif
300d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
301d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return true;
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
303