1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2009 The Android Open Source Project
4152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com */
8152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com#include "SkColorPriv.h"
11152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
12879a252d090a0929c11d8963dbd4328b11d0916freed@android.com/*
13879a252d090a0929c11d8963dbd4328b11d0916freed@android.com    Filter_32_opaque
14fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
15879a252d090a0929c11d8963dbd4328b11d0916freed@android.com    There is no hard-n-fast rule that the filtering must produce
16879a252d090a0929c11d8963dbd4328b11d0916freed@android.com    exact results for the color components, but if the 4 incoming colors are
17879a252d090a0929c11d8963dbd4328b11d0916freed@android.com    all opaque, then the output color must also be opaque. Subsequent parts of
18879a252d090a0929c11d8963dbd4328b11d0916freed@android.com    the drawing pipeline may rely on this (e.g. which blitrow proc to use).
19879a252d090a0929c11d8963dbd4328b11d0916freed@android.com */
20879a252d090a0929c11d8963dbd4328b11d0916freed@android.com
213ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.comstatic inline void Filter_32_opaque(unsigned x, unsigned y,
22152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com                                    SkPMColor a00, SkPMColor a01,
23152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com                                    SkPMColor a10, SkPMColor a11,
243ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.com                                    SkPMColor* dstColor) {
25152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    SkASSERT((unsigned)x <= 0xF);
26152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    SkASSERT((unsigned)y <= 0xF);
27fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
28152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    int xy = x * y;
29f31fa24914c683abcc2c860093b142725c43fbe6commit-bot@chromium.org    const uint32_t mask = 0xFF00FF;
30fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
31152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    int scale = 256 - 16*y - 16*x + xy;
32152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    uint32_t lo = (a00 & mask) * scale;
33152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    uint32_t hi = ((a00 >> 8) & mask) * scale;
34fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
35152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    scale = 16*x - xy;
36152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a01 & mask) * scale;
37152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a01 >> 8) & mask) * scale;
38fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
39152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    scale = 16*y - xy;
40152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a10 & mask) * scale;
41152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a10 >> 8) & mask) * scale;
42fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
43152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a11 & mask) * xy;
44152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a11 >> 8) & mask) * xy;
45fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
46152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
47152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com}
48152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
493ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.comstatic inline void Filter_32_alpha(unsigned x, unsigned y,
503ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.com                                   SkPMColor a00, SkPMColor a01,
513ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.com                                   SkPMColor a10, SkPMColor a11,
523ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.com                                   SkPMColor* dstColor,
533ada0efdc8de8316df8113ec54ffd1a3f33ecd21digit@google.com                                   unsigned alphaScale) {
54152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    SkASSERT((unsigned)x <= 0xF);
55152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    SkASSERT((unsigned)y <= 0xF);
56152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    SkASSERT(alphaScale <= 256);
57fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
58152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    int xy = x * y;
59f31fa24914c683abcc2c860093b142725c43fbe6commit-bot@chromium.org    const uint32_t mask = 0xFF00FF;
60fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
61152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    int scale = 256 - 16*y - 16*x + xy;
62152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    uint32_t lo = (a00 & mask) * scale;
63152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    uint32_t hi = ((a00 >> 8) & mask) * scale;
64fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
65152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    scale = 16*x - xy;
66152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a01 & mask) * scale;
67152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a01 >> 8) & mask) * scale;
68fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
69152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    scale = 16*y - xy;
70152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a10 & mask) * scale;
71152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a10 >> 8) & mask) * scale;
72fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
73152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo += (a11 & mask) * xy;
74152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi += ((a11 >> 8) & mask) * xy;
75152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
76152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    lo = ((lo >> 8) & mask) * alphaScale;
77152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    hi = ((hi >> 8) & mask) * alphaScale;
78152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
79152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
80152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com}
81152f748386143475daf9da31aceb424dc7c8a7e6reed@android.com
828b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com// Two color version, where we filter only along 1 axis
838b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.comstatic inline void Filter_32_opaque(unsigned t,
848b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                    SkPMColor color0,
858b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                    SkPMColor color1,
868b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                    SkPMColor* dstColor) {
878b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    SkASSERT((unsigned)t <= 0xF);
888b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
89f31fa24914c683abcc2c860093b142725c43fbe6commit-bot@chromium.org    const uint32_t mask = 0xFF00FF;
908b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
918b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    int scale = 256 - 16*t;
928b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    uint32_t lo = (color0 & mask) * scale;
938b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    uint32_t hi = ((color0 >> 8) & mask) * scale;
948b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
958b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    scale = 16*t;
968b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    lo += (color1 & mask) * scale;
978b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    hi += ((color1 >> 8) & mask) * scale;
988b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
998b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
1008b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com}
1018b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
1028b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com// Two color version, where we filter only along 1 axis
1038b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.comstatic inline void Filter_32_alpha(unsigned t,
1048b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                   SkPMColor color0,
1058b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                   SkPMColor color1,
1068b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                   SkPMColor* dstColor,
1078b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com                                   unsigned alphaScale) {
1088b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    SkASSERT((unsigned)t <= 0xF);
1098b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    SkASSERT(alphaScale <= 256);
1108b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
111f31fa24914c683abcc2c860093b142725c43fbe6commit-bot@chromium.org    const uint32_t mask = 0xFF00FF;
1128b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
1138b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    int scale = 256 - 16*t;
1148b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    uint32_t lo = (color0 & mask) * scale;
1158b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    uint32_t hi = ((color0 >> 8) & mask) * scale;
1168b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
1178b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    scale = 16*t;
1188b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    lo += (color1 & mask) * scale;
1198b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    hi += ((color1 >> 8) & mask) * scale;
1208b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
1218b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    lo = ((lo >> 8) & mask) * alphaScale;
1228b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    hi = ((hi >> 8) & mask) * alphaScale;
1238b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com
1248b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
1258b8bf4d12ecf8fb340a1362c91a8a57395dd31a3robertphillips@google.com}
126