feat: validate gradient color stops
This commit is contained in:
parent
9fe52cf8b2
commit
8bbdac7c18
2 changed files with 38 additions and 16 deletions
|
|
@ -1069,9 +1069,10 @@ func renderDoubleOval(tl *geo.Point, width, height float64, fill, fillStroke, st
|
||||||
return renderOval(tl, width, height, fill, fillStroke, stroke, style, inlineTheme) + renderOval(innerTL, width-10, height-10, fill, "", stroke, style, inlineTheme)
|
return renderOval(tl, width, height, fill, fillStroke, stroke, style, inlineTheme) + renderOval(innerTL, width-10, height-10, fill, "", stroke, style, inlineTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
func defineGradients(writer io.Writer, cssGradient string) {
|
func defineGradients(writer io.Writer, cssGradient string) error {
|
||||||
gradient, _ := color.ParseGradient(cssGradient)
|
gradient, err := color.ParseGradient(cssGradient)
|
||||||
fmt.Fprint(writer, fmt.Sprintf(`<defs>%s</defs>`, color.GradientToSVG(gradient)))
|
fmt.Fprint(writer, fmt.Sprintf(`<defs>%s</defs>`, color.GradientToSVG(gradient)))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func defineShadowFilter(writer io.Writer) {
|
func defineShadowFilter(writer io.Writer) {
|
||||||
|
|
@ -2278,28 +2279,42 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if color.IsGradient(diagram.Root.Fill) {
|
if color.IsGradient(diagram.Root.Fill) {
|
||||||
defineGradients(buf, diagram.Root.Fill)
|
if err := defineGradients(buf, diagram.Root.Fill); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if color.IsGradient(diagram.Root.Stroke) {
|
if color.IsGradient(diagram.Root.Stroke) {
|
||||||
defineGradients(buf, diagram.Root.Stroke)
|
if err := defineGradients(buf, diagram.Root.Stroke); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, s := range diagram.Shapes {
|
for _, s := range diagram.Shapes {
|
||||||
if color.IsGradient(s.Fill) {
|
if color.IsGradient(s.Fill) {
|
||||||
defineGradients(buf, s.Fill)
|
if err := defineGradients(buf, s.Fill); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if color.IsGradient(s.Stroke) {
|
if color.IsGradient(s.Stroke) {
|
||||||
defineGradients(buf, s.Stroke)
|
if err := defineGradients(buf, s.Stroke); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if color.IsGradient(s.Color) {
|
if color.IsGradient(s.Color) {
|
||||||
defineGradients(buf, s.Color)
|
if err := defineGradients(buf, s.Color); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range diagram.Connections {
|
for _, c := range diagram.Connections {
|
||||||
if color.IsGradient(c.Stroke) {
|
if color.IsGradient(c.Stroke) {
|
||||||
defineGradients(buf, c.Stroke)
|
if err := defineGradients(buf, c.Stroke); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if color.IsGradient(c.Fill) {
|
if color.IsGradient(c.Fill) {
|
||||||
defineGradients(buf, c.Fill)
|
if err := defineGradients(buf, c.Fill); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mazznoer/csscolorparser"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Gradient struct {
|
type Gradient struct {
|
||||||
|
|
@ -46,23 +48,26 @@ func ParseGradient(cssGradient string) (Gradient, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
firstParam := strings.TrimSpace(paramList[0])
|
firstParam := strings.TrimSpace(paramList[0])
|
||||||
|
var err error
|
||||||
if gradient.Type == "linear" && (strings.HasSuffix(firstParam, "deg") || strings.HasPrefix(firstParam, "to ")) {
|
if gradient.Type == "linear" && (strings.HasSuffix(firstParam, "deg") || strings.HasPrefix(firstParam, "to ")) {
|
||||||
gradient.Direction = firstParam
|
gradient.Direction = firstParam
|
||||||
colorStops := paramList[1:]
|
colorStops := paramList[1:]
|
||||||
if len(colorStops) == 0 {
|
if len(colorStops) == 0 {
|
||||||
return Gradient{}, errors.New("no color stops in gradient")
|
return Gradient{}, errors.New("no color stops in gradient")
|
||||||
}
|
}
|
||||||
gradient.ColorStops = parseColorStops(colorStops)
|
gradient.ColorStops, err = parseColorStops(colorStops)
|
||||||
} else if gradient.Type == "radial" && (firstParam == "circle" || firstParam == "ellipse") {
|
} else if gradient.Type == "radial" && (firstParam == "circle" || firstParam == "ellipse") {
|
||||||
gradient.Direction = firstParam
|
gradient.Direction = firstParam
|
||||||
colorStops := paramList[1:]
|
colorStops := paramList[1:]
|
||||||
if len(colorStops) == 0 {
|
if len(colorStops) == 0 {
|
||||||
return Gradient{}, errors.New("no color stops in gradient")
|
return Gradient{}, errors.New("no color stops in gradient")
|
||||||
}
|
}
|
||||||
gradient.ColorStops = parseColorStops(colorStops)
|
gradient.ColorStops, err = parseColorStops(colorStops)
|
||||||
} else {
|
} else {
|
||||||
gradient.ColorStops = parseColorStops(paramList)
|
gradient.ColorStops, err = parseColorStops(paramList)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return Gradient{}, err
|
||||||
}
|
}
|
||||||
gradient.ID = UniqueGradientID(cssGradient)
|
gradient.ID = UniqueGradientID(cssGradient)
|
||||||
|
|
||||||
|
|
@ -97,12 +102,14 @@ func splitParams(params string) []string {
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseColorStops(params []string) []ColorStop {
|
func parseColorStops(params []string) ([]ColorStop, error) {
|
||||||
var colorStops []ColorStop
|
var colorStops []ColorStop
|
||||||
for _, p := range params {
|
for _, p := range params {
|
||||||
p = strings.TrimSpace(p)
|
p = strings.TrimSpace(p)
|
||||||
parts := strings.Fields(p)
|
parts := strings.Fields(p)
|
||||||
|
if _, err := csscolorparser.Parse(parts[0]); err != nil {
|
||||||
|
return nil, fmt.Errorf("%s is not a valid color format", parts[0])
|
||||||
|
}
|
||||||
switch len(parts) {
|
switch len(parts) {
|
||||||
case 1:
|
case 1:
|
||||||
colorStops = append(colorStops, ColorStop{Color: parts[0]})
|
colorStops = append(colorStops, ColorStop{Color: parts[0]})
|
||||||
|
|
@ -112,7 +119,7 @@ func parseColorStops(params []string) []ColorStop {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return colorStops
|
return colorStops, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GradientToSVG(gradient Gradient) string {
|
func GradientToSVG(gradient Gradient) string {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue