SkFDot6.h 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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. #ifndef SkFDot6_DEFINED
  8. #define SkFDot6_DEFINED
  9. #include "include/core/SkMath.h"
  10. #include "include/core/SkScalar.h"
  11. #include "include/private/SkFixed.h"
  12. #include "include/private/SkTo.h"
  13. typedef int32_t SkFDot6;
  14. /* This uses the magic number approach suggested here:
  15. * http://stereopsis.com/sree/fpu2006.html and used in
  16. * _cairo_fixed_from_double. It does banker's rounding
  17. * (i.e. round to nearest even)
  18. */
  19. inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0)
  20. {
  21. union {
  22. double fDouble;
  23. int32_t fBits[2];
  24. } tmp;
  25. int fractionalBits = 6 + shift;
  26. double magic = (1LL << (52 - (fractionalBits))) * 1.5;
  27. tmp.fDouble = SkScalarToDouble(x) + magic;
  28. #ifdef SK_CPU_BENDIAN
  29. return tmp.fBits[1];
  30. #else
  31. return tmp.fBits[0];
  32. #endif
  33. }
  34. #define SK_FDot6One (64)
  35. #define SK_FDot6Half (32)
  36. #ifdef SK_DEBUG
  37. inline SkFDot6 SkIntToFDot6(int x) {
  38. SkASSERT(SkToS16(x) == x);
  39. return x << 6;
  40. }
  41. #else
  42. #define SkIntToFDot6(x) ((x) << 6)
  43. #endif
  44. #define SkFDot6Floor(x) ((x) >> 6)
  45. #define SkFDot6Ceil(x) (((x) + 63) >> 6)
  46. #define SkFDot6Round(x) (((x) + 32) >> 6)
  47. #define SkFixedToFDot6(x) ((x) >> 10)
  48. inline SkFixed SkFDot6ToFixed(SkFDot6 x) {
  49. SkASSERT((SkLeftShift(x, 10) >> 10) == x);
  50. return SkLeftShift(x, 10);
  51. }
  52. #define SkScalarToFDot6(x) (SkFDot6)((x) * 64)
  53. #define SkFDot6ToScalar(x) ((SkScalar)(x) * 0.015625f)
  54. #define SkFDot6ToFloat SkFDot6ToScalar
  55. inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b) {
  56. SkASSERT(b != 0);
  57. if (SkTFitsIn<int16_t>(a)) {
  58. return SkLeftShift(a, 16) / b;
  59. } else {
  60. return SkFixedDiv(a, b);
  61. }
  62. }
  63. #endif