Mercurial > hg > orthanc-stone
comparison Framework/Scene2D/Internals/CairoInfoPanelRenderer.cpp @ 1325:be17fed8c7c5 broker
Added flag in InfoPanelSceneLayer to
apply the scene rotation to the
displayed image.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 24 Mar 2020 20:34:28 +0100 |
parents | 2d8ab34c8c91 |
children |
comparison
equal
deleted
inserted
replaced
1324:4d8d642f7036 | 1325:be17fed8c7c5 |
---|---|
32 const InfoPanelSceneLayer& l = dynamic_cast<const InfoPanelSceneLayer&>(layer); | 32 const InfoPanelSceneLayer& l = dynamic_cast<const InfoPanelSceneLayer&>(layer); |
33 | 33 |
34 texture_.Copy(l.GetTexture(), true); | 34 texture_.Copy(l.GetTexture(), true); |
35 anchor_ = l.GetAnchor(); | 35 anchor_ = l.GetAnchor(); |
36 isLinearInterpolation_ = l.IsLinearInterpolation(); | 36 isLinearInterpolation_ = l.IsLinearInterpolation(); |
37 applySceneRotation_ = l.ShouldApplySceneRotation(); | |
37 } | 38 } |
38 | 39 |
39 | |
40 void CairoInfoPanelRenderer::Render(const AffineTransform2D& transform, | 40 void CairoInfoPanelRenderer::Render(const AffineTransform2D& transform, |
41 unsigned int canvasWidth, | 41 unsigned int canvasWidth, |
42 unsigned int canvasHeight) | 42 unsigned int canvasHeight) |
43 { | 43 { |
44 int dx, dy; | 44 int dx, dy; |
45 InfoPanelSceneLayer::ComputeAnchorLocation( | 45 InfoPanelSceneLayer::ComputeAnchorLocation( |
46 dx, dy, anchor_, texture_.GetWidth(), texture_.GetHeight(), | 46 dx, dy, anchor_, texture_.GetWidth(), texture_.GetHeight(), |
47 canvasWidth, canvasHeight); | 47 canvasWidth, canvasHeight); |
48 | 48 |
49 cairo_t* cr = target_.GetCairoContext(); | 49 cairo_t* cr = target_.GetCairoContext(); |
50 | |
51 cairo_save(cr); | 50 cairo_save(cr); |
52 | 51 |
53 cairo_matrix_t t; | 52 if (applySceneRotation_) |
54 cairo_matrix_init_identity(&t); | 53 { |
55 cairo_matrix_translate(&t, dx, dy); | 54 // the transformation is as follows: |
56 cairo_transform(cr, &t); | 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. | |
57 | 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 } | |
58 cairo_set_operator(cr, CAIRO_OPERATOR_OVER); | 115 cairo_set_operator(cr, CAIRO_OPERATOR_OVER); |
59 cairo_set_source_surface(cr, texture_.GetObject(), 0, 0); | 116 cairo_set_source_surface(cr, texture_.GetObject(), 0, 0); |
60 | 117 |
61 if (isLinearInterpolation_) | 118 if (isLinearInterpolation_) |
62 { | 119 { |