11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmap.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMask.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef ClearLow3Bits_DEFINED 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define ClearLow3Bits_DEFINED 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #define ClearLow3Bits(x) ((unsigned)(x) >> 3 << 3) 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_NAME name of function(const SkBitmap& bitmap, const SkMask& mask, const SkIRect& clip, SK_BLITBWMASK_ARGS) 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_ARGS list of additional arguments to SK_BLITBWMASK_NAME, beginning with a comma 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8 name of function(U8CPU byteMask, SK_BLITBWMASK_DEVTYPE* dst, int x, int y) 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_GETADDR either getAddr32 or getAddr16 or getAddr8 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_DEVTYPE either U32 or U16 or U8 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void SK_BLITBWMASK_NAME(const SkBitmap& bitmap, const SkMask& srcMask, const SkIRect& clip SK_BLITBWMASK_ARGS) 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(clip.fRight <= srcMask.fBounds.fRight); 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int cx = clip.fLeft; 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int cy = clip.fTop; 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int maskLeft = srcMask.fBounds.fLeft; 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned mask_rowBytes = srcMask.fRowBytes; 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned bitmap_rowBytes = bitmap.rowBytes(); 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned height = clip.height(); 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(mask_rowBytes != 0); 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(bitmap_rowBytes != 0); 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(height != 0); 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint8_t* bits = srcMask.getAddr1(cx, cy); 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_DEVTYPE* device = bitmap.SK_BLITBWMASK_GETADDR(cx, cy); 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight) 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_DEVTYPE* dst = device; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned rb = mask_rowBytes; 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project U8CPU mask = *bits++; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8(mask, dst); 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst += 8; 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--rb != 0); 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left_edge = cx - maskLeft; 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left_edge >= 0); 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite_edge = clip.fRight - maskLeft; 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(rite_edge > left_edge); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left_mask = 0xFF >> (left_edge & 7); 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite_mask = 0xFF << (8 - (rite_edge & 7)); 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // check for empty right mask, so we don't read off the end (or go slower than we need to) 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (rite_mask == 0) 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(full_runs >= 0); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project full_runs -= 1; 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite_mask = 0xFF; 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left_mask == 0xFF) 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project full_runs -= 1; 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // back up manually so we can keep in sync with our byte-aligned src 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // and not trigger an assert from the getAddr## function 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project device -= left_edge & 7; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // have cx reflect our actual starting x-coord 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project cx -= left_edge & 7; 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (full_runs < 0) 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left_mask &= rite_mask; 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left_mask != 0); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project U8CPU mask = *bits & left_mask; 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8(mask, device); 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits += mask_rowBytes; 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int runs = full_runs; 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_DEVTYPE* dst = device; 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint8_t* b = bits; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project U8CPU mask; 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mask = *b++ & left_mask; 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8(mask, dst); 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst += 8; 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (--runs >= 0) 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mask = *b++; 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8(mask, dst); 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst += 8; 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mask = *b & rite_mask; 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_BLITBWMASK_BLIT8(mask, dst); 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits += mask_rowBytes; 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes); 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (--height != 0); 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_NAME 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_ARGS 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_BLIT8 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_GETADDR 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_DEVTYPE 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#undef SK_BLITBWMASK_DOROWSETUP 130