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