| Index: src/core/SkBlitter.cpp
|
| diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
|
| index 1bc9963eeb0db1a1d5007d812c77affe0f61807c..064dc16eda4fd98f4ed9de1f821ab2ec67a0567c 100644
|
| --- a/src/core/SkBlitter.cpp
|
| +++ b/src/core/SkBlitter.cpp
|
| @@ -83,18 +83,18 @@ void SkBlitter::blitAntiRect(int x, int y, int width, int height,
|
|
|
| static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
|
| const uint8_t bits[],
|
| - U8CPU left_mask, int rowBytes,
|
| - U8CPU right_mask) {
|
| + uint8_t left_mask, ptrdiff_t rowBytes,
|
| + uint8_t right_mask) {
|
| int inFill = 0;
|
| int pos = 0;
|
|
|
| while (--rowBytes >= 0) {
|
| - unsigned b = *bits++ & left_mask;
|
| + uint8_t b = *bits++ & left_mask;
|
| if (rowBytes == 0) {
|
| b &= right_mask;
|
| }
|
|
|
| - for (unsigned test = 0x80; test != 0; test >>= 1) {
|
| + for (uint8_t test = 0x80U; test != 0; test >>= 1) {
|
| if (b & test) {
|
| if (!inFill) {
|
| pos = x;
|
| @@ -108,7 +108,7 @@ static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
|
| }
|
| x += 1;
|
| }
|
| - left_mask = 0xFF;
|
| + left_mask = 0xFFU;
|
| }
|
|
|
| // final cleanup
|
| @@ -117,6 +117,11 @@ static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
|
| }
|
| }
|
|
|
| +// maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8.
|
| +static uint8_t generate_right_mask(int maskBitCount) {
|
| + return static_cast<uint8_t>(0xFF00U >> maskBitCount);
|
| +}
|
| +
|
| void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
|
| SkASSERT(mask.fBounds.contains(clip));
|
|
|
| @@ -124,54 +129,55 @@ void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
|
| int cx = clip.fLeft;
|
| int cy = clip.fTop;
|
| int maskLeft = mask.fBounds.fLeft;
|
| - int mask_rowBytes = mask.fRowBytes;
|
| + int maskRowBytes = mask.fRowBytes;
|
| int height = clip.height();
|
|
|
| const uint8_t* bits = mask.getAddr1(cx, cy);
|
|
|
| + SkDEBUGCODE(const uint8_t* endOfImage =
|
| + mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes
|
| + + ((mask.fBounds.width() + 7) >> 3));
|
| +
|
| if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
|
| while (--height >= 0) {
|
| - bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
|
| - bits += mask_rowBytes;
|
| + int affectedRightBit = mask.fBounds.width() - 1;
|
| + ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1;
|
| + SkASSERT(bits + rowBytes <= endOfImage);
|
| + U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
|
| + bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask);
|
| + bits += maskRowBytes;
|
| cy += 1;
|
| }
|
| } else {
|
| - int left_edge = cx - maskLeft;
|
| - SkASSERT(left_edge >= 0);
|
| - int rite_edge = clip.fRight - maskLeft;
|
| - SkASSERT(rite_edge > left_edge);
|
| -
|
| - int left_mask = 0xFF >> (left_edge & 7);
|
| - int rite_mask = 0xFF << (8 - (rite_edge & 7));
|
| - int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
|
| -
|
| - // check for empty right mask, so we don't read off the end (or go slower than we need to)
|
| - if (rite_mask == 0) {
|
| - SkASSERT(full_runs >= 0);
|
| - full_runs -= 1;
|
| - rite_mask = 0xFF;
|
| - }
|
| - if (left_mask == 0xFF) {
|
| - full_runs -= 1;
|
| - }
|
| -
|
| - // back up manually so we can keep in sync with our byte-aligned src
|
| - // have cx reflect our actual starting x-coord
|
| - cx -= left_edge & 7;
|
| + // Bits is calculated as the offset into the mask at the point {cx, cy} therfore, all
|
| + // addressing into the bit mask is relative to that point. Since this is an address
|
| + // calculated from a arbitrary bit in that byte, calculate the left most bit.
|
| + int bitsLeft = cx - ((cx - maskLeft) & 7);
|
| +
|
| + // Everything is relative to the bitsLeft.
|
| + int leftEdge = cx - bitsLeft;
|
| + SkASSERT(leftEdge >= 0);
|
| + int rightEdge = clip.fRight - bitsLeft;
|
| + SkASSERT(rightEdge > leftEdge);
|
| +
|
| + // Calculate left byte and mask
|
| + const uint8_t* leftByte = bits;
|
| + U8CPU leftMask = 0xFFU >> (leftEdge & 7);
|
| +
|
| + // Calculate right byte and mask
|
| + int affectedRightBit = rightEdge - 1;
|
| + const uint8_t* rightByte = bits + (affectedRightBit >> 3);
|
| + U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
|
| +
|
| + // leftByte and rightByte are byte locations therefore, to get a count of bytes the
|
| + // code must add one.
|
| + ptrdiff_t rowBytes = rightByte - leftByte + 1;
|
|
|
| - if (full_runs < 0) {
|
| - SkASSERT((left_mask & rite_mask) != 0);
|
| - while (--height >= 0) {
|
| - bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
|
| - bits += mask_rowBytes;
|
| - cy += 1;
|
| - }
|
| - } else {
|
| - while (--height >= 0) {
|
| - bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
|
| - bits += mask_rowBytes;
|
| - cy += 1;
|
| - }
|
| + while (--height >= 0) {
|
| + SkASSERT(bits + rowBytes <= endOfImage);
|
| + bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask);
|
| + bits += maskRowBytes;
|
| + cy += 1;
|
| }
|
| }
|
| } else {
|
|
|