Krita Source Code Documentation
Loading...
Searching...
No Matches
KisScreentoneGeneratorTemplateSampler.h
Go to the documentation of this file.
1/*
2 * KDE. Krita Project.
3 *
4 * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#ifndef KISSCREENTONEGENERATORTEMPLATESAMPLER_H
10#define KISSCREENTONEGENERATORTEMPLATESAMPLER_H
11
12#include <QtGlobal>
13
14#include <cmath>
15
16template <typename Template>
18{
19public:
21 : m_template(the_template)
22 {}
23
24 qreal operator()(qreal x, qreal y) const
25 {
26 // Get the coordinates in template space
27 QPointF p(
28 x + std::round(m_template.screenPosition().x()),
29 y + std::round(m_template.screenPosition().y())
30 );
31 // Get the coordinates in screen space
32 const QPointF screenPos = m_template.templateToScreenTransform().map(p);
33 // Get x/y indices in macrocell units or the current macrocell tile
34 // position
35 const qreal a = -std::floor(screenPos.x() / static_cast<qreal>(m_template.macrocellSize().width()));
36 const qreal b = -std::floor(screenPos.y() / static_cast<qreal>(m_template.macrocellSize().height()));
37 // Get the correspondent point in the (0, 0) macrocell tile
38 p += QPointF(a * m_template.v1().x() + b * m_template.v2().x(), a * m_template.v1().y() + b * m_template.v2().y());
39
40 const int i = static_cast<int>(std::floor(p.x())) + m_template.originOffset().x();
41 const int j = static_cast<int>(std::floor(p.y())) + m_template.originOffset().y();
42 const int macrocellPointIndex = j * m_template.templateSize().width() + i;
43 return m_template.templateData()[macrocellPointIndex];
44 }
45
46private:
47 const Template& m_template;
48};
49
50template <typename Template>
52{
53public:
55 : m_template(the_template)
56 {}
57
58 qreal operator()(qreal x, qreal y) const
59 {
60 // Get the coordinates in screen space
61 qreal xx, yy;
62 m_template.imageToScreenTransform().map(x, y, &xx, &yy);
63 // Convert to coordinate inside the macrocell
64 xx -= std::floor(xx / m_template.macrocellSize().width()) * m_template.macrocellSize().width();
65 yy -= std::floor(yy / m_template.macrocellSize().height()) * m_template.macrocellSize().height();
66 // Get template coordinates
67 QPointF templatePoint = m_template.screenToTemplateTransform().map(QPointF(xx, yy)) +
68 m_template.originOffset();
69
70 // Bilinear interpolation
71 // Get integer coordinates of the template points to use in the interpolation
72 const int ix0 =
73 templatePoint.x() < 0.0 ? m_template.templateSize().width() - 1 :
74 (templatePoint.x() >= m_template.templateSize().width() ? 0.0 :
75 static_cast<int>(std::floor(templatePoint.x())));
76 const int iy0 =
77 templatePoint.y() < 0.0 ? m_template.templateSize().height() - 1 :
78 (templatePoint.y() >= m_template.templateSize().height() ? 0.0 :
79 static_cast<int>(std::floor(templatePoint.y())));
80 const int ix1 = ix0 == m_template.templateSize().width() - 1 ? 0 : ix0 + 1;
81 const int iy1 = iy0 == m_template.templateSize().height() - 1 ? 0 : iy0 + 1;
82 // Get the template values for the points
83 const qreal topLeftValue = m_template.templateData()[iy0 * m_template.templateSize().width() + ix0];
84 const qreal topRightValue = m_template.templateData()[iy0 * m_template.templateSize().width() + ix1];
85 const qreal bottomLeftValue = m_template.templateData()[iy1 * m_template.templateSize().width() + ix0];
86 const qreal bottomRightValue = m_template.templateData()[iy1 * m_template.templateSize().width() + ix1];
87 // Get the fractional part of the point to use in the interpolation
88 const qreal fractionalX = templatePoint.x() - std::floor(templatePoint.x());
89 const qreal fractionalY = templatePoint.y() - std::floor(templatePoint.y());
90 // Perform bilinear interpolation
91 const qreal a = topLeftValue * (1.0 - fractionalX) + topRightValue * fractionalX;
92 const qreal b = bottomLeftValue * (1.0 - fractionalX) + bottomRightValue * fractionalX;
93 const qreal c = a * (1.0 - fractionalY) + b * fractionalY;
94 // ----
95 return c;
96 }
97
98private:
99 const Template& m_template;
100};
101
102#endif
const Params2D p