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