Text Shadow Implementation via copied renderer.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / atlas-mesh-factory.cpp
1  /*
2  * Copyright (c) 2015 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   float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks );
87
88   // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
89   fBlockX += oneAndAHalfTexelX;
90   fBlockY += oneAndAHalfTexelY;
91
92   float texelWidthOffset = texelWidth + texelX;
93   float texelHeightOffset = texelHeight + texelY;
94
95   // Top left
96   vertex.mPosition.x = topLeft.x;
97   vertex.mPosition.y = topLeft.y;
98   vertex.mTexCoords.x = fBlockX;
99   vertex.mTexCoords.y = fBlockY;
100
101   mesh.mVertices.Reserve( 4u );
102   mesh.mVertices.PushBack( vertex );
103
104   // Top Right
105   vertex.mPosition.x = topLeft.x + vertexWidth;
106   vertex.mPosition.y = topLeft.y;
107   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
108   vertex.mTexCoords.y = fBlockY;
109
110   mesh.mVertices.PushBack( vertex );
111
112   // Bottom Left
113   vertex.mPosition.x = topLeft.x;
114   vertex.mPosition.y = topLeft.y + vertexHeight;
115   vertex.mTexCoords.x = fBlockX;
116   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
117
118   mesh.mVertices.PushBack( vertex );
119
120   // Bottom Right
121   vertex.mPosition.x = topLeft.x + vertexWidth;
122   vertex.mPosition.y = topLeft.y + vertexHeight;
123   vertex.mTexCoords.x = fBlockX + texelWidthOffset;
124   vertex.mTexCoords.y = fBlockY + texelHeightOffset;
125
126   mesh.mVertices.PushBack( vertex );
127
128   // Six indices in counter clockwise winding
129   mesh.mIndices.Reserve( 6u );
130   mesh.mIndices.PushBack( 1u );
131   mesh.mIndices.PushBack( 0u );
132   mesh.mIndices.PushBack( 2u );
133   mesh.mIndices.PushBack( 2u );
134   mesh.mIndices.PushBack( 3u );
135   mesh.mIndices.PushBack( 1u );
136 }
137
138 void AppendMesh( Toolkit::AtlasManager::Mesh2D& first,
139                  const Toolkit::AtlasManager::Mesh2D& second )
140 {
141   const uint32_t verticesCount = first.mVertices.Size();
142   first.mVertices.Insert( first.mVertices.End(),
143                           second.mVertices.Begin(),
144                           second.mVertices.End() );
145
146   const uint32_t indicesCount = first.mIndices.Size();
147   first.mIndices.Insert( first.mIndices.End(),
148                          second.mIndices.Begin(),
149                          second.mIndices.End() );
150
151   for( Vector<unsigned int>::Iterator it = first.mIndices.Begin() + indicesCount,
152          endIt = first.mIndices.End();
153        it != endIt;
154        ++it )
155   {
156     *it += verticesCount;
157   }
158 }
159
160 } // namespace AtlasMeshFactory
161
162 } // namespace Internal
163
164 } // namespace Toolkit
165
166 } // namespace Dali