Updated all cpp files to new format
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / atlas-mesh-factory.cpp
1 /*
2  * Copyright (c) 2021 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 namespace Toolkit
23 {
24 namespace Internal
25 {
26 namespace AtlasMeshFactory
27 {
28 void CreateQuad(SizeType                                imageWidth,
29                 SizeType                                imageHeight,
30                 SizeType                                block,
31                 const Toolkit::AtlasManager::AtlasSize& atlasSize,
32                 const Vector2&                          position,
33                 Toolkit::AtlasManager::Mesh2D&          mesh)
34 {
35   Toolkit::AtlasManager::Vertex2D vertex;
36
37   SizeType blockWidth  = atlasSize.mBlockWidth;
38   SizeType blockHeight = atlasSize.mBlockHeight;
39
40   float vertexBlockWidth  = static_cast<float>(blockWidth);
41   float vertexBlockHeight = static_cast<float>(blockHeight);
42
43   SizeType atlasWidth  = atlasSize.mWidth;
44   SizeType atlasHeight = atlasSize.mHeight;
45
46   SizeType atlasWidthInBlocks = (atlasWidth - 1u) / blockWidth;
47
48   // Get the normalized size of a texel in both directions
49   float texelX = 1.0f / static_cast<float>(atlasWidth);
50   float texelY = 1.0f / static_cast<float>(atlasHeight);
51
52   float oneAndAHalfTexelX = texelX + (texelX * 0.5f);
53   float oneAndAHalfTexelY = texelY + (texelY * 0.5f);
54
55   float texelBlockWidth  = texelX * vertexBlockWidth;
56   float texelBlockHeight = texelY * vertexBlockHeight;
57
58   uint32_t pixelsX = imageWidth % blockWidth;
59   uint32_t pixelsY = imageHeight % blockHeight;
60
61   if(!pixelsX)
62   {
63     pixelsX = blockWidth;
64   }
65   if(!pixelsY)
66   {
67     pixelsY = blockHeight;
68   }
69   float vertexWidth  = static_cast<float>(pixelsX);
70   float vertexHeight = static_cast<float>(pixelsY);
71   float texelWidth   = texelX * vertexWidth;
72   float texelHeight  = texelY * vertexHeight;
73
74   // We're going to 'blit' half a pixel more on each edge
75   vertexWidth++;
76   vertexHeight++;
77
78   // Move back half a pixel
79   Vector2 topLeft = Vector2(position.x - 0.5f, position.y - 0.5f);
80
81   float fBlockX = texelBlockWidth * static_cast<float>(block % atlasWidthInBlocks);
82
83   // In the next expression, we have purposely made ( block / atlasWidthInBlocks ) yield an integer value and then convert to float as
84   // we do not want the remainder in that expression to affect the value of fBlockY
85   float fBlockY = texelBlockHeight * static_cast<float>(block / atlasWidthInBlocks);
86
87   // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
88   fBlockX += oneAndAHalfTexelX;
89   fBlockY += oneAndAHalfTexelY;
90
91   float texelWidthOffset  = texelWidth + texelX;
92   float texelHeightOffset = texelHeight + texelY;
93
94   // Top left
95   vertex.mPosition.x  = topLeft.x;
96   vertex.mPosition.y  = topLeft.y;
97   vertex.mTexCoords.x = fBlockX;
98   vertex.mTexCoords.y = fBlockY;
99
100   mesh.mVertices.Reserve(4u);
101   mesh.mVertices.PushBack(vertex);
102
103   // Top Right
104   vertex.mPosition.x  = topLeft.x + vertexWidth;
105   vertex.mPosition.y  = topLeft.y;
106   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
107   vertex.mTexCoords.y = fBlockY;
108
109   mesh.mVertices.PushBack(vertex);
110
111   // Bottom Left
112   vertex.mPosition.x  = topLeft.x;
113   vertex.mPosition.y  = topLeft.y + vertexHeight;
114   vertex.mTexCoords.x = fBlockX;
115   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
116
117   mesh.mVertices.PushBack(vertex);
118
119   // Bottom Right
120   vertex.mPosition.x  = topLeft.x + vertexWidth;
121   vertex.mPosition.y  = topLeft.y + vertexHeight;
122   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
123   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
124
125   mesh.mVertices.PushBack(vertex);
126
127   // Six indices in counter clockwise winding
128   mesh.mIndices.Reserve(6u);
129   mesh.mIndices.PushBack(1u);
130   mesh.mIndices.PushBack(0u);
131   mesh.mIndices.PushBack(2u);
132   mesh.mIndices.PushBack(2u);
133   mesh.mIndices.PushBack(3u);
134   mesh.mIndices.PushBack(1u);
135 }
136
137 void AppendMesh(Toolkit::AtlasManager::Mesh2D&       first,
138                 const Toolkit::AtlasManager::Mesh2D& second)
139 {
140   const uint32_t verticesCount = first.mVertices.Size();
141   first.mVertices.Insert(first.mVertices.End(),
142                          second.mVertices.Begin(),
143                          second.mVertices.End());
144
145   const uint32_t indicesCount = first.mIndices.Size();
146   first.mIndices.Insert(first.mIndices.End(),
147                         second.mIndices.Begin(),
148                         second.mIndices.End());
149
150   for(Vector<unsigned short>::Iterator it    = first.mIndices.Begin() + indicesCount,
151                                        endIt = first.mIndices.End();
152       it != endIt;
153       ++it)
154   {
155     *it += verticesCount;
156   }
157 }
158
159 } // namespace AtlasMeshFactory
160
161 } // namespace Internal
162
163 } // namespace Toolkit
164
165 } // namespace Dali