gfx/skia/trunk/src/core/SkBitmap_scroll.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkBitmap_scroll.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,105 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2011 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +#include "SkBitmap.h"
    1.12 +#include "SkRegion.h"
    1.13 +
    1.14 +bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy,
    1.15 +                          SkRegion* inval) const
    1.16 +{
    1.17 +    if (this->isImmutable() || kUnknown_SkColorType == this->colorType()) {
    1.18 +        return false;
    1.19 +    }
    1.20 +
    1.21 +    if (NULL != subset) {
    1.22 +        SkBitmap tmp;
    1.23 +
    1.24 +        return  this->extractSubset(&tmp, *subset) &&
    1.25 +                // now call again with no rectangle
    1.26 +                tmp.scrollRect(NULL, dx, dy, inval);
    1.27 +    }
    1.28 +
    1.29 +    int shift = this->bytesPerPixel() >> 1;
    1.30 +    int width = this->width();
    1.31 +    int height = this->height();
    1.32 +
    1.33 +    // check if there's nothing to do
    1.34 +    if ((dx | dy) == 0 || width <= 0 || height <= 0) {
    1.35 +        if (NULL != inval) {
    1.36 +            inval->setEmpty();
    1.37 +        }
    1.38 +        return true;
    1.39 +    }
    1.40 +
    1.41 +    // compute the inval region now, before we see if there are any pixels
    1.42 +    if (NULL != inval) {
    1.43 +        SkIRect r;
    1.44 +
    1.45 +        r.set(0, 0, width, height);
    1.46 +        // initial the region with the entire bounds
    1.47 +        inval->setRect(r);
    1.48 +        // do the "scroll"
    1.49 +        r.offset(dx, dy);
    1.50 +
    1.51 +        // check if we scrolled completely away
    1.52 +        if (!SkIRect::Intersects(r, inval->getBounds())) {
    1.53 +            // inval has already been updated...
    1.54 +            return true;
    1.55 +        }
    1.56 +
    1.57 +        // compute the dirty area
    1.58 +        inval->op(r, SkRegion::kDifference_Op);
    1.59 +    }
    1.60 +
    1.61 +    SkAutoLockPixels    alp(*this);
    1.62 +    // if we have no pixels, just return (inval is already updated)
    1.63 +    // don't call readyToDraw(), since we don't require a colortable per se
    1.64 +    if (this->getPixels() == NULL) {
    1.65 +        return true;
    1.66 +    }
    1.67 +
    1.68 +    char*       dst = (char*)this->getPixels();
    1.69 +    const char* src = dst;
    1.70 +    int         rowBytes = (int)this->rowBytes();    // need rowBytes to be signed
    1.71 +
    1.72 +    if (dy <= 0) {
    1.73 +        src -= dy * rowBytes;
    1.74 +        height += dy;
    1.75 +    } else {
    1.76 +        dst += dy * rowBytes;
    1.77 +        height -= dy;
    1.78 +        // now jump src/dst to the last scanline
    1.79 +        src += (height - 1) * rowBytes;
    1.80 +        dst += (height - 1) * rowBytes;
    1.81 +        // now invert rowbytes so we copy backwards in the loop
    1.82 +        rowBytes = -rowBytes;
    1.83 +    }
    1.84 +
    1.85 +    if (dx <= 0) {
    1.86 +        src -= dx << shift;
    1.87 +        width += dx;
    1.88 +    } else {
    1.89 +        dst += dx << shift;
    1.90 +        width -= dx;
    1.91 +    }
    1.92 +
    1.93 +    // If the X-translation would push it completely beyond the region,
    1.94 +    // then there's nothing to draw.
    1.95 +    if (width <= 0) {
    1.96 +        return true;
    1.97 +    }
    1.98 +
    1.99 +    width <<= shift;    // now width is the number of bytes to move per line
   1.100 +    while (--height >= 0) {
   1.101 +        memmove(dst, src, width);
   1.102 +        dst += rowBytes;
   1.103 +        src += rowBytes;
   1.104 +    }
   1.105 +
   1.106 +    this->notifyPixelsChanged();
   1.107 +    return true;
   1.108 +}

mercurial