1 /***************************************************************************
3 * Copyright 2010,2011 BMW Car IT GmbH
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 ****************************************************************************/
20 #ifndef _VIEWPORTTRANSFORM_H_
21 #define _VIEWPORTTRANSFORM_H_
23 #include "FloatRectangle.h"
25 class ViewportTransform
30 * Returns true if surface is completely cropped by the given layer source region
32 static bool isFullyCropped(const Rectangle& surfaceDestination, const Rectangle& layerSource);
35 * Apply Source View of Layer to the given surface source and destination regions, ie cropping surface parts to layer source view
37 static void applyLayerSource(const FloatRectangle& layerSource, FloatRectangle& surfaceSource, FloatRectangle& surfaceDestination);
40 * Apply Destination View of Layer to the given surface destination region, ie scale and movement relative
41 * to scaling and position of layer
43 static void applyLayerDestination(const FloatRectangle& layerDestination,
44 const FloatRectangle& layerSource,
45 FloatRectangle& regionToScale);
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.
52 static void transformRectangleToTextureCoordinates(const FloatRectangle& rectangle,
53 const float originalWidth,
54 const float originalHeight,
55 float* textureCoordinates);
59 inline bool ViewportTransform::isFullyCropped(const Rectangle& surfaceDestination, const Rectangle& layerSource)
61 // is surface completely to the right of layer source region?
62 if (surfaceDestination.x >= layerSource.x + layerSource.width)
64 // is surface completely beneath layer source region?
65 if (surfaceDestination.y >= layerSource.y + layerSource.height)
67 // is surface completely to the left of layer source region?
68 if (surfaceDestination.x + surfaceDestination.width <= layerSource.x)
70 // is surface completely above layer source region?
71 if (surfaceDestination.y + surfaceDestination.height <= layerSource.y)
76 inline void ViewportTransform::applyLayerSource(const FloatRectangle& layerSource,
77 FloatRectangle& surfaceSource,
78 FloatRectangle& surfaceDestination)
81 float surfaceInverseScaleX = surfaceSource.width / surfaceDestination.width;
82 float surfaceInverseScaleY = surfaceSource.height / surfaceDestination.height;
87 cropamount = layerSource.x - surfaceDestination.x;
88 if (cropamount > 0.0f)
90 surfaceDestination.x = 0.0f;
91 surfaceDestination.width -= cropamount;
93 // crop a proportional part of the source region
94 surfaceSource.x += cropamount * surfaceInverseScaleX;
95 surfaceSource.width -= cropamount * surfaceInverseScaleX;
99 surfaceDestination.x -= layerSource.x;
103 cropamount = surfaceDestination.x + surfaceDestination.width - layerSource.width;
104 if (cropamount > 0.0f)
106 surfaceDestination.width -= cropamount;
108 // crop a proportional part of the source region
109 surfaceSource.width -= cropamount * surfaceInverseScaleX;
115 cropamount = layerSource.y - surfaceDestination.y;
116 if (cropamount > 0.0f)
118 surfaceDestination.y = 0.0f;
119 surfaceDestination.height -= cropamount;
121 // crop a proportional part of the source region
122 surfaceSource.y += cropamount * surfaceInverseScaleY;
123 surfaceSource.height -= cropamount * surfaceInverseScaleY;
127 surfaceDestination.y -= layerSource.y;
131 cropamount = surfaceDestination.y + surfaceDestination.height - layerSource.height;
132 if (cropamount > 0.0f)
134 surfaceDestination.height -= cropamount;
136 // crop a proportional part of the source region
137 surfaceSource.height -= cropamount * surfaceInverseScaleY;
141 inline void ViewportTransform::applyLayerDestination(const FloatRectangle& layerDestination,
142 const FloatRectangle& layerSource,
143 FloatRectangle& regionToScale)
145 float scaleX = layerDestination.width / layerSource.width;
146 float scaleY = layerDestination.height / layerSource.height;
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;
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;
163 inline void ViewportTransform::transformRectangleToTextureCoordinates(const FloatRectangle& rectangle,
164 const float originalWidth,
165 const float originalHeight,
166 float* textureCoordinates)
168 // move texture coordinate proportional to the cropped pixels
169 float percentageCroppedFromLeftSide = rectangle.x / originalWidth;
170 textureCoordinates[0] = percentageCroppedFromLeftSide;
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;
178 // move texture coordinate proportional to the cropped pixels
179 float percentageCroppedFromTopSide = rectangle.y / originalHeight;
180 textureCoordinates[1] = percentageCroppedFromTopSide;
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;
188 #endif /* _VIEWPORTTRANSFORM_H_ */