(i int)
| 388 | } |
| 389 | |
| 390 | func (p *Path) optimizeInnerBend(i int) { |
| 391 | // i is the index of the line segment in the inner bend connecting both edges |
| 392 | ai := i - cmdLen(p.d[i-1]) |
| 393 | bi := i + cmdLen(p.d[i]) |
| 394 | if ai == 0 { |
| 395 | return |
| 396 | } |
| 397 | |
| 398 | a0 := Point{p.d[ai-3], p.d[ai-2]} |
| 399 | b0 := Point{p.d[bi-3], p.d[bi-2]} |
| 400 | if bi == len(p.d) { |
| 401 | // inner bend is at the path's start |
| 402 | bi = 4 |
| 403 | } |
| 404 | |
| 405 | // TODO: implement other segment combinations |
| 406 | zs_ := [2]Intersection{} |
| 407 | zs := zs_[:] |
| 408 | if (p.d[ai] == LineToCmd || p.d[ai] == CloseCmd) && (p.d[bi] == LineToCmd || p.d[bi] == CloseCmd) { |
| 409 | zs = intersectionSegment(zs[:0], a0, p.d[ai:ai+4], b0, p.d[bi:bi+4]) |
| 410 | // TODO: check conditions for pathological cases |
| 411 | if len(zs) == 1 && zs[0].T[0] != 0.0 && zs[0].T[0] != 1.0 && zs[0].T[1] != 0.0 && zs[0].T[1] != 1.0 { |
| 412 | p.d[ai+1] = zs[0].X |
| 413 | p.d[ai+2] = zs[0].Y |
| 414 | if bi == 4 { |
| 415 | // inner bend is at the path's start |
| 416 | if p.d[i] == CloseCmd { |
| 417 | if p.d[ai] == LineToCmd { |
| 418 | p.d[ai] = CloseCmd |
| 419 | p.d[ai+3] = CloseCmd |
| 420 | } else { |
| 421 | p.d = append(p.d, CloseCmd, zs[0].X, zs[1].Y, CloseCmd) |
| 422 | } |
| 423 | } |
| 424 | p.d = p.d[:i] |
| 425 | p.d[1] = zs[0].X |
| 426 | p.d[2] = zs[0].Y |
| 427 | } else { |
| 428 | p.d = append(p.d[:i], p.d[bi:]...) |
| 429 | } |
| 430 | } |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | type pathStrokeState struct { |
| 435 | cmd float64 |
no test coverage detected