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 static void initBBox(SwShape& sdata)
155 sdata.bbox.xMin = sdata.bbox.yMin = 0;
156 sdata.bbox.xMax = sdata.bbox.yMax = 0;
160 static bool updateBBox(SwShape& sdata)
162 auto outline = sdata.outline;
165 auto pt = outline->pts;
168 if (outline->ptsCnt <= 0) {
180 for(size_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
182 if (xMin > pt->x) xMin = pt->x;
183 if (xMax < pt->y) xMax = pt->x;
184 if (yMin > pt->y) yMin = pt->y;
185 if (yMax < pt->y) yMax = pt->y;
187 sdata.bbox.xMin = round(xMin - 0.49);
188 sdata.bbox.xMax = round(xMax + 0.49);
189 sdata.bbox.yMin = round(yMin - 0.49);
190 sdata.bbox.yMax = round(yMax + 0.49);
192 if (xMax - xMin < 1 || yMax - yMin < 1) return false;
198 /************************************************************************/
199 /* External Class Implementation */
200 /************************************************************************/
202 bool shapeTransformOutline(const ShapeNode& shape, SwShape& sdata)
209 void shapeDelRle(const ShapeNode& shape, SwShape& sdata)
211 if (sdata.rle.spans) free(sdata.rle.spans);
212 sdata.rle.spans = nullptr;
216 bool shapeGenRle(const ShapeNode& shape, SwShape& sdata)
218 shapeDelRle(shape, sdata);
219 if (!updateBBox(sdata)) return false;
220 return rleRender(sdata);
224 void shapeDelOutline(const ShapeNode& shape, SwShape& sdata)
226 if (!sdata.outline) return;
228 SwOutline* outline = sdata.outline;
229 if (outline->cntrs) free(outline->cntrs);
230 if (outline->pts) free(outline->pts);
231 if (outline->tags) free(outline->tags);
234 sdata.outline = nullptr;
238 bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
242 const PathCommand* cmds = nullptr;
243 auto cmdCnt = shape.pathCommands(&cmds);
245 const Point* pts = nullptr;
246 auto ptsCnt = shape.pathCoords(&pts);
248 //No actual shape data
249 if (cmdCnt == 0 || ptsCnt == 0) return false;
252 auto outlinePtsCnt = 0;
253 auto outlineCntrsCnt = 0;
254 // auto closed = false;
256 for (auto i = 0; i < cmdCnt; ++i) {
257 switch(*(cmds + i)) {
258 case PathCommand::Close: {
262 case PathCommand::MoveTo: {
267 case PathCommand::LineTo: {
271 case PathCommand::CubicTo: {
278 ++outlinePtsCnt; //for close
279 ++outlineCntrsCnt; //for end
281 SwOutline* outline = sdata.outline;
284 outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
287 cout << "Outline was already allocated? How?" << endl;
290 //TODO: Probabry we can copy pts from shape directly.
291 growOutlinePoint(*outline, outlinePtsCnt);
292 growOutlineContour(*outline, outlineCntrsCnt);
295 while (cmdCnt-- > 0) {
297 case PathCommand::Close: {
298 outlineClose(*outline);
301 case PathCommand::MoveTo: {
302 outlineMoveTo(*outline, pts);
306 case PathCommand::LineTo: {
307 outlineLineTo(*outline, pts);
311 case PathCommand::CubicTo: {
312 outlineCubicTo(*outline, pts, pts + 1, pts + 2);
320 outlineEnd(*outline);
323 //outline->flags = SwOutline::FillRule::Winding;
325 sdata.outline = outline;
331 #endif /* _TVG_SW_SHAPE_H_ */