File indexing completed on 2024-04-28 03:42:27

0001 /*
0002     SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 
0008 #pragma once
0009 
0010 #include <stdint.h>
0011 #include <QRect>
0012 #include <QVector>
0013 
0014 class ImageMask
0015 {
0016 public:
0017     /**
0018      * @brief ImageMask Create an image mask with image dimensions
0019      * @param width image width
0020      * @param height image height
0021      */
0022     ImageMask(const uint16_t width=0, const uint16_t height=0);
0023     virtual ~ImageMask(){};
0024 
0025     /**
0026      * @brief setImageGeometry set the image geometry
0027      * @param width image width
0028      * @param height image height
0029      */
0030     virtual void setImageGeometry(const uint16_t width, const uint16_t height);
0031 
0032     /**
0033      * @brief isVisible test if the given position is visible
0034      * @return in this basic version, a point is visible as long as it lies
0035      * within the image dimensions
0036      */
0037     virtual bool isVisible(uint16_t posX, uint16_t posY);
0038 
0039     /**
0040      * @brief translate which position on the frame has a point after masking
0041      * @param original point to be translated
0042      * @return same position as on the original image
0043      */
0044     QPointF translate(QPointF original) { return original; }
0045 
0046     /**
0047      * @brief active is the mask active (pure virtual)
0048      */
0049     virtual bool active() = 0;
0050 
0051     uint16_t width() const;
0052 
0053     uint16_t height() const;
0054 
0055 protected:
0056     uint16_t m_width, m_height;
0057 
0058     virtual void refresh() = 0;
0059 };
0060 
0061 class ImageRingMask : public ImageMask
0062 {
0063 public:
0064     /**
0065      * @brief ImageRingMask Create an image mask with a ring form
0066      * @param innerRadius inner ring radius in percent
0067      * @param outerRadius outer ring radius in percent
0068      * @param width image width
0069      * @param height image height
0070      */
0071     ImageRingMask(const float innerRadius=0, const float outerRadius=1, const uint16_t width=0, const uint16_t height=0);
0072 
0073     virtual ~ImageRingMask() {};
0074 
0075     /**
0076      * @brief isVisible test if the given position is visible
0077      * @return check if the position is inside the outer radius and outside the inner radius
0078      */
0079     bool isVisible(uint16_t posX, uint16_t posY) override;
0080 
0081     /**
0082      * @brief active The mask is active if either the inner radius > 0% or the outer radius < 100%
0083      */
0084     bool active() override { return m_width > 0 && m_height > 0 && (m_innerRadius > 0 || m_outerRadius < 1.0); };
0085 
0086     float innerRadius() const;
0087     void setInnerRadius(float newInnerRadius);
0088 
0089     float outerRadius() const;
0090     void setOuterRadius(float newOuterRadius);
0091 
0092 protected:
0093     // mask radius in percent of image diagonal
0094     float m_innerRadius {0};
0095     float m_outerRadius {1.0};
0096     // cached values for fast visibility calculation
0097     long m_InnerRadiusSquare, m_OuterRadiusSquare;
0098     // re-calculate the cached squares
0099     virtual void refresh() override;
0100 };
0101 
0102 class ImageMosaicMask : public ImageMask
0103 {
0104 public:
0105     /**
0106      * @brief ImageMosaicMask Creates a 3x3 mosaic mask
0107      * @param tileWidth width of a single mosaic tile (in percent of the image width)
0108      * @param space space between the mosaic tiles
0109      * @param width source image width
0110      * @param height source image height
0111      */
0112     ImageMosaicMask (const uint16_t tileWidth, const uint16_t space, const uint16_t width=0, const uint16_t height=0);
0113 
0114     /**
0115      * @brief isVisible test if the given position is visible
0116      * @return check if the position is inside one of the tiles
0117      */
0118     virtual bool isVisible(uint16_t posX, uint16_t posY) override;
0119 
0120     /**
0121      * @brief translate Calculate the new position of a point inside of the mosaic
0122      * @param original original position
0123      * @return position inside the mosaic
0124      */
0125     QPointF translate(QPointF original);
0126 
0127     /**
0128      * @brief active The mask is active if the mosaic raster is present
0129      */
0130     bool active() override { return m_width > 0 && m_height > 0 && m_tiles.length() > 0; };
0131 
0132     const QVector<QRect> tiles();
0133 
0134     float tileWidth() const;
0135     void setTileWidth(float newTileWidth);
0136 
0137     uint16_t space() const;
0138     void setSpace(uint16_t newSpace);
0139 
0140 
0141 protected:
0142     // width of a single mosaic tile (in percent of the image width)
0143     float m_tileWidth;
0144     // space between the mosaic tiles
0145     uint16_t m_space;
0146     // 3x3 mosaic raster, sorted linewise top down
0147     QVector<QRect> m_tiles;
0148     // re-calculate the tiles
0149     virtual void refresh() override;
0150 };