1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkFloat_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkFloat_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFixed.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkFloat { 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFloat() {} 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setZero() { fPacked = 0; } 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// void setShift(int value, int shift) { fPacked = SetShift(value, shift); } 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setInt(int value) { fPacked = SetShift(value, 0); } 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setFixed(SkFixed value) { fPacked = SetShift(value, -16); } 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// int getShift(int shift) const { return GetShift(fPacked, shift); } 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int getInt() const { return GetShift(fPacked, 0); } 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed getFixed() const { return GetShift(fPacked, -16); } 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void abs() { fPacked = Abs(fPacked); } 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void negate() { fPacked = Neg(fPacked); } 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void shiftLeft(int bits) { fPacked = Shift(fPacked, bits); } 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setShiftLeft(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, bits); } 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void shiftRight(int bits) { fPacked = Shift(fPacked, -bits); } 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setShiftRight(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, -bits); } 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void add(const SkFloat& a) { fPacked = Add(fPacked, a.fPacked); } 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setAdd(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, b.fPacked); } 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void sub(const SkFloat& a) { fPacked = Add(fPacked, Neg(a.fPacked)); } 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setSub(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, Neg(b.fPacked)); } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void mul(const SkFloat& a) { fPacked = Mul(fPacked, a.fPacked); } 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setMul(const SkFloat& a, const SkFloat& b) { fPacked = Mul(a.fPacked, b.fPacked); } 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void div(const SkFloat& a) { fPacked = Div(fPacked, a.fPacked); } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setDiv(const SkFloat& a, const SkFloat& b) { fPacked = Div(a.fPacked, b.fPacked); } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void sqrt() { fPacked = Sqrt(fPacked); } 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setSqrt(const SkFloat& a) { fPacked = Sqrt(a.fPacked); } 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void cubeRoot() { fPacked = CubeRoot(fPacked); } 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setCubeRoot(const SkFloat& a) { fPacked = CubeRoot(a.fPacked); } 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator==(const SkFloat& a, const SkFloat& b) { return a.fPacked == b.fPacked; } 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator!=(const SkFloat& a, const SkFloat& b) { return a.fPacked != b.fPacked; } 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator<(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) < 0; } 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator<=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) <= 0; } 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator>(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) > 0; } 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator>=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) >= 0; } 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void UnitTest(); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void assertEquals(float f, int tolerance = 0) 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com union { 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float fFloat; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fPacked; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } tmp; 70fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.fFloat = f; 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int d = tmp.fPacked - fPacked; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkAbs32(d) <= tolerance); 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float getFloat() const 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com union { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float fFloat; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fPacked; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } tmp; 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.fPacked = fPacked; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return tmp.fFloat; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fPacked; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int GetShift(int32_t packed, int shift); 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t SetShift(int value, int shift); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Neg(int32_t); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Abs(int32_t packed) { return (uint32_t)(packed << 1) >> 1; } 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Shift(int32_t, int bits); 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Add(int32_t, int32_t); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Mul(int32_t, int32_t); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t MulInt(int32_t, int); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Div(int32_t, int32_t); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t DivInt(int32_t, int); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Invert(int32_t); 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t Sqrt(int32_t); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t CubeRoot(int32_t); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int Cmp(int32_t, int32_t); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 108