Krita Source Code Documentation
Loading...
Searching...
No Matches
KisCoordinatesConverter Class Reference

#include <kis_coordinates_converter.h>

+ Inheritance diagram for KisCoordinatesConverter:

Classes

struct  Private
 

Public Member Functions

void beginRotation ()
 
qreal clampZoom (qreal zoom) const
 
qreal devicePixelRatio () const
 
QPoint documentOffset () const
 
QPointF documentOffsetF () const
 
template<class T >
_Private::Traits< T >::Result documentToFlake (const T &obj) const
 
QTransform documentToFlakeTransform () const
 
template<class T >
_Private::Traits< T >::Result documentToImage (const T &obj) const
 
template<class T >
_Private::Traits< T >::Result documentToWidget (const T &obj) const
 
QTransform documentToWidgetTransform () const
 
qreal effectivePhysicalZoom () const
 
qreal effectiveZoom () const
 
void enableNatureGestureFlag ()
 
void endRotation ()
 
QPointF flakeCenterPoint () const
 
template<class T >
_Private::Traits< T >::Result flakeToDocument (const T &obj) const
 
template<class T >
_Private::Traits< T >::Result flakeToWidget (const T &obj) const
 
QTransform flakeToWidgetTransform () const
 
QSizeF getCanvasWidgetSize () const
 
void getOpenGLCheckersInfo (const QRectF &viewportRect, QTransform *textureTransform, QTransform *modelTransform, QRectF *textureRect, QRectF *modelRect, const bool scrollCheckers) const
 
void getQPainterCheckersInfo (QTransform *transform, QPointF *brushOrigin, QPolygonF *polygon, const bool scrollCheckers) const
 
QPointF imageCenterInWidgetPixel () const
 
void imagePhysicalScale (qreal *scaleX, qreal *scaleY) const
 
QRectF imageRectInDocumentPixels () const
 
QRect imageRectInImagePixels () const
 
QRectF imageRectInViewportPixels () const
 
QRectF imageRectInWidgetPixels () const
 
void imageScale (qreal *scaleX, qreal *scaleY) const
 
QSizeF imageSizeInFlakePixels () const
 
template<class T >
_Private::Traits< T >::Result imageToDocument (const T &obj) const
 
QTransform imageToDocumentTransform () const
 
template<class T >
_Private::Traits< T >::Result imageToViewport (const T &obj) const
 
QTransform imageToViewportTransform () const
 
template<class T >
_Private::Traits< T >::Result imageToWidget (const T &obj) const
 
QTransform imageToWidgetTransform () const
 
 KisCoordinatesConverter ()
 
KoViewTransformStillPoint makeDocStillPoint (const QPointF &docPoint) const override
 Creates a still point that links the docPoint of the image (in document pixels!) to the corresponding point on the screen (in the canvas widget).
 
KoViewTransformStillPoint makeWidgetStillPoint (const QPointF &viewPoint) const override
 Creates a still point that links the viewPoint of the widget to the corresponding point of the image.
 
QPoint maximumOffset () const
 
qreal maxZoom () const
 
QPoint minimumOffset () const
 
qreal minZoom () const
 
void mirror (const std::optional< KoViewTransformStillPoint > &stillPoint, bool mirrorXAxis, bool mirrorYAxis)
 mirrors the canvas
 
QPointF preferredTransformationCenter () const
 returns the point in image coordinates which is supposed to be the default still point for the transformations of the canvas. It returns the point of the image that is "roughly" mapped to to the center of the canvas widget.
 
void resetRotation (const std::optional< KoViewTransformStillPoint > &stillPoint)
 resets canvas rotation
 
void rotate (const std::optional< KoViewTransformStillPoint > &stillPoint, qreal angle)
 rotates the canvas
 
qreal rotationAngle () const
 
void setCanvasWidgetSize (QSizeF size)
 
void setCanvasWidgetSizeKeepZoom (const QSizeF &size)
 
void setDevicePixelRatio (qreal value)
 
void setDocumentOffset (const QPointF &offset)
 
void setExtraReferencesBounds (const QRect &imageRect)
 
void setImage (KisImageWSP image)
 
void setImageBounds (const QRect &rect, const QPointF oldImageStillPoint, const QPointF newImageStillPoint)
 
void setImageResolution (qreal xRes, qreal yRes)
 
void setZoom (KoZoomMode::Mode mode, qreal zoom, qreal resolutionX, qreal resolutionY, const std::optional< KoViewTransformStillPoint > &stillPoint)
 changes the zoom mode of the canvas
 
void setZoom (qreal zoom) override
 
QPointF snapToDevicePixel (const QPointF &point) const
 Adjust a given pair of coordinates to the nearest device pixel according to the value of devicePixelRatio.
 
QSizeF snapWidgetSizeToDevicePixel (const QSizeF &size) const
 
QVector< qreal > standardZoomLevels () const
 
QSize viewportDevicePixelSize () const
 
template<class T >
_Private::Traits< T >::Result viewportToImage (const T &obj) const
 
template<class T >
_Private::Traits< T >::Result viewportToWidget (const T &obj) const
 
QTransform viewportToWidgetTransform () const
 
QTransform viewToWidget () const override
 
QPointF widgetCenterPoint () const
 
QRectF widgetRectInFlakePixels () const
 
QRectF widgetRectInImagePixels () const
 
template<class T >
_Private::Traits< T >::Result widgetToDocument (const T &obj) const
 
template<class T >
_Private::Traits< T >::Result widgetToFlake (const T &obj) const
 
template<class T >
_Private::Traits< T >::Result widgetToImage (const T &obj) const
 
QTransform widgetToView () const override
 
template<class T >
_Private::Traits< T >::Result widgetToViewport (const T &obj) const
 
bool xAxisMirrored () const
 
bool yAxisMirrored () const
 
void zoomTo (const QRectF &widgetRect)
 
 ~KisCoordinatesConverter () override
 
- Public Member Functions inherited from KoZoomHandler
QPointF documentToView (const QPointF &documentPoint) const override
 
QRectF documentToView (const QRectF &documentRect) const override
 
QSizeF documentToView (const QSizeF &documentSize) const override
 
qreal documentToViewX (qreal documentX) const override
 
qreal documentToViewY (qreal documentY) const override
 
 KoZoomHandler ()
 
qreal resolutionX () const
 
qreal resolutionY () const
 
void setDpi (int dpiX, int dpiY)
 
void setResolution (qreal resolutionX, qreal resolutionY)
 
void setZoom (qreal zoom) override
 
virtual void setZoomedResolution (qreal zoomedResolutionX, qreal zoomedResolutionY)
 
void setZoomMarginSize (int size)
 
void setZoomMode (KoZoomMode::Mode zoomMode)
 
qreal unzoomItX (qreal x) const
 
qreal unzoomItY (qreal y) const
 
QPointF viewToDocument (const QPointF &viewPoint) const override
 
QRectF viewToDocument (const QRectF &viewRect) const override
 
QSizeF viewToDocument (const QSizeF &viewSize) const override
 
qreal viewToDocumentX (qreal viewX) const override
 
qreal viewToDocumentY (qreal viewY) const override
 
qreal zoom () const
 
virtual void zoom (qreal *zoomX, qreal *zoomY) const
 
void zoom (qreal *zoomX, qreal *zoomY) const override
 
qreal zoomedResolutionX () const
 
qreal zoomedResolutionY () const
 
qreal zoomFactorX () const
 
qreal zoomFactorY () const
 
int zoomInPercent () const
 
qreal zoomItX (qreal z) const
 
qreal zoomItY (qreal z) const
 
int zoomMarginSize () const
 
KoZoomMode::Mode zoomMode () const
 
 ~KoZoomHandler () override
 
- Public Member Functions inherited from KoViewConverter
QTransform documentToView () const
 
 KoViewConverter ()
 
QTransform viewToDocument () const
 
qreal zoom () const
 
virtual ~KoViewConverter ()
 

Static Public Member Functions

static qreal findNextZoom (qreal currentZoom, const QVector< qreal > &zoomLevels)
 
static qreal findPrevZoom (qreal currentZoom, const QVector< qreal > &zoomLevels)
 

Private Member Functions

QPointF centeringCorrection () const
 
void correctOffsetToTransformationAndSnap ()
 
void correctTransformationToOffset ()
 
void recalculateOffsetBoundsAndCrop ()
 
void recalculateTransformations ()
 
void recalculateZoomLevelLimits ()
 
void resetPreferredTransformationCenter ()
 

Private Attributes

Private *const m_d
 

Friends

class KisCoordinatesConverterTest
 
class KisZoomAndPanTest
 

Additional Inherited Members

- Protected Attributes inherited from KoZoomHandler
qreal m_resolutionX
 
qreal m_resolutionY
 
qreal m_zoomedResolutionX
 
qreal m_zoomedResolutionY
 
int m_zoomMarginSize
 
KoZoomMode::Mode m_zoomMode
 

Detailed Description

Definition at line 48 of file kis_coordinates_converter.h.

Constructor & Destructor Documentation

◆ KisCoordinatesConverter()

KisCoordinatesConverter::KisCoordinatesConverter ( )

Definition at line 216 of file kis_coordinates_converter.cpp.

◆ ~KisCoordinatesConverter()

KisCoordinatesConverter::~KisCoordinatesConverter ( )
override

Definition at line 219 of file kis_coordinates_converter.cpp.

220{
221 delete m_d;
222}

References m_d.

Member Function Documentation

◆ beginRotation()

◆ centeringCorrection()

QPointF KisCoordinatesConverter::centeringCorrection ( ) const
private

When vastScrolling value is less than 0.5 it is possible that the whole scrolling area (viewport) will be smaller than the size of the widget. In such cases the image should be centered in the widget. Previously we used a special parameter documentOrigin for this purpose, now the value for this centering is calculated dynamically, helping the offset to center the image inside the widget

Note that the correction is null when the size of the document plus vast scrolling reserve is larger than the widget. This is always true for vastScrolling parameter > 0.5.

Definition at line 96 of file kis_coordinates_converter.cpp.

97{
98 KisConfig cfg(true);
99
100 QSize documentSize = imageRectInWidgetPixels().toAlignedRect().size();
101 QPointF dPoint(documentSize.width(), documentSize.height());
102 QPointF wPoint(m_d->canvasWidgetSize.width(), m_d->canvasWidgetSize.height());
103
104 QPointF minOffset = -cfg.vastScrolling() * wPoint;
105 QPointF maxOffset = dPoint - wPoint + cfg.vastScrolling() * wPoint;
106
107 QPointF range = maxOffset - minOffset;
108
109 range.rx() = qMin(range.x(), (qreal)0.0);
110 range.ry() = qMin(range.y(), (qreal)0.0);
111
112 range /= 2;
113
114 return -range;
115}

References KisCoordinatesConverter::Private::canvasWidgetSize, imageRectInWidgetPixels(), m_d, and KisConfig::vastScrolling().

◆ clampZoom()

qreal KisCoordinatesConverter::clampZoom ( qreal zoom) const

Definition at line 927 of file kis_coordinates_converter.cpp.

928{
929 return std::clamp(zoom, minZoom(), maxZoom());
930}
qreal zoom() const

References maxZoom(), minZoom(), and KoZoomHandler::zoom().

◆ correctOffsetToTransformationAndSnap()

void KisCoordinatesConverter::correctOffsetToTransformationAndSnap ( )
private

The document offset and the position of the top left corner of the image must always coincide, that is why we need to correct them to and fro.

When we change zoom level, the calculation of the new offset is done by KoCanvasControllerWidget, that is why we just passively fix the flakeToWidget transform to conform the offset and wait until the canvas controller will recenter us.

But when we do our own transformations of the canvas, like rotation and mirroring, we cannot rely on the centering of the canvas controller and we do it ourselves. Then we just set new offset and return its value to be set in the canvas controller explicitly.

Definition at line 173 of file kis_coordinates_converter.cpp.

174{
177}
QPointF snapToDevicePixel(const QPointF &point) const
Adjust a given pair of coordinates to the nearest device pixel according to the value of devicePixelR...

References centeringCorrection(), KisCoordinatesConverter::Private::documentOffset, imageRectInWidgetPixels(), m_d, and snapToDevicePixel().

◆ correctTransformationToOffset()

void KisCoordinatesConverter::correctTransformationToOffset ( )
private

Definition at line 179 of file kis_coordinates_converter.cpp.

180{
181 QPointF topLeft = imageRectInWidgetPixels().topLeft();
182 QPointF diff = (-topLeft) - m_d->documentOffset;
183 diff += centeringCorrection();
184 m_d->flakeToWidget *= QTransform::fromTranslate(diff.x(), diff.y());
185}

References centeringCorrection(), KisCoordinatesConverter::Private::documentOffset, KisCoordinatesConverter::Private::flakeToWidget, imageRectInWidgetPixels(), and m_d.

◆ devicePixelRatio()

qreal KisCoordinatesConverter::devicePixelRatio ( ) const

◆ documentOffset()

QPoint KisCoordinatesConverter::documentOffset ( ) const

Definition at line 357 of file kis_coordinates_converter.cpp.

358{
359 return QPoint(int(m_d->documentOffset.x()), int(m_d->documentOffset.y()));
360}

References KisCoordinatesConverter::Private::documentOffset, and m_d.

◆ documentOffsetF()

QPointF KisCoordinatesConverter::documentOffsetF ( ) const

Definition at line 362 of file kis_coordinates_converter.cpp.

363{
364 return m_d->documentOffset;
365}

References KisCoordinatesConverter::Private::documentOffset, and m_d.

◆ documentToFlake()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::documentToFlake ( const T & obj) const
inline

Definition at line 182 of file kis_coordinates_converter.h.

static T map(const QTransform &transform, const T &obj)

References _Private::Traits< T >::map().

◆ documentToFlakeTransform()

QTransform KisCoordinatesConverter::documentToFlakeTransform ( ) const

◆ documentToImage()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::documentToImage ( const T & obj) const
inline

Definition at line 179 of file kis_coordinates_converter.h.

179{ return _Private::Traits<T>::map(imageToDocumentTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ documentToWidget()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::documentToWidget ( const T & obj) const
inline

◆ documentToWidgetTransform()

QTransform KisCoordinatesConverter::documentToWidgetTransform ( ) const

◆ effectivePhysicalZoom()

qreal KisCoordinatesConverter::effectivePhysicalZoom ( ) const

Definition at line 550 of file kis_coordinates_converter.cpp.

551{
552 qreal scaleX, scaleY;
553 this->imagePhysicalScale(&scaleX, &scaleY);
554
555 if (scaleX != scaleY) {
556 qWarning() << "WARNING: Zoom is not isotropic!" << ppVar(scaleX) << ppVar(scaleY) << ppVar(qFuzzyCompare(scaleX, scaleY));
557 }
558
559 // zoom by average of x and y
560 return 0.5 * (scaleX + scaleY);
561}
void imagePhysicalScale(qreal *scaleX, qreal *scaleY) const
static bool qFuzzyCompare(half p1, half p2)
#define ppVar(var)
Definition kis_debug.h:155

References imagePhysicalScale(), ppVar, and qFuzzyCompare().

◆ effectiveZoom()

qreal KisCoordinatesConverter::effectiveZoom ( ) const

A composition of to scale methods: zoom level + image resolution

Definition at line 537 of file kis_coordinates_converter.cpp.

538{
539 qreal scaleX, scaleY;
540 this->imageScale(&scaleX, &scaleY);
541
542 if (scaleX != scaleY) {
543 qWarning() << "WARNING: Zoom is not isotropic!" << ppVar(scaleX) << ppVar(scaleY) << ppVar(qFuzzyCompare(scaleX, scaleY));
544 }
545
546 // zoom by average of x and y
547 return 0.5 * (scaleX + scaleY);
548}
void imageScale(qreal *scaleX, qreal *scaleY) const

References imageScale(), ppVar, and qFuzzyCompare().

◆ enableNatureGestureFlag()

void KisCoordinatesConverter::enableNatureGestureFlag ( )

◆ endRotation()

◆ findNextZoom()

qreal KisCoordinatesConverter::findNextZoom ( qreal currentZoom,
const QVector< qreal > & zoomLevels )
static

Definition at line 957 of file kis_coordinates_converter.cpp.

958{
959 return KoZoomMode::findNextZoom(currentZoom, zoomLevels);
960}
static qreal findNextZoom(qreal currentZoom, const QVector< qreal > &zoomLevels)

References KoZoomMode::findNextZoom().

◆ findPrevZoom()

qreal KisCoordinatesConverter::findPrevZoom ( qreal currentZoom,
const QVector< qreal > & zoomLevels )
static

Definition at line 962 of file kis_coordinates_converter.cpp.

963{
964 return KoZoomMode::findPrevZoom(currentZoom, zoomLevels);
965}
static qreal findPrevZoom(qreal currentZoom, const QVector< qreal > &zoomLevels)

References KoZoomMode::findPrevZoom().

◆ flakeCenterPoint()

QPointF KisCoordinatesConverter::flakeCenterPoint ( ) const

Definition at line 855 of file kis_coordinates_converter.cpp.

856{
857 QRectF widgetRect = widgetRectInFlakePixels();
858 return QPointF(widgetRect.left() + widgetRect.width() / 2,
859 widgetRect.top() + widgetRect.height() / 2);
860}

References widgetRectInFlakePixels().

◆ flakeToDocument()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::flakeToDocument ( const T & obj) const
inline

Definition at line 184 of file kis_coordinates_converter.h.

184{ return _Private::Traits<T>::map(documentToFlakeTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ flakeToWidget()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::flakeToWidget ( const T & obj) const
inline

◆ flakeToWidgetTransform()

QTransform KisCoordinatesConverter::flakeToWidgetTransform ( ) const

Definition at line 742 of file kis_coordinates_converter.cpp.

742 {
743 return m_d->flakeToWidget;
744}

References KisCoordinatesConverter::Private::flakeToWidget, and m_d.

◆ getCanvasWidgetSize()

QSizeF KisCoordinatesConverter::getCanvasWidgetSize ( ) const

Definition at line 224 of file kis_coordinates_converter.cpp.

225{
226 return m_d->canvasWidgetSize;
227}

References KisCoordinatesConverter::Private::canvasWidgetSize, and m_d.

◆ getOpenGLCheckersInfo()

void KisCoordinatesConverter::getOpenGLCheckersInfo ( const QRectF & viewportRect,
QTransform * textureTransform,
QTransform * modelTransform,
QRectF * textureRect,
QRectF * modelRect,
const bool scrollCheckers ) const

Definition at line 787 of file kis_coordinates_converter.cpp.

793{
794 if(scrollCheckers) {
795 *textureTransform = QTransform();
796 *textureRect = QRectF(0, 0, viewportRect.width(),viewportRect.height());
797 }
798 else {
799 *textureTransform = viewportToWidgetTransform();
800 *textureRect = viewportRect;
801 }
802
803 *modelTransform = viewportToWidgetTransform();
804 *modelRect = viewportRect;
805}

References viewportToWidgetTransform().

◆ getQPainterCheckersInfo()

void KisCoordinatesConverter::getQPainterCheckersInfo ( QTransform * transform,
QPointF * brushOrigin,
QPolygonF * polygon,
const bool scrollCheckers ) const

Qt has different rounding for QPainter::drawRect/drawImage. The image is rounded mathematically, while rect in aligned to the next integer. That causes transparent line appear on the canvas.

See: https://bugreports.qt.nokia.com/browse/QTBUG-22827

Definition at line 758 of file kis_coordinates_converter.cpp.

762{
772 QRectF imageRect = imageRectInViewportPixels();
773 imageRect.adjust(0,0,-0.5,-0.5);
774
775 if (scrollCheckers) {
776 *transform = viewportToWidgetTransform();
777 *polygon = imageRect;
778 *brushOrigin = imageToViewport(QPointF(0,0));
779 }
780 else {
781 *transform = QTransform();
782 *polygon = viewportToWidgetTransform().map(imageRect);
783 *brushOrigin = QPoint(0,0);
784 }
785}
_Private::Traits< T >::Result imageToViewport(const T &obj) const

References imageRectInViewportPixels(), imageToViewport(), and viewportToWidgetTransform().

◆ imageCenterInWidgetPixel()

QPointF KisCoordinatesConverter::imageCenterInWidgetPixel ( ) const

Definition at line 807 of file kis_coordinates_converter.cpp.

808{
809 QPolygonF poly = imageToWidget(QPolygon(m_d->imageBounds));
810 return (poly[0] + poly[1] + poly[2] + poly[3]) / 4.0;
811}
_Private::Traits< T >::Result imageToWidget(const T &obj) const

References KisCoordinatesConverter::Private::imageBounds, imageToWidget(), and m_d.

◆ imagePhysicalScale()

void KisCoordinatesConverter::imagePhysicalScale ( qreal * scaleX,
qreal * scaleY ) const

Definition at line 882 of file kis_coordinates_converter.cpp.

883{
884 imageScale(scaleX, scaleY);
885 *scaleX *= m_d->devicePixelRatio;
886 *scaleY *= m_d->devicePixelRatio;
887}

References KisCoordinatesConverter::Private::devicePixelRatio, imageScale(), and m_d.

◆ imageRectInDocumentPixels()

QRectF KisCoordinatesConverter::imageRectInDocumentPixels ( ) const

Definition at line 831 of file kis_coordinates_converter.cpp.

832{
834}
_Private::Traits< T >::Result imageToDocument(const T &obj) const

References KisCoordinatesConverter::Private::imageBounds, imageToDocument(), and m_d.

◆ imageRectInImagePixels()

QRect KisCoordinatesConverter::imageRectInImagePixels ( ) const

Definition at line 826 of file kis_coordinates_converter.cpp.

827{
828 return m_d->imageBounds;
829}

References KisCoordinatesConverter::Private::imageBounds, and m_d.

◆ imageRectInViewportPixels()

QRectF KisCoordinatesConverter::imageRectInViewportPixels ( ) const

◆ imageRectInWidgetPixels()

QRectF KisCoordinatesConverter::imageRectInWidgetPixels ( ) const

◆ imageScale()

void KisCoordinatesConverter::imageScale ( qreal * scaleX,
qreal * scaleY ) const

Definition at line 867 of file kis_coordinates_converter.cpp.

868{
869 // get the x and y zoom level of the canvas
870 qreal zoomX, zoomY;
871 KoZoomHandler::zoom(&zoomX, &zoomY);
872
873 // Get the KisImage resolution
874 qreal resX = m_d->imageXRes;
875 qreal resY = m_d->imageYRes;
876
877 // Compute the scale factors
878 *scaleX = zoomX / resX;
879 *scaleY = zoomY / resY;
880}

References KisCoordinatesConverter::Private::imageXRes, KisCoordinatesConverter::Private::imageYRes, m_d, and KoZoomHandler::zoom().

◆ imageSizeInFlakePixels()

QSizeF KisCoordinatesConverter::imageSizeInFlakePixels ( ) const

Definition at line 836 of file kis_coordinates_converter.cpp.

837{
838 qreal scaleX, scaleY;
839 imageScale(&scaleX, &scaleY);
840 QSize imageSize = m_d->imageBounds.size();
841
842 return QSizeF(imageSize.width() * scaleX, imageSize.height() * scaleY);
843}

References KisCoordinatesConverter::Private::imageBounds, imageScale(), and m_d.

◆ imageToDocument()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::imageToDocument ( const T & obj) const
inline

◆ imageToDocumentTransform()

QTransform KisCoordinatesConverter::imageToDocumentTransform ( ) const

◆ imageToViewport()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::imageToViewport ( const T & obj) const
inline

◆ imageToViewportTransform()

◆ imageToWidget()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::imageToWidget ( const T & obj) const
inline

◆ imageToWidgetTransform()

QTransform KisCoordinatesConverter::imageToWidgetTransform ( ) const

◆ makeDocStillPoint()

KoViewTransformStillPoint KisCoordinatesConverter::makeDocStillPoint ( const QPointF & docPoint) const
overridevirtual

Creates a still point that links the docPoint of the image (in document pixels!) to the corresponding point on the screen (in the canvas widget).

The link is "baked" in KoViewTransformStillPoint object, hence intermediate transformations will not affect it.

Reimplemented in KisCoordinatesConverter.

Reimplemented from KoViewConverter.

Definition at line 972 of file kis_coordinates_converter.cpp.

973{
974 return {docPoint, documentToWidget(docPoint)};
975}
_Private::Traits< T >::Result documentToWidget(const T &obj) const

References documentToWidget().

◆ makeWidgetStillPoint()

KoViewTransformStillPoint KisCoordinatesConverter::makeWidgetStillPoint ( const QPointF & viewPoint) const
overridevirtual

Creates a still point that links the viewPoint of the widget to the corresponding point of the image.

The link is "baked" in KoViewTransformStillPoint object, hence intermediate transformations will not affect it.

Reimplemented in KisCoordinatesConverter.

Reimplemented from KoViewConverter.

Definition at line 967 of file kis_coordinates_converter.cpp.

968{
969 return {widgetToDocument(viewPoint), viewPoint};
970}
_Private::Traits< T >::Result widgetToDocument(const T &obj) const

References widgetToDocument().

◆ maximumOffset()

QPoint KisCoordinatesConverter::maximumOffset ( ) const

◆ maxZoom()

qreal KisCoordinatesConverter::maxZoom ( ) const

◆ minimumOffset()

QPoint KisCoordinatesConverter::minimumOffset ( ) const

◆ minZoom()

qreal KisCoordinatesConverter::minZoom ( ) const

◆ mirror()

void KisCoordinatesConverter::mirror ( const std::optional< KoViewTransformStillPoint > & stillPoint,
bool mirrorXAxis,
bool mirrorYAxis )

mirrors the canvas

For the meaning of stillPoint

See also
setZoom()

Definition at line 628 of file kis_coordinates_converter.cpp.

629{
630 bool keepOrientation = false; // XXX: Keep here for now, maybe some day we can restore the parameter again.
631
632 KoViewTransformStillPoint effectiveStillPoint =
633 stillPoint ? *stillPoint :
635
636
637 if (kisSquareDistance(effectiveStillPoint.viewPoint(), widgetCenterPoint()) > 2.0) {
638 // when mirroring not against the center, reset the zoom mode
640 }
641
642 const QPointF oldDocumentOffset = m_d->documentOffset;
643
644 bool doXMirroring = m_d->isXAxisMirrored ^ mirrorXAxis;
645 bool doYMirroring = m_d->isYAxisMirrored ^ mirrorYAxis;
646 qreal scaleX = doXMirroring ? -1.0 : 1.0;
647 qreal scaleY = doYMirroring ? -1.0 : 1.0;
648 QTransform mirror = QTransform::fromScale(scaleX, scaleY);
649
650 QTransform rot;
651 rot.rotate(m_d->rotationAngle);
652
653 m_d->flakeToWidget *= QTransform::fromTranslate(-effectiveStillPoint.viewPoint().x(),-effectiveStillPoint.viewPoint().y());
654
655 if (keepOrientation) {
656 m_d->flakeToWidget *= rot.inverted();
657 }
658
660
661 if (keepOrientation) {
662 m_d->flakeToWidget *= rot;
663 }
664
665 m_d->flakeToWidget *= QTransform::fromTranslate(effectiveStillPoint.viewPoint().x(),effectiveStillPoint.viewPoint().y());
666
667
668 if (!keepOrientation && (doXMirroring ^ doYMirroring)) {
670 }
671
672 m_d->isXAxisMirrored = mirrorXAxis;
673 m_d->isYAxisMirrored = mirrorYAxis;
674
676
678 // we were "centered", so let's try to keep the offset as before
679 m_d->documentOffset = oldDocumentOffset;
680 } else {
682 const QPointF newStillPoint = documentToWidget(effectiveStillPoint.docPoint());
683 const QPointF offset = newStillPoint - effectiveStillPoint.viewPoint();
685 }
686
688
689 if (stillPoint) {
691 }
692}
void mirror(const std::optional< KoViewTransformStillPoint > &stillPoint, bool mirrorXAxis, bool mirrorYAxis)
mirrors the canvas
KoZoomMode::Mode zoomMode() const
void setZoomMode(KoZoomMode::Mode zoomMode)
@ ZOOM_CONSTANT
zoom x %
Definition KoZoomMode.h:24
qreal kisSquareDistance(const QPointF &pt1, const QPointF &pt2)
Definition kis_global.h:194

References correctOffsetToTransformationAndSnap(), KoViewTransformStillPoint::docPoint(), KisCoordinatesConverter::Private::documentOffset, documentToWidget(), KisCoordinatesConverter::Private::flakeToWidget, KisCoordinatesConverter::Private::isXAxisMirrored, KisCoordinatesConverter::Private::isYAxisMirrored, kisSquareDistance(), m_d, mirror(), KisCoordinatesConverter::Private::preferredTransformationCenterInDocumentPixels(), recalculateTransformations(), resetPreferredTransformationCenter(), KisCoordinatesConverter::Private::rotationAngle, KoZoomHandler::setZoomMode(), snapToDevicePixel(), KoViewTransformStillPoint::viewPoint(), widgetCenterPoint(), KoZoomMode::ZOOM_CONSTANT, and KoZoomHandler::zoomMode().

◆ preferredTransformationCenter()

QPointF KisCoordinatesConverter::preferredTransformationCenter ( ) const

returns the point in image coordinates which is supposed to be the default still point for the transformations of the canvas. It returns the point of the image that is "roughly" mapped to to the center of the canvas widget.

Some of the methods of the converter accept std::optional<KoViewTransformStillPoint> for a still point, over which the transformation should happen. When this argument is std::nullotp, then preferredTransformationCenter() is used.

One important property of preferredTransformationCenter() is that it is not changed when the canvas is transformed over it, even when pixel alignment happens. It means that preferredTransformationCenter() may not exactly map to the center of the widget, due to hardware-pixel-alignment.

Keeping this value unchanged allows us to avoid drifts of the offset when zooming and rotating the canvas.

Definition at line 367 of file kis_coordinates_converter.cpp.

References m_d, and KisCoordinatesConverter::Private::preferredTransformationCenterImage.

◆ recalculateOffsetBoundsAndCrop()

void KisCoordinatesConverter::recalculateOffsetBoundsAndCrop ( )
private

Definition at line 117 of file kis_coordinates_converter.cpp.

118{
119 if (!m_d->canvasWidgetSize.isValid()) return;
120
121 KisConfig cfg(true);
122
123 const QRect refRect = imageToWidget(m_d->extraReferencesBounds).toAlignedRect();
124
125 QRect documentRect = imageRectInWidgetPixels().toAlignedRect();
126 QPointF dPointMax(qMax(documentRect.width(), refRect.right() + 1 - documentRect.x()),
127 qMax(documentRect.height(), refRect.bottom() + 1 - documentRect.y()));
128 QPointF dPointMin(qMin(0, refRect.left() - documentRect.x()),
129 qMin(0, refRect.top() - documentRect.y()));
130 QPointF wPoint(m_d->canvasWidgetSize.width(), m_d->canvasWidgetSize.height());
131
132 QPointF minOffset = dPointMin - cfg.vastScrolling() * wPoint;
133 QPointF maxOffset = dPointMax - wPoint + cfg.vastScrolling() * wPoint;
134
135 m_d->minimumOffset = minOffset.toPoint();
136 m_d->maximumOffset = maxOffset.toPoint();
137
138 const QRectF limitRect(m_d->minimumOffset, m_d->maximumOffset);
139
140 if (!limitRect.contains(m_d->documentOffset)) {
142 qDebug() << " corrected offset:" << m_d->documentOffset;
144 }
145}
Point clampPoint(Point pt, const Rect &bounds)

References KisCoordinatesConverter::Private::canvasWidgetSize, KisAlgebra2D::clampPoint(), correctTransformationToOffset(), KisCoordinatesConverter::Private::documentOffset, KisCoordinatesConverter::Private::extraReferencesBounds, imageRectInWidgetPixels(), imageToWidget(), m_d, KisCoordinatesConverter::Private::maximumOffset, KisCoordinatesConverter::Private::minimumOffset, snapToDevicePixel(), and KisConfig::vastScrolling().

◆ recalculateTransformations()

void KisCoordinatesConverter::recalculateTransformations ( )
private

Definition at line 192 of file kis_coordinates_converter.cpp.

193{
194 m_d->imageToDocument = QTransform::fromScale(1 / m_d->imageXRes,
195 1 / m_d->imageYRes);
196
197 qreal zoomX, zoomY;
198 KoZoomHandler::zoom(&zoomX, &zoomY);
199 m_d->documentToFlake = QTransform::fromScale(zoomX, zoomY);
200
203
204 QRectF irect = imageRectInWidgetPixels();
205 QRectF wrect = QRectF(QPoint(0,0), m_d->canvasWidgetSize);
206 QRectF rrect = irect & wrect;
207
208 QTransform reversedTransform = flakeToWidgetTransform().inverted();
209 QRectF canvasBounds = reversedTransform.mapRect(rrect);
210 QPointF offset = canvasBounds.topLeft();
211
212 m_d->widgetToViewport = reversedTransform * QTransform::fromTranslate(-offset.x(), -offset.y());
213}

References KisCoordinatesConverter::Private::canvasWidgetSize, correctTransformationToOffset(), KisCoordinatesConverter::Private::documentToFlake, flakeToWidgetTransform(), imageRectInWidgetPixels(), KisCoordinatesConverter::Private::imageToDocument, KisCoordinatesConverter::Private::imageXRes, KisCoordinatesConverter::Private::imageYRes, m_d, recalculateOffsetBoundsAndCrop(), KisCoordinatesConverter::Private::widgetToViewport, and KoZoomHandler::zoom().

◆ recalculateZoomLevelLimits()

void KisCoordinatesConverter::recalculateZoomLevelLimits ( )
private

Definition at line 942 of file kis_coordinates_converter.cpp.

943{
944 qreal minDimension = 0.0;
945
946 if (m_d->imageBounds.width() < m_d->imageBounds.height()) {
948 } else {
950 }
951
952 m_d->minZoom = qMin(100.0 / minDimension, 0.1);
953 m_d->maxZoom = 90.0;
954 m_d->standardZoomLevels.clear(); // TODO: reset only on real change!
955}
qreal resolutionX() const
qreal resolutionY() const
auto minDimension(Size size) -> decltype(size.width())
KisValueCache< StandardZoomLevelsInitializer > standardZoomLevels

References KisCoordinatesConverter::Private::imageBounds, KisCoordinatesConverter::Private::imageXRes, KisCoordinatesConverter::Private::imageYRes, m_d, KisCoordinatesConverter::Private::maxZoom, KisCoordinatesConverter::Private::minZoom, KoZoomHandler::resolutionX(), KoZoomHandler::resolutionY(), and KisCoordinatesConverter::Private::standardZoomLevels.

◆ resetPreferredTransformationCenter()

void KisCoordinatesConverter::resetPreferredTransformationCenter ( )
private

◆ resetRotation()

void KisCoordinatesConverter::resetRotation ( const std::optional< KoViewTransformStillPoint > & stillPoint)

resets canvas rotation

For the meaning of stillPoint

See also
setZoom()

Definition at line 704 of file kis_coordinates_converter.cpp.

705{
706 KoViewTransformStillPoint effectiveStillPoint =
707 stillPoint ? *stillPoint :
709
710 QTransform rot;
711 rot.rotate(-m_d->rotationAngle);
712
713 m_d->flakeToWidget *= rot;
714 m_d->rotationAngle = 0.0;
716
719
720 const QPointF newStillPoint = documentToWidget(effectiveStillPoint.docPoint());
721 const QPointF offset = newStillPoint - effectiveStillPoint.viewPoint();
724
725 if (stillPoint) {
727 }
728}

References correctOffsetToTransformationAndSnap(), KoViewTransformStillPoint::docPoint(), KisCoordinatesConverter::Private::documentOffset, documentToWidget(), KisCoordinatesConverter::Private::flakeToWidget, m_d, KisCoordinatesConverter::Private::preferredTransformationCenterInDocumentPixels(), recalculateTransformations(), resetPreferredTransformationCenter(), KisCoordinatesConverter::Private::rotationAngle, KisCoordinatesConverter::Private::rotationIsOrthogonal, snapToDevicePixel(), KoViewTransformStillPoint::viewPoint(), and widgetCenterPoint().

◆ rotate()

void KisCoordinatesConverter::rotate ( const std::optional< KoViewTransformStillPoint > & stillPoint,
qreal angle )

rotates the canvas

For the meaning of stillPoint

See also
setZoom()

Definition at line 586 of file kis_coordinates_converter.cpp.

587{
589
590 KoViewTransformStillPoint effectiveStillPoint =
591 stillPoint ? *stillPoint :
593
594 QTransform rot;
595 rot.rotate(angle);
596
598 {
599 // Modal (begin/end) rotation. Transform from the stable base.
601 m_d->rotationAngle = std::fmod(m_d->rotationBaseAngle + angle, 360.0);
602 }
603 else
604 {
605 // Immediate rotation, directly applied to the canvas transformation.
606 m_d->rotationAngle = std::fmod(m_d->rotationAngle + angle, 360.0);
607 }
608
609 {
610 const qreal numQuadrants = m_d->rotationAngle / 90.0;
611 m_d->rotationIsOrthogonal = std::floor(numQuadrants) == numQuadrants;
612 }
613
614 m_d->flakeToWidget *= rot;
617
618 const QPointF newStillPoint = documentToWidget(effectiveStillPoint.docPoint());
619 const QPointF offset = newStillPoint - effectiveStillPoint.viewPoint();
622
623 if (stillPoint) {
625 }
626}

References correctOffsetToTransformationAndSnap(), KoViewTransformStillPoint::docPoint(), KisCoordinatesConverter::Private::documentOffset, documentToWidget(), KisCoordinatesConverter::Private::flakeToWidget, KisCoordinatesConverter::Private::isNativeGesture, KisCoordinatesConverter::Private::isRotating, m_d, KisCoordinatesConverter::Private::preferredTransformationCenterInDocumentPixels(), recalculateTransformations(), resetPreferredTransformationCenter(), KisCoordinatesConverter::Private::rotationAngle, KisCoordinatesConverter::Private::rotationBaseAngle, KisCoordinatesConverter::Private::rotationBaseTransform, KisCoordinatesConverter::Private::rotationIsOrthogonal, KoZoomHandler::setZoomMode(), snapToDevicePixel(), KoViewTransformStillPoint::viewPoint(), widgetCenterPoint(), and KoZoomMode::ZOOM_CONSTANT.

◆ rotationAngle()

qreal KisCoordinatesConverter::rotationAngle ( ) const

Definition at line 372 of file kis_coordinates_converter.cpp.

373{
374 return m_d->rotationAngle;
375}

References m_d, and KisCoordinatesConverter::Private::rotationAngle.

◆ setCanvasWidgetSize()

void KisCoordinatesConverter::setCanvasWidgetSize ( QSizeF size)

Definition at line 229 of file kis_coordinates_converter.cpp.

230{
233
234 // the widget center has changed, hence the preferred
235 // center changes as well
237}
QSizeF snapWidgetSizeToDevicePixel(const QSizeF &size) const

References KisCoordinatesConverter::Private::canvasWidgetSize, m_d, recalculateTransformations(), resetPreferredTransformationCenter(), and snapWidgetSizeToDevicePixel().

◆ setCanvasWidgetSizeKeepZoom()

void KisCoordinatesConverter::setCanvasWidgetSizeKeepZoom ( const QSizeF & size)

WARNING: we can safely call setZoom() after changing widget size only for non-constant modes, because they have no still points, they always align to the center of the widget. Constant mode, reads the state of the canvas before transformation to calculate the position of the still point, hence we cannot change the state separately.

Definition at line 388 of file kis_coordinates_converter.cpp.

389{
391
393 // in constant mode we just preserve the document offset
394 // (as much as we can in relation to the vast scroll factor)
395 } else {
403 setZoom(zoomMode(), 777.0, resolutionX(), resolutionY(), std::nullopt);
404 }
405}
void setZoom(qreal zoom) override

References KoZoomHandler::resolutionX(), KoZoomHandler::resolutionY(), setCanvasWidgetSize(), setZoom(), KoZoomMode::ZOOM_CONSTANT, and KoZoomHandler::zoomMode().

◆ setDevicePixelRatio()

void KisCoordinatesConverter::setDevicePixelRatio ( qreal value)

Definition at line 239 of file kis_coordinates_converter.cpp.

240{
242}
float value(const T *src, size_t ch)

References KisCoordinatesConverter::Private::devicePixelRatio, m_d, and value().

◆ setDocumentOffset()

void KisCoordinatesConverter::setDocumentOffset ( const QPointF & offset)

Definition at line 329 of file kis_coordinates_converter.cpp.

330{
331 // when changing the offset manually, the mode is explicitly
332 // reset to constant
334
335 // The given offset is in widget logical pixels. In order to prevent fuzzy
336 // canvas rendering at 100% pixel-perfect zoom level when devicePixelRatio
337 // is not integral, we adjusts the offset to map to whole device pixels.
338
339 // Steps to reproduce the issue (when no snapping):
340 // 1) Download an image with 1px vertical black and white stripes
341 // 2) Enable fractional HiDPI support in Krita
342 // 3) Set display scaling to 1.5 or 2.5
343 // 4) Try to change offset of the image. If offset is unaligned, then
344 // the image will disappear on the canvas.
345
348
350}

References KisCoordinatesConverter::Private::documentOffset, m_d, recalculateTransformations(), resetPreferredTransformationCenter(), KoZoomHandler::setZoomMode(), snapToDevicePixel(), and KoZoomMode::ZOOM_CONSTANT.

◆ setExtraReferencesBounds()

void KisCoordinatesConverter::setExtraReferencesBounds ( const QRect & imageRect)

Definition at line 269 of file kis_coordinates_converter.cpp.

270{
271 if (imageRect == m_d->extraReferencesBounds) return;
272
273 // this value affects scroll range only, so no need to do extra
274 // still point tracking
275 m_d->extraReferencesBounds = imageRect;
277}

References KisCoordinatesConverter::Private::extraReferencesBounds, m_d, and recalculateTransformations().

◆ setImage()

void KisCoordinatesConverter::setImage ( KisImageWSP image)

Definition at line 244 of file kis_coordinates_converter.cpp.

245{
246 m_d->imageXRes = image->xRes();
247 m_d->imageYRes = image->yRes();
248
249 // we should **not** call setResolution() here, since
250 // it is a different kind of resolution that is used
251 // to convert the image to the physical size of the display
252
253 m_d->imageBounds = image->bounds();
256
257 if (m_d->canvasWidgetSize.isEmpty()) {
258 // if setImage() comes before setCanvasWidgetSize(), then just remember the
259 // proposed mode and postpone the actual recentering of the image
260 // (this case is supposed to happen in unittests only)
263 } else {
264 // the default mode after initialization is "Zoom Page"
265 setZoom(KoZoomMode::ZOOM_PAGE, 777.7, resolutionX(), resolutionY(), std::nullopt);
266 }
267}
double xRes() const
double yRes() const
QRect bounds() const override
@ ZOOM_PAGE
zoom page
Definition KoZoomMode.h:25

References KisImage::bounds(), KisCoordinatesConverter::Private::canvasWidgetSize, KisCoordinatesConverter::Private::imageBounds, KisCoordinatesConverter::Private::imageXRes, KisCoordinatesConverter::Private::imageYRes, m_d, KisCoordinatesConverter::Private::preferredTransformationCenterImage, recalculateTransformations(), recalculateZoomLevelLimits(), KoZoomHandler::resolutionX(), KoZoomHandler::resolutionY(), setZoom(), KoZoomHandler::setZoomMode(), KisImage::xRes(), KisImage::yRes(), and KoZoomMode::ZOOM_PAGE.

◆ setImageBounds()

void KisCoordinatesConverter::setImageBounds ( const QRect & rect,
const QPointF oldImageStillPoint,
const QPointF newImageStillPoint )

Definition at line 279 of file kis_coordinates_converter.cpp.

280{
281 if (rect == m_d->imageBounds) return;
282
283 const QPointF oldWidgetStillPoint = imageToWidget(oldImageStillPoint);
284
285 // we reset zoom mode to constant to make sure that
286 // the image changes visually for the user
288
292
293 const QPointF newWidgetStillPoint = imageToWidget(newImageStillPoint);
294 m_d->documentOffset = snapToDevicePixel(m_d->documentOffset + newWidgetStillPoint - oldWidgetStillPoint);
296
298}

References KisCoordinatesConverter::Private::documentOffset, KisCoordinatesConverter::Private::imageBounds, imageToWidget(), m_d, recalculateTransformations(), recalculateZoomLevelLimits(), resetPreferredTransformationCenter(), KoZoomHandler::setZoomMode(), snapToDevicePixel(), and KoZoomMode::ZOOM_CONSTANT.

◆ setImageResolution()

void KisCoordinatesConverter::setImageResolution ( qreal xRes,
qreal yRes )

Definition at line 300 of file kis_coordinates_converter.cpp.

301{
302 // we consiter the center of the image to be the still point
303 // on the canvas
304
305 if (qFuzzyCompare(xRes, m_d->imageXRes) && qFuzzyCompare(yRes, m_d->imageYRes)) return;
306
307 const QPointF oldImageCenter = imageCenterInWidgetPixel();
308
309 // we should **not** call setResolution() here, since
310 // it is a different kind of resolution that is used
311 // to convert the image to the physical size of the display
312
313 // we reset zoom mode to constant to make sure that
314 // the image changes visually for the user
316
317 m_d->imageXRes = xRes;
318 m_d->imageYRes = yRes;
321
322 const QPointF newImageCenter = imageCenterInWidgetPixel();
323 m_d->documentOffset = snapToDevicePixel(m_d->documentOffset + newImageCenter - oldImageCenter);
325
327}

References KisCoordinatesConverter::Private::documentOffset, imageCenterInWidgetPixel(), KisCoordinatesConverter::Private::imageXRes, KisCoordinatesConverter::Private::imageYRes, m_d, qFuzzyCompare(), recalculateTransformations(), recalculateZoomLevelLimits(), resetPreferredTransformationCenter(), KoZoomHandler::setZoomMode(), snapToDevicePixel(), and KoZoomMode::ZOOM_CONSTANT.

◆ setZoom() [1/2]

void KisCoordinatesConverter::setZoom ( KoZoomMode::Mode mode,
qreal zoom,
qreal resolutionX,
qreal resolutionY,
const std::optional< KoViewTransformStillPoint > & stillPoint )

changes the zoom mode of the canvas

When mode is KoZoomMode::ZOOM_CONSTANT, stillPoint instructs the converter to keep the passed point "still", i.e. to make sure that stillPoint.docPoint() maps to stillPoint.widgetPoint() on screen.

Please make sure that there is no guarantee that the still point will map to the passed points exactly! The still point may be offset by at most (0.5 * sqrt(2) / devicePixelRatio()) due to hardware pixel alignment.

This alignment is the reason why we pass both document and view points as a still point, because both values should be kept constant during iterative zoom operations. Otherwise the canvas will drift to the side because of the pixel alignmentl.

If stillPoint is std::nullopt, then the zooming happens over preferredTransformationCenter(), which is basically the center of canvas widget, but with some guards against the drifting.

only constant mode is a subject for clamping, fit-modes are allowed to zoom as much as needed

Definition at line 433 of file kis_coordinates_converter.cpp.

434{
435 const int cfgMargin = zoomMarginSize();
436
437 auto updateDisplayResolution = [&]() {
441 }
442 };
443
444 if(mode == KoZoomMode::ZOOM_CONSTANT) {
445 if(qFuzzyIsNull(zoom)) return;
446
450
451 KoViewTransformStillPoint effectiveStillPoint =
452 stillPoint ? *stillPoint :
454
455 updateDisplayResolution();
459
460 const QPointF newStillPoint = documentToWidget(effectiveStillPoint.docPoint());
461 const QPointF offset = newStillPoint - effectiveStillPoint.viewPoint();
464
465 if (stillPoint) {
467 }
468
469 } else if (mode == KoZoomMode::ZOOM_PAGE || mode == KoZoomMode::ZOOM_WIDTH || mode == KoZoomMode::ZOOM_HEIGHT) {
470 updateDisplayResolution();
472
474
475 const QSizeF documentSize = imageRectInWidgetPixels().size();
476 const qreal zoomCoeffX = (m_d->canvasWidgetSize.width() - 2 * cfgMargin) / documentSize.width();
477 const qreal zoomCoeffY = (m_d->canvasWidgetSize.height() - 2 * cfgMargin) / documentSize.height();
478
479 const bool fitToWidth = [&]() {
480 if (mode == KoZoomMode::ZOOM_PAGE) {
481 return zoomCoeffX < zoomCoeffY;
482 } else if (mode == KoZoomMode::ZOOM_HEIGHT) {
483 return false;
484 } else if (mode == KoZoomMode::ZOOM_WIDTH) {
485 return true;
486 }
487 Q_UNREACHABLE_RETURN(true);
488 }();
489
490 KoZoomHandler::setZoom(this->zoom() * (fitToWidth ? zoomCoeffX : zoomCoeffY));
493
494 const QPointF offset = imageCenterInWidgetPixel() - widgetCenterPoint();
495
496 QPointF newDocumentOffset = m_d->documentOffset + offset;
497
498 // just explicitly set minimal axis offset to zero to
499 // avoid imperfections of floating point numbers
500 if (fitToWidth) {
501 newDocumentOffset.setX(-cfgMargin);
502 } else {
503 newDocumentOffset.setY(-cfgMargin);
504 }
505
506 m_d->documentOffset = snapToDevicePixel(newDocumentOffset);
508
510 }
511}
int zoomMarginSize() const
void setZoom(qreal zoom) override
void setResolution(qreal resolutionX, qreal resolutionY)
@ ZOOM_WIDTH
zoom pagewidth
Definition KoZoomMode.h:26
@ ZOOM_HEIGHT
zoom pageheight
Definition KoZoomMode.h:27
static bool qFuzzyIsNull(half h)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QAction * fitToWidth(const QObject *recvr, const char *slot, QObject *parent)

References KisCoordinatesConverter::Private::canvasWidgetSize, clampZoom(), KoViewTransformStillPoint::docPoint(), KisCoordinatesConverter::Private::documentOffset, documentToWidget(), imageCenterInWidgetPixel(), imageRectInWidgetPixels(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, KisCoordinatesConverter::Private::preferredTransformationCenterInDocumentPixels(), qFuzzyCompare(), qFuzzyIsNull(), recalculateTransformations(), recalculateZoomLevelLimits(), resetPreferredTransformationCenter(), KoZoomHandler::resolutionX(), KoZoomHandler::resolutionY(), KoZoomHandler::setResolution(), KoZoomHandler::setZoom(), KoZoomHandler::setZoomMode(), snapToDevicePixel(), KoViewTransformStillPoint::viewPoint(), widgetCenterPoint(), KoZoomHandler::zoom(), KoZoomMode::ZOOM_CONSTANT, KoZoomMode::ZOOM_HEIGHT, KoZoomMode::ZOOM_PAGE, KoZoomMode::ZOOM_WIDTH, and KoZoomHandler::zoomMarginSize().

◆ setZoom() [2/2]

void KisCoordinatesConverter::setZoom ( qreal zoom)
overridevirtual

Set the zoom level. 1.0 is 100%.

Reimplemented from KoViewConverter.

Definition at line 377 of file kis_coordinates_converter.cpp.

378{
379 // when changing the offset manually, the mode is explicitly
380 // reset to constant, this method is used in unittests mostly
382
386}

References recalculateTransformations(), resetPreferredTransformationCenter(), KoZoomHandler::setZoom(), KoZoomHandler::setZoomMode(), KoZoomHandler::zoom(), and KoZoomMode::ZOOM_CONSTANT.

◆ snapToDevicePixel()

QPointF KisCoordinatesConverter::snapToDevicePixel ( const QPointF & point) const

Adjust a given pair of coordinates to the nearest device pixel according to the value of devicePixelRatio.

Parameters
pointa point in logical pixel space
Returns
The point in logical pixel space but adjusted to the nearest device pixel

Definition at line 897 of file kis_coordinates_converter.cpp.

898{
900 return point;
901 }
902
903 QPoint devicePixel = (point * m_d->devicePixelRatio).toPoint();
904 // These adjusted coords will be in logical pixel but is aligned in device
905 // pixel space for pixel-perfect rendering.
906 return QPointF(devicePixel) / m_d->devicePixelRatio;
907}

References KisCoordinatesConverter::Private::devicePixelRatio, m_d, and KisCoordinatesConverter::Private::rotationIsOrthogonal.

◆ snapWidgetSizeToDevicePixel()

QSizeF KisCoordinatesConverter::snapWidgetSizeToDevicePixel ( const QSizeF & size) const

Definition at line 407 of file kis_coordinates_converter.cpp.

408{
409 if (qFuzzyCompare(m_d->devicePixelRatio, 1.0)) return size;
410
411 // This is how QOpenGLCanvas sets the FBO and the viewport size. If
412 // devicePixelRatioF() is non-integral, the result is truncated.
413 // *Correction*: The FBO size is actually rounded, but the glViewport call
414 // uses integer truncation and that's what really matters.
415 const int viewportWidth = static_cast<int>(size.width() * m_d->devicePixelRatio);
416 const int viewportHeight = static_cast<int>(size.height() * m_d->devicePixelRatio);
417
418 // The widget size may be an integer but here we actually want to give
419 // KisCoordinatesConverter the logical viewport size aligned to device
420 // pixels.
421 return QSizeF(viewportWidth, viewportHeight) / m_d->devicePixelRatio;
422}
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisCoordinatesConverter::Private::devicePixelRatio, m_d, and qFuzzyCompare().

◆ standardZoomLevels()

QVector< qreal > KisCoordinatesConverter::standardZoomLevels ( ) const

Definition at line 932 of file kis_coordinates_converter.cpp.

933{
934 return m_d->standardZoomLevels.value();
935}

References m_d, and KisCoordinatesConverter::Private::standardZoomLevels.

◆ viewportDevicePixelSize()

QSize KisCoordinatesConverter::viewportDevicePixelSize ( ) const

Definition at line 424 of file kis_coordinates_converter.cpp.

425{
426 // TODO: add an assert and a unittest to verify that there is no
427 // actual rounding happens, only intolerances!
428 return qFuzzyCompare(m_d->devicePixelRatio, 1.0) ?
429 m_d->canvasWidgetSize.toSize() :
431}

References KisCoordinatesConverter::Private::canvasWidgetSize, KisCoordinatesConverter::Private::devicePixelRatio, m_d, and qFuzzyCompare().

◆ viewportToImage()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::viewportToImage ( const T & obj) const
inline

Definition at line 159 of file kis_coordinates_converter.h.

159{ return _Private::Traits<T>::map(imageToViewportTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ viewportToWidget()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::viewportToWidget ( const T & obj) const
inline

◆ viewportToWidgetTransform()

QTransform KisCoordinatesConverter::viewportToWidgetTransform ( ) const

Definition at line 750 of file kis_coordinates_converter.cpp.

750 {
751 return m_d->widgetToViewport.inverted();
752}

References m_d, and KisCoordinatesConverter::Private::widgetToViewport.

◆ viewToWidget()

QTransform KisCoordinatesConverter::viewToWidget ( ) const
overridevirtual

Reimplemented from KoViewConverter.

Definition at line 909 of file kis_coordinates_converter.cpp.

910{
911 return flakeToWidgetTransform();
912}

References flakeToWidgetTransform().

◆ widgetCenterPoint()

QPointF KisCoordinatesConverter::widgetCenterPoint ( ) const

Definition at line 862 of file kis_coordinates_converter.cpp.

863{
864 return QPointF(m_d->canvasWidgetSize.width() / 2.0, m_d->canvasWidgetSize.height() / 2.0);
865}

References KisCoordinatesConverter::Private::canvasWidgetSize, and m_d.

◆ widgetRectInFlakePixels()

QRectF KisCoordinatesConverter::widgetRectInFlakePixels ( ) const

Definition at line 845 of file kis_coordinates_converter.cpp.

846{
847 return widgetToFlake(QRectF(QPoint(0,0), m_d->canvasWidgetSize));
848}
_Private::Traits< T >::Result widgetToFlake(const T &obj) const

References KisCoordinatesConverter::Private::canvasWidgetSize, m_d, and widgetToFlake().

◆ widgetRectInImagePixels()

QRectF KisCoordinatesConverter::widgetRectInImagePixels ( ) const

Definition at line 850 of file kis_coordinates_converter.cpp.

851{
852 return widgetToImage(QRectF(QPoint(0,0), m_d->canvasWidgetSize));
853}

References KisCoordinatesConverter::Private::canvasWidgetSize, m_d, and widgetToImage().

◆ widgetToDocument()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::widgetToDocument ( const T & obj) const
inline

Definition at line 174 of file kis_coordinates_converter.h.

174{ return _Private::Traits<T>::map(documentToWidgetTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ widgetToFlake()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::widgetToFlake ( const T & obj) const
inline

Definition at line 164 of file kis_coordinates_converter.h.

164{ return _Private::Traits<T>::map(flakeToWidgetTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ widgetToImage()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::widgetToImage ( const T & obj) const
inline

Definition at line 189 of file kis_coordinates_converter.h.

189{ return _Private::Traits<T>::map(imageToWidgetTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ widgetToView()

QTransform KisCoordinatesConverter::widgetToView ( ) const
overridevirtual

Reimplemented from KoViewConverter.

Definition at line 914 of file kis_coordinates_converter.cpp.

915{
916 return flakeToWidgetTransform().inverted();
917}

References flakeToWidgetTransform().

◆ widgetToViewport()

template<class T >
_Private::Traits< T >::Result KisCoordinatesConverter::widgetToViewport ( const T & obj) const
inline

Definition at line 167 of file kis_coordinates_converter.h.

167{ return _Private::Traits<T>::map(viewportToWidgetTransform().inverted(), obj); }

References _Private::Traits< T >::map().

◆ xAxisMirrored()

bool KisCoordinatesConverter::xAxisMirrored ( ) const

Definition at line 694 of file kis_coordinates_converter.cpp.

695{
696 return m_d->isXAxisMirrored;
697}

References KisCoordinatesConverter::Private::isXAxisMirrored, and m_d.

◆ yAxisMirrored()

bool KisCoordinatesConverter::yAxisMirrored ( ) const

Definition at line 699 of file kis_coordinates_converter.cpp.

700{
701 return m_d->isYAxisMirrored;
702}

References KisCoordinatesConverter::Private::isYAxisMirrored, and m_d.

◆ zoomTo()

void KisCoordinatesConverter::zoomTo ( const QRectF & widgetRect)

Definition at line 513 of file kis_coordinates_converter.cpp.

514{
515 KIS_SAFE_ASSERT_RECOVER_RETURN(!zoomRectWidget.isEmpty());
516
517 const QPointF zoomPortionCenterInImagePixels = widgetToImage(zoomRectWidget.center());
518
519 const qreal zoomCoeffX = m_d->canvasWidgetSize.width() / zoomRectWidget.width();
520 const qreal zoomCoeffY = m_d->canvasWidgetSize.height() / zoomRectWidget.height();
521
522 const bool fitToWidth = zoomCoeffX < zoomCoeffY;
523
524 KoZoomHandler::setZoom(this->zoom() * (fitToWidth ? zoomCoeffX : zoomCoeffY));
527
528 const QPointF offset = imageToWidget(zoomPortionCenterInImagePixels) - widgetCenterPoint();
529 QPointF newDocumentOffset = m_d->documentOffset + offset;
530
531 m_d->documentOffset = snapToDevicePixel(newDocumentOffset);
533
535}

References KisCoordinatesConverter::Private::canvasWidgetSize, KisCoordinatesConverter::Private::documentOffset, imageToWidget(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, recalculateTransformations(), resetPreferredTransformationCenter(), KoZoomHandler::setZoom(), KoZoomHandler::setZoomMode(), snapToDevicePixel(), widgetCenterPoint(), widgetToImage(), KoZoomHandler::zoom(), and KoZoomMode::ZOOM_CONSTANT.

Friends And Related Symbol Documentation

◆ KisCoordinatesConverterTest

friend class KisCoordinatesConverterTest
friend

Definition at line 250 of file kis_coordinates_converter.h.

◆ KisZoomAndPanTest

friend class KisZoomAndPanTest
friend

Definition at line 249 of file kis_coordinates_converter.h.

Member Data Documentation

◆ m_d

Private* const KisCoordinatesConverter::m_d
private

Definition at line 262 of file kis_coordinates_converter.h.


The documentation for this class was generated from the following files: