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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2011 Google Inc.
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8 #include "SkBitmap.h"
michael@0 9 #include "SkRegion.h"
michael@0 10
michael@0 11 bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy,
michael@0 12 SkRegion* inval) const
michael@0 13 {
michael@0 14 if (this->isImmutable() || kUnknown_SkColorType == this->colorType()) {
michael@0 15 return false;
michael@0 16 }
michael@0 17
michael@0 18 if (NULL != subset) {
michael@0 19 SkBitmap tmp;
michael@0 20
michael@0 21 return this->extractSubset(&tmp, *subset) &&
michael@0 22 // now call again with no rectangle
michael@0 23 tmp.scrollRect(NULL, dx, dy, inval);
michael@0 24 }
michael@0 25
michael@0 26 int shift = this->bytesPerPixel() >> 1;
michael@0 27 int width = this->width();
michael@0 28 int height = this->height();
michael@0 29
michael@0 30 // check if there's nothing to do
michael@0 31 if ((dx | dy) == 0 || width <= 0 || height <= 0) {
michael@0 32 if (NULL != inval) {
michael@0 33 inval->setEmpty();
michael@0 34 }
michael@0 35 return true;
michael@0 36 }
michael@0 37
michael@0 38 // compute the inval region now, before we see if there are any pixels
michael@0 39 if (NULL != inval) {
michael@0 40 SkIRect r;
michael@0 41
michael@0 42 r.set(0, 0, width, height);
michael@0 43 // initial the region with the entire bounds
michael@0 44 inval->setRect(r);
michael@0 45 // do the "scroll"
michael@0 46 r.offset(dx, dy);
michael@0 47
michael@0 48 // check if we scrolled completely away
michael@0 49 if (!SkIRect::Intersects(r, inval->getBounds())) {
michael@0 50 // inval has already been updated...
michael@0 51 return true;
michael@0 52 }
michael@0 53
michael@0 54 // compute the dirty area
michael@0 55 inval->op(r, SkRegion::kDifference_Op);
michael@0 56 }
michael@0 57
michael@0 58 SkAutoLockPixels alp(*this);
michael@0 59 // if we have no pixels, just return (inval is already updated)
michael@0 60 // don't call readyToDraw(), since we don't require a colortable per se
michael@0 61 if (this->getPixels() == NULL) {
michael@0 62 return true;
michael@0 63 }
michael@0 64
michael@0 65 char* dst = (char*)this->getPixels();
michael@0 66 const char* src = dst;
michael@0 67 int rowBytes = (int)this->rowBytes(); // need rowBytes to be signed
michael@0 68
michael@0 69 if (dy <= 0) {
michael@0 70 src -= dy * rowBytes;
michael@0 71 height += dy;
michael@0 72 } else {
michael@0 73 dst += dy * rowBytes;
michael@0 74 height -= dy;
michael@0 75 // now jump src/dst to the last scanline
michael@0 76 src += (height - 1) * rowBytes;
michael@0 77 dst += (height - 1) * rowBytes;
michael@0 78 // now invert rowbytes so we copy backwards in the loop
michael@0 79 rowBytes = -rowBytes;
michael@0 80 }
michael@0 81
michael@0 82 if (dx <= 0) {
michael@0 83 src -= dx << shift;
michael@0 84 width += dx;
michael@0 85 } else {
michael@0 86 dst += dx << shift;
michael@0 87 width -= dx;
michael@0 88 }
michael@0 89
michael@0 90 // If the X-translation would push it completely beyond the region,
michael@0 91 // then there's nothing to draw.
michael@0 92 if (width <= 0) {
michael@0 93 return true;
michael@0 94 }
michael@0 95
michael@0 96 width <<= shift; // now width is the number of bytes to move per line
michael@0 97 while (--height >= 0) {
michael@0 98 memmove(dst, src, width);
michael@0 99 dst += rowBytes;
michael@0 100 src += rowBytes;
michael@0 101 }
michael@0 102
michael@0 103 this->notifyPixelsChanged();
michael@0 104 return true;
michael@0 105 }

mercurial