• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SK_BLITBWMASK_NAME(const SkBitmap & bitmap,const SkMask & srcMask,const SkIRect & clip SK_BLITBWMASK_ARGS)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