19e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com/* 29e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Copyright 2012 Google Inc. 39e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * 49e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be 59e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * found in the LICENSE file. 69e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com */ 7639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#ifndef __DataTypes_h__ 8639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#define __DataTypes_h__ 9639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 10aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com#include <float.h> // for FLT_EPSILON 11aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com#include <math.h> // for fabs, sqrt 12aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com 1345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkPoint.h" 1445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 15ebf95ba28db75212a1313edc947ed68decc30273caryclark@google.com#define FORCE_RELEASE 0 // set force release to 1 for multiple thread -- no debugging 16ebf95ba28db75212a1313edc947ed68decc30273caryclark@google.com#define ONE_OFF_DEBUG 1 17d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com#define ONE_OFF_DEBUG_MATHEMATICA 0 182e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com 19beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com// FIXME: move these into SkTypes.h 20beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.comtemplate <typename T> inline T SkTMax(T a, T b) { 21beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com if (a < b) 22beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com a = b; 23beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return a; 24beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com} 25beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com 26beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.comtemplate <typename T> inline T SkTMin(T a, T b) { 27beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com if (a > b) 28beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com a = b; 29beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return a; 30beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com} 31beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com 320b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.comextern bool AlmostEqualUlps(float A, float B); 336d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.cominline bool AlmostEqualUlps(double A, double B) { return AlmostEqualUlps((float) A, (float) B); } 346d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com 350b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com// FIXME: delete 36b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.comint UlpsDiff(float A, float B); 37b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 389f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) 3947d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com// DBL_EPSILON == 2.22045e-16 409f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.comconst double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; 4145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comconst double FLT_EPSILON_HALF = FLT_EPSILON / 2; 4273ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.comconst double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; 4373ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.comconst double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); 4485ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.comconst double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; 4547d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.comconst double DBL_EPSILON_ERR = DBL_EPSILON * 4; // tune -- allow a few bits of error 46996d78b7cf9863a5b574fc1b64b1715cad4d0a23caryclark@google.comconst double ROUGH_EPSILON = FLT_EPSILON * 64; 471304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.comconst double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; 48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 4945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.cominline bool approximately_zero(double x) { 50b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com return fabs(x) < FLT_EPSILON; 51b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 52b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 53a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.cominline bool precisely_zero(double x) { 5447d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com return fabs(x) < DBL_EPSILON_ERR; 55a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.com} 56a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.com 57c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.cominline bool approximately_zero(float x) { 58c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com return fabs(x) < FLT_EPSILON; 59c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com} 60c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com 619f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.cominline bool approximately_zero_cubed(double x) { 629f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return fabs(x) < FLT_EPSILON_CUBED; 639f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com} 649f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com 6545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.cominline bool approximately_zero_half(double x) { 6645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return fabs(x) < FLT_EPSILON_HALF; 6745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 6845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 69d1688744d537d928699b6069f99c4470a0f6e772caryclark@google.cominline bool approximately_zero_squared(double x) { 7073ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com return fabs(x) < FLT_EPSILON_SQUARED; 7173ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com} 7273ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com 7373ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.cominline bool approximately_zero_sqrt(double x) { 7473ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com return fabs(x) < FLT_EPSILON_SQRT; 75d1688744d537d928699b6069f99c4470a0f6e772caryclark@google.com} 76d1688744d537d928699b6069f99c4470a0f6e772caryclark@google.com 7785ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.cominline bool approximately_zero_inverse(double x) { 7885ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.com return fabs(x) > FLT_EPSILON_INVERSE; 7985ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.com} 8085ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.com 81beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com// FIXME: if called multiple times with the same denom, we want to pass 1/y instead 82f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.cominline bool approximately_zero_when_compared_to(double x, double y) { 83beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return x == 0 || fabs(x / y) < FLT_EPSILON; 84f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com} 85f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com 869f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use 879f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// AlmostEqualUlps instead. 88b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.cominline bool approximately_equal(double x, double y) { 899f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com#if 1 900b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com return approximately_zero(x - y); 919f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com#else 929f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// see http://visualstudiomagazine.com/blogs/tool-tracker/2011/11/compare-floating-point-numbers.aspx 934024f32d99b63a599c544a49f526e53c25135159skia.committer@gmail.com// this allows very small (e.g. degenerate) values to compare unequally, but in this case, 949f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// AlmostEqualUlps should be used instead. 959f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com if (x == y) { 969f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return true; 979f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com } 989f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com double absY = fabs(y); 999f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com if (x == 0) { 1009f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return absY < FLT_EPSILON; 1019f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com } 1029f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com double absX = fabs(x); 1039f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com if (y == 0) { 1049f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return absX < FLT_EPSILON; 1059f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com } 1069f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return fabs(x - y) < (absX > absY ? absX : absY) * FLT_EPSILON; 1079f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com#endif 108b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 109b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 11047d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.cominline bool precisely_equal(double x, double y) { 11147d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com return precisely_zero(x - y); 11247d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com} 11347d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com 11445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.cominline bool approximately_equal_half(double x, double y) { 11545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return approximately_zero_half(x - y); 11645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 11745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 118b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.cominline bool approximately_equal_squared(double x, double y) { 119b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com return approximately_equal(x, y); 120b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 121b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 122b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.cominline bool approximately_greater(double x, double y) { 1235e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return x - FLT_EPSILON >= y; 1245e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com} 1255e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com 1265e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.cominline bool approximately_greater_or_equal(double x, double y) { 1275e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return x + FLT_EPSILON > y; 128b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 129b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 130b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.cominline bool approximately_lesser(double x, double y) { 1315e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return x + FLT_EPSILON <= y; 1325e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com} 1335e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com 1345e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.cominline bool approximately_lesser_or_equal(double x, double y) { 1355e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return x - FLT_EPSILON < y; 136b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 137b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 138c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.cominline double approximately_pin(double x) { 139c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com return approximately_zero(x) ? 0 : x; 140c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com} 141c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com 142c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.cominline float approximately_pin(float x) { 143c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com return approximately_zero(x) ? 0 : x; 144c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com} 145c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com 1463350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.cominline bool approximately_greater_than_one(double x) { 1473350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com return x > 1 - FLT_EPSILON; 1483350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com} 1493350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 150185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.cominline bool precisely_greater_than_one(double x) { 15147d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com return x > 1 - DBL_EPSILON_ERR; 152185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.com} 153185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.com 1543350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.cominline bool approximately_less_than_zero(double x) { 1553350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com return x < FLT_EPSILON; 1563350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com} 1573350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 158185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.cominline bool precisely_less_than_zero(double x) { 15947d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com return x < DBL_EPSILON_ERR; 160185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.com} 161185c7c47983dde02b5542cf45fe3fc58a3ecb055caryclark@google.com 162b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.cominline bool approximately_negative(double x) { 163b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com return x < FLT_EPSILON; 164b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com} 165b45a1b46ee25e9b19800b028bb1ca925212ac7b4caryclark@google.com 166a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.cominline bool precisely_negative(double x) { 16747d73daa7a971e7eee5822def7922f7d43b2dc47caryclark@google.com return x < DBL_EPSILON_ERR; 168a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.com} 169a461ff0866526bc51dbd4c4f9f066a727ec21510caryclark@google.com 1703350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.cominline bool approximately_one_or_less(double x) { 1713350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com return x < 1 + FLT_EPSILON; 1723350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com} 1733350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 1743350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.cominline bool approximately_positive(double x) { 1753350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com return x > -FLT_EPSILON; 1763350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com} 1773350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 178e7bd5f4041701cbab87f6e779eb18fbb9fe74216caryclark@google.cominline bool approximately_positive_squared(double x) { 17973ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com return x > -(FLT_EPSILON_SQUARED); 180e7bd5f4041701cbab87f6e779eb18fbb9fe74216caryclark@google.com} 181e7bd5f4041701cbab87f6e779eb18fbb9fe74216caryclark@google.com 1823350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.cominline bool approximately_zero_or_more(double x) { 1833350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com return x > -FLT_EPSILON; 1843350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com} 1853350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 186235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.cominline bool approximately_between(double a, double b, double c) { 187235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com return a <= c ? approximately_negative(a - b) && approximately_negative(b - c) 188235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com : approximately_negative(b - a) && approximately_negative(c - b); 189235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com} 190235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com 191235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com// returns true if (a <= b <= c) || (a >= b >= c) 192235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.cominline bool between(double a, double b, double c) { 193aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); 194235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com return (a - b) * (c - b) <= 0; 195235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com} 1963350c3c68ab75cd08721da3a938b8d2b10096d70caryclark@google.com 1971304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.cominline bool more_roughly_equal(double x, double y) { 1981304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com return fabs(x - y) < MORE_ROUGH_EPSILON; 1991304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com} 2001304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com 20145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.cominline bool roughly_equal(double x, double y) { 20245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return fabs(x - y) < ROUGH_EPSILON; 20345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 20445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 2057ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.comstruct _Point; 2067ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2077ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.comstruct _Vector { 208639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double x; 209639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double y; 210639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 2117ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com friend _Point operator+(const _Point& a, const _Vector& b); 21273ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com 2137ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com void operator+=(const _Vector& v) { 21405c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com x += v.x; 21505c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com y += v.y; 21605c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com } 21705c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com 2187ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com void operator-=(const _Vector& v) { 219639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com x -= v.x; 220639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com y -= v.y; 221639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 222639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 22305c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com void operator/=(const double s) { 22405c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com x /= s; 22505c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com y /= s; 22605c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com } 22705c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com 22805c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com void operator*=(const double s) { 22905c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com x *= s; 23005c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com y *= s; 23105c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com } 23205c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com 2337ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double cross(const _Vector& a) const { 2347ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return x * a.y - y * a.x; 2357ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2367ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2377ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double dot(const _Vector& a) const { 2387ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return x * a.x + y * a.y; 2397ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2407ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2417ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double length() const { 2427ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return sqrt(lengthSquared()); 2437ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2447ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2457ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double lengthSquared() const { 2467ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return x * x + y * y; 2477ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2487ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2497ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com SkVector asSkVector() const { 2507ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com SkVector v = {SkDoubleToScalar(x), SkDoubleToScalar(y)}; 2517ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com return v; 2527ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2537ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com}; 2547ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2557ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.comstruct _Point { 2567ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double x; 2577ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com double y; 2587ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2597ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com friend _Vector operator-(const _Point& a, const _Point& b); 2607ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2617ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com void operator+=(const _Vector& v) { 2627ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com x += v.x; 2637ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com y += v.y; 2647ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2657ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 2667ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com void operator-=(const _Vector& v) { 2677ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com x -= v.x; 2687ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com y -= v.y; 2697ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com } 2707ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com 271639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com friend bool operator==(const _Point& a, const _Point& b) { 272639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com return a.x == b.x && a.y == b.y; 273639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 274639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 275639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com friend bool operator!=(const _Point& a, const _Point& b) { 2769f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com return a.x != b.x || a.y != b.y; 277639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 278d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 2790b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com // note: this can not be implemented with 2800b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com // return approximately_equal(a.y, y) && approximately_equal(a.x, x); 2810b7da433fe0eaa2833d1b2900715b013b36d93dacaryclark@google.com // because that will not take the magnitude of the values 282639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com bool approximatelyEqual(const _Point& a) const { 283beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.x), fabs(a.y)))); 284beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com if (denom == 0) { 285beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return true; 286beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com } 287beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com double inv = 1 / denom; 288beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return approximately_equal(x * inv, a.x * inv) && approximately_equal(y * inv, a.y * inv); 28945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 290044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com 291c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com bool approximatelyEqual(const SkPoint& a) const { 292c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.fX), fabs(a.fY)))); 293c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com if (denom == 0) { 294c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com return true; 295c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com } 296c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com double inv = 1 / denom; 297c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com return approximately_equal(x * inv, a.fX * inv) && approximately_equal(y * inv, a.fY * inv); 298c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com } 299c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com 30045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com bool approximatelyEqualHalf(const _Point& a) const { 30145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.x), fabs(a.y)))); 30245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (denom == 0) { 30345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return true; 30445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 30545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com double inv = 1 / denom; 30645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return approximately_equal_half(x * inv, a.x * inv) 30745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com && approximately_equal_half(y * inv, a.y * inv); 308639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 3090c38ed3b1d704a0ed6147299046f51fd52e841a2skia.committer@gmail.com 310f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com bool approximatelyZero() const { 311f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com return approximately_zero(x) && approximately_zero(y); 312f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com } 313044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com 31445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint asSkPoint() const { 31545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint pt = {SkDoubleToScalar(x), SkDoubleToScalar(y)}; 31645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return pt; 31745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 31815dd300ac6d7695b4d2aca81d8f3648eae704451skia.committer@gmail.com 319f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com double distance(const _Point& a) const { 3207ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com _Vector temp = *this - a; 321f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com return temp.length(); 322f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com } 323f9502d7dfad5b361a3cdaa42eb75b593c95f79d8caryclark@google.com 324beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com double distanceSquared(const _Point& a) const { 3257ff5c841bf669826b4cbd708ae1a6b3527f15dcacaryclark@google.com _Vector temp = *this - a; 326beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com return temp.lengthSquared(); 327beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com } 328beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com 3291304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com double moreRoughlyEqual(const _Point& a) const { 3301304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com return more_roughly_equal(a.y, y) && more_roughly_equal(a.x, x); 3311304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com } 3321304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com 3335e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com double roughlyEqual(const _Point& a) const { 3345e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com return roughly_equal(a.y, y) && roughly_equal(a.x, x); 3355e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com } 336639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com}; 337639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 338639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comtypedef _Point _Line[2]; 339639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comtypedef _Point Quadratic[3]; 340beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.comtypedef _Point Triangle[3]; 341639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comtypedef _Point Cubic[4]; 342639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 343639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct _Rect { 344639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double left; 345639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double top; 346639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double right; 347639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com double bottom; 348d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 349639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com void add(const _Point& pt) { 350639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (left > pt.x) { 351639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com left = pt.x; 352639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 353639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (top > pt.y) { 354639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com top = pt.y; 355639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 356639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (right < pt.x) { 357639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com right = pt.x; 358639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 359639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (bottom < pt.y) { 360639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com bottom = pt.y; 361639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 362639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 363055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com 364235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com // FIXME: used by debugging only ? 36505c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com bool contains(const _Point& pt) const { 366235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com return approximately_between(left, pt.x, right) 367235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com && approximately_between(top, pt.y, bottom); 368235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com } 369d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 37005c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com bool intersects(_Rect& r) const { 371aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com SkASSERT(left <= right); 372aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com SkASSERT(top <= bottom); 373aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com SkASSERT(r.left <= r.right); 374aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com SkASSERT(r.top <= r.bottom); 37585ec74ca543b13739db1ad55dedd7bdfae4ab1a6caryclark@google.com return r.left <= right && left <= r.right && r.top <= bottom && top <= r.bottom; 37605c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com } 37705c4bad470722bc4e5e6ae3d79aa8bcf9e732f06caryclark@google.com 378c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com void set(const _Point& pt) { 379c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com left = right = pt.x; 380c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com top = bottom = pt.y; 381c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com } 382d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 383639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com void setBounds(const _Line& line) { 384c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com set(line[0]); 385639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com add(line[1]); 386639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 387d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 388c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com void setBounds(const Cubic& ); 389c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com void setBounds(const Quadratic& ); 390c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com void setRawBounds(const Cubic& ); 391c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com void setRawBounds(const Quadratic& ); 392639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com}; 393639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 394639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct CubicPair { 395639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Cubic& first() const { return (const Cubic&) pts[0]; } 396639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Cubic& second() const { return (const Cubic&) pts[3]; } 397639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com _Point pts[7]; 398639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com}; 399639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 400639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct QuadraticPair { 401639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Quadratic& first() const { return (const Quadratic&) pts[0]; } 402639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Quadratic& second() const { return (const Quadratic&) pts[2]; } 403639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com _Point pts[5]; 404639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com}; 405639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 406beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com// FIXME: move these into SkFloatingPoint.h 407beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com#include "SkFloatingPoint.h" 4089f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com 409beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com#define sk_double_isnan(a) sk_float_isnan(a) 4109f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com 411c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com// FIXME: move these to debugging file 412753b870c62bd22cee3d9a15efc634822724084acmtklein#ifdef SK_DEBUG 4135e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.comvoid mathematica_ize(char* str, size_t bufferSize); 414c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.combool valid_wind(int winding); 415c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.comvoid winding_printf(int winding); 4165e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com#endif 4175e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com 418639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#endif // __DataTypes_h__ 419