1 2/* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#include "SkBitmap.h" 11#include "SkMask.h" 12 13#ifndef ClearLow3Bits_DEFINED 14#define ClearLow3Bits_DEFINED 15 #define ClearLow3Bits(x) ((unsigned)(x) >> 3 << 3) 16#endif 17 18/* 19 SK_BLITBWMASK_NAME name of function(const SkBitmap& bitmap, const SkMask& mask, const SkIRect& clip, SK_BLITBWMASK_ARGS) 20 SK_BLITBWMASK_ARGS list of additional arguments to SK_BLITBWMASK_NAME, beginning with a comma 21 SK_BLITBWMASK_BLIT8 name of function(U8CPU byteMask, SK_BLITBWMASK_DEVTYPE* dst, int x, int y) 22 SK_BLITBWMASK_GETADDR either getAddr32 or getAddr16 or getAddr8 23 SK_BLITBWMASK_DEVTYPE either U32 or U16 or U8 24*/ 25 26static void SK_BLITBWMASK_NAME(const SkBitmap& bitmap, const SkMask& srcMask, const SkIRect& clip SK_BLITBWMASK_ARGS) 27{ 28 SkASSERT(clip.fRight <= srcMask.fBounds.fRight); 29 30 int cx = clip.fLeft; 31 int cy = clip.fTop; 32 int maskLeft = srcMask.fBounds.fLeft; 33 unsigned mask_rowBytes = srcMask.fRowBytes; 34 unsigned bitmap_rowBytes = bitmap.rowBytes(); 35 unsigned height = clip.height(); 36 37 SkASSERT(mask_rowBytes != 0); 38 SkASSERT(bitmap_rowBytes != 0); 39 SkASSERT(height != 0); 40 41 const uint8_t* bits = srcMask.getAddr1(cx, cy); 42 SK_BLITBWMASK_DEVTYPE* device = bitmap.SK_BLITBWMASK_GETADDR(cx, cy); 43 44 if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight) 45 { 46 do { 47 SK_BLITBWMASK_DEVTYPE* dst = device; 48 unsigned rb = mask_rowBytes; 49 do { 50 U8CPU mask = *bits++; 51 SK_BLITBWMASK_BLIT8(mask, dst); 52 dst += 8; 53 } while (--rb != 0); 54 device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 55 } while (--height != 0); 56 } 57 else 58 { 59 int left_edge = cx - maskLeft; 60 SkASSERT(left_edge >= 0); 61 int rite_edge = clip.fRight - maskLeft; 62 SkASSERT(rite_edge > left_edge); 63 64 int left_mask = 0xFF >> (left_edge & 7); 65 int rite_mask = 0xFF << (8 - (rite_edge & 7)); 66 int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 67 68 // check for empty right mask, so we don't read off the end (or go slower than we need to) 69 if (rite_mask == 0) 70 { 71 SkASSERT(full_runs >= 0); 72 full_runs -= 1; 73 rite_mask = 0xFF; 74 } 75 if (left_mask == 0xFF) 76 full_runs -= 1; 77 78 // back up manually so we can keep in sync with our byte-aligned src 79 // and not trigger an assert from the getAddr## function 80 device -= left_edge & 7; 81 // have cx reflect our actual starting x-coord 82 cx -= left_edge & 7; 83 84 if (full_runs < 0) 85 { 86 left_mask &= rite_mask; 87 SkASSERT(left_mask != 0); 88 do { 89 U8CPU mask = *bits & left_mask; 90 SK_BLITBWMASK_BLIT8(mask, device); 91 bits += mask_rowBytes; 92 device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 93 } while (--height != 0); 94 } 95 else 96 { 97 do { 98 int runs = full_runs; 99 SK_BLITBWMASK_DEVTYPE* dst = device; 100 const uint8_t* b = bits; 101 U8CPU mask; 102 103 mask = *b++ & left_mask; 104 SK_BLITBWMASK_BLIT8(mask, dst); 105 dst += 8; 106 107 while (--runs >= 0) 108 { 109 mask = *b++; 110 SK_BLITBWMASK_BLIT8(mask, dst); 111 dst += 8; 112 } 113 114 mask = *b & rite_mask; 115 SK_BLITBWMASK_BLIT8(mask, dst); 116 117 bits += mask_rowBytes; 118 device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 119 } while (--height != 0); 120 } 121 } 122} 123 124#undef SK_BLITBWMASK_NAME 125#undef SK_BLITBWMASK_ARGS 126#undef SK_BLITBWMASK_BLIT8 127#undef SK_BLITBWMASK_GETADDR 128#undef SK_BLITBWMASK_DEVTYPE 129#undef SK_BLITBWMASK_DOROWSETUP 130