diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /image/ImageRegion.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | image/ImageRegion.h | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/image/ImageRegion.h b/image/ImageRegion.h new file mode 100644 index 0000000000..ed592bbbea --- /dev/null +++ b/image/ImageRegion.h @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_image_ImageRegion_h +#define mozilla_image_ImageRegion_h + +#include "gfxMatrix.h" +#include "gfxPoint.h" +#include "gfxRect.h" +#include "gfxTypes.h" +#include "mozilla/gfx/Matrix.h" +#include "mozilla/gfx/Types.h" +#include "nsSize.h" +#include "PLDHashTable.h" // for PLDHashNumber + +namespace mozilla { +namespace image { + +/** + * An axis-aligned rectangle in tiled image space, with an optional sampling + * restriction rect. The drawing code ensures that if a sampling restriction + * rect is present, any pixels sampled during the drawing process are found + * within that rect. + * + * The sampling restriction rect exists primarily for callers which perform + * pixel snapping. Other callers should generally use one of the Create() + * overloads. + */ +class ImageRegion { + typedef mozilla::gfx::ExtendMode ExtendMode; + + public: + static ImageRegion Empty() { + return ImageRegion(gfxRect(), ExtendMode::CLAMP); + } + + static ImageRegion Create(const gfxRect& aRect, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageRegion(aRect, aExtendMode); + } + + static ImageRegion Create(const gfxSize& aSize, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageRegion(gfxRect(0, 0, aSize.width, aSize.height), aExtendMode); + } + + static ImageRegion Create(const nsIntSize& aSize, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageRegion(gfxRect(0, 0, aSize.width, aSize.height), aExtendMode); + } + + static ImageRegion CreateWithSamplingRestriction( + const gfxRect& aRect, const gfxRect& aRestriction, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageRegion(aRect, aRestriction, aExtendMode); + } + + bool IsRestricted() const { return mIsRestricted; } + const gfxRect& Rect() const { return mRect; } + + const gfxRect& Restriction() const { + MOZ_ASSERT(mIsRestricted); + return mRestriction; + } + + bool RestrictionContains(const gfxRect& aRect) const { + if (!mIsRestricted) { + return true; + } + return mRestriction.Contains(aRect); + } + + ImageRegion Intersect(const gfxRect& aRect) const { + if (mIsRestricted) { + return CreateWithSamplingRestriction(aRect.Intersect(mRect), + aRect.Intersect(mRestriction)); + } + return Create(aRect.Intersect(mRect)); + } + + gfxRect IntersectAndRestrict(const gfxRect& aRect) const { + gfxRect intersection = mRect.Intersect(aRect); + if (mIsRestricted) { + intersection = mRestriction.Intersect(intersection); + } + return intersection; + } + + void MoveBy(gfxFloat dx, gfxFloat dy) { + mRect.MoveBy(dx, dy); + if (mIsRestricted) { + mRestriction.MoveBy(dx, dy); + } + } + + void Scale(gfxFloat sx, gfxFloat sy) { + mRect.Scale(sx, sy); + if (mIsRestricted) { + mRestriction.Scale(sx, sy); + } + } + + void TransformBy(const gfxMatrix& aMatrix) { + mRect = aMatrix.TransformRect(mRect); + if (mIsRestricted) { + mRestriction = aMatrix.TransformRect(mRestriction); + } + } + + void TransformBoundsBy(const gfxMatrix& aMatrix) { + mRect = aMatrix.TransformBounds(mRect); + if (mIsRestricted) { + mRestriction = aMatrix.TransformBounds(mRestriction); + } + } + + ImageRegion operator-(const gfxPoint& aPt) const { + if (mIsRestricted) { + return CreateWithSamplingRestriction(mRect - aPt, mRestriction - aPt); + } + return Create(mRect - aPt); + } + + ImageRegion operator+(const gfxPoint& aPt) const { + if (mIsRestricted) { + return CreateWithSamplingRestriction(mRect + aPt, mRestriction + aPt); + } + return Create(mRect + aPt); + } + + gfx::ExtendMode GetExtendMode() const { return mExtendMode; } + + /* ImageRegion() : mIsRestricted(false) { } */ + + private: + explicit ImageRegion(const gfxRect& aRect, ExtendMode aExtendMode) + : mRect(aRect), mExtendMode(aExtendMode), mIsRestricted(false) {} + + ImageRegion(const gfxRect& aRect, const gfxRect& aRestriction, + ExtendMode aExtendMode) + : mRect(aRect), + mRestriction(aRestriction), + mExtendMode(aExtendMode), + mIsRestricted(true) {} + + gfxRect mRect; + gfxRect mRestriction; + ExtendMode mExtendMode; + bool mIsRestricted; +}; + +/** + * An axis-aligned rectangle in tiled image space, with an optional sampling + * restriction rect. The drawing code ensures that if a sampling restriction + * rect is present, any pixels sampled during the drawing process are found + * within that rect. + * + * The sampling restriction rect exists primarily for callers which perform + * pixel snapping. Other callers should generally use one of the Create() + * overloads. + */ +class ImageIntRegion { + typedef mozilla::gfx::ExtendMode ExtendMode; + + public: + static ImageIntRegion Empty() { + return ImageIntRegion(mozilla::gfx::IntRect(), ExtendMode::CLAMP); + } + + static ImageIntRegion Create(const mozilla::gfx::IntRect& aRect, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageIntRegion(aRect, aExtendMode); + } + + static ImageIntRegion Create(const mozilla::gfx::IntSize& aSize, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageIntRegion( + mozilla::gfx::IntRect(0, 0, aSize.width, aSize.height), aExtendMode); + } + + static ImageIntRegion CreateWithSamplingRestriction( + const mozilla::gfx::IntRect& aRect, + const mozilla::gfx::IntRect& aRestriction, + ExtendMode aExtendMode = ExtendMode::CLAMP) { + return ImageIntRegion(aRect, aRestriction, aExtendMode); + } + + bool IsRestricted() const { return mIsRestricted; } + const mozilla::gfx::IntRect& Rect() const { return mRect; } + + const mozilla::gfx::IntRect& Restriction() const { + MOZ_ASSERT(mIsRestricted); + return mRestriction; + } + + bool RestrictionContains(const mozilla::gfx::IntRect& aRect) const { + if (!mIsRestricted) { + return true; + } + return mRestriction.Contains(aRect); + } + + ImageIntRegion Intersect(const mozilla::gfx::IntRect& aRect) const { + if (mIsRestricted) { + return CreateWithSamplingRestriction(aRect.Intersect(mRect), + aRect.Intersect(mRestriction)); + } + return Create(aRect.Intersect(mRect)); + } + + mozilla::gfx::IntRect IntersectAndRestrict( + const mozilla::gfx::IntRect& aRect) const { + mozilla::gfx::IntRect intersection = mRect.Intersect(aRect); + if (mIsRestricted) { + intersection = mRestriction.Intersect(intersection); + } + return intersection; + } + + gfx::ExtendMode GetExtendMode() const { return mExtendMode; } + + ImageRegion ToImageRegion() const { + if (mIsRestricted) { + return ImageRegion::CreateWithSamplingRestriction( + gfxRect(mRect.x, mRect.y, mRect.width, mRect.height), + gfxRect(mRestriction.x, mRestriction.y, mRestriction.width, + mRestriction.height), + mExtendMode); + } + return ImageRegion::Create( + gfxRect(mRect.x, mRect.y, mRect.width, mRect.height), mExtendMode); + } + + bool operator==(const ImageIntRegion& aOther) const { + return mExtendMode == aOther.mExtendMode && + mIsRestricted == aOther.mIsRestricted && + mRect.IsEqualEdges(aOther.mRect) && + (!mIsRestricted || mRestriction.IsEqualEdges(aOther.mRestriction)); + } + + PLDHashNumber Hash() const { + return HashGeneric(mRect.x, mRect.y, mRect.width, mRect.height, + mRestriction.x, mRestriction.y, mRestriction.width, + mRestriction.height, mExtendMode, mIsRestricted); + } + + /* ImageIntRegion() : mIsRestricted(false) { } */ + + private: + explicit ImageIntRegion(const mozilla::gfx::IntRect& aRect, + ExtendMode aExtendMode) + : mRect(aRect), mExtendMode(aExtendMode), mIsRestricted(false) {} + + ImageIntRegion(const mozilla::gfx::IntRect& aRect, + const mozilla::gfx::IntRect& aRestriction, + ExtendMode aExtendMode) + : mRect(aRect), + mRestriction(aRestriction), + mExtendMode(aExtendMode), + mIsRestricted(true) {} + + mozilla::gfx::IntRect mRect; + mozilla::gfx::IntRect mRestriction; + ExtendMode mExtendMode; + bool mIsRestricted; +}; + +} // namespace image +} // namespace mozilla + +#endif // mozilla_image_ImageRegion_h |