svg_path.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2017 The oksvg Authors. All rights reserved.
  2. // created: 2/12/2017 by S.R.Wiley
  3. //
  4. // utils.go implements translation of an SVG2.0 path into a rasterx Path.
  5. package oksvg
  6. import (
  7. "image/color"
  8. "github.com/srwiley/rasterx"
  9. "golang.org/x/image/math/fixed"
  10. )
  11. // SvgPath binds a style to a path.
  12. type SvgPath struct {
  13. PathStyle
  14. Path rasterx.Path
  15. }
  16. // Draw the compiled SvgPath into the Dasher.
  17. func (svgp *SvgPath) Draw(r *rasterx.Dasher, opacity float64) {
  18. svgp.DrawTransformed(r, opacity, rasterx.Identity)
  19. }
  20. // DrawTransformed draws the compiled SvgPath into the Dasher while applying transform t.
  21. func (svgp *SvgPath) DrawTransformed(r *rasterx.Dasher, opacity float64, t rasterx.Matrix2D) {
  22. m := svgp.mAdder.M
  23. svgp.mAdder.M = t.Mult(m)
  24. defer func() { svgp.mAdder.M = m }() // Restore untransformed matrix
  25. if svgp.fillerColor != nil {
  26. r.Clear()
  27. rf := &r.Filler
  28. rf.SetWinding(svgp.UseNonZeroWinding)
  29. svgp.mAdder.Adder = rf // This allows transformations to be applied
  30. svgp.Path.AddTo(&svgp.mAdder)
  31. switch fillerColor := svgp.fillerColor.(type) {
  32. case color.Color:
  33. rf.SetColor(rasterx.ApplyOpacity(fillerColor, svgp.FillOpacity*opacity))
  34. case rasterx.Gradient:
  35. if fillerColor.Units == rasterx.ObjectBoundingBox {
  36. fRect := rf.Scanner.GetPathExtent()
  37. mnx, mny := float64(fRect.Min.X)/64, float64(fRect.Min.Y)/64
  38. mxx, mxy := float64(fRect.Max.X)/64, float64(fRect.Max.Y)/64
  39. fillerColor.Bounds.X, fillerColor.Bounds.Y = mnx, mny
  40. fillerColor.Bounds.W, fillerColor.Bounds.H = mxx-mnx, mxy-mny
  41. }
  42. rf.SetColor(fillerColor.GetColorFunction(svgp.FillOpacity * opacity))
  43. }
  44. rf.Draw()
  45. // default is true
  46. rf.SetWinding(true)
  47. }
  48. if svgp.linerColor != nil {
  49. r.Clear()
  50. svgp.mAdder.Adder = r
  51. lineGap := svgp.LineGap
  52. if lineGap == nil {
  53. lineGap = DefaultStyle.LineGap
  54. }
  55. lineCap := svgp.LineCap
  56. if lineCap == nil {
  57. lineCap = DefaultStyle.LineCap
  58. }
  59. leadLineCap := lineCap
  60. if svgp.LeadLineCap != nil {
  61. leadLineCap = svgp.LeadLineCap
  62. }
  63. r.SetStroke(fixed.Int26_6(svgp.LineWidth*64),
  64. fixed.Int26_6(svgp.MiterLimit*64), leadLineCap, lineCap,
  65. lineGap, svgp.LineJoin, svgp.Dash, svgp.DashOffset)
  66. svgp.Path.AddTo(&svgp.mAdder)
  67. switch linerColor := svgp.linerColor.(type) {
  68. case color.Color:
  69. r.SetColor(rasterx.ApplyOpacity(linerColor, svgp.LineOpacity*opacity))
  70. case rasterx.Gradient:
  71. if linerColor.Units == rasterx.ObjectBoundingBox {
  72. fRect := r.Scanner.GetPathExtent()
  73. mnx, mny := float64(fRect.Min.X)/64, float64(fRect.Min.Y)/64
  74. mxx, mxy := float64(fRect.Max.X)/64, float64(fRect.Max.Y)/64
  75. linerColor.Bounds.X, linerColor.Bounds.Y = mnx, mny
  76. linerColor.Bounds.W, linerColor.Bounds.H = mxx-mnx, mxy-mny
  77. }
  78. r.SetColor(linerColor.GetColorFunction(svgp.LineOpacity * opacity))
  79. }
  80. r.Draw()
  81. }
  82. }
  83. // GetFillColor returns the fill color of the SvgPath if one is defined and otherwise returns colornames.Black
  84. func (svgp *SvgPath) GetFillColor() color.Color {
  85. return getColor(svgp.fillerColor)
  86. }
  87. // GetLineColor returns the stroke color of the SvgPath if one is defined and otherwise returns colornames.Black
  88. func (svgp *SvgPath) GetLineColor() color.Color {
  89. return getColor(svgp.linerColor)
  90. }
  91. // SetFillColor sets the fill color of the SvgPath
  92. func (svgp *SvgPath) SetFillColor(clr color.Color) {
  93. svgp.fillerColor = clr
  94. }
  95. // SetLineColor sets the line color of the SvgPath
  96. func (svgp *SvgPath) SetLineColor(clr color.Color) {
  97. svgp.linerColor = clr
  98. }