michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef MOZILLA_GFX_TOOLS_H_ michael@0: #define MOZILLA_GFX_TOOLS_H_ michael@0: michael@0: #include "Types.h" michael@0: #include "Point.h" michael@0: #include michael@0: #if defined(_MSC_VER) && (_MSC_VER < 1600) michael@0: #define hypotf _hypotf michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: michael@0: static inline bool michael@0: IsOperatorBoundByMask(CompositionOp aOp) { michael@0: switch (aOp) { michael@0: case CompositionOp::OP_IN: michael@0: case CompositionOp::OP_OUT: michael@0: case CompositionOp::OP_DEST_IN: michael@0: case CompositionOp::OP_DEST_ATOP: michael@0: case CompositionOp::OP_SOURCE: michael@0: return false; michael@0: default: michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: template michael@0: struct ClassStorage michael@0: { michael@0: char bytes[sizeof(T)]; michael@0: michael@0: const T *addr() const { return (const T *)bytes; } michael@0: T *addr() { return (T *)(void *)bytes; } michael@0: }; michael@0: michael@0: static inline bool michael@0: FuzzyEqual(Float aA, Float aB, Float aErr) michael@0: { michael@0: if ((aA + aErr >= aB) && (aA - aErr <= aB)) { michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: static inline void michael@0: NudgeToInteger(float *aVal) michael@0: { michael@0: float r = floorf(*aVal + 0.5f); michael@0: // The error threshold should be proportional to the rounded value. This michael@0: // bounds the relative error introduced by the nudge operation. However, michael@0: // when the rounded value is 0, the error threshold can't be proportional michael@0: // to the rounded value (we'd never round), so we just choose the same michael@0: // threshold as for a rounded value of 1. michael@0: if (FuzzyEqual(r, *aVal, r == 0.0f ? 1e-6f : fabs(r*1e-6f))) { michael@0: *aVal = r; michael@0: } michael@0: } michael@0: michael@0: static inline Float michael@0: Distance(Point aA, Point aB) michael@0: { michael@0: return hypotf(aB.x - aA.x, aB.y - aA.y); michael@0: } michael@0: michael@0: static inline int michael@0: BytesPerPixel(SurfaceFormat aFormat) michael@0: { michael@0: switch (aFormat) { michael@0: case SurfaceFormat::A8: michael@0: return 1; michael@0: case SurfaceFormat::R5G6B5: michael@0: return 2; michael@0: default: michael@0: return 4; michael@0: } michael@0: } michael@0: michael@0: template michael@0: struct AlignedArray michael@0: { michael@0: AlignedArray() michael@0: : mStorage(nullptr) michael@0: , mPtr(nullptr) michael@0: { michael@0: } michael@0: michael@0: MOZ_ALWAYS_INLINE AlignedArray(size_t aSize) michael@0: : mStorage(nullptr) michael@0: { michael@0: Realloc(aSize); michael@0: } michael@0: michael@0: MOZ_ALWAYS_INLINE ~AlignedArray() michael@0: { michael@0: delete [] mStorage; michael@0: } michael@0: michael@0: void Dealloc() michael@0: { michael@0: delete [] mStorage; michael@0: mStorage = mPtr = nullptr; michael@0: } michael@0: michael@0: MOZ_ALWAYS_INLINE void Realloc(size_t aSize) michael@0: { michael@0: delete [] mStorage; michael@0: mStorage = new (std::nothrow) T[aSize + (alignment - 1)]; michael@0: if (uintptr_t(mStorage) % alignment) { michael@0: // Our storage does not start at a -byte boundary. Make sure mData does! michael@0: mPtr = (T*)(uintptr_t(mStorage) + michael@0: (alignment - (uintptr_t(mStorage) % alignment))); michael@0: } else { michael@0: mPtr = mStorage; michael@0: } michael@0: } michael@0: michael@0: MOZ_ALWAYS_INLINE operator T*() michael@0: { michael@0: return mPtr; michael@0: } michael@0: michael@0: T *mStorage; michael@0: T *mPtr; michael@0: }; michael@0: michael@0: template michael@0: int32_t GetAlignedStride(int32_t aStride) michael@0: { michael@0: if (aStride % alignment) { michael@0: return aStride + (alignment - (aStride % alignment)); michael@0: } michael@0: michael@0: return aStride; michael@0: } michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif /* MOZILLA_GFX_TOOLS_H_ */