1#include "SkUnitMappers.h"
2
3SkDiscreteMapper::SkDiscreteMapper(int segments)
4{
5    if (segments < 2)
6    {
7        fSegments = 0;
8        fScale = 0;
9    }
10    else
11    {
12        if (segments > 0xFFFF)
13            segments = 0xFFFF;
14        fSegments = segments;
15        fScale = SK_Fract1 / (segments - 1);
16    }
17}
18
19uint16_t SkDiscreteMapper::mapUnit16(uint16_t input)
20{
21    SkFixed x = input * fSegments >> 16;
22    x = x * fScale >> 14;
23    x += x << 15 >> 31; // map 0x10000 to 0xFFFF
24    return SkToU16(x);
25}
26
27SkDiscreteMapper::SkDiscreteMapper(SkFlattenableReadBuffer& rb)
28    : SkUnitMapper(rb)
29{
30    fSegments = rb.readU32();
31    fScale = rb.readU32();
32}
33
34SkFlattenable::Factory SkDiscreteMapper::getFactory()
35{
36    return Create;
37}
38
39SkFlattenable* SkDiscreteMapper::Create(SkFlattenableReadBuffer& rb)
40{
41    return SkNEW_ARGS(SkDiscreteMapper, (rb));
42}
43
44void SkDiscreteMapper::flatten(SkFlattenableWriteBuffer& wb)
45{
46    this->INHERITED::flatten(wb);
47
48    wb.write32(fSegments);
49    wb.write32(fScale);
50}
51
52///////////////////////////////////////////////////////////////////////////////
53
54uint16_t SkCosineMapper::mapUnit16(uint16_t input)
55{
56    /*  we want to call cosine(input * pi/2) treating input as [0...1)
57        however, the straight multitply would overflow 32bits since input is
58        16bits and pi/2 is 17bits, so we shift down our pi const before we mul
59    */
60    SkFixed rads = (unsigned)(input * (SK_FixedPI >> 2)) >> 15;
61    SkFixed x = SkFixedCos(rads);
62    x += x << 15 >> 31; // map 0x10000 to 0xFFFF
63    return SkToU16(x);
64}
65
66SkCosineMapper::SkCosineMapper(SkFlattenableReadBuffer& rb)
67    : SkUnitMapper(rb)
68{
69}
70
71SkFlattenable::Factory SkCosineMapper::getFactory()
72{
73    return Create;
74}
75
76SkFlattenable* SkCosineMapper::Create(SkFlattenableReadBuffer& rb)
77{
78    return SkNEW_ARGS(SkCosineMapper, (rb));
79}
80
81