2 * Copyright (c) 2023 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>
25 #include <dali-toolkit/internal/visuals/npatch-data.h>
31 namespace NPatchHelper
36 * @brief Creates the geometry formed from the vertices and indices
38 * @param[in] vertices The vertices to generate the geometry from
39 * @param[in] indices The indices to generate the geometry from
40 * @return The geometry formed from the vertices and indices
42 Geometry GenerateGeometry(const Vector<Vector2>& vertices, const Vector<uint16_t>& indices)
44 Property::Map vertexFormat;
45 vertexFormat["aPosition"] = Property::VECTOR2;
46 VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
47 if(vertices.Size() > 0)
49 vertexBuffer.SetData(&vertices[0], vertices.Size());
52 // Create the geometry object
53 Geometry geometry = Geometry::New();
54 geometry.AddVertexBuffer(vertexBuffer);
55 if(indices.Size() > 0)
57 geometry.SetIndexBuffer(&indices[0], indices.Size());
64 * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid
66 * @param[out] indices The indices to add to
67 * @param[in] rowIdx The row index to start the quad
68 * @param[in] nextRowIdx The index to the next row
70 void AddQuadIndices(Vector<uint16_t>& indices, uint32_t rowIdx, uint32_t nextRowIdx)
72 indices.PushBack(rowIdx);
73 indices.PushBack(nextRowIdx + 1);
74 indices.PushBack(rowIdx + 1);
76 indices.PushBack(rowIdx);
77 indices.PushBack(nextRowIdx);
78 indices.PushBack(nextRowIdx + 1);
82 * @brief Adds the vertices to create for npatch
83 * @param[out] vertices The vertices to add to
84 * @param[in] x The x value of vector
85 * @param[in] y The y value of vector
87 void AddVertex(Vector<Vector2>& vertices, uint32_t x, uint32_t y)
89 vertices.PushBack(Vector2(x, y));
92 } // unnamed namespace
94 Geometry CreateGridGeometry(Uint16Pair gridSize)
96 uint16_t gridWidth = gridSize.GetWidth();
97 uint16_t gridHeight = gridSize.GetHeight();
100 Vector<Vector2> vertices;
101 vertices.Reserve((gridWidth + 1u) * (gridHeight + 1u));
103 for(uint32_t y = 0u; y < gridHeight + 1u; ++y)
105 for(uint32_t x = 0u; x < gridWidth + 1u; ++x)
107 AddVertex(vertices, x, y);
112 Vector<uint16_t> indices;
113 indices.Reserve(gridWidth * gridHeight * 6u);
115 uint32_t rowIdx = 0u;
116 uint32_t nextRowIdx = gridWidth + 1u;
117 for(uint32_t y = 0u; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx)
119 for(uint32_t x = 0u; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
121 AddQuadIndices(indices, rowIdx, nextRowIdx);
125 return GenerateGeometry(vertices, indices);
128 Geometry CreateBorderGeometry(Uint16Pair gridSize)
130 uint16_t gridWidth = gridSize.GetWidth();
131 uint16_t gridHeight = gridSize.GetHeight();
134 Vector<Vector2> vertices;
135 vertices.Reserve((gridWidth + 1u) * (gridHeight + 1u));
141 for(uint16_t x = 0; x < gridWidth + 1u; ++x)
143 AddVertex(vertices, x, y);
147 for(; y < gridHeight - 1u; ++y)
150 AddVertex(vertices, 0u, y);
151 AddVertex(vertices, 1u, y);
154 AddVertex(vertices, gridWidth - 1u, y);
155 AddVertex(vertices, gridWidth, y);
159 for(; y < gridHeight + 1u; ++y)
161 for(uint16_t x = 0; x < gridWidth + 1u; ++x)
163 AddVertex(vertices, x, y);
168 Vector<uint16_t> indices;
169 indices.Reserve(gridWidth * gridHeight * 6u);
172 uint32_t rowIdx = 0u;
173 uint32_t nextRowIdx = gridWidth + 1u;
174 for(uint16_t x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
176 AddQuadIndices(indices, rowIdx, nextRowIdx);
181 rowIdx = gridWidth + 1u;
182 nextRowIdx = (gridWidth + 1u) * 2u;
184 uint16_t increment = gridWidth - 1u;
189 AddQuadIndices(indices, rowIdx, nextRowIdx);
191 rowIdx = gridWidth * 2u;
192 nextRowIdx = (gridWidth + 1u) * 2u + 2u;
194 AddQuadIndices(indices, rowIdx, nextRowIdx);
197 rowIdx = nextRowIdx - 2u;
198 nextRowIdx = rowIdx + 4u;
199 for(uint16_t y = 2u; y < 2u * (gridHeight - 3u); ++y, rowIdx += 2u, nextRowIdx += 2u)
201 AddQuadIndices(indices, rowIdx, nextRowIdx);
206 AddQuadIndices(indices, rowIdx, nextRowIdx);
209 nextRowIdx += gridWidth - 1u;
211 AddQuadIndices(indices, rowIdx, nextRowIdx);
215 rowIdx = nextRowIdx - gridWidth + 1u;
216 nextRowIdx = rowIdx + gridWidth + 1u;
217 for(uint16_t x = 0u; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
219 AddQuadIndices(indices, rowIdx, nextRowIdx);
222 return GenerateGeometry(vertices, indices);
225 void RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent)
227 uint16_t prevEnd = 0;
228 uint16_t prevFix = 0;
229 uint16_t prevStretch = 0;
231 for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i)
233 uint16_t start = it->GetX();
234 uint16_t end = it->GetY();
236 uint16_t fix = prevFix + start - prevEnd;
237 uint16_t stretch = prevStretch + end - start;
239 std::stringstream uniform;
240 uniform << uniformName << "[" << i << "]";
241 renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch));
245 prevStretch = stretch;
249 prevFix += imageExtent - prevEnd;
250 std::stringstream uniform;
251 uniform << uniformName << "[" << i << "]";
252 renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch));
256 void ApplyTextureAndUniforms(Renderer& renderer, const Internal::NPatchData* data)
258 TextureSet textureSet;
259 textureSet = data->GetTextures();
261 if(data->GetStretchPixelsX().Size() == 1u && data->GetStretchPixelsY().Size() == 1u)
263 //special case for 9 patch
264 Uint16Pair stretchX = data->GetStretchPixelsX()[0];
265 Uint16Pair stretchY = data->GetStretchPixelsY()[0];
267 uint16_t stretchWidth = (stretchX.GetY() >= stretchX.GetX()) ? stretchX.GetY() - stretchX.GetX() : 0u;
268 uint16_t stretchHeight = (stretchY.GetY() >= stretchY.GetX()) ? stretchY.GetY() - stretchY.GetX() : 0u;
270 renderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
271 renderer.RegisterProperty("uFixed[1]", Vector2(stretchX.GetX(), stretchY.GetX()));
272 renderer.RegisterProperty("uFixed[2]", Vector2(data->GetCroppedWidth() - stretchWidth, data->GetCroppedHeight() - stretchHeight));
273 renderer.RegisterProperty("uStretchTotal", Vector2(stretchWidth, stretchHeight));
277 renderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO);
278 renderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO);
280 RegisterStretchProperties(renderer, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth());
281 RegisterStretchProperties(renderer, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight());
285 } // namespace NPatchHelper
287 } // namespace Toolkit