Home | History | Annotate | Download | only in core
      1 /* libs/graphics/sgl/SkBlitBWMaskTemplate.h
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "SkBitmap.h"
     19 #include "SkMask.h"
     20 
     21 #ifndef ClearLow3Bits_DEFINED
     22 #define ClearLow3Bits_DEFINED
     23     #define ClearLow3Bits(x)    ((unsigned)(x) >> 3 << 3)
     24 #endif
     25 
     26 /*
     27     SK_BLITBWMASK_NAME          name of function(const SkBitmap& bitmap, const SkMask& mask, const SkIRect& clip, SK_BLITBWMASK_ARGS)
     28     SK_BLITBWMASK_ARGS          list of additional arguments to SK_BLITBWMASK_NAME, beginning with a comma
     29     SK_BLITBWMASK_BLIT8         name of function(U8CPU byteMask, SK_BLITBWMASK_DEVTYPE* dst, int x, int y)
     30     SK_BLITBWMASK_GETADDR       either getAddr32 or getAddr16 or getAddr8
     31     SK_BLITBWMASK_DEVTYPE       either U32 or U16 or U8
     32 */
     33 
     34 static void SK_BLITBWMASK_NAME(const SkBitmap& bitmap, const SkMask& srcMask, const SkIRect& clip SK_BLITBWMASK_ARGS)
     35 {
     36     SkASSERT(clip.fRight <= srcMask.fBounds.fRight);
     37 
     38     int cx = clip.fLeft;
     39     int cy = clip.fTop;
     40     int maskLeft = srcMask.fBounds.fLeft;
     41     unsigned mask_rowBytes = srcMask.fRowBytes;
     42     unsigned bitmap_rowBytes = bitmap.rowBytes();
     43     unsigned height = clip.height();
     44 
     45     SkASSERT(mask_rowBytes != 0);
     46     SkASSERT(bitmap_rowBytes != 0);
     47     SkASSERT(height != 0);
     48 
     49     const uint8_t* bits = srcMask.getAddr1(cx, cy);
     50     SK_BLITBWMASK_DEVTYPE* device = bitmap.SK_BLITBWMASK_GETADDR(cx, cy);
     51 
     52     if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight)
     53     {
     54         do {
     55             SK_BLITBWMASK_DEVTYPE* dst = device;
     56             unsigned rb = mask_rowBytes;
     57             do {
     58                 U8CPU mask = *bits++;
     59                 SK_BLITBWMASK_BLIT8(mask, dst);
     60                 dst += 8;
     61             } while (--rb != 0);
     62             device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes);
     63         } while (--height != 0);
     64     }
     65     else
     66     {
     67         int left_edge = cx - maskLeft;
     68         SkASSERT(left_edge >= 0);
     69         int rite_edge = clip.fRight - maskLeft;
     70         SkASSERT(rite_edge > left_edge);
     71 
     72         int left_mask = 0xFF >> (left_edge & 7);
     73         int rite_mask = 0xFF << (8 - (rite_edge & 7));
     74         int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
     75 
     76         // check for empty right mask, so we don't read off the end (or go slower than we need to)
     77         if (rite_mask == 0)
     78         {
     79             SkASSERT(full_runs >= 0);
     80             full_runs -= 1;
     81             rite_mask = 0xFF;
     82         }
     83         if (left_mask == 0xFF)
     84             full_runs -= 1;
     85 
     86         // back up manually so we can keep in sync with our byte-aligned src
     87         // and not trigger an assert from the getAddr## function
     88         device -= left_edge & 7;
     89         // have cx reflect our actual starting x-coord
     90         cx -= left_edge & 7;
     91 
     92         if (full_runs < 0)
     93         {
     94             left_mask &= rite_mask;
     95             SkASSERT(left_mask != 0);
     96             do {
     97                 U8CPU mask = *bits & left_mask;
     98                 SK_BLITBWMASK_BLIT8(mask, device);
     99                 bits += mask_rowBytes;
    100                 device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes);
    101             } while (--height != 0);
    102         }
    103         else
    104         {
    105             do {
    106                 int runs = full_runs;
    107                 SK_BLITBWMASK_DEVTYPE* dst = device;
    108                 const uint8_t* b = bits;
    109                 U8CPU   mask;
    110 
    111                 mask = *b++ & left_mask;
    112                 SK_BLITBWMASK_BLIT8(mask, dst);
    113                 dst += 8;
    114 
    115                 while (--runs >= 0)
    116                 {
    117                     mask = *b++;
    118                     SK_BLITBWMASK_BLIT8(mask, dst);
    119                     dst += 8;
    120                 }
    121 
    122                 mask = *b & rite_mask;
    123                 SK_BLITBWMASK_BLIT8(mask, dst);
    124 
    125                 bits += mask_rowBytes;
    126                 device = (SK_BLITBWMASK_DEVTYPE*)((char*)device + bitmap_rowBytes);
    127             } while (--height != 0);
    128         }
    129     }
    130 }
    131 
    132 #undef SK_BLITBWMASK_NAME
    133 #undef SK_BLITBWMASK_ARGS
    134 #undef SK_BLITBWMASK_BLIT8
    135 #undef SK_BLITBWMASK_GETADDR
    136 #undef SK_BLITBWMASK_DEVTYPE
    137 #undef SK_BLITBWMASK_DOROWSETUP
    138