04934dcad2dba96a817f8829c28880277c32b230
[platform/core/graphics/tizenvg.git] / src / lib / tvgShapePath.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 #ifndef _TVG_SHAPE_PATH_CPP_
23 #define _TVG_SHAPE_PATH_CPP_
24
25 #include "tvgCommon.h"
26
27 /************************************************************************/
28 /* Internal Class Implementation                                        */
29 /************************************************************************/
30
31 struct ShapePath
32 {
33     PathCommand* cmds = nullptr;
34     uint32_t cmdCnt = 0;
35     uint32_t reservedCmdCnt = 0;
36
37     Point *pts = nullptr;
38     uint32_t ptsCnt = 0;
39     uint32_t reservedPtsCnt = 0;
40
41
42     ~ShapePath()
43     {
44         if (cmds) free(cmds);
45         if (pts) free(pts);
46     }
47
48     void reserveCmd(uint32_t cmdCnt)
49     {
50         if (cmdCnt <= reservedCmdCnt) return;
51         reservedCmdCnt = cmdCnt;
52         cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt));
53     }
54
55     void reservePts(uint32_t ptsCnt)
56     {
57         if (ptsCnt <= reservedPtsCnt) return;
58         reservedPtsCnt = ptsCnt;
59         pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt));
60     }
61
62     void grow(uint32_t cmdCnt, uint32_t ptsCnt)
63     {
64         reserveCmd(this->cmdCnt + cmdCnt);
65         reservePts(this->ptsCnt + ptsCnt);
66     }
67
68     void reset()
69     {
70         cmdCnt = 0;
71         ptsCnt = 0;
72     }
73
74     void append(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt)
75     {
76         memcpy(this->cmds + this->cmdCnt, cmds, sizeof(PathCommand) * cmdCnt);
77         memcpy(this->pts + this->ptsCnt, pts, sizeof(Point) * ptsCnt);
78         this->cmdCnt += cmdCnt;
79         this->ptsCnt += ptsCnt;
80     }
81
82     void moveTo(float x, float y)
83     {
84         if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
85         if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
86
87         cmds[cmdCnt++] = PathCommand::MoveTo;
88         pts[ptsCnt++] = {x, y};
89     }
90
91     void lineTo(float x, float y)
92     {
93         if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
94         if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
95
96         cmds[cmdCnt++] = PathCommand::LineTo;
97         pts[ptsCnt++] = {x, y};
98     }
99
100     void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y)
101     {
102         if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
103         if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2);
104
105         cmds[cmdCnt++] = PathCommand::CubicTo;
106         pts[ptsCnt++] = {cx1, cy1};
107         pts[ptsCnt++] = {cx2, cy2};
108         pts[ptsCnt++] = {x, y};
109     }
110
111     void close()
112     {
113         if (cmdCnt > 0 && cmds[cmdCnt - 1] == PathCommand::Close) return;
114
115         if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
116         cmds[cmdCnt++] = PathCommand::Close;
117     }
118
119     bool bounds(float* x, float* y, float* w, float* h)
120     {
121         if (ptsCnt == 0) return false;
122
123         Point min = { pts[0].x, pts[0].y };
124         Point max = { pts[0].x, pts[0].y };
125
126         for(uint32_t i = 1; i < ptsCnt; ++i) {
127             if (pts[i].x < min.x) min.x = pts[i].x;
128             if (pts[i].y < min.y) min.y = pts[i].y;
129             if (pts[i].x > max.x) max.x = pts[i].x;
130             if (pts[i].y > max.y) max.y = pts[i].y;
131         }
132
133         if (x) *x = min.x;
134         if (y) *y = min.y;
135         if (w) *w = max.x - min.x;
136         if (h) *h = max.y - min.y;
137
138         return true;
139     }
140 };
141
142 #endif //_TVG_SHAPE_PATH_CPP_