LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkDeviceLooper.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 37 65 56.9 %
Date: 2017-07-14 16:53:18 Functions: 5 7 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "SkDeviceLooper.h"
       9             : 
      10         213 : SkDeviceLooper::SkDeviceLooper(const SkPixmap& base, const SkRasterClip& rc, const SkIRect& bounds,
      11         213 :                                bool aa)
      12             :     : fBaseDst(base)
      13             :     , fBaseRC(rc)
      14         213 :     , fDelta(aa ? kAA_Delta : kBW_Delta)
      15             : {
      16             :     // sentinels that next() has not yet been called, and so our mapper functions
      17             :     // should not be called either.
      18         213 :     fCurrDst = nullptr;
      19         213 :     fCurrRC = nullptr;
      20             : 
      21         213 :     if (!rc.isEmpty()) {
      22             :         // clip must be contained by the bitmap
      23         213 :         SkASSERT(SkIRect::MakeWH(base.width(), base.height()).contains(rc.getBounds()));
      24             :     }
      25             : 
      26         213 :     if (rc.isEmpty() || !fClippedBounds.intersect(bounds, rc.getBounds())) {
      27           0 :         fState = kDone_State;
      28         213 :     } else if (this->fitsInDelta(fClippedBounds)) {
      29         213 :         fState = kSimple_State;
      30             :     } else {
      31             :         // back up by 1 DX, so that next() will put us in a correct starting
      32             :         // position.
      33           0 :         fCurrOffset.set(fClippedBounds.left() - fDelta,
      34           0 :                         fClippedBounds.top());
      35           0 :         fState = kComplex_State;
      36             :     }
      37         213 : }
      38             : 
      39         213 : SkDeviceLooper::~SkDeviceLooper() {}
      40             : 
      41         213 : void SkDeviceLooper::mapRect(SkRect* dst, const SkRect& src) const {
      42         213 :     SkASSERT(kDone_State != fState);
      43         213 :     SkASSERT(fCurrDst);
      44         213 :     SkASSERT(fCurrRC);
      45             : 
      46         213 :     *dst = src;
      47         213 :     dst->offset(SkIntToScalar(-fCurrOffset.fX),
      48         426 :                 SkIntToScalar(-fCurrOffset.fY));
      49         213 : }
      50             : 
      51         213 : void SkDeviceLooper::mapMatrix(SkMatrix* dst, const SkMatrix& src) const {
      52         213 :     SkASSERT(kDone_State != fState);
      53         213 :     SkASSERT(fCurrDst);
      54         213 :     SkASSERT(fCurrRC);
      55             : 
      56         213 :     *dst = src;
      57         213 :     dst->postTranslate(SkIntToScalar(-fCurrOffset.fX), SkIntToScalar(-fCurrOffset.fY));
      58         213 : }
      59             : 
      60           0 : bool SkDeviceLooper::computeCurrBitmapAndClip() {
      61           0 :     SkASSERT(kComplex_State == fState);
      62             : 
      63             :     SkIRect r = SkIRect::MakeXYWH(fCurrOffset.x(), fCurrOffset.y(),
      64           0 :                                   fDelta, fDelta);
      65           0 :     if (!fBaseDst.extractSubset(&fSubsetDst, r)) {
      66           0 :         fSubsetRC.setEmpty();
      67             :     } else {
      68           0 :         fBaseRC.translate(-r.left(), -r.top(), &fSubsetRC);
      69           0 :         (void)fSubsetRC.op(SkIRect::MakeWH(fDelta, fDelta), SkRegion::kIntersect_Op);
      70             :     }
      71             : 
      72           0 :     fCurrDst = &fSubsetDst;
      73           0 :     fCurrRC = &fSubsetRC;
      74           0 :     return !fCurrRC->isEmpty();
      75             : }
      76             : 
      77           0 : static bool next_tile(const SkIRect& boundary, int delta, SkIPoint* offset) {
      78             :     // can we move to the right?
      79           0 :     if (offset->x() + delta < boundary.right()) {
      80           0 :         offset->fX += delta;
      81           0 :         return true;
      82             :     }
      83             : 
      84             :     // reset to the left, but move down a row
      85           0 :     offset->fX = boundary.left();
      86           0 :     if (offset->y() + delta < boundary.bottom()) {
      87           0 :         offset->fY += delta;
      88           0 :         return true;
      89             :     }
      90             : 
      91             :     // offset is now outside of boundary, so we're done
      92           0 :     return false;
      93             : }
      94             : 
      95         426 : bool SkDeviceLooper::next() {
      96         426 :     switch (fState) {
      97             :         case kDone_State:
      98             :             // in theory, we should not get called here, since we must have
      99             :             // previously returned false, but we check anyway.
     100           0 :             break;
     101             : 
     102             :         case kSimple_State:
     103             :             // first time for simple
     104         426 :             if (nullptr == fCurrDst) {
     105         213 :                 fCurrDst = &fBaseDst;
     106         213 :                 fCurrRC = &fBaseRC;
     107         213 :                 fCurrOffset.set(0, 0);
     108         213 :                 return true;
     109             :             }
     110             :             // 2nd time for simple, we are done
     111         213 :             break;
     112             : 
     113             :         case kComplex_State:
     114             :             // need to propogate fCurrOffset through clippedbounds
     115             :             // left to right, until we wrap around and move down
     116             : 
     117           0 :             while (next_tile(fClippedBounds, fDelta, &fCurrOffset)) {
     118           0 :                 if (this->computeCurrBitmapAndClip()) {
     119           0 :                     return true;
     120             :                 }
     121             :             }
     122           0 :             break;
     123             :     }
     124         213 :     fState = kDone_State;
     125         213 :     return false;
     126             : }

Generated by: LCOV version 1.13