1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkClampRange_DEFINED
9#define SkClampRange_DEFINED
10
11#include "SkFixed.h"
12#include "SkScalar.h"
13
14#define SkGradFixed               SkFixed3232
15
16// We want the largest 32.32 value representable as a float. (float)0x7FFFFFFF
17// becomes too big, due to limited mantissa on the float and its rounding rules, so
18// we have to manually compute the next smaller value (aka nextafter).
19
20// #define SkGradFixedMaxScalar nextafterf(SkFixed3232ToFloat(SkFixed3232Max), 0)
21// #define SkGradFixedMinScalar nextafterf(SkFixed3232ToFloat(SkFixed3232Min), 0)
22#define SkGradFixedMaxScalar      ( 2147483520.0f)
23#define SkGradFixedMinScalar      (-2147483520.0f)
24#define SkScalarPinToGradFixed(x) SkScalarToFixed3232(SkTPin(x,                   \
25                                                             SkGradFixedMinScalar,\
26                                                             SkGradFixedMaxScalar))
27#define SkFixedToGradFixed(x)     SkFixedToFixed3232(x)
28#define SkGradFixedToFixed(x)     (SkFixed)((x) >> 16)
29#define kFracMax_SkGradFixed      0xFFFFFFFFLL
30
31/**
32 *  Iteration fixed fx by dx, clamping as you go to [0..kFracMax_SkGradFixed], this class
33 *  computes the (up to) 3 spans there are:
34 *
35 *  range0: use constant value V0
36 *  range1: iterate as usual fx += dx
37 *  range2: use constant value V1
38 */
39struct SkClampRange {
40    int fCount0;    // count for fV0
41    int fCount1;    // count for interpolating (fV0...fV1)
42    int fCount2;    // count for fV1
43    SkGradFixed fFx1;   // initial fx value for the fCount1 range.
44                    // only valid if fCount1 > 0
45    int fV0, fV1;
46
47    void init(SkGradFixed fx, SkGradFixed dx, int count, int v0, int v1);
48
49    void validate(int count) const {
50#ifdef SK_DEBUG
51        SkASSERT(fCount0 >= 0);
52        SkASSERT(fCount1 >= 0);
53        SkASSERT(fCount2 >= 0);
54        SkASSERT(fCount0 + fCount1 + fCount2 == count);
55#endif
56    }
57
58private:
59    void initFor1(SkGradFixed fx);
60};
61
62#endif
63