180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageView.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimator.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageDecoder.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMatrix.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSystemEventTypes.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTime.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkImageView::SkImageView()
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrix        = NULL;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fScaleType    = kMatrix_ScaleType;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fData.fAnim    = NULL;        // handles initializing the other union values
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fDataIsAnim    = true;
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fUriIsValid    = false;    // an empty string is not valid
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkImageView::~SkImageView()
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMatrix)
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        sk_free(fMatrix);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->freeData();
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::getUri(SkString* uri) const
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (uri)
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *uri = fUri;
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::setUri(const char uri[])
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!fUri.equals(uri))
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fUri.set(uri);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->onUriChange();
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::setUri(const SkString& uri)
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fUri != uri)
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fUri = uri;
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->onUriChange();
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::setScaleType(ScaleType st)
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)st <= kFitEnd_ScaleType);
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((ScaleType)fScaleType != st)
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fScaleType = SkToU8(st);
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fUriIsValid)
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->inval(NULL);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkImageView::getImageMatrix(SkMatrix* matrix) const
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMatrix)
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(!fMatrix->isIdentity());
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (matrix)
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *matrix = *fMatrix;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (matrix)
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            matrix->reset();
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::setImageMatrix(const SkMatrix* matrix)
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool changed = false;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (matrix && !matrix->isIdentity())
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fMatrix == NULL)
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *fMatrix = *matrix;
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        changed = true;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else    // set us to identity
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fMatrix)
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(!fMatrix->isIdentity());
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            sk_free(fMatrix);
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fMatrix = NULL;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            changed = true;
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // only redraw if we changed our matrix and we're not in scaleToFit mode
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->inval(NULL);
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////////////////////
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkImageView::onEvent(const SkEvent& evt)
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (evt.isType(SK_EventType_Inval))
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fUriIsValid)
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->inval(NULL);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return this->INHERITED::onEvent(evt);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(st != SkImageView::kMatrix_ScaleType);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (SkMatrix::ScaleToFit)(st - 1);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::onDraw(SkCanvas* canvas)
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect    src;
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!this->getDataBounds(&src))
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;        // nothing to draw
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoCanvasRestore    restore(canvas, true);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix            matrix;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this->getScaleType() == kMatrix_ScaleType)
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (void)this->getImageMatrix(&matrix);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRect    dst;
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst.set(0, 0, this->width(), this->height());
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->concat(matrix);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint    paint;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fDataIsAnim)
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMSec    now = SkTime::GetMSecs();
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (diff == SkAnimator::kDifferent)
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->inval(NULL);
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else if (diff == SkAnimator::kPartiallyDifferent)
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkRect    bounds;
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fData.fAnim->getInvalBounds(&bounds);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            matrix.mapRect(&bounds);    // get the bounds into view coordinates
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->inval(&bounds);
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::onInflate(dom, node);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* src = dom.findAttr(node, "src");
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (src)
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setUri(src);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int    index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (index >= 0)
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setScaleType((ScaleType)index);
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // need inflate syntax/reader for matrix
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////////////
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImageView::onUriChange()
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this->freeData())
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->inval(NULL);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fUriIsValid = true;        // give ensureUriIsLoaded() a shot at the new uri
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkImageView::freeData()
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fData.fAnim)    // test is valid for all union values
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fDataIsAnim)
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete fData.fAnim;
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete fData.fBitmap;
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData.fAnim = NULL;    // valid for all union values
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkImageView::getDataBounds(SkRect* bounds)
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(bounds);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this->ensureUriIsLoaded())
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar width, height;
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fDataIsAnim)
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            {
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // cons up fake bounds
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                width = this->width();
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                height = this->height();
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            width = SkIntToScalar(fData.fBitmap->width());
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            height = SkIntToScalar(fData.fBitmap->height());
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bounds->set(0, 0, width, height);
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkImageView::ensureUriIsLoaded()
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fData.fAnim)    // test is valid for all union values
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fUriIsValid);
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!fUriIsValid)
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // try to load the url
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fUri.endsWith(".xml"))    // assume it is screenplay
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimator* anim = new SkAnimator;
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!anim->decodeURI(fUri.c_str()))
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete anim;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fUriIsValid = false;
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        anim->setHostEventSink(this);
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData.fAnim = anim;
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDataIsAnim = true;
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else    // assume it is an image format
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #if 0
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkBitmap* bitmap = new SkBitmap;
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete bitmap;
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fUriIsValid = false;
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fData.fBitmap = bitmap;
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDataIsAnim = false;
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #else
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #endif
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
303