|
|
|
|
|
|
|
|
|
|
return totalW != 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int windingLine(float x0, float y0, float x1, float y1, float x, float y) { |
|
|
|
if (y0 == y1) { |
|
|
|
return 0; |
|
|
|
|
|
|
readonly float _distTol; |
|
|
|
readonly float _tessTol; |
|
|
|
|
|
|
|
readonly List<PathPath> _paths = new List<PathPath>(); |
|
|
|
readonly List<PathPoint> _points = new List<PathPoint>(); |
|
|
|
readonly List<Vector3> _vertices = new List<Vector3>(); |
|
|
|
readonly ArrayRef<PathPath> _paths = new ArrayRef<PathPath>(); |
|
|
|
readonly ArrayRef<PathPoint> _points = new ArrayRef<PathPoint>(); |
|
|
|
List<Vector3> _vertices = null; |
|
|
|
|
|
|
|
MeshMesh _fillMesh; |
|
|
|
bool _fillConvex; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public void addPath() { |
|
|
|
this._paths.Add(new PathPath { |
|
|
|
first = this._points.Count, |
|
|
|
this._paths.add(new PathPath { |
|
|
|
first = this._points.length, |
|
|
|
winding = PathWinding.counterClockwise |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void _addPoint(PathPoint point) { |
|
|
|
if (this._paths.Count == 0) { |
|
|
|
if (this._paths.length == 0) { |
|
|
|
ref var path = ref this._paths.refAt(this._paths.Count - 1); |
|
|
|
ref var path = ref this._paths.array[this._paths.length - 1]; |
|
|
|
ref var pt = ref this._points.refAt(this._points.Count - 1); |
|
|
|
ref var pt = ref this._points.array[this._points.length - 1]; |
|
|
|
if (PathUtils.ptEquals(pt.x, pt.y, point.x, point.y, this._distTol)) { |
|
|
|
pt.flags |= point.flags; |
|
|
|
return; |
|
|
|
|
|
|
this._points.Add(point); |
|
|
|
this._points.add(point); |
|
|
|
path.count++; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
PointFlags flags) { |
|
|
|
float x1, y1; |
|
|
|
if (this._points.Count == 0) { |
|
|
|
if (this._points.length == 0) { |
|
|
|
ref var pt = ref this._points.refAt(this._points.Count - 1); |
|
|
|
ref var pt = ref this._points.array[this._points.length - 1]; |
|
|
|
x1 = pt.x; |
|
|
|
y1 = pt.y; |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public void closePath() { |
|
|
|
if (this._paths.Count == 0) { |
|
|
|
if (this._paths.length == 0) { |
|
|
|
ref var path = ref this._paths.refAt(this._paths.Count - 1); |
|
|
|
ref var path = ref this._paths.array[this._paths.length - 1]; |
|
|
|
if (this._paths.Count == 0) { |
|
|
|
if (this._paths.length == 0) { |
|
|
|
ref var path = ref this._paths.refAt(this._paths.Count - 1); |
|
|
|
ref var path = ref this._paths.array[this._paths.length - 1]; |
|
|
|
var points = this._points.array(); |
|
|
|
var paths = this._paths.array(); |
|
|
|
for (var j = 0; j < paths.Length; j++) { |
|
|
|
ref var path = ref paths[j]; |
|
|
|
var points = this._points; |
|
|
|
var paths = this._paths; |
|
|
|
for (var j = 0; j < paths.length; j++) { |
|
|
|
ref var path = ref paths.array[j]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
if (PathUtils.ptEquals(p0.x, p0.y, p1.x, p1.y, this._distTol)) { |
|
|
|
path.count--; |
|
|
|
path.closed = true; |
|
|
|
|
|
|
if (path.winding == PathWinding.clockwise) { |
|
|
|
PathUtils.polyReverse(this._points, path.first, path.count); |
|
|
|
PathUtils.polyReverse(points.array, path.first, path.count); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
var points = this._points.array(); |
|
|
|
var paths = this._paths.array(); |
|
|
|
for (var j = 0; j < paths.Length; j++) { |
|
|
|
ref var path = ref paths[j]; |
|
|
|
var points = this._points; |
|
|
|
var paths = this._paths; |
|
|
|
for (var j = 0; j < paths.length; j++) { |
|
|
|
ref var path = ref paths.array[j]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
for (var i = 0; i < path.count; i++) { |
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
p0.dx = p1.x - p0.x; // no need to normalize
|
|
|
|
p0.dy = p1.y - p0.y; |
|
|
|
ip0 = ip1++; |
|
|
|
|
|
|
ip0 = path.first + path.count - 1; |
|
|
|
ip1 = path.first; |
|
|
|
for (var i = 0; i < path.count; i++) { |
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
|
|
|
|
float cross = p1.dx * p0.dy - p0.dx * p1.dy; |
|
|
|
if (cross < 0.0f) { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this._vertices.Clear(); |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
|
|
|
|
var cvertices = 0; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
cvertices += path.count; |
|
|
|
} |
|
|
|
|
|
|
|
this._vertices = new List<Vector3>(cvertices); |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
ref var p = ref points[path.first + j]; |
|
|
|
ref var p = ref points.array[path.first + j]; |
|
|
|
this._vertices.Add(new Vector2(p.x, p.y)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._expandFill(); |
|
|
|
|
|
|
|
var paths = this._paths.array(); |
|
|
|
var paths = this._paths; |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var indices = new List<int>(cindices); |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
this._fillMesh = mesh; |
|
|
|
|
|
|
|
this._fillConvex = false; |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 2) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
void _calculateJoins(float w, StrokeJoin lineJoin, float miterLimit) { |
|
|
|
float iw = w > 0.0f ? 1.0f / w : 0.0f; |
|
|
|
|
|
|
|
var points = this._points.array(); |
|
|
|
var paths = this._paths.array(); |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
var points = this._points; |
|
|
|
var paths = this._paths; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
for (var j = 0; j < path.count; j++) { |
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
p0.dx = p1.x - p0.x; |
|
|
|
p0.dy = p1.y - p0.y; |
|
|
|
p0.len = PathUtils.normalize(ref p0.dx, ref p0.dy); |
|
|
|
|
|
|
ip0 = path.first + path.count - 1; |
|
|
|
ip1 = path.first; |
|
|
|
for (var j = 0; j < path.count; j++) { |
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
float dlx0 = p0.dy; |
|
|
|
float dly0 = -p0.dx; |
|
|
|
float dlx1 = p1.dy; |
|
|
|
|
|
|
ncap = PathUtils.curveDivs(w, Mathf.PI, this._tessTol); |
|
|
|
} |
|
|
|
|
|
|
|
this._vertices.Clear(); |
|
|
|
var points = this._points; |
|
|
|
var paths = this._paths; |
|
|
|
var points = this._points.array(); |
|
|
|
var paths = this._paths.array(); |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
var cvertices = 0; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
cvertices += path.count * 2; |
|
|
|
cvertices += 4; |
|
|
|
} |
|
|
|
|
|
|
|
this._vertices = new List<Vector3>(cvertices); |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
e = path.count - 1; |
|
|
|
} |
|
|
|
|
|
|
|
ref var p0 = ref points[ip0]; |
|
|
|
ref var p1 = ref points[ip1]; |
|
|
|
ref var p0 = ref points.array[ip0]; |
|
|
|
ref var p1 = ref points.array[ip1]; |
|
|
|
|
|
|
|
if (!path.closed) { |
|
|
|
if (lineCap == StrokeCap.butt) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (var j = s; j < e; j++) { |
|
|
|
p0 = ref points[ip0]; |
|
|
|
p1 = ref points[ip1]; |
|
|
|
p0 = ref points.array[ip0]; |
|
|
|
p1 = ref points.array[ip1]; |
|
|
|
|
|
|
|
if ((p1.flags & (PointFlags.bevel | PointFlags.innerBevel)) != 0) { |
|
|
|
if (lineJoin == StrokeJoin.round) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!path.closed) { |
|
|
|
p0 = ref points[ip0]; |
|
|
|
p1 = ref points[ip1]; |
|
|
|
p0 = ref points.array[ip0]; |
|
|
|
p1 = ref points.array[ip1]; |
|
|
|
if (lineCap == StrokeCap.butt) { |
|
|
|
this._vertices.buttCapEnd(p1, p0.dx, p0.dy, w, 0.0f); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
this._expandStroke(strokeWidth, lineCap, lineJoin, miterLimit); |
|
|
|
|
|
|
|
var paths = this._paths.array(); |
|
|
|
var paths = this._paths; |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var indices = new List<int>(cindices); |
|
|
|
for (var i = 0; i < paths.Length; i++) { |
|
|
|
ref var path = ref paths[i]; |
|
|
|
for (var i = 0; i < paths.length; i++) { |
|
|
|
ref var path = ref paths.array[i]; |
|
|
|
if (path.count <= 1) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
return area * 0.5f; |
|
|
|
} |
|
|
|
|
|
|
|
public static void polyReverse(List<PathPoint> pts, int s, int npts) { |
|
|
|
public static void polyReverse(PathPoint[] pts, int s, int npts) { |
|
|
|
int i = s, j = s + npts - 1; |
|
|
|
while (i < j) { |
|
|
|
var tmp = pts[i]; |
|
|
|