예제 #1
0
template <DstType D> void srcover_1(const SkXfermode::PM4fState& state, uint32_t dst[],
                                    const SkPM4f& src, int count, const SkAlpha aa[]) {
    Sk4f s4 = Sk4f::Load(src.fVec);
    Sk4f scale = Sk4f(1 - get_alpha(s4));

    if (aa) {
        for (int i = 0; i < count; ++i) {
            unsigned a = aa[i];
            if (0 == a) {
                continue;
            }
            Sk4f d4 = load_dst<D>(dst[i]);
            Sk4f r4;
            if (a != 0xFF) {
                s4 = scale_by_coverage(s4, a);
                r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
            } else {
                r4 = s4 + d4 * scale;
            }
            dst[i] = store_dst<D>(r4);
        }
    } else {
        for (int i = 0; i < count; ++i) {
            Sk4f d4 = load_dst<D>(dst[i]);
            Sk4f r4 = s4 + d4 * scale;
            dst[i] = store_dst<D>(r4);
        }
    }
}
예제 #2
0
static void srcover_srgb_dst_1(const SkXfermode*, uint32_t dst[],
                               const SkPM4f* src, int count, const SkAlpha aa[]) {
    Sk4f s4 = src->to4f_pmorder();
    Sk4f dst_scale = Sk4f(1 - get_alpha(s4));

    if (aa) {
        for (int i = 0; i < count; ++i) {
            unsigned a = aa[i];
            if (0 == a) {
                continue;
            }
            Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
            Sk4f r4;
            if (a != 0xFF) {
                const Sk4f s4_aa = scale_by_coverage(s4, a);
                r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa));
            } else {
                r4 = s4 + d4 * dst_scale;
            }
            dst[i] = to_4b(linear_unit_to_srgb_255f(r4));
        }
    } else {
        while (count >= 4) {
            auto d = load_4_srgb(dst);

            auto s = Sk4x4f{{ src->r() }, { src->g() }, { src->b() }, { src->a() }};
        #if defined(SK_PMCOLOR_IS_BGRA)
            SkTSwap(s.r, s.b);
        #endif

            auto invSA = 1.0f - s.a;
            auto r = s.r + d.r * invSA,
                 g = s.g + d.g * invSA,
                 b = s.b + d.b * invSA,
                 a = s.a + d.a * invSA;

            store_4_srgb(dst, Sk4x4f{r,g,b,a});
            count -= 4;
            dst += 4;
        }
        for (int i = 0; i < count; ++i) {
            Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
            dst[i] = to_4b(linear_unit_to_srgb_255f(s4 + d4 * dst_scale));
        }
    }
}
예제 #3
0
template <DstType D> void srcover_n(const SkXfermode*, uint32_t dst[],
                                    const SkPM4f src[], int count, const SkAlpha aa[]) {
    if (aa) {
        for (int i = 0; i < count; ++i) {
            unsigned a = aa[i];
            if (0 == a) {
                continue;
            }
            Sk4f s4 = src[i].to4f_pmorder();
            Sk4f d4 = load_dst<D>(dst[i]);
            if (a != 0xFF) {
                s4 = scale_by_coverage(s4, a);
            }
            Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
            dst[i] = store_dst<D>(r4);
        }
    } else {
        while (count >= 4 && D == kSRGB_Dst) {
            auto d = load_4_srgb(dst);

            auto s = Sk4x4f::Transpose(src->fVec);
        #if defined(SK_PMCOLOR_IS_BGRA)
            SkTSwap(s.r, s.b);
        #endif

            auto invSA = 1.0f - s.a;
            auto r = s.r + d.r * invSA,
                 g = s.g + d.g * invSA,
                 b = s.b + d.b * invSA,
                 a = s.a + d.a * invSA;

            store_4_srgb(dst, Sk4x4f{r,g,b,a});
            count -= 4;
            dst += 4;
            src += 4;
        }
        for (int i = 0; i < count; ++i) {
            Sk4f s4 = src[i].to4f_pmorder();
            Sk4f d4 = load_dst<D>(dst[i]);
            Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
            dst[i] = store_dst<D>(r4);
        }
    }
}
예제 #4
0
static void srcover_linear_dst_1(const SkXfermode*, uint32_t dst[],
                                 const SkPM4f* src, int count, const SkAlpha aa[]) {
    const Sk4f s4 = src->to4f_pmorder();
    const Sk4f dst_scale = Sk4f(1 - get_alpha(s4));

    if (aa) {
        for (int i = 0; i < count; ++i) {
            unsigned a = aa[i];
            if (0 == a) {
                continue;
            }
            Sk4f d4 = Sk4f_fromL32(dst[i]);
            Sk4f r4;
            if (a != 0xFF) {
                Sk4f s4_aa = scale_by_coverage(s4, a);
                r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa));
            } else {
                r4 = s4 + d4 * dst_scale;
            }
            dst[i] = Sk4f_toL32(r4);
        }
    } else {
        const Sk4f s4_255 = s4 * Sk4f(255) + Sk4f(0.5f);   // +0.5 to pre-bias for rounding
        while (count >= 4) {
            Sk4f d0 = to_4f(dst[0]);
            Sk4f d1 = to_4f(dst[1]);
            Sk4f d2 = to_4f(dst[2]);
            Sk4f d3 = to_4f(dst[3]);
            Sk4f_ToBytes((uint8_t*)dst,
                         s4_255 + d0 * dst_scale,
                         s4_255 + d1 * dst_scale,
                         s4_255 + d2 * dst_scale,
                         s4_255 + d3 * dst_scale);
            dst += 4;
            count -= 4;
        }
        for (int i = 0; i < count; ++i) {
            Sk4f d4 = to_4f(dst[i]);
            dst[i] = to_4b(s4_255 + d4 * dst_scale);
        }
    }
}