180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMask.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef ClearLow3Bits_DEFINED 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define ClearLow3Bits_DEFINED 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define ClearLow3Bits(x) ((unsigned)(x) >> 3 << 3) 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_NAME name of function(const SkBitmap& bitmap, const SkMask& mask, const SkIRect& clip, SK_BLITBWMASK_ARGS) 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_ARGS list of additional arguments to SK_BLITBWMASK_NAME, beginning with a comma 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8 name of function(U8CPU byteMask, SK_BLITBWMASK_DEVTYPE* dst, int x, int y) 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_GETADDR either getAddr32 or getAddr16 or getAddr8 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_DEVTYPE either U32 or U16 or U8 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void SK_BLITBWMASK_NAME(const SkBitmap& bitmap, const SkMask& srcMask, const SkIRect& clip SK_BLITBWMASK_ARGS) 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(clip.fRight <= srcMask.fBounds.fRight); 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int cx = clip.fLeft; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int cy = clip.fTop; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int maskLeft = srcMask.fBounds.fLeft; 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned mask_rowBytes = srcMask.fRowBytes; 34096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger size_t bitmap_rowBytes = bitmap.rowBytes(); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned height = clip.height(); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(mask_rowBytes != 0); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(bitmap_rowBytes != 0); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(height != 0); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* bits = srcMask.getAddr1(cx, cy); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_DEVTYPE* device = bitmap.SK_BLITBWMASK_GETADDR(cx, cy); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight) 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_DEVTYPE* dst = device; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned rb = mask_rowBytes; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU mask = *bits++; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8(mask, dst); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 8; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--rb != 0); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--height != 0); 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left_edge = cx - maskLeft; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(left_edge >= 0); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rite_edge = clip.fRight - maskLeft; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(rite_edge > left_edge); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left_mask = 0xFF >> (left_edge & 7); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rite_mask = 0xFF << (8 - (rite_edge & 7)); 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rite_mask &= 0xFF; // only want low-8 bits of mask 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check for empty right mask, so we don't read off the end (or go slower than we need to) 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (rite_mask == 0) 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(full_runs >= 0); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru full_runs -= 1; 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rite_mask = 0xFF; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (left_mask == 0xFF) 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru full_runs -= 1; 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // back up manually so we can keep in sync with our byte-aligned src 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // and not trigger an assert from the getAddr## function 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru device -= left_edge & 7; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (full_runs < 0) 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left_mask &= rite_mask; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(left_mask != 0); 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU mask = *bits & left_mask; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8(mask, device); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits += mask_rowBytes; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--height != 0); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int runs = full_runs; 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_DEVTYPE* dst = device; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* b = bits; 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU mask; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask = *b++ & left_mask; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8(mask, dst); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 8; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (--runs >= 0) 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask = *b++; 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8(mask, dst); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 8; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask = *b & rite_mask; 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_BLITBWMASK_BLIT8(mask, dst); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits += mask_rowBytes; 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--height != 0); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_NAME 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_ARGS 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_BLIT8 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_GETADDR 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_DEVTYPE 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#undef SK_BLITBWMASK_DOROWSETUP 129