github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/app/imaging/svg.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package imaging
     5  
     6  import (
     7  	"encoding/xml"
     8  	"io"
     9  	"regexp"
    10  	"strconv"
    11  
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  // SVGInfo holds information for a SVG image.
    16  type SVGInfo struct {
    17  	Width  int
    18  	Height int
    19  }
    20  
    21  // ParseSVG returns information for the given SVG input data.
    22  func ParseSVG(svgReader io.Reader) (SVGInfo, error) {
    23  	var parsedSVG struct {
    24  		Width   string `xml:"width,attr,omitempty"`
    25  		Height  string `xml:"height,attr,omitempty"`
    26  		ViewBox string `xml:"viewBox,attr,omitempty"`
    27  	}
    28  	svgInfo := SVGInfo{
    29  		Width:  0,
    30  		Height: 0,
    31  	}
    32  	viewBoxPattern := regexp.MustCompile("^([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)$")
    33  	dimensionPattern := regexp.MustCompile("(?i)^([0-9]+)(?:px)?$")
    34  
    35  	// decode provided SVG
    36  	if err := xml.NewDecoder(svgReader).Decode(&parsedSVG); err != nil {
    37  		return svgInfo, err
    38  	}
    39  
    40  	// prefer viewbox for SVG dimensions over width/height
    41  	if viewBoxMatches := viewBoxPattern.FindStringSubmatch(parsedSVG.ViewBox); len(viewBoxMatches) == 5 {
    42  		svgInfo.Width, _ = strconv.Atoi(viewBoxMatches[3])
    43  		svgInfo.Height, _ = strconv.Atoi(viewBoxMatches[4])
    44  	} else if parsedSVG.Width != "" && parsedSVG.Height != "" {
    45  		widthMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Width)
    46  		heightMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Height)
    47  		if len(widthMatches) == 2 && len(heightMatches) == 2 {
    48  			svgInfo.Width, _ = strconv.Atoi(widthMatches[1])
    49  			svgInfo.Height, _ = strconv.Atoi(heightMatches[1])
    50  		}
    51  	}
    52  
    53  	// if width and/or height are still zero, create new error
    54  	if svgInfo.Width == 0 || svgInfo.Height == 0 {
    55  		return svgInfo, errors.New("unable to extract SVG dimensions")
    56  	}
    57  	return svgInfo, nil
    58  }