2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
26 namespace AtlasMeshFactory
28 void CreateQuad(SizeType imageWidth,
31 const Toolkit::AtlasManager::AtlasSize& atlasSize,
32 const Vector2& position,
33 Toolkit::AtlasManager::Mesh2D& mesh)
35 Toolkit::AtlasManager::Vertex2D vertex;
37 SizeType blockWidth = atlasSize.mBlockWidth;
38 SizeType blockHeight = atlasSize.mBlockHeight;
40 float vertexBlockWidth = static_cast<float>(blockWidth);
41 float vertexBlockHeight = static_cast<float>(blockHeight);
43 SizeType atlasWidth = atlasSize.mWidth;
44 SizeType atlasHeight = atlasSize.mHeight;
46 SizeType atlasWidthInBlocks = (atlasWidth - 1u) / blockWidth;
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);
52 float oneAndAHalfTexelX = texelX + (texelX * 0.5f);
53 float oneAndAHalfTexelY = texelY + (texelY * 0.5f);
55 float texelBlockWidth = texelX * vertexBlockWidth;
56 float texelBlockHeight = texelY * vertexBlockHeight;
58 uint32_t pixelsX = imageWidth % blockWidth;
59 uint32_t pixelsY = imageHeight % blockHeight;
67 pixelsY = blockHeight;
69 float vertexWidth = static_cast<float>(pixelsX);
70 float vertexHeight = static_cast<float>(pixelsY);
71 float texelWidth = texelX * vertexWidth;
72 float texelHeight = texelY * vertexHeight;
74 // We're going to 'blit' half a pixel more on each edge
78 // Move back half a pixel
79 Vector2 topLeft = Vector2(position.x - 0.5f, position.y - 0.5f);
81 float fBlockX = texelBlockWidth * static_cast<float>(block % atlasWidthInBlocks);
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);
87 // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
88 fBlockX += oneAndAHalfTexelX;
89 fBlockY += oneAndAHalfTexelY;
91 float texelWidthOffset = texelWidth + texelX;
92 float texelHeightOffset = texelHeight + texelY;
95 vertex.mPosition.x = topLeft.x;
96 vertex.mPosition.y = topLeft.y;
97 vertex.mTexCoords.x = fBlockX;
98 vertex.mTexCoords.y = fBlockY;
100 mesh.mVertices.Reserve(4u);
101 mesh.mVertices.PushBack(vertex);
104 vertex.mPosition.x = topLeft.x + vertexWidth;
105 vertex.mPosition.y = topLeft.y;
106 vertex.mTexCoords.x = fBlockX + texelWidthOffset;
107 vertex.mTexCoords.y = fBlockY;
109 mesh.mVertices.PushBack(vertex);
112 vertex.mPosition.x = topLeft.x;
113 vertex.mPosition.y = topLeft.y + vertexHeight;
114 vertex.mTexCoords.x = fBlockX;
115 vertex.mTexCoords.y = fBlockY + texelHeightOffset;
117 mesh.mVertices.PushBack(vertex);
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;
125 mesh.mVertices.PushBack(vertex);
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);
137 void AppendMesh(Toolkit::AtlasManager::Mesh2D& first,
138 const Toolkit::AtlasManager::Mesh2D& second)
140 const uint32_t verticesCount = first.mVertices.Size();
141 first.mVertices.Insert(first.mVertices.End(),
142 second.mVertices.Begin(),
143 second.mVertices.End());
145 const uint32_t indicesCount = first.mIndices.Size();
146 first.mIndices.Insert(first.mIndices.End(),
147 second.mIndices.Begin(),
148 second.mIndices.End());
150 for(Vector<unsigned short>::Iterator it = first.mIndices.Begin() + indicesCount,
151 endIt = first.mIndices.End();
155 *it += verticesCount;
159 } // namespace AtlasMeshFactory
161 } // namespace Internal
163 } // namespace Toolkit