2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
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.
17 #ifndef _TVG_SW_SHAPE_H_
18 #define _TVG_SW_SHAPE_H_
20 #include "tvgSwCommon.h"
22 /************************************************************************/
23 /* Internal Class Implementation */
24 /************************************************************************/
26 static void growOutlineContour(SwOutline& outline, size_t n)
30 outline.cntrs = nullptr;
32 outline.reservedCntrsCnt = 0;
35 if (outline.reservedCntrsCnt >= outline.cntrsCnt + n) return;
37 cout << "Grow Cntrs: " << outline.reservedCntrsCnt << " -> " << outline.cntrsCnt + n << endl;;
38 outline.reservedCntrsCnt = n;
39 outline.cntrs = static_cast<size_t*>(realloc(outline.cntrs, n * sizeof(size_t)));
40 assert(outline.cntrs);
44 static void growOutlinePoint(SwOutline& outline, size_t n)
48 outline.pts = nullptr;
50 outline.tags = nullptr;
51 outline.reservedPtsCnt = 0;
56 if (outline.reservedPtsCnt >= outline.ptsCnt + n) return;
58 cout << "Grow Pts: " << outline.reservedPtsCnt << " -> " << outline.ptsCnt + n << endl;
59 outline.reservedPtsCnt = n;
60 outline.pts = static_cast<Point*>(realloc(outline.pts, n * sizeof(Point)));
62 outline.tags = static_cast<char*>(realloc(outline.tags, n * sizeof(char)));
67 static void outlineEnd(SwOutline& outline)
69 growOutlineContour(outline, 1);
70 if (outline.ptsCnt > 0) {
71 outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
77 static void outlineMoveTo(SwOutline& outline, const Point* pt)
81 growOutlinePoint(outline, 1);
83 outline.pts[outline.ptsCnt] = *pt;
84 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON;
86 if (outline.ptsCnt > 0) {
87 growOutlineContour(outline, 1);
88 outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
96 static void outlineLineTo(SwOutline& outline, const Point* pt)
100 growOutlinePoint(outline, 1);
102 outline.pts[outline.ptsCnt] = *pt;
103 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON;
109 static void outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* pt)
111 assert(ctrl1 && ctrl2 && pt);
113 growOutlinePoint(outline, 3);
115 outline.pts[outline.ptsCnt] = *ctrl1;
116 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_CUBIC;
119 outline.pts[outline.ptsCnt] = *ctrl2;
120 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_CUBIC;
123 outline.pts[outline.ptsCnt] = *ctrl1;
124 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON;
129 static bool outlineClose(SwOutline& outline)
133 if (outline.cntrsCnt > 0) {
134 i = outline.cntrs[outline.cntrsCnt - 1] + 1;
139 //Make sure there is at least one point in the current path
140 if (outline.ptsCnt == i) return false;
143 growOutlinePoint(outline, 1);
145 outline.pts[outline.ptsCnt] = outline.pts[i];
146 outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON;
153 /************************************************************************/
154 /* External Class Implementation */
155 /************************************************************************/
157 bool shapeGenRle(const ShapeNode& shape, SwShape& sdata)
165 bool shapeUpdateBBox(const ShapeNode& shape, SwShape& sdata)
172 void shapeDelOutline(const ShapeNode& shape, SwShape& sdata)
174 if (!sdata.outline) return;
176 SwOutline* outline = sdata.outline;
177 if (outline->cntrs) free(outline->cntrs);
178 if (outline->pts) free(outline->pts);
179 if (outline->tags) free(outline->tags);
182 sdata.outline = nullptr;
186 bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
188 const PathCommand* cmds = nullptr;
189 auto cmdCnt = shape.pathCommands(&cmds);
191 const Point* pts = nullptr;
192 auto ptsCnt = shape.pathCoords(&pts);
194 //No actual shape data
195 if (cmdCnt == 0 || ptsCnt == 0) return false;
198 auto outlinePtsCnt = 0;
199 auto outlineCntrsCnt = 0;
200 // auto closed = false;
202 for (auto i = 0; i < cmdCnt; ++i) {
203 switch(*(cmds + i)) {
204 case PathCommand::Close: {
208 case PathCommand::MoveTo: {
213 case PathCommand::LineTo: {
217 case PathCommand::CubicTo: {
224 ++outlinePtsCnt; //for close
225 ++outlineCntrsCnt; //for end
227 SwOutline* outline = sdata.outline;
230 outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
233 cout << "Outline was already allocated? How?" << endl;
236 growOutlinePoint(*outline, outlinePtsCnt);
237 growOutlineContour(*outline, outlineCntrsCnt);
240 while (cmdCnt-- > 0) {
242 case PathCommand::Close: {
243 outlineClose(*outline);
246 case PathCommand::MoveTo: {
247 outlineMoveTo(*outline, pts);
251 case PathCommand::LineTo: {
252 outlineLineTo(*outline, pts);
256 case PathCommand::CubicTo: {
257 outlineCubicTo(*outline, pts, pts + 1, pts + 2);
265 outlineEnd(*outline);
267 sdata.outline = outline;
273 #endif /* _TVG_SW_SHAPE_H_ */