RenderPath renders a path to the canvas using a style and a transformation matrix.
(path *canvas.Path, style canvas.Style, m canvas.Matrix)
| 86 | |
| 87 | // RenderPath renders a path to the canvas using a style and a transformation matrix. |
| 88 | func (r *Rasterizer) RenderPath(path *canvas.Path, style canvas.Style, m canvas.Matrix) { |
| 89 | bounds := canvas.Rect{} |
| 90 | var fill, stroke *canvas.Path |
| 91 | if style.HasFill() { |
| 92 | fill = path.Copy().Transform(m) |
| 93 | bounds = fill.FastBounds() |
| 94 | } |
| 95 | if style.HasStroke() { |
| 96 | tolerance := canvas.PixelTolerance / r.resolution.DPMM() |
| 97 | stroke = path |
| 98 | if 0 < len(style.Dashes) { |
| 99 | dashOffset, dashes := canvas.ScaleDash(style.StrokeWidth, style.DashOffset, style.Dashes) |
| 100 | stroke = stroke.Dash(dashOffset, dashes...) |
| 101 | } |
| 102 | stroke = stroke.Stroke(style.StrokeWidth, style.StrokeCapper, style.StrokeJoiner, tolerance) |
| 103 | stroke = stroke.Transform(m) |
| 104 | if style.HasFill() { |
| 105 | bounds = bounds.Add(stroke.FastBounds()) |
| 106 | } else { |
| 107 | bounds = stroke.FastBounds() |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | r.scanner.SetWinding(style.FillRule == canvas.NonZero) |
| 112 | |
| 113 | size := r.Bounds().Size() |
| 114 | if style.HasFill() { |
| 115 | if style.Fill.IsPattern() { |
| 116 | if hatch, ok := style.Fill.Pattern.(*canvas.HatchPattern); ok { |
| 117 | style.Fill = hatch.Fill |
| 118 | fill = hatch.Tile(fill) |
| 119 | } else { |
| 120 | pattern := style.Fill.Pattern.Transform(m).SetColorSpace(r.colorSpace) |
| 121 | pattern.RenderTo(r, fill) |
| 122 | } |
| 123 | } |
| 124 | if style.Fill.IsGradient() { |
| 125 | mInv := m.Inv() |
| 126 | gradient := style.Fill.Gradient.SetColorSpace(r.colorSpace) |
| 127 | r.scanner.Clear() |
| 128 | r.scanner.SetColor(rasterx.ColorFunc(func(x, y int) color.Color { |
| 129 | p := canvas.Point{(float64(x) + 0.5) / float64(r.resolution), (float64(size.Y-y) - 0.5) / float64(r.resolution)} |
| 130 | p = mInv.Dot(p) |
| 131 | return gradient.At(p.X, p.Y) |
| 132 | })) |
| 133 | fill.ToScanxScanner(r.scanner, float64(size.Y), r.resolution) |
| 134 | r.scanner.Draw() |
| 135 | } else if style.Fill.IsColor() { |
| 136 | c := r.colorSpace.ToLinear(style.Fill.Color) |
| 137 | r.scanner.Clear() |
| 138 | r.scanner.SetColor(color.Color(r.Image.ColorModel().Convert(c))) |
| 139 | fill.ToScanxScanner(r.scanner, float64(size.Y), r.resolution) |
| 140 | r.scanner.Draw() |
| 141 | } |
| 142 | } |
| 143 | if style.HasStroke() { |
| 144 | if style.Stroke.IsPattern() { |
| 145 | if hatch, ok := style.Stroke.Pattern.(*canvas.HatchPattern); ok { |
nothing calls this directly
no test coverage detected