AddPathEndpoints adds all line segments of p to the queue q. The first command is converted to a MoveToCmd and any CloseCmd that is not at the end is converted to a LineToCmd.
(p *Path, seg int, clipping bool)
| 361 | // AddPathEndpoints adds all line segments of p to the queue q. The first command is converted to a MoveToCmd and any CloseCmd that |
| 362 | // is not at the end is converted to a LineToCmd. |
| 363 | func (q *SweepEvents) AddPathEndpoints(p *Path, seg int, clipping bool) int { |
| 364 | if len(p.d) == 0 { |
| 365 | return seg |
| 366 | } |
| 367 | |
| 368 | // TODO: change this if we allow non-flat paths |
| 369 | // allocate all memory at once to prevent multiple allocations/memmoves below |
| 370 | n := len(p.d) / 4 |
| 371 | if cap(*q) < len(*q)+n { |
| 372 | q2 := make(SweepEvents, len(*q), len(*q)+n) |
| 373 | copy(q2, *q) |
| 374 | *q = q2 |
| 375 | } |
| 376 | |
| 377 | open := !p.Closed() |
| 378 | start := Point{p.d[1], p.d[2]} |
| 379 | if math.IsNaN(start.X) || math.IsInf(start.X, 0.0) || math.IsNaN(start.Y) || math.IsInf(start.Y, 0.0) { |
| 380 | panic("path has NaN or Inf") |
| 381 | } else if open && p.d[len(p.d)-3] == p.d[1] && p.d[len(p.d)-2] == p.d[2] { |
| 382 | open = false // start and end points coincide, consider path closed |
| 383 | } |
| 384 | for i := 4; i < len(p.d); { |
| 385 | cmd := p.d[i] |
| 386 | if cmd != LineToCmd && cmd != CloseCmd { |
| 387 | panic("non-flat paths not supported") |
| 388 | } else if cmd == CloseCmd && (p.d[len(p.d)-3] != p.d[1] || p.d[len(p.d)-2] != p.d[2]) { |
| 389 | panic("invalid close command in path") |
| 390 | } |
| 391 | |
| 392 | n := cmdLen(cmd) |
| 393 | end := Point{p.d[i+n-3], p.d[i+n-2]} |
| 394 | if math.IsNaN(end.X) || math.IsInf(end.X, 0.0) || math.IsNaN(end.Y) || math.IsInf(end.Y, 0.0) { |
| 395 | panic("path has NaN or Inf") |
| 396 | } |
| 397 | i += n |
| 398 | seg++ |
| 399 | |
| 400 | if start == end { |
| 401 | // skip zero-length lineTo or close command |
| 402 | continue |
| 403 | } |
| 404 | |
| 405 | vertical := start.X == end.X |
| 406 | increasing := start.X < end.X |
| 407 | if vertical { |
| 408 | increasing = start.Y < end.Y |
| 409 | } |
| 410 | a := boPointPool.Get().(*SweepPoint) |
| 411 | b := boPointPool.Get().(*SweepPoint) |
| 412 | *a = SweepPoint{ |
| 413 | Point: start, |
| 414 | clipping: clipping, |
| 415 | open: open, |
| 416 | end: open && i == 4+n, |
| 417 | segment: seg, |
| 418 | left: increasing, |
| 419 | increasing: increasing, |
| 420 | vertical: vertical, |
no test coverage detected