180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2008 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkFloat_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkFloat_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFixed.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkFloat {
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFloat() {}
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setZero() { fPacked = 0; }
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  void    setShift(int value, int shift) { fPacked = SetShift(value, shift); }
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setInt(int value) { fPacked = SetShift(value, 0); }
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setFixed(SkFixed value) { fPacked = SetShift(value, -16); }
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setFract(SkFract value) { fPacked = SetShift(value, -30); }
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  int     getShift(int shift) const { return GetShift(fPacked, shift); }
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int     getInt() const { return GetShift(fPacked, 0); }
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed getFixed() const { return GetShift(fPacked, -16); }
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFract getFract() const { return GetShift(fPacked, -30); }
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    abs() { fPacked = Abs(fPacked); }
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    negate() { fPacked = Neg(fPacked); }
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    shiftLeft(int bits) { fPacked = Shift(fPacked, bits); }
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setShiftLeft(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, bits); }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    shiftRight(int bits) { fPacked = Shift(fPacked, -bits); }
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setShiftRight(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, -bits); }
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    add(const SkFloat& a) { fPacked = Add(fPacked, a.fPacked); }
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setAdd(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, b.fPacked); }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    sub(const SkFloat& a) { fPacked = Add(fPacked, Neg(a.fPacked)); }
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setSub(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, Neg(b.fPacked)); }
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    mul(const SkFloat& a) { fPacked = Mul(fPacked, a.fPacked); }
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setMul(const SkFloat& a, const SkFloat& b) { fPacked = Mul(a.fPacked, b.fPacked); }
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    div(const SkFloat& a) { fPacked = Div(fPacked, a.fPacked); }
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setDiv(const SkFloat& a, const SkFloat& b) { fPacked = Div(a.fPacked, b.fPacked); }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    sqrt() { fPacked = Sqrt(fPacked); }
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setSqrt(const SkFloat& a) { fPacked = Sqrt(a.fPacked); }
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    cubeRoot() { fPacked = CubeRoot(fPacked); }
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void    setCubeRoot(const SkFloat& a) { fPacked = CubeRoot(a.fPacked); }
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator==(const SkFloat& a, const SkFloat& b) { return a.fPacked == b.fPacked; }
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator!=(const SkFloat& a, const SkFloat& b) { return a.fPacked != b.fPacked; }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator<(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) < 0; }
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator<=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) <= 0; }
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator>(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) > 0; }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend bool operator>=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) >= 0; }
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static void UnitTest();
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void assertEquals(float f, int tolerance = 0)
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        union {
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float   fFloat;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int32_t fPacked;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } tmp;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.fFloat = f;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int d = tmp.fPacked - fPacked;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(SkAbs32(d) <= tolerance);
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float getFloat() const
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        union {
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float   fFloat;
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int32_t fPacked;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } tmp;
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.fPacked = fPacked;
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return tmp.fFloat;
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t fPacked;
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int GetShift(int32_t packed, int shift);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t SetShift(int value, int shift);
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Neg(int32_t);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Abs(int32_t packed) { return (uint32_t)(packed << 1) >> 1; }
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Shift(int32_t, int bits);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Add(int32_t, int32_t);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Mul(int32_t, int32_t);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t MulInt(int32_t, int);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Div(int32_t, int32_t);
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t DivInt(int32_t, int);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Invert(int32_t);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t Sqrt(int32_t);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int32_t CubeRoot(int32_t);
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static int Cmp(int32_t, int32_t);
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
110