1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
2474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com/*
3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2009 The Android Open Source Project
4474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com *
5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file.
7474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com */
8474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
9685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
10474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com#include "SkColorPriv.h"
11474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
125e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com/*
135e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com    Filter_32_opaque
14935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
155e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com    There is no hard-n-fast rule that the filtering must produce
165e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com    exact results for the color components, but if the 4 incoming colors are
175e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com    all opaque, then the output color must also be opaque. Subsequent parts of
185e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com    the drawing pipeline may rely on this (e.g. which blitrow proc to use).
195e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com */
205e38dfefd7ee71059f5b3df6cc1960bf674a1bd7reed@android.com
21dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.comstatic inline void Filter_32_opaque(unsigned x, unsigned y,
22474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com                                    SkPMColor a00, SkPMColor a01,
23474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com                                    SkPMColor a10, SkPMColor a11,
24dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.com                                    SkPMColor* dstColor) {
25474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    SkASSERT((unsigned)x <= 0xF);
26474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    SkASSERT((unsigned)y <= 0xF);
27935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
28474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    int xy = x * y;
29d5678c1f4e6a438f87d0d2e2ce553e1443affa85ctguil@chromium.org    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
30935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
31474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    int scale = 256 - 16*y - 16*x + xy;
32474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    uint32_t lo = (a00 & mask) * scale;
33474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    uint32_t hi = ((a00 >> 8) & mask) * scale;
34935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
35474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    scale = 16*x - xy;
36474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a01 & mask) * scale;
37474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a01 >> 8) & mask) * scale;
38935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
39474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    scale = 16*y - xy;
40474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a10 & mask) * scale;
41474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a10 >> 8) & mask) * scale;
42935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
43474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a11 & mask) * xy;
44474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a11 >> 8) & mask) * xy;
45935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
46474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
47474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com}
48474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
49dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.comstatic inline void Filter_32_alpha(unsigned x, unsigned y,
50dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.com                                   SkPMColor a00, SkPMColor a01,
51dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.com                                   SkPMColor a10, SkPMColor a11,
52dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.com                                   SkPMColor* dstColor,
53dc1842b04f206fc63e6ba85aea1ed00f24bb295adigit@google.com                                   unsigned alphaScale) {
54474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    SkASSERT((unsigned)x <= 0xF);
55474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    SkASSERT((unsigned)y <= 0xF);
56474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    SkASSERT(alphaScale <= 256);
57935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
58474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    int xy = x * y;
59d5678c1f4e6a438f87d0d2e2ce553e1443affa85ctguil@chromium.org    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
60935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
61474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    int scale = 256 - 16*y - 16*x + xy;
62474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    uint32_t lo = (a00 & mask) * scale;
63474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    uint32_t hi = ((a00 >> 8) & mask) * scale;
64935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
65474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    scale = 16*x - xy;
66474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a01 & mask) * scale;
67474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a01 >> 8) & mask) * scale;
68935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
69474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    scale = 16*y - xy;
70474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a10 & mask) * scale;
71474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a10 >> 8) & mask) * scale;
72935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com
73474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo += (a11 & mask) * xy;
74474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi += ((a11 >> 8) & mask) * xy;
75474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
76474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    lo = ((lo >> 8) & mask) * alphaScale;
77474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    hi = ((hi >> 8) & mask) * alphaScale;
78474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
79474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
80474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com}
81474831c2d4b750b4c312d32059b006cdcaeb2276reed@android.com
8252dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com// Two color version, where we filter only along 1 axis
8352dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.comstatic inline void Filter_32_opaque(unsigned t,
8452dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                    SkPMColor color0,
8552dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                    SkPMColor color1,
8652dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                    SkPMColor* dstColor) {
8752dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    SkASSERT((unsigned)t <= 0xF);
8852dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
8952dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    static const uint32_t mask = gMask_00FF00FF; //0x00FF00FF;
9052dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
9152dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    int scale = 256 - 16*t;
9252dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    uint32_t lo = (color0 & mask) * scale;
9352dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    uint32_t hi = ((color0 >> 8) & mask) * scale;
9452dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
9552dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    scale = 16*t;
9652dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    lo += (color1 & mask) * scale;
9752dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    hi += ((color1 >> 8) & mask) * scale;
9852dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
9952dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
10052dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com}
10152dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
10252dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com// Two color version, where we filter only along 1 axis
10352dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.comstatic inline void Filter_32_alpha(unsigned t,
10452dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                   SkPMColor color0,
10552dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                   SkPMColor color1,
10652dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                   SkPMColor* dstColor,
10752dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com                                   unsigned alphaScale) {
10852dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    SkASSERT((unsigned)t <= 0xF);
10952dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    SkASSERT(alphaScale <= 256);
11052dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
11152dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    static const uint32_t mask = gMask_00FF00FF; //0x00FF00FF;
11252dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
11352dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    int scale = 256 - 16*t;
11452dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    uint32_t lo = (color0 & mask) * scale;
11552dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    uint32_t hi = ((color0 >> 8) & mask) * scale;
11652dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
11752dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    scale = 16*t;
11852dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    lo += (color1 & mask) * scale;
11952dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    hi += ((color1 >> 8) & mask) * scale;
12052dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
12152dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    lo = ((lo >> 8) & mask) * alphaScale;
12252dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    hi = ((hi >> 8) & mask) * alphaScale;
12352dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com
12452dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com    *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
12552dbd0c37e5bc5f98820b9c083ace69002560d5crobertphillips@google.com}
126