Refactorying code related to broken image
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / utility / npatch-helper.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
18 // CLASS HEADER
19 #include <dali-toolkit/devel-api/utility/npatch-helper.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 namespace Dali
25 {
26 namespace Toolkit
27 {
28 namespace NPatchHelper
29 {
30 namespace
31 {
32 /**
33  * @brief Creates the geometry formed from the vertices and indices
34  *
35  * @param[in]  vertices             The vertices to generate the geometry from
36  * @param[in]  indices              The indices to generate the geometry from
37  * @return The geometry formed from the vertices and indices
38  */
39 Geometry GenerateGeometry(const Vector<Vector2>& vertices, const Vector<unsigned short>& indices)
40 {
41   Property::Map vertexFormat;
42   vertexFormat["aPosition"] = Property::VECTOR2;
43   VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
44   if(vertices.Size() > 0)
45   {
46     vertexBuffer.SetData(&vertices[0], vertices.Size());
47   }
48
49   // Create the geometry object
50   Geometry geometry = Geometry::New();
51   geometry.AddVertexBuffer(vertexBuffer);
52   if(indices.Size() > 0)
53   {
54     geometry.SetIndexBuffer(&indices[0], indices.Size());
55   }
56
57   return geometry;
58 }
59
60 /**
61  * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid
62  *
63  * @param[out] indices     The indices to add to
64  * @param[in]  rowIdx      The row index to start the quad
65  * @param[in]  nextRowIdx  The index to the next row
66  */
67 void AddQuadIndices(Vector<unsigned short>& indices, unsigned int rowIdx, unsigned int nextRowIdx)
68 {
69   indices.PushBack(rowIdx);
70   indices.PushBack(nextRowIdx + 1);
71   indices.PushBack(rowIdx + 1);
72
73   indices.PushBack(rowIdx);
74   indices.PushBack(nextRowIdx);
75   indices.PushBack(nextRowIdx + 1);
76 }
77
78 /**
79  * @brief Adds the vertices to create for npatch
80  * @param[out] vertices The vertices to add to
81  * @param[in]  x        The x value of vector
82  * @param[in]  y        The y value of vector
83  */
84 void AddVertex(Vector<Vector2>& vertices, unsigned int x, unsigned int y)
85 {
86   vertices.PushBack(Vector2(x, y));
87 }
88
89 } // unnamed namespace
90
91 Geometry CreateGridGeometry(Uint16Pair gridSize)
92 {
93   uint16_t gridWidth  = gridSize.GetWidth();
94   uint16_t gridHeight = gridSize.GetHeight();
95
96   // Create vertices
97   Vector<Vector2> vertices;
98   vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
99
100   for(int y = 0; y < gridHeight + 1; ++y)
101   {
102     for(int x = 0; x < gridWidth + 1; ++x)
103     {
104       AddVertex(vertices, x, y);
105     }
106   }
107
108   // Create indices
109   Vector<unsigned short> indices;
110   indices.Reserve(gridWidth * gridHeight * 6);
111
112   unsigned int rowIdx     = 0;
113   unsigned int nextRowIdx = gridWidth + 1;
114   for(int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx)
115   {
116     for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
117     {
118       AddQuadIndices(indices, rowIdx, nextRowIdx);
119     }
120   }
121
122   return GenerateGeometry(vertices, indices);
123 }
124
125 Geometry CreateBorderGeometry(Uint16Pair gridSize)
126 {
127   uint16_t gridWidth  = gridSize.GetWidth();
128   uint16_t gridHeight = gridSize.GetHeight();
129
130   // Create vertices
131   Vector<Vector2> vertices;
132   vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
133
134   //top
135   int y = 0;
136   for(; y < 2; ++y)
137   {
138     for(int x = 0; x < gridWidth + 1; ++x)
139     {
140       AddVertex(vertices, x, y);
141     }
142   }
143
144   for(; y < gridHeight - 1; ++y)
145   {
146     //left
147     AddVertex(vertices, 0, y);
148     AddVertex(vertices, 1, y);
149
150     //right
151     AddVertex(vertices, gridWidth - 1, y);
152     AddVertex(vertices, gridWidth, y);
153   }
154
155   //bottom
156   for(; y < gridHeight + 1; ++y)
157   {
158     for(int x = 0; x < gridWidth + 1; ++x)
159     {
160       AddVertex(vertices, x, y);
161     }
162   }
163
164   // Create indices
165   Vector<unsigned short> indices;
166   indices.Reserve(gridWidth * gridHeight * 6);
167
168   //top
169   unsigned int rowIdx     = 0;
170   unsigned int nextRowIdx = gridWidth + 1;
171   for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
172   {
173     AddQuadIndices(indices, rowIdx, nextRowIdx);
174   }
175
176   if(gridHeight > 2)
177   {
178     rowIdx     = gridWidth + 1;
179     nextRowIdx = (gridWidth + 1) * 2;
180
181     unsigned increment = gridWidth - 1;
182     if(gridHeight > 3)
183     {
184       increment = 2;
185       //second row left
186       AddQuadIndices(indices, rowIdx, nextRowIdx);
187
188       rowIdx     = gridWidth * 2;
189       nextRowIdx = (gridWidth + 1) * 2 + 2;
190       //second row right
191       AddQuadIndices(indices, rowIdx, nextRowIdx);
192
193       //left and right
194       rowIdx     = nextRowIdx - 2;
195       nextRowIdx = rowIdx + 4;
196       for(int y = 2; y < 2 * (gridHeight - 3); ++y, rowIdx += 2, nextRowIdx += 2)
197       {
198         AddQuadIndices(indices, rowIdx, nextRowIdx);
199       }
200     }
201
202     //second row left
203     AddQuadIndices(indices, rowIdx, nextRowIdx);
204
205     rowIdx += increment;
206     nextRowIdx += gridWidth - 1;
207     //second row right
208     AddQuadIndices(indices, rowIdx, nextRowIdx);
209   }
210
211   //bottom
212   rowIdx     = nextRowIdx - gridWidth + 1;
213   nextRowIdx = rowIdx + gridWidth + 1;
214   for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
215   {
216     AddQuadIndices(indices, rowIdx, nextRowIdx);
217   }
218
219   return GenerateGeometry(vertices, indices);
220 }
221
222 void RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent)
223 {
224   uint16_t     prevEnd     = 0;
225   uint16_t     prevFix     = 0;
226   uint16_t     prevStretch = 0;
227   unsigned int i           = 1;
228   for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i)
229   {
230     uint16_t start = it->GetX();
231     uint16_t end   = it->GetY();
232
233     uint16_t fix     = prevFix + start - prevEnd;
234     uint16_t stretch = prevStretch + end - start;
235
236     std::stringstream uniform;
237     uniform << uniformName << "[" << i << "]";
238     renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch));
239
240     prevEnd     = end;
241     prevFix     = fix;
242     prevStretch = stretch;
243   }
244
245   {
246     prevFix += imageExtent - prevEnd;
247     std::stringstream uniform;
248     uniform << uniformName << "[" << i << "]";
249     renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch));
250   }
251 }
252
253 void ApplyTextureAndUniforms(Renderer& renderer, const Internal::NPatchData* data)
254 {
255   TextureSet        textureSet;
256   textureSet = data->GetTextures();
257
258   if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
259   {
260     //special case for 9 patch
261     Uint16Pair stretchX = data->GetStretchPixelsX()[0];
262     Uint16Pair stretchY = data->GetStretchPixelsY()[0];
263
264     uint16_t stretchWidth  = (stretchX.GetY() >= stretchX.GetX()) ? stretchX.GetY() - stretchX.GetX() : 0;
265     uint16_t stretchHeight = (stretchY.GetY() >= stretchY.GetX()) ? stretchY.GetY() - stretchY.GetX() : 0;
266
267     renderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
268     renderer.RegisterProperty("uFixed[1]", Vector2(stretchX.GetX(), stretchY.GetX()));
269     renderer.RegisterProperty("uFixed[2]", Vector2(data->GetCroppedWidth() - stretchWidth, data->GetCroppedHeight() - stretchHeight));
270     renderer.RegisterProperty("uStretchTotal", Vector2(stretchWidth, stretchHeight));
271   }
272   else
273   {
274     renderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO);
275     renderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO);
276
277     RegisterStretchProperties(renderer, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth());
278     RegisterStretchProperties(renderer, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight());
279   }
280 }
281
282 } // namespace NPatchHelper
283
284 } // namespace Toolkit
285
286 } // namespace Dali