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.
19 #include <dali-toolkit/devel-api/utility/npatch-helper.h>
22 #include <dali/integration-api/debug.h>
28 namespace NPatchHelper
33 * @brief Creates the geometry formed from the vertices and indices
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
39 Geometry GenerateGeometry(const Vector<Vector2>& vertices, const Vector<unsigned short>& indices)
41 Property::Map vertexFormat;
42 vertexFormat["aPosition"] = Property::VECTOR2;
43 VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
44 if(vertices.Size() > 0)
46 vertexBuffer.SetData(&vertices[0], vertices.Size());
49 // Create the geometry object
50 Geometry geometry = Geometry::New();
51 geometry.AddVertexBuffer(vertexBuffer);
52 if(indices.Size() > 0)
54 geometry.SetIndexBuffer(&indices[0], indices.Size());
61 * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid
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
67 void AddQuadIndices(Vector<unsigned short>& indices, unsigned int rowIdx, unsigned int nextRowIdx)
69 indices.PushBack(rowIdx);
70 indices.PushBack(nextRowIdx + 1);
71 indices.PushBack(rowIdx + 1);
73 indices.PushBack(rowIdx);
74 indices.PushBack(nextRowIdx);
75 indices.PushBack(nextRowIdx + 1);
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
84 void AddVertex(Vector<Vector2>& vertices, unsigned int x, unsigned int y)
86 vertices.PushBack(Vector2(x, y));
89 } // unnamed namespace
91 Geometry CreateGridGeometry(Uint16Pair gridSize)
93 uint16_t gridWidth = gridSize.GetWidth();
94 uint16_t gridHeight = gridSize.GetHeight();
97 Vector<Vector2> vertices;
98 vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
100 for(int y = 0; y < gridHeight + 1; ++y)
102 for(int x = 0; x < gridWidth + 1; ++x)
104 AddVertex(vertices, x, y);
109 Vector<unsigned short> indices;
110 indices.Reserve(gridWidth * gridHeight * 6);
112 unsigned int rowIdx = 0;
113 unsigned int nextRowIdx = gridWidth + 1;
114 for(int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx)
116 for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
118 AddQuadIndices(indices, rowIdx, nextRowIdx);
122 return GenerateGeometry(vertices, indices);
125 Geometry CreateBorderGeometry(Uint16Pair gridSize)
127 uint16_t gridWidth = gridSize.GetWidth();
128 uint16_t gridHeight = gridSize.GetHeight();
131 Vector<Vector2> vertices;
132 vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
138 for(int x = 0; x < gridWidth + 1; ++x)
140 AddVertex(vertices, x, y);
144 for(; y < gridHeight - 1; ++y)
147 AddVertex(vertices, 0, y);
148 AddVertex(vertices, 1, y);
151 AddVertex(vertices, gridWidth - 1, y);
152 AddVertex(vertices, gridWidth, y);
156 for(; y < gridHeight + 1; ++y)
158 for(int x = 0; x < gridWidth + 1; ++x)
160 AddVertex(vertices, x, y);
165 Vector<unsigned short> indices;
166 indices.Reserve(gridWidth * gridHeight * 6);
169 unsigned int rowIdx = 0;
170 unsigned int nextRowIdx = gridWidth + 1;
171 for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
173 AddQuadIndices(indices, rowIdx, nextRowIdx);
178 rowIdx = gridWidth + 1;
179 nextRowIdx = (gridWidth + 1) * 2;
181 unsigned increment = gridWidth - 1;
186 AddQuadIndices(indices, rowIdx, nextRowIdx);
188 rowIdx = gridWidth * 2;
189 nextRowIdx = (gridWidth + 1) * 2 + 2;
191 AddQuadIndices(indices, rowIdx, nextRowIdx);
194 rowIdx = nextRowIdx - 2;
195 nextRowIdx = rowIdx + 4;
196 for(int y = 2; y < 2 * (gridHeight - 3); ++y, rowIdx += 2, nextRowIdx += 2)
198 AddQuadIndices(indices, rowIdx, nextRowIdx);
203 AddQuadIndices(indices, rowIdx, nextRowIdx);
206 nextRowIdx += gridWidth - 1;
208 AddQuadIndices(indices, rowIdx, nextRowIdx);
212 rowIdx = nextRowIdx - gridWidth + 1;
213 nextRowIdx = rowIdx + gridWidth + 1;
214 for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
216 AddQuadIndices(indices, rowIdx, nextRowIdx);
219 return GenerateGeometry(vertices, indices);
222 void RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent)
224 uint16_t prevEnd = 0;
225 uint16_t prevFix = 0;
226 uint16_t prevStretch = 0;
228 for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i)
230 uint16_t start = it->GetX();
231 uint16_t end = it->GetY();
233 uint16_t fix = prevFix + start - prevEnd;
234 uint16_t stretch = prevStretch + end - start;
236 std::stringstream uniform;
237 uniform << uniformName << "[" << i << "]";
238 renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch));
242 prevStretch = stretch;
246 prevFix += imageExtent - prevEnd;
247 std::stringstream uniform;
248 uniform << uniformName << "[" << i << "]";
249 renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch));
253 void ApplyTextureAndUniforms(Renderer& renderer, const Internal::NPatchData* data)
255 TextureSet textureSet;
256 textureSet = data->GetTextures();
258 if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
260 //special case for 9 patch
261 Uint16Pair stretchX = data->GetStretchPixelsX()[0];
262 Uint16Pair stretchY = data->GetStretchPixelsY()[0];
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;
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));
274 renderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO);
275 renderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO);
277 RegisterStretchProperties(renderer, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth());
278 RegisterStretchProperties(renderer, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight());
282 } // namespace NPatchHelper
284 } // namespace Toolkit