comparison OrthancStone/Sources/Scene2D/Internals/CairoInfoPanelRenderer.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Scene2D/Internals/CairoInfoPanelRenderer.cpp@be17fed8c7c5
children 85e117739eca
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "CairoInfoPanelRenderer.h"
23
24 #include "../InfoPanelSceneLayer.h"
25
26 namespace OrthancStone
27 {
28 namespace Internals
29 {
30 void CairoInfoPanelRenderer::Update(const ISceneLayer& layer)
31 {
32 const InfoPanelSceneLayer& l = dynamic_cast<const InfoPanelSceneLayer&>(layer);
33
34 texture_.Copy(l.GetTexture(), true);
35 anchor_ = l.GetAnchor();
36 isLinearInterpolation_ = l.IsLinearInterpolation();
37 applySceneRotation_ = l.ShouldApplySceneRotation();
38 }
39
40 void CairoInfoPanelRenderer::Render(const AffineTransform2D& transform,
41 unsigned int canvasWidth,
42 unsigned int canvasHeight)
43 {
44 int dx, dy;
45 InfoPanelSceneLayer::ComputeAnchorLocation(
46 dx, dy, anchor_, texture_.GetWidth(), texture_.GetHeight(),
47 canvasWidth, canvasHeight);
48
49 cairo_t* cr = target_.GetCairoContext();
50 cairo_save(cr);
51
52 if (applySceneRotation_)
53 {
54 // the transformation is as follows:
55 // - originally, the image is aligned so that its top left corner
56 // is at 0,0
57 // - first, we translate the image by -w/2,-h/2
58 // - then we rotate it, so that the next rotation will make the
59 // image rotate around its center.
60 // - then, we translate the image by +w/2,+h/2 to put it
61 // back in place
62 // - the fourth and last transform is the one that brings the
63 // image to its desired anchored location.
64
65 int32_t halfWidth =
66 static_cast<int32_t>(0.5 * texture_.GetWidth());
67
68 int32_t halfHeight =
69 static_cast<int32_t>(0.5 * texture_.GetHeight());
70
71 AffineTransform2D translation1 =
72 AffineTransform2D::CreateOffset(-halfWidth, -halfHeight);
73
74 const Matrix& sceneTransformM = transform.GetHomogeneousMatrix();
75 Matrix r;
76 Matrix q;
77 LinearAlgebra::RQDecomposition3x3(r, q, sceneTransformM);
78
79 // first, put the scene rotation in a cairo matrix
80 cairo_matrix_t m;
81 cairo_matrix_init(
82 &m, q(0, 0), q(1, 0), q(0, 1), q(1, 1), q(0, 2), q(1, 2));
83
84 // now let's build the transform piece by piece
85 // first translation (directly written in `transform`)
86 cairo_matrix_t transform;
87 cairo_matrix_init_identity(&transform);
88 cairo_matrix_translate(&transform, -halfWidth, -halfHeight);
89
90 // then the rotation
91 cairo_matrix_multiply(&transform, &transform, &m);
92
93 // then the second translation
94 {
95 cairo_matrix_t translation2;
96 cairo_matrix_init_translate(&translation2, halfWidth, halfHeight);
97 cairo_matrix_multiply(&transform, &transform, &m);
98 }
99
100 // then the last translation
101 {
102 cairo_matrix_t translation3;
103 cairo_matrix_init_translate(&translation3, dx, dy);
104 cairo_matrix_multiply(&transform, &transform, &translation3);
105 }
106 cairo_transform(cr, &transform);
107 }
108 else
109 {
110 cairo_matrix_t t;
111 cairo_matrix_init_identity(&t);
112 cairo_matrix_translate(&t, dx, dy);
113 cairo_transform(cr, &t);
114 }
115 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
116 cairo_set_source_surface(cr, texture_.GetObject(), 0, 0);
117
118 if (isLinearInterpolation_)
119 {
120 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BILINEAR);
121 }
122 else
123 {
124 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
125 }
126
127 cairo_paint(cr);
128
129 cairo_restore(cr);
130 }
131 }
132 }