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