@react-native-ohos/react-native-clippathview 1.1.9-rc.1 → 1.1.9-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{harmony/clipPath/README.OpenSource → README.OpenSource} +2 -2
- package/README.md +15 -15
- package/harmony/clipPath/index.ets +2 -0
- package/harmony/clipPath/oh-package.json5 +1 -1
- package/harmony/clipPath/src/main/cpp/ClipPathProps.h +120 -63
- package/harmony/clipPath/src/main/cpp/ClipPathViewComponentInstance.cpp +43 -37
- package/harmony/clipPath/src/main/cpp/ClipPathViewComponentInstance.h +6 -1
- package/harmony/clipPath/src/main/cpp/ClipPathViewNoneComponentInstance.cpp +43 -36
- package/harmony/clipPath/src/main/cpp/ClipPathViewNoneNode.cpp +166 -90
- package/harmony/clipPath/src/main/cpp/ClipPathViewNoneNode.h +100 -84
- package/harmony/clipPath/src/main/cpp/RNCClipPathTurboModule.cpp +2 -2
- package/harmony/clipPath/src/main/cpp/RNCClipPathTurboModule.h +10 -7
- package/harmony/clipPath/src/main/cpp/SVGPathParser.cpp +261 -222
- package/harmony/clipPath/src/main/cpp/SVGPathParser.h +4 -4
- package/harmony/clipPath/src/main/cpp/SVGViewBox.cpp +9 -9
- package/harmony/clipPath/src/main/cpp/ShadowNodes.cpp +4 -2
- package/harmony/clipPath/src/main/cpp/pen_style_node.h +20 -4
- package/harmony/clipPath/src/main/ets/{ClipPathPackage.ts → ClipPathPackage.ets} +2 -1
- package/harmony/clipPath.har +0 -0
- package/package.json +10 -8
- package/harmony/clipPath/BuildProfile.ets +0 -6
- package/harmony/clipPath/OAT.xml +0 -39
- package/react-native-clippath.podspec +0 -30
- /package/harmony/clipPath/{ts.ts → ts.ets} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* you may not use this file except in compliance with the License.
|
|
5
5
|
* You may obtain a copy of the License at
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
8
|
*
|
|
9
9
|
* Unless required by applicable law or agreed to in writing, software
|
|
10
10
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
#include <native_drawing/drawing_path.h>
|
|
18
18
|
#include <stdexcept>
|
|
19
19
|
#include <sstream>
|
|
20
|
-
#include
|
|
20
|
+
#include <cmath>
|
|
21
21
|
#include <cctype>
|
|
22
22
|
#include "cmath"
|
|
23
23
|
#include "vector"
|
|
@@ -36,12 +36,13 @@ float SVGPathParser::mPenDownX = 0.0f;
|
|
|
36
36
|
float SVGPathParser::mPenDownY = 0.0f;
|
|
37
37
|
bool SVGPathParser::mPenDown = false;
|
|
38
38
|
|
|
39
|
-
OH_Drawing_Path *SVGPathParser::parse(const std::string d)
|
|
39
|
+
OH_Drawing_Path *SVGPathParser::parse(const std::string d)
|
|
40
|
+
{
|
|
40
41
|
if (d.empty()) {
|
|
41
42
|
return nullptr;
|
|
42
43
|
}
|
|
43
44
|
OH_Drawing_Path *cPath_ = OH_Drawing_PathCreate();
|
|
44
|
-
char
|
|
45
|
+
char prevCmd = ' ';
|
|
45
46
|
l = d.length();
|
|
46
47
|
s = d;
|
|
47
48
|
i = 0;
|
|
@@ -55,13 +56,11 @@ OH_Drawing_Path *SVGPathParser::parse(const std::string d) {
|
|
|
55
56
|
mPenDown = false;
|
|
56
57
|
|
|
57
58
|
while (i < l) {
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
SkipSpaces();
|
|
60
60
|
if (i >= l) {
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
bool has_prev_cmd = prev_cmd != ' ';
|
|
63
|
+
bool has_prev_cmd = prevCmd != ' ';
|
|
65
64
|
char first_char = s.at(i);
|
|
66
65
|
|
|
67
66
|
if (!has_prev_cmd && first_char != 'M' && first_char != 'm') {
|
|
@@ -71,34 +70,33 @@ OH_Drawing_Path *SVGPathParser::parse(const std::string d) {
|
|
|
71
70
|
throw std::logic_error(oss.str());
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
// TODO: simplify
|
|
75
73
|
bool is_implicit_move_to;
|
|
76
74
|
char cmd;
|
|
77
|
-
if (
|
|
75
|
+
if (IsCmd(first_char)) {
|
|
78
76
|
is_implicit_move_to = false;
|
|
79
77
|
cmd = first_char;
|
|
80
78
|
i += 1;
|
|
81
79
|
} else if (is_number_start(first_char) && has_prev_cmd) {
|
|
82
|
-
if (
|
|
80
|
+
if (prevCmd == 'Z' || prevCmd == 'z') {
|
|
83
81
|
// ClosePath cannot be followed by a number.
|
|
84
82
|
std::ostringstream oss;
|
|
85
83
|
oss << "Unexpected number after 'z' (s=" << s << ")";
|
|
86
84
|
throw std::logic_error(oss.str());
|
|
87
85
|
}
|
|
88
86
|
|
|
89
|
-
if (
|
|
87
|
+
if (prevCmd == 'M' || prevCmd == 'm') {
|
|
90
88
|
// 'If a moveto is followed by multiple pairs of coordinates,
|
|
91
89
|
// the subsequent pairs are treated as implicit lineto commands.'
|
|
92
90
|
// So we parse them as LineTo.
|
|
93
91
|
is_implicit_move_to = true;
|
|
94
|
-
if (is_absolute(
|
|
92
|
+
if (is_absolute(prevCmd)) {
|
|
95
93
|
cmd = 'L';
|
|
96
94
|
} else {
|
|
97
95
|
cmd = 'l';
|
|
98
96
|
}
|
|
99
97
|
} else {
|
|
100
98
|
is_implicit_move_to = false;
|
|
101
|
-
cmd =
|
|
99
|
+
cmd = prevCmd;
|
|
102
100
|
}
|
|
103
101
|
} else {
|
|
104
102
|
std::ostringstream oss;
|
|
@@ -107,203 +105,219 @@ OH_Drawing_Path *SVGPathParser::parse(const std::string d) {
|
|
|
107
105
|
}
|
|
108
106
|
bool absolute = is_absolute(cmd);
|
|
109
107
|
switch (cmd) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
parse_list_number(), parse_list_number(), cPath_);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case 'C': {
|
|
149
|
-
curveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(),
|
|
108
|
+
case 'm': {
|
|
109
|
+
rnoh:
|
|
110
|
+
move(parse_list_number(), parse_list_number(), cPath_);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'M': {
|
|
114
|
+
moveTo(parse_list_number(), parse_list_number(), cPath_);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'l': {
|
|
118
|
+
line(parse_list_number(), parse_list_number(), cPath_);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case 'L': {
|
|
122
|
+
lineTo(parse_list_number(), parse_list_number(), cPath_);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case 'h': {
|
|
126
|
+
line(parse_list_number(), 0, cPath_);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'H': {
|
|
130
|
+
lineTo(parse_list_number(), mPenY, cPath_);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'v': {
|
|
134
|
+
line(0, parse_list_number(), cPath_);
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case 'V': {
|
|
138
|
+
lineTo(mPenX, parse_list_number(), cPath_);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case 'c': {
|
|
142
|
+
curve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(),
|
|
150
143
|
parse_list_number(), parse_list_number(), cPath_);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case 'C': {
|
|
147
|
+
curveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(),
|
|
148
|
+
parse_list_number(), parse_list_number(), cPath_);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 's': {
|
|
152
|
+
smoothCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), cPath_);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 'S': {
|
|
156
|
+
smoothCurveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(),
|
|
157
|
+
cPath_);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case 'q': {
|
|
161
|
+
quadraticBezierCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(),
|
|
162
|
+
cPath_);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 'Q': {
|
|
166
|
+
quadraticBezierCurveTo(parse_list_number(), parse_list_number(), parse_list_number(),
|
|
167
|
+
parse_list_number(), cPath_);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 't': {
|
|
171
|
+
smoothQuadraticBezierCurve(parse_list_number(), parse_list_number(), cPath_);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case 'T': {
|
|
175
|
+
smoothQuadraticBezierCurveTo(parse_list_number(), parse_list_number(), cPath_);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case 'a': {
|
|
179
|
+
arc(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(),
|
|
180
|
+
parse_list_number(), parse_list_number(), cPath_);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case 'A': {
|
|
184
|
+
arcTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(),
|
|
185
|
+
parse_list_number(), parse_list_number(), cPath_);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case 'z':
|
|
189
|
+
case 'Z': {
|
|
190
|
+
close(cPath_);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
default: {
|
|
194
|
+
std::ostringstream oss;
|
|
195
|
+
oss << "Unexpected comand " << cmd << ",s=" << s << ")";
|
|
196
|
+
throw std::logic_error(oss.str());
|
|
197
|
+
}
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
if (is_implicit_move_to) {
|
|
202
201
|
if (absolute) {
|
|
203
|
-
|
|
202
|
+
prevCmd = 'M';
|
|
204
203
|
} else {
|
|
205
|
-
|
|
204
|
+
prevCmd = 'm';
|
|
206
205
|
}
|
|
207
206
|
} else {
|
|
208
|
-
|
|
207
|
+
prevCmd = cmd;
|
|
209
208
|
}
|
|
210
209
|
}
|
|
211
210
|
return cPath_;
|
|
212
211
|
}
|
|
213
212
|
|
|
214
|
-
void SVGPathParser::move(float x, float y, OH_Drawing_Path *cPath_)
|
|
213
|
+
void SVGPathParser::move(float x, float y, OH_Drawing_Path *cPath_)
|
|
214
|
+
{
|
|
215
|
+
moveTo(x + mPenX, y + mPenY, cPath_);
|
|
216
|
+
}
|
|
215
217
|
|
|
216
|
-
void SVGPathParser::moveTo(float x, float y, OH_Drawing_Path *cPath_)
|
|
218
|
+
void SVGPathParser::moveTo(float x, float y, OH_Drawing_Path *cPath_)
|
|
219
|
+
{
|
|
217
220
|
mPenDownX = mPivotX = mPenX = x;
|
|
218
221
|
mPenDownY = mPivotY = mPenY = y;
|
|
219
222
|
OH_Drawing_PathMoveTo(cPath_, x * mScale, y * mScale);
|
|
220
223
|
}
|
|
221
224
|
|
|
222
|
-
void SVGPathParser::line(float x, float y, OH_Drawing_Path *cPath_)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
void SVGPathParser::line(float x, float y, OH_Drawing_Path *cPath_)
|
|
226
|
+
{
|
|
227
|
+
lineTo(x + mPenX, y + mPenY, cPath_);
|
|
228
|
+
}
|
|
229
|
+
void SVGPathParser::lineTo(float x, float y, OH_Drawing_Path *cPath_)
|
|
230
|
+
{
|
|
231
|
+
SetPenDown();
|
|
226
232
|
mPivotX = mPenX = x;
|
|
227
233
|
mPivotY = mPenY = y;
|
|
228
234
|
OH_Drawing_PathLineTo(cPath_, x * mScale, y * mScale);
|
|
229
235
|
}
|
|
230
236
|
|
|
231
|
-
void SVGPathParser::curve(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
237
|
+
void SVGPathParser::curve(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
238
|
+
{
|
|
232
239
|
curveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY, ex + mPenX, ey + mPenY, cPath_);
|
|
233
240
|
}
|
|
234
241
|
|
|
235
|
-
void SVGPathParser::curveTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
242
|
+
void SVGPathParser::curveTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
243
|
+
{
|
|
236
244
|
mPivotX = c2x;
|
|
237
245
|
mPivotY = c2y;
|
|
238
246
|
cubicTo(c1x, c1y, c2x, c2y, ex, ey, cPath_);
|
|
239
247
|
}
|
|
240
248
|
|
|
241
|
-
void SVGPathParser::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
242
|
-
|
|
249
|
+
void SVGPathParser::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
250
|
+
{
|
|
251
|
+
SetPenDown();
|
|
243
252
|
mPenX = ex;
|
|
244
253
|
mPenY = ey;
|
|
245
254
|
OH_Drawing_PathCubicTo(cPath_, c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
|
|
246
255
|
}
|
|
247
256
|
|
|
248
257
|
|
|
249
|
-
void SVGPathParser::smoothCurve(float c1x, float c1y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
258
|
+
void SVGPathParser::smoothCurve(float c1x, float c1y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
259
|
+
{
|
|
250
260
|
smoothCurveTo(c1x + mPenX, c1y + mPenY, ex + mPenX, ey + mPenY, cPath_);
|
|
251
261
|
}
|
|
252
|
-
void SVGPathParser::smoothCurveTo(float c1x, float c1y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
253
|
-
|
|
262
|
+
void SVGPathParser::smoothCurveTo(float c1x, float c1y, float ex, float ey, OH_Drawing_Path *cPath_)
|
|
263
|
+
{
|
|
254
264
|
float c2x = c1x;
|
|
255
265
|
float c2y = c1y;
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
int count2 = 2;
|
|
267
|
+
c1x = (mPenX * count2) - mPivotX;
|
|
268
|
+
c1y = (mPenY * count2) - mPivotY;
|
|
258
269
|
mPivotX = c2x;
|
|
259
270
|
mPivotY = c2y;
|
|
260
271
|
cubicTo(c1x, c1y, c2x, c2y, ex, ey, cPath_);
|
|
261
272
|
}
|
|
262
273
|
|
|
263
|
-
void SVGPathParser::quadraticBezierCurve(float c1x, float c1y, float c2x, float c2y, OH_Drawing_Path *cPath_)
|
|
274
|
+
void SVGPathParser::quadraticBezierCurve(float c1x, float c1y, float c2x, float c2y, OH_Drawing_Path *cPath_)
|
|
275
|
+
{
|
|
264
276
|
quadraticBezierCurveTo(c1x + mPenX, c1y + mPenY, c2x + mPenX, c2y + mPenY, cPath_);
|
|
265
277
|
}
|
|
266
278
|
|
|
267
|
-
void SVGPathParser::quadraticBezierCurveTo(float c1x, float c1y, float c2x, float c2y, OH_Drawing_Path *cPath_)
|
|
268
|
-
|
|
279
|
+
void SVGPathParser::quadraticBezierCurveTo(float c1x, float c1y, float c2x, float c2y, OH_Drawing_Path *cPath_)
|
|
280
|
+
{
|
|
281
|
+
int count2 = 2;
|
|
282
|
+
int count3 = 3;
|
|
269
283
|
mPivotX = c1x;
|
|
270
284
|
mPivotY = c1y;
|
|
271
285
|
float ex = c2x;
|
|
272
286
|
float ey = c2y;
|
|
273
|
-
c2x = (ex + c1x *
|
|
274
|
-
c2y = (ey + c1y *
|
|
275
|
-
c1x = (mPenX + c1x *
|
|
276
|
-
c1y = (mPenY + c1y *
|
|
287
|
+
c2x = (ex + c1x * count2) / count3;
|
|
288
|
+
c2y = (ey + c1y * count2) / count3;
|
|
289
|
+
c1x = (mPenX + c1x * count2) / count3;
|
|
290
|
+
c1y = (mPenY + c1y * count2) / count3;
|
|
277
291
|
cubicTo(c1x, c1y, c2x, c2y, ex, ey, cPath_);
|
|
278
292
|
}
|
|
279
293
|
|
|
280
|
-
void SVGPathParser::smoothQuadraticBezierCurve(float c1x, float c1y, OH_Drawing_Path *cPath_)
|
|
294
|
+
void SVGPathParser::smoothQuadraticBezierCurve(float c1x, float c1y, OH_Drawing_Path *cPath_)
|
|
295
|
+
{
|
|
281
296
|
smoothQuadraticBezierCurveTo(c1x + mPenX, c1y + mPenY, cPath_);
|
|
282
297
|
}
|
|
283
298
|
|
|
284
|
-
void SVGPathParser::smoothQuadraticBezierCurveTo(float c1x, float c1y, OH_Drawing_Path *cPath_)
|
|
285
|
-
|
|
299
|
+
void SVGPathParser::smoothQuadraticBezierCurveTo(float c1x, float c1y, OH_Drawing_Path *cPath_)
|
|
300
|
+
{
|
|
286
301
|
float c2x = c1x;
|
|
287
302
|
float c2y = c1y;
|
|
288
|
-
|
|
289
|
-
|
|
303
|
+
int count2 = 2;
|
|
304
|
+
c1x = (mPenX * count2) - mPivotX;
|
|
305
|
+
c1y = (mPenY * count2) - mPivotY;
|
|
290
306
|
quadraticBezierCurveTo(c1x, c1y, c2x, c2y, cPath_);
|
|
291
307
|
}
|
|
292
308
|
void SVGPathParser::arc(float rx, float ry, float rotation, bool outer, bool clockwise, float x, float y,
|
|
293
|
-
|
|
309
|
+
OH_Drawing_Path *cPath_)
|
|
310
|
+
{
|
|
294
311
|
arcTo(rx, ry, rotation, outer, clockwise, x + mPenX, y + mPenY, cPath_);
|
|
295
312
|
}
|
|
296
313
|
|
|
297
314
|
void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool clockwise, float x, float y,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
// clockwise: " + clockwise + " x: " + x + " y: " + y);
|
|
315
|
+
OH_Drawing_Path *cPath_)
|
|
316
|
+
{
|
|
301
317
|
float tX = mPenX;
|
|
302
318
|
float tY = mPenY;
|
|
303
|
-
|
|
304
319
|
ry = abs(ry == 0 ? (rx == 0 ? (y - tY) : rx) : ry);
|
|
305
320
|
rx = abs(rx == 0 ? (x - tX) : rx);
|
|
306
|
-
|
|
307
321
|
if (rx == 0 || ry == 0 || (x == tX && y == tY)) {
|
|
308
322
|
lineTo(x, y, cPath_);
|
|
309
323
|
return;
|
|
@@ -316,8 +330,9 @@ void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool c
|
|
|
316
330
|
y -= tY;
|
|
317
331
|
|
|
318
332
|
// Ellipse Center
|
|
319
|
-
|
|
320
|
-
float
|
|
333
|
+
int count2 = 2;
|
|
334
|
+
float cx = cos * x / count2 + sin * y / count2;
|
|
335
|
+
float cy = -sin * x / count2 + cos * y / count2;
|
|
321
336
|
float rxry = rx * rx * ry * ry;
|
|
322
337
|
float rycx = ry * ry * cx * cx;
|
|
323
338
|
float rxcy = rx * rx * cy * cy;
|
|
@@ -327,8 +342,8 @@ void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool c
|
|
|
327
342
|
a = std::sqrt(1 - a / rxry);
|
|
328
343
|
rx *= a;
|
|
329
344
|
ry *= a;
|
|
330
|
-
cx = x /
|
|
331
|
-
cy = y /
|
|
345
|
+
cx = x / count2;
|
|
346
|
+
cy = y / count2;
|
|
332
347
|
} else {
|
|
333
348
|
a = std::sqrt(a / (rxcy + rycx));
|
|
334
349
|
|
|
@@ -337,8 +352,8 @@ void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool c
|
|
|
337
352
|
}
|
|
338
353
|
float cxd = -a * cy * rx / ry;
|
|
339
354
|
float cyd = a * cx * ry / rx;
|
|
340
|
-
cx = cos * cxd - sin * cyd + x /
|
|
341
|
-
cy = sin * cxd + cos * cyd + y /
|
|
355
|
+
cx = cos * cxd - sin * cyd + x / count2;
|
|
356
|
+
cy = sin * cxd + cos * cyd + y / count2;
|
|
342
357
|
}
|
|
343
358
|
|
|
344
359
|
// Rotation + Scale Transform
|
|
@@ -356,27 +371,29 @@ void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool c
|
|
|
356
371
|
x += tX;
|
|
357
372
|
y += tY;
|
|
358
373
|
|
|
359
|
-
|
|
374
|
+
SetPenDown();
|
|
360
375
|
|
|
361
376
|
mPenX = mPivotX = x;
|
|
362
377
|
mPenY = mPivotY = y;
|
|
378
|
+
int count180 = 180;
|
|
379
|
+
int count360 = 360;
|
|
380
|
+
double point180 = 180.0;
|
|
363
381
|
|
|
364
382
|
if (rx != ry || rad != 0.f) {
|
|
365
383
|
arcToBezier(cx, cy, rx, ry, sa, ea, clockwise, rad, cPath_);
|
|
366
384
|
} else {
|
|
367
|
-
|
|
368
|
-
float
|
|
369
|
-
float
|
|
370
|
-
float sweep = abs((start - end) - std::floor((start - end) / 360) * 360);
|
|
385
|
+
float start = static_cast<float>(sa * point180 / M_PI);
|
|
386
|
+
float end = static_cast<float>(ea * point180 / M_PI);
|
|
387
|
+
float sweep = abs((start - end) - std::floor((start - end) / count360) * count360);
|
|
371
388
|
|
|
372
389
|
|
|
373
390
|
if (outer) {
|
|
374
|
-
if (sweep <
|
|
375
|
-
sweep =
|
|
391
|
+
if (sweep < count180) {
|
|
392
|
+
sweep = count360 - sweep;
|
|
376
393
|
}
|
|
377
394
|
} else {
|
|
378
|
-
if (sweep >
|
|
379
|
-
sweep =
|
|
395
|
+
if (sweep > count180) {
|
|
396
|
+
sweep = count360 - sweep;
|
|
380
397
|
}
|
|
381
398
|
}
|
|
382
399
|
|
|
@@ -384,17 +401,19 @@ void SVGPathParser::arcTo(float rx, float ry, float rotation, bool outer, bool c
|
|
|
384
401
|
sweep = -sweep;
|
|
385
402
|
}
|
|
386
403
|
OH_Drawing_PathArcTo(cPath_, (cx - rx) * mScale, (cy - rx) * mScale, (cx + rx) * mScale, (cy + rx) * mScale,
|
|
387
|
-
|
|
404
|
+
start, sweep);
|
|
388
405
|
}
|
|
389
406
|
}
|
|
390
|
-
void SVGPathParser::
|
|
407
|
+
void SVGPathParser::SetPenDown()
|
|
408
|
+
{
|
|
391
409
|
if (!mPenDown) {
|
|
392
410
|
mPenDownX = mPenX;
|
|
393
411
|
mPenDownY = mPenY;
|
|
394
412
|
mPenDown = true;
|
|
395
413
|
}
|
|
396
414
|
}
|
|
397
|
-
void SVGPathParser::close(OH_Drawing_Path *cPath_)
|
|
415
|
+
void SVGPathParser::close(OH_Drawing_Path *cPath_)
|
|
416
|
+
{
|
|
398
417
|
if (mPenDown) {
|
|
399
418
|
mPenX = mPenDownX;
|
|
400
419
|
mPenY = mPenDownY;
|
|
@@ -403,7 +422,8 @@ void SVGPathParser::close(OH_Drawing_Path *cPath_) {
|
|
|
403
422
|
}
|
|
404
423
|
}
|
|
405
424
|
void SVGPathParser::arcToBezier(float cx, float cy, float rx, float ry, float sa, float ea, bool clockwise, float rad,
|
|
406
|
-
|
|
425
|
+
OH_Drawing_Path *cPath_)
|
|
426
|
+
{
|
|
407
427
|
// Inverse Rotation + Scale Transform
|
|
408
428
|
float cos = std::cos(rad);
|
|
409
429
|
float sin = std::sin(rad);
|
|
@@ -414,109 +434,126 @@ void SVGPathParser::arcToBezier(float cx, float cy, float rx, float ry, float sa
|
|
|
414
434
|
|
|
415
435
|
// Bezier Curve Approximation
|
|
416
436
|
float arc = ea - sa;
|
|
437
|
+
int count2 = 2;
|
|
438
|
+
int count4 = 4;
|
|
439
|
+
double point3 = 3.0;
|
|
417
440
|
if (arc < 0 && clockwise) {
|
|
418
|
-
arc += M_PI *
|
|
441
|
+
arc += M_PI * count2;
|
|
419
442
|
} else if (arc > 0 && !clockwise) {
|
|
420
|
-
arc -= M_PI *
|
|
443
|
+
arc -= M_PI * count2;
|
|
421
444
|
}
|
|
422
445
|
|
|
423
|
-
int n = (
|
|
446
|
+
int n = static_cast<int>(std::ceil(std::abs(round(arc / (M_PI / count2)))));
|
|
424
447
|
|
|
425
448
|
float step = arc / n;
|
|
426
|
-
float k =
|
|
449
|
+
float k = static_cast<float>((count4 / point3) * std::tan(step / count4));
|
|
427
450
|
float x = std::cos(sa);
|
|
428
451
|
float y = std::sin(sa);
|
|
429
452
|
|
|
430
|
-
for (int
|
|
453
|
+
for (int counti = 0; counti < n; counti++) {
|
|
431
454
|
float cp1x = x - k * y;
|
|
432
455
|
float cp1y = y + k * x;
|
|
433
456
|
|
|
434
457
|
sa += step;
|
|
435
|
-
|
|
436
|
-
|
|
458
|
+
float newX = std::cos(sa);
|
|
459
|
+
float newY = std::sin(sa);
|
|
437
460
|
|
|
438
|
-
float cp2x =
|
|
439
|
-
float cp2y =
|
|
461
|
+
float cp2x = newX + k * newY;
|
|
462
|
+
float cp2y = newY - k * newX;
|
|
440
463
|
|
|
441
464
|
float c1x = (cx + xx * cp1x + yx * cp1y);
|
|
442
465
|
float c1y = (cy + xy * cp1x + yy * cp1y);
|
|
443
466
|
float c2x = (cx + xx * cp2x + yx * cp2y);
|
|
444
467
|
float c2y = (cy + xy * cp2x + yy * cp2y);
|
|
445
|
-
float ex = (cx + xx *
|
|
446
|
-
float ey = (cy + xy *
|
|
468
|
+
float ex = (cx + xx * newX + yx * newY);
|
|
469
|
+
float ey = (cy + xy * newX + yy * newY);
|
|
447
470
|
OH_Drawing_PathCubicTo(cPath_, c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale,
|
|
448
|
-
|
|
471
|
+
ey * mScale);
|
|
449
472
|
}
|
|
450
473
|
}
|
|
451
474
|
|
|
452
|
-
double SVGPathParser::_round(double val)
|
|
475
|
+
double SVGPathParser::_round(double val)
|
|
476
|
+
{
|
|
453
477
|
double multiplier = pow(10, 4);
|
|
454
478
|
return round(val * multiplier) / multiplier;
|
|
455
479
|
}
|
|
456
480
|
|
|
457
|
-
void SVGPathParser::
|
|
458
|
-
|
|
481
|
+
void SVGPathParser::SkipSpaces()
|
|
482
|
+
{
|
|
483
|
+
while (i < l && std::isspace(s.at(i))) {
|
|
459
484
|
i++;
|
|
485
|
+
}
|
|
460
486
|
}
|
|
461
|
-
bool SVGPathParser::
|
|
487
|
+
bool SVGPathParser::IsCmd(char c)
|
|
488
|
+
{
|
|
462
489
|
switch (c) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
490
|
+
case 'M':
|
|
491
|
+
case 'm':
|
|
492
|
+
case 'Z':
|
|
493
|
+
case 'z':
|
|
494
|
+
case 'L':
|
|
495
|
+
case 'l':
|
|
496
|
+
case 'H':
|
|
497
|
+
case 'h':
|
|
498
|
+
case 'V':
|
|
499
|
+
case 'v':
|
|
500
|
+
case 'C':
|
|
501
|
+
case 'c':
|
|
502
|
+
case 'S':
|
|
503
|
+
case 's':
|
|
504
|
+
case 'Q':
|
|
505
|
+
case 'q':
|
|
506
|
+
case 'T':
|
|
507
|
+
case 't':
|
|
508
|
+
case 'A':
|
|
509
|
+
case 'a':
|
|
510
|
+
return true;
|
|
511
|
+
default:
|
|
512
|
+
return false;
|
|
484
513
|
}
|
|
485
514
|
return false;
|
|
486
515
|
}
|
|
487
516
|
|
|
488
517
|
|
|
489
|
-
bool SVGPathParser::is_number_start(char c)
|
|
518
|
+
bool SVGPathParser::is_number_start(char c)
|
|
519
|
+
{
|
|
520
|
+
return (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+';
|
|
521
|
+
}
|
|
490
522
|
|
|
491
|
-
bool SVGPathParser::is_absolute(char c)
|
|
523
|
+
bool SVGPathParser::is_absolute(char c)
|
|
524
|
+
{
|
|
525
|
+
return std::isupper(c);
|
|
526
|
+
}
|
|
492
527
|
// By the SVG spec 'large-arc' and 'sweep' must contain only one char
|
|
493
528
|
// and can be written without any separators, e.g.: 10 20 30 01 10 20.
|
|
494
529
|
|
|
495
|
-
bool SVGPathParser::parse_flag()
|
|
496
|
-
|
|
530
|
+
bool SVGPathParser::parse_flag()
|
|
531
|
+
{
|
|
532
|
+
SkipSpaces();
|
|
497
533
|
|
|
498
534
|
char c = s.at(i);
|
|
499
535
|
switch (c) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
i += 1;
|
|
503
|
-
if (i < l && s.at(i) == ',') {
|
|
536
|
+
case '0':
|
|
537
|
+
case '1': {
|
|
504
538
|
i += 1;
|
|
539
|
+
if (i < l && s.at(i) == ',') {
|
|
540
|
+
i += 1;
|
|
541
|
+
}
|
|
542
|
+
SkipSpaces();
|
|
543
|
+
break;
|
|
505
544
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
std::ostringstream oss;
|
|
511
|
-
oss << "Unexpected flag" << c << ",i=" << i << ",s=" << s;
|
|
512
|
-
throw std::logic_error(oss.str());
|
|
545
|
+
default:
|
|
546
|
+
std::ostringstream oss;
|
|
547
|
+
oss << "Unexpected flag" << c << ",i=" << i << ",s=" << s;
|
|
548
|
+
throw std::logic_error(oss.str());
|
|
513
549
|
}
|
|
514
550
|
|
|
515
551
|
return c == '1';
|
|
516
552
|
}
|
|
517
553
|
|
|
518
554
|
|
|
519
|
-
float SVGPathParser::parse_list_number()
|
|
555
|
+
float SVGPathParser::parse_list_number()
|
|
556
|
+
{
|
|
520
557
|
if (i == l) {
|
|
521
558
|
std::ostringstream oss;
|
|
522
559
|
oss << "Unexpected end (s=" << s << ")";
|
|
@@ -524,15 +561,16 @@ float SVGPathParser::parse_list_number() {
|
|
|
524
561
|
}
|
|
525
562
|
|
|
526
563
|
float n = parse_number();
|
|
527
|
-
|
|
564
|
+
SkipSpaces();
|
|
528
565
|
parse_list_separator();
|
|
529
566
|
|
|
530
567
|
return n;
|
|
531
568
|
}
|
|
532
569
|
|
|
533
|
-
float SVGPathParser::parse_number()
|
|
570
|
+
float SVGPathParser::parse_number()
|
|
571
|
+
{
|
|
534
572
|
// Strip off leading whitespaces.
|
|
535
|
-
|
|
573
|
+
SkipSpaces();
|
|
536
574
|
|
|
537
575
|
if (i == l) {
|
|
538
576
|
std::ostringstream oss;
|
|
@@ -552,7 +590,7 @@ float SVGPathParser::parse_number() {
|
|
|
552
590
|
|
|
553
591
|
// Consume integer.
|
|
554
592
|
if (c >= '0' && c <= '9') {
|
|
555
|
-
|
|
593
|
+
SkipDigits();
|
|
556
594
|
if (i < l) {
|
|
557
595
|
c = s.at(i);
|
|
558
596
|
}
|
|
@@ -565,7 +603,7 @@ float SVGPathParser::parse_number() {
|
|
|
565
603
|
// Consume fraction.
|
|
566
604
|
if (c == '.') {
|
|
567
605
|
i += 1;
|
|
568
|
-
|
|
606
|
+
SkipDigits();
|
|
569
607
|
if (i < l) {
|
|
570
608
|
c = s.at(i);
|
|
571
609
|
}
|
|
@@ -580,9 +618,9 @@ float SVGPathParser::parse_number() {
|
|
|
580
618
|
|
|
581
619
|
if (c == '+' || c == '-') {
|
|
582
620
|
i += 1;
|
|
583
|
-
|
|
621
|
+
SkipDigits();
|
|
584
622
|
} else if (c >= '0' && c <= '9') {
|
|
585
|
-
|
|
623
|
+
SkipDigits();
|
|
586
624
|
} else {
|
|
587
625
|
std::ostringstream oss;
|
|
588
626
|
oss << "Invalid number formating character " << c << ",i=" << i << ",s=" << s;
|
|
@@ -590,10 +628,8 @@ float SVGPathParser::parse_number() {
|
|
|
590
628
|
}
|
|
591
629
|
}
|
|
592
630
|
}
|
|
593
|
-
|
|
594
631
|
std::string num = s.substr(start, i);
|
|
595
632
|
float n = std::stof(num);
|
|
596
|
-
|
|
597
633
|
// inf, nan, etc. are an error.
|
|
598
634
|
if (std::isinf(n) || std::isnan(n)) {
|
|
599
635
|
std::ostringstream oss;
|
|
@@ -604,14 +640,17 @@ float SVGPathParser::parse_number() {
|
|
|
604
640
|
return n;
|
|
605
641
|
}
|
|
606
642
|
|
|
607
|
-
void SVGPathParser::parse_list_separator()
|
|
643
|
+
void SVGPathParser::parse_list_separator()
|
|
644
|
+
{
|
|
608
645
|
if (i < l && s.at(i) == ',') {
|
|
609
646
|
i += 1;
|
|
610
647
|
}
|
|
611
648
|
}
|
|
612
649
|
|
|
613
|
-
void SVGPathParser::
|
|
614
|
-
|
|
650
|
+
void SVGPathParser::SkipDigits()
|
|
651
|
+
{
|
|
652
|
+
while (i < l && std::isdigit(s.at(i))) {
|
|
615
653
|
i++;
|
|
654
|
+
}
|
|
616
655
|
}
|
|
617
656
|
}; // namespace rnoh
|