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 {