Health: added thread dead-lock detection
[profile/ivi/layer-management.git] / LayerManagerBase / include / ViewportTransform.h
1 /***************************************************************************
2  *
3  * Copyright 2010,2011 BMW Car IT GmbH
4  *
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  ****************************************************************************/
19
20 #ifndef _VIEWPORTTRANSFORM_H_
21 #define _VIEWPORTTRANSFORM_H_
22
23 #include "FloatRectangle.h"
24
25 class ViewportTransform
26 {
27 public:
28
29     /*
30      * Returns true if surface is completely cropped by the given layer source region
31      */
32     static bool isFullyCropped(const Rectangle& surfaceDestination, const Rectangle& layerSource);
33
34     /*
35      * Apply Source View of Layer to the given surface source and destination regions, ie cropping surface parts to layer source view
36      */
37     static void applyLayerSource(const FloatRectangle& layerSource, FloatRectangle& surfaceSource, FloatRectangle& surfaceDestination);
38
39     /*
40      * Apply Destination View of Layer to the given surface destination region, ie scale and movement relative
41      * to scaling and position of layer
42      */
43     static void applyLayerDestination(const FloatRectangle& layerDestination,
44                                         const FloatRectangle& layerSource,
45                                         FloatRectangle& regionToScale);
46
47     /*
48      * Calculate Texture Coordinates as relation of the given rectangle to original values.
49      * Example: x position of 10 with an original width of 40 will yield a texture coordinate of 10/40=0.25f.
50      * This function expects textureCoordinates to be an allocated float array of size 4, in which the texture coordinates will be returned.
51      */
52     static void transformRectangleToTextureCoordinates(const FloatRectangle& rectangle,
53                                                         const float originalWidth,
54                                                         const float originalHeight,
55                                                         float* textureCoordinates);
56 };
57
58
59 inline bool ViewportTransform::isFullyCropped(const Rectangle& surfaceDestination, const Rectangle& layerSource)
60 {
61     // is surface completely to the right of layer source region?
62     if (surfaceDestination.x >= layerSource.x + layerSource.width)
63         return true;
64     // is surface completely beneath layer source region?
65     if (surfaceDestination.y >= layerSource.y + layerSource.height)
66         return true;
67     // is surface completely to the left of layer source region?
68     if (surfaceDestination.x + surfaceDestination.width <= layerSource.x)
69         return true;
70     // is surface completely above layer source region?
71     if (surfaceDestination.y + surfaceDestination.height <= layerSource.y)
72         return true;
73     return false;
74 }
75
76 inline void ViewportTransform::applyLayerSource(const FloatRectangle& layerSource,
77                                                 FloatRectangle& surfaceSource,
78                                                 FloatRectangle& surfaceDestination)
79 {
80     float cropamount = 0;
81     float surfaceInverseScaleX = surfaceSource.width / surfaceDestination.width;
82     float surfaceInverseScaleY = surfaceSource.height / surfaceDestination.height;
83
84     // X
85
86     // Crop from left
87     cropamount = layerSource.x - surfaceDestination.x;
88     if (cropamount > 0.0f)
89     {
90         surfaceDestination.x = 0.0f;
91         surfaceDestination.width -= cropamount;
92
93         // crop a proportional part of the source region
94         surfaceSource.x += cropamount * surfaceInverseScaleX;
95         surfaceSource.width -= cropamount * surfaceInverseScaleX;
96     }
97     else
98     {
99         surfaceDestination.x -= layerSource.x;
100     }
101
102     // Crop from right
103     cropamount = surfaceDestination.x + surfaceDestination.width - layerSource.width;
104     if (cropamount > 0.0f)
105     {
106         surfaceDestination.width -= cropamount;
107
108         // crop a proportional part of the source region
109         surfaceSource.width -= cropamount * surfaceInverseScaleX;
110     }
111
112     // Y
113
114     // Crop from top
115     cropamount = layerSource.y - surfaceDestination.y;
116     if (cropamount > 0.0f)
117     {
118         surfaceDestination.y = 0.0f;
119         surfaceDestination.height -= cropamount;
120
121         // crop a proportional part of the source region
122         surfaceSource.y += cropamount * surfaceInverseScaleY;
123         surfaceSource.height -= cropamount * surfaceInverseScaleY;
124     }
125     else
126     {
127         surfaceDestination.y -= layerSource.y;
128     }
129
130     // Crop from bottom
131     cropamount = surfaceDestination.y + surfaceDestination.height - layerSource.height;
132     if (cropamount > 0.0f)
133     {
134         surfaceDestination.height -= cropamount;
135
136         // crop a proportional part of the source region
137         surfaceSource.height -= cropamount * surfaceInverseScaleY;
138     }
139 }
140
141 inline void ViewportTransform::applyLayerDestination(const FloatRectangle& layerDestination,
142                                                         const FloatRectangle& layerSource,
143                                                         FloatRectangle& regionToScale)
144 {
145     float scaleX = layerDestination.width / layerSource.width;
146     float scaleY = layerDestination.height / layerSource.height;
147
148     // scale position proportional to change in float*layer size
149     regionToScale.x *= scaleX;
150     // scale width proportional to change in layer size
151     regionToScale.width *= scaleX;
152     // after scaling, move surface because its position should be relative to moved layer
153     regionToScale.x += layerDestination.x;
154
155     // scale position proportional to change in layer size
156     regionToScale.y *= scaleY;
157     // scale width proportional to change in layer size
158     regionToScale.height *= scaleY;
159     // after scaling, move surface because its position should be relative to moved layer
160     regionToScale.y += layerDestination.y;
161 }
162
163 inline void ViewportTransform::transformRectangleToTextureCoordinates(const FloatRectangle& rectangle,
164                                                                         const float originalWidth,
165                                                                         const float originalHeight,
166                                                                         float* textureCoordinates)
167 {
168     // move texture coordinate proportional to the cropped pixels
169     float percentageCroppedFromLeftSide = rectangle.x / originalWidth;
170     textureCoordinates[0] = percentageCroppedFromLeftSide;
171
172     // move texture coordinate proportional to the cropped pixels
173     uint newRightSide = rectangle.x + rectangle.width;
174     float percentageCroppedFromRightSide = (originalWidth - newRightSide) / originalWidth;
175     textureCoordinates[2] = 1.0f - percentageCroppedFromRightSide;
176
177     // the same for Y
178     // move texture coordinate proportional to the cropped pixels
179     float percentageCroppedFromTopSide = rectangle.y / originalHeight;
180     textureCoordinates[1] = percentageCroppedFromTopSide;
181
182     // move texture coordinate proportional to the cropped pixels
183     int newBottomSide = rectangle.y + rectangle.height;
184     float percentageCroppedFromBottomSide = (originalHeight - newBottomSide) / originalHeight;
185     textureCoordinates[3] = 1.0f - percentageCroppedFromBottomSide;
186 }
187
188 #endif /* _VIEWPORTTRANSFORM_H_ */