Fix various SVACE errors
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / atlas-mesh-factory.cpp
1  /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
19
20 namespace Dali
21 {
22
23 namespace Toolkit
24 {
25
26 namespace Internal
27 {
28
29 namespace AtlasMeshFactory
30 {
31
32 void CreateQuad( SizeType imageWidth,
33                  SizeType imageHeight,
34                  SizeType block,
35                  const Toolkit::AtlasManager::AtlasSize& atlasSize,
36                  const Vector2& position,
37                  Toolkit::AtlasManager::Mesh2D& mesh )
38 {
39   Toolkit::AtlasManager::Vertex2D vertex;
40
41   SizeType blockWidth = atlasSize.mBlockWidth;
42   SizeType blockHeight = atlasSize.mBlockHeight;
43
44   float vertexBlockWidth = static_cast< float >( blockWidth );
45   float vertexBlockHeight = static_cast< float >( blockHeight );
46
47   SizeType atlasWidth = atlasSize.mWidth;
48   SizeType atlasHeight = atlasSize.mHeight;
49
50   SizeType atlasWidthInBlocks = ( atlasWidth - 1u ) / blockWidth;
51
52   // Get the normalized size of a texel in both directions
53   float texelX = 1.0f / static_cast< float >( atlasWidth );
54   float texelY = 1.0f / static_cast< float >( atlasHeight );
55
56   float oneAndAHalfTexelX = texelX + ( texelX * 0.5f );
57   float oneAndAHalfTexelY = texelY + ( texelY * 0.5f );
58
59   float texelBlockWidth = texelX * vertexBlockWidth;
60   float texelBlockHeight = texelY * vertexBlockHeight;
61
62   uint32_t pixelsX = imageWidth % blockWidth;
63   uint32_t pixelsY = imageHeight % blockHeight;
64
65   if ( !pixelsX )
66   {
67     pixelsX = blockWidth;
68   }
69   if ( !pixelsY )
70   {
71     pixelsY = blockHeight;
72   }
73   float vertexWidth = static_cast< float >( pixelsX );
74   float vertexHeight = static_cast< float >( pixelsY );
75   float texelWidth = texelX * vertexWidth;
76   float texelHeight = texelY * vertexHeight;
77
78   // We're going to 'blit' half a pixel more on each edge
79   vertexWidth++;
80   vertexHeight++;
81
82   // Move back half a pixel
83   Vector2 topLeft = Vector2( position.x - 0.5f, position.y - 0.5f );
84
85   float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks );
86
87   // In the next expression, we have purposely made ( block / atlasWidthInBlocks ) yield an integer value and then convert to float as
88   // we do not want the remainder in that expression to affect the value of fBlockY
89   float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks );
90
91   // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
92   fBlockX += oneAndAHalfTexelX;
93   fBlockY += oneAndAHalfTexelY;
94
95   float texelWidthOffset = texelWidth + texelX;
96   float texelHeightOffset = texelHeight + texelY;
97
98   // Top left
99   vertex.mPosition.x = topLeft.x;
100   vertex.mPosition.y = topLeft.y;
101   vertex.mTexCoords.x = fBlockX;
102   vertex.mTexCoords.y = fBlockY;
103
104   mesh.mVertices.Reserve( 4u );
105   mesh.mVertices.PushBack( vertex );
106
107   // Top Right
108   vertex.mPosition.x = topLeft.x + vertexWidth;
109   vertex.mPosition.y = topLeft.y;
110   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
111   vertex.mTexCoords.y = fBlockY;
112
113   mesh.mVertices.PushBack( vertex );
114
115   // Bottom Left
116   vertex.mPosition.x = topLeft.x;
117   vertex.mPosition.y = topLeft.y + vertexHeight;
118   vertex.mTexCoords.x = fBlockX;
119   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
120
121   mesh.mVertices.PushBack( vertex );
122
123   // Bottom Right
124   vertex.mPosition.x = topLeft.x + vertexWidth;
125   vertex.mPosition.y = topLeft.y + vertexHeight;
126   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
127   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
128
129   mesh.mVertices.PushBack( vertex );
130
131   // Six indices in counter clockwise winding
132   mesh.mIndices.Reserve( 6u );
133   mesh.mIndices.PushBack( 1u );
134   mesh.mIndices.PushBack( 0u );
135   mesh.mIndices.PushBack( 2u );
136   mesh.mIndices.PushBack( 2u );
137   mesh.mIndices.PushBack( 3u );
138   mesh.mIndices.PushBack( 1u );
139 }
140
141 void AppendMesh( Toolkit::AtlasManager::Mesh2D& first,
142                  const Toolkit::AtlasManager::Mesh2D& second )
143 {
144   const uint32_t verticesCount = first.mVertices.Size();
145   first.mVertices.Insert( first.mVertices.End(),
146                           second.mVertices.Begin(),
147                           second.mVertices.End() );
148
149   const uint32_t indicesCount = first.mIndices.Size();
150   first.mIndices.Insert( first.mIndices.End(),
151                          second.mIndices.Begin(),
152                          second.mIndices.End() );
153
154   for( Vector<unsigned short>::Iterator it = first.mIndices.Begin() + indicesCount,
155          endIt = first.mIndices.End();
156        it != endIt;
157        ++it )
158   {
159     *it += verticesCount;
160   }
161 }
162
163 } // namespace AtlasMeshFactory
164
165 } // namespace Internal
166
167 } // namespace Toolkit
168
169 } // namespace Dali