ToVectorRasterizer rasterizes the path to *vector.Rasterizer using the given rasterizer and resolution.
(ras *vector.Rasterizer, resolution Resolution)
| 2466 | |
| 2467 | // ToVectorRasterizer rasterizes the path to *vector.Rasterizer using the given rasterizer and resolution. |
| 2468 | func (p *Path) ToVectorRasterizer(ras *vector.Rasterizer, resolution Resolution) { |
| 2469 | dpmm := resolution.DPMM() |
| 2470 | tolerance := PixelTolerance / dpmm // tolerance of 1/10 of a pixel |
| 2471 | dy := float64(ras.Bounds().Size().Y) |
| 2472 | for i := 0; i < len(p.d); { |
| 2473 | cmd := p.d[i] |
| 2474 | switch cmd { |
| 2475 | case MoveToCmd: |
| 2476 | ras.MoveTo(float32(p.d[i+1]*dpmm), float32(dy-p.d[i+2]*dpmm)) |
| 2477 | case LineToCmd: |
| 2478 | ras.LineTo(float32(p.d[i+1]*dpmm), float32(dy-p.d[i+2]*dpmm)) |
| 2479 | case QuadToCmd, CubeToCmd, ArcToCmd: |
| 2480 | // flatten |
| 2481 | var q *Path |
| 2482 | var start Point |
| 2483 | if 0 < i { |
| 2484 | start = Point{p.d[i-3], p.d[i-2]} |
| 2485 | } |
| 2486 | if cmd == QuadToCmd { |
| 2487 | cp := Point{p.d[i+1], p.d[i+2]} |
| 2488 | end := Point{p.d[i+3], p.d[i+4]} |
| 2489 | q = flattenQuadraticBezier(start, cp, end, tolerance) |
| 2490 | } else if cmd == CubeToCmd { |
| 2491 | cp1 := Point{p.d[i+1], p.d[i+2]} |
| 2492 | cp2 := Point{p.d[i+3], p.d[i+4]} |
| 2493 | end := Point{p.d[i+5], p.d[i+6]} |
| 2494 | q = flattenCubicBezier(start, cp1, cp2, end, tolerance) |
| 2495 | } else { |
| 2496 | rx, ry, phi := p.d[i+1], p.d[i+2], p.d[i+3] |
| 2497 | large, sweep := toArcFlags(p.d[i+4]) |
| 2498 | end := Point{p.d[i+5], p.d[i+6]} |
| 2499 | q = flattenEllipticArc(start, rx, ry, phi, large, sweep, end, tolerance) |
| 2500 | } |
| 2501 | for j := 4; j < len(q.d); j += 4 { |
| 2502 | ras.LineTo(float32(q.d[j+1]*dpmm), float32(dy-q.d[j+2]*dpmm)) |
| 2503 | } |
| 2504 | case CloseCmd: |
| 2505 | ras.ClosePath() |
| 2506 | default: |
| 2507 | panic("quadratic and cubic Béziers and arcs should have been replaced") |
| 2508 | } |
| 2509 | i += cmdLen(cmd) |
| 2510 | } |
| 2511 | if !p.Closed() { |
| 2512 | // implicitly close path |
| 2513 | ras.ClosePath() |
| 2514 | } |
| 2515 | } |
| 2516 | |
| 2517 | func fixedPoint26_6(x, y float64) fixed.Point26_6 { |
| 2518 | const Scale = float64(int(1) << 6) |