2 * Copyright (c) 2016 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>
29 namespace AtlasMeshFactory
32 void CreateQuad( SizeType imageWidth,
35 const Toolkit::AtlasManager::AtlasSize& atlasSize,
36 const Vector2& position,
37 Toolkit::AtlasManager::Mesh2D& mesh )
39 Toolkit::AtlasManager::Vertex2D vertex;
41 SizeType blockWidth = atlasSize.mBlockWidth;
42 SizeType blockHeight = atlasSize.mBlockHeight;
44 float vertexBlockWidth = static_cast< float >( blockWidth );
45 float vertexBlockHeight = static_cast< float >( blockHeight );
47 SizeType atlasWidth = atlasSize.mWidth;
48 SizeType atlasHeight = atlasSize.mHeight;
50 SizeType atlasWidthInBlocks = ( atlasWidth - 1u ) / blockWidth;
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 );
56 float oneAndAHalfTexelX = texelX + ( texelX * 0.5f );
57 float oneAndAHalfTexelY = texelY + ( texelY * 0.5f );
59 float texelBlockWidth = texelX * vertexBlockWidth;
60 float texelBlockHeight = texelY * vertexBlockHeight;
62 uint32_t pixelsX = imageWidth % blockWidth;
63 uint32_t pixelsY = imageHeight % blockHeight;
71 pixelsY = blockHeight;
73 float vertexWidth = static_cast< float >( pixelsX );
74 float vertexHeight = static_cast< float >( pixelsY );
75 float texelWidth = texelX * vertexWidth;
76 float texelHeight = texelY * vertexHeight;
78 // We're going to 'blit' half a pixel more on each edge
82 // Move back half a pixel
83 Vector2 topLeft = Vector2( position.x - 0.5f, position.y - 0.5f );
85 float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks );
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 );
91 // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
92 fBlockX += oneAndAHalfTexelX;
93 fBlockY += oneAndAHalfTexelY;
95 float texelWidthOffset = texelWidth + texelX;
96 float texelHeightOffset = texelHeight + texelY;
99 vertex.mPosition.x = topLeft.x;
100 vertex.mPosition.y = topLeft.y;
101 vertex.mTexCoords.x = fBlockX;
102 vertex.mTexCoords.y = fBlockY;
104 mesh.mVertices.Reserve( 4u );
105 mesh.mVertices.PushBack( vertex );
108 vertex.mPosition.x = topLeft.x + vertexWidth;
109 vertex.mPosition.y = topLeft.y;
110 vertex.mTexCoords.x = fBlockX + texelWidthOffset;
111 vertex.mTexCoords.y = fBlockY;
113 mesh.mVertices.PushBack( vertex );
116 vertex.mPosition.x = topLeft.x;
117 vertex.mPosition.y = topLeft.y + vertexHeight;
118 vertex.mTexCoords.x = fBlockX;
119 vertex.mTexCoords.y = fBlockY + texelHeightOffset;
121 mesh.mVertices.PushBack( vertex );
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;
129 mesh.mVertices.PushBack( vertex );
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 );
141 void AppendMesh( Toolkit::AtlasManager::Mesh2D& first,
142 const Toolkit::AtlasManager::Mesh2D& second )
144 const uint32_t verticesCount = first.mVertices.Size();
145 first.mVertices.Insert( first.mVertices.End(),
146 second.mVertices.Begin(),
147 second.mVertices.End() );
149 const uint32_t indicesCount = first.mIndices.Size();
150 first.mIndices.Insert( first.mIndices.End(),
151 second.mIndices.Begin(),
152 second.mIndices.End() );
154 for( Vector<unsigned short>::Iterator it = first.mIndices.Begin() + indicesCount,
155 endIt = first.mIndices.End();
159 *it += verticesCount;
163 } // namespace AtlasMeshFactory
165 } // namespace Internal
167 } // namespace Toolkit