1 /*
2  * Copyright 2009 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 "SkColorPriv.h"
10 
11 /*
12     Filter_32_opaque
13 
14     There is no hard-n-fast rule that the filtering must produce
15     exact results for the color components, but if the 4 incoming colors are
16     all opaque, then the output color must also be opaque. Subsequent parts of
17     the drawing pipeline may rely on this (e.g. which blitrow proc to use).
18  */
19 
Filter_32_opaque(unsigned x,unsigned y,SkPMColor a00,SkPMColor a01,SkPMColor a10,SkPMColor a11,SkPMColor * dstColor)20 static inline void Filter_32_opaque(unsigned x, unsigned y,
21                                     SkPMColor a00, SkPMColor a01,
22                                     SkPMColor a10, SkPMColor a11,
23                                     SkPMColor* dstColor) {
24     SkASSERT((unsigned)x <= 0xF);
25     SkASSERT((unsigned)y <= 0xF);
26 
27     int xy = x * y;
28     const uint32_t mask = 0xFF00FF;
29 
30     int scale = 256 - 16*y - 16*x + xy;
31     uint32_t lo = (a00 & mask) * scale;
32     uint32_t hi = ((a00 >> 8) & mask) * scale;
33 
34     scale = 16*x - xy;
35     lo += (a01 & mask) * scale;
36     hi += ((a01 >> 8) & mask) * scale;
37 
38     scale = 16*y - xy;
39     lo += (a10 & mask) * scale;
40     hi += ((a10 >> 8) & mask) * scale;
41 
42     lo += (a11 & mask) * xy;
43     hi += ((a11 >> 8) & mask) * xy;
44 
45     *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
46 }
47 
Filter_32_alpha(unsigned x,unsigned y,SkPMColor a00,SkPMColor a01,SkPMColor a10,SkPMColor a11,SkPMColor * dstColor,unsigned alphaScale)48 static inline void Filter_32_alpha(unsigned x, unsigned y,
49                                    SkPMColor a00, SkPMColor a01,
50                                    SkPMColor a10, SkPMColor a11,
51                                    SkPMColor* dstColor,
52                                    unsigned alphaScale) {
53     SkASSERT((unsigned)x <= 0xF);
54     SkASSERT((unsigned)y <= 0xF);
55     SkASSERT(alphaScale <= 256);
56 
57     int xy = x * y;
58     const uint32_t mask = 0xFF00FF;
59 
60     int scale = 256 - 16*y - 16*x + xy;
61     uint32_t lo = (a00 & mask) * scale;
62     uint32_t hi = ((a00 >> 8) & mask) * scale;
63 
64     scale = 16*x - xy;
65     lo += (a01 & mask) * scale;
66     hi += ((a01 >> 8) & mask) * scale;
67 
68     scale = 16*y - xy;
69     lo += (a10 & mask) * scale;
70     hi += ((a10 >> 8) & mask) * scale;
71 
72     lo += (a11 & mask) * xy;
73     hi += ((a11 >> 8) & mask) * xy;
74 
75     lo = ((lo >> 8) & mask) * alphaScale;
76     hi = ((hi >> 8) & mask) * alphaScale;
77 
78     *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
79 }
80 
81 // Two color version, where we filter only along 1 axis
Filter_32_opaque(unsigned t,SkPMColor color0,SkPMColor color1,SkPMColor * dstColor)82 static inline void Filter_32_opaque(unsigned t,
83                                     SkPMColor color0,
84                                     SkPMColor color1,
85                                     SkPMColor* dstColor) {
86     SkASSERT((unsigned)t <= 0xF);
87 
88     const uint32_t mask = 0xFF00FF;
89 
90     int scale = 256 - 16*t;
91     uint32_t lo = (color0 & mask) * scale;
92     uint32_t hi = ((color0 >> 8) & mask) * scale;
93 
94     scale = 16*t;
95     lo += (color1 & mask) * scale;
96     hi += ((color1 >> 8) & mask) * scale;
97 
98     *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
99 }
100 
101 // Two color version, where we filter only along 1 axis
Filter_32_alpha(unsigned t,SkPMColor color0,SkPMColor color1,SkPMColor * dstColor,unsigned alphaScale)102 static inline void Filter_32_alpha(unsigned t,
103                                    SkPMColor color0,
104                                    SkPMColor color1,
105                                    SkPMColor* dstColor,
106                                    unsigned alphaScale) {
107     SkASSERT((unsigned)t <= 0xF);
108     SkASSERT(alphaScale <= 256);
109 
110     const uint32_t mask = 0xFF00FF;
111 
112     int scale = 256 - 16*t;
113     uint32_t lo = (color0 & mask) * scale;
114     uint32_t hi = ((color0 >> 8) & mask) * scale;
115 
116     scale = 16*t;
117     lo += (color1 & mask) * scale;
118     hi += ((color1 >> 8) & mask) * scale;
119 
120     lo = ((lo >> 8) & mask) * alphaScale;
121     hi = ((hi >> 8) & mask) * alphaScale;
122 
123     *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
124 }
125