aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/tdewolff/minify/svg
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tdewolff/minify/svg')
-rw-r--r--vendor/github.com/tdewolff/minify/svg/pathdata.go10
-rw-r--r--vendor/github.com/tdewolff/minify/svg/pathdata_test.go11
-rw-r--r--vendor/github.com/tdewolff/minify/svg/svg.go35
-rw-r--r--vendor/github.com/tdewolff/minify/svg/svg_test.go6
-rw-r--r--vendor/github.com/tdewolff/minify/svg/table.go12
5 files changed, 22 insertions, 52 deletions
diff --git a/vendor/github.com/tdewolff/minify/svg/pathdata.go b/vendor/github.com/tdewolff/minify/svg/pathdata.go
index f14e847..7268879 100644
--- a/vendor/github.com/tdewolff/minify/svg/pathdata.go
+++ b/vendor/github.com/tdewolff/minify/svg/pathdata.go
@@ -33,6 +33,8 @@ func NewPathData(o *Minifier) *PathData {
}
}
+// ShortenPathData takes a full pathdata string and returns a shortened version. The original string is overwritten.
+// It parses all commands (M, A, Z, ...) and coordinates (numbers) and calls copyInstruction for each command.
func (p *PathData) ShortenPathData(b []byte) []byte {
var x0, y0 float64
var cmd byte
@@ -74,6 +76,8 @@ func (p *PathData) ShortenPathData(b []byte) []byte {
return b[:j]
}
+// copyInstruction copies pathdata of a single command, but may be comprised of multiple sets for that command. For example, L takes two coordinates, but this function may process 2*N coordinates. Lowercase commands are relative commands, where the coordinates are relative to the previous point. Uppercase commands have absolute coordinates.
+// We update p.x and p.y (the current coordinates) according to the commands given. For each set of coordinates we call shortenCurPosInstruction and shortenAltPosInstruction. The former just minifies the coordinates, the latter will inverse the lowercase/uppercase of the command, and see if the coordinates get smaller due to that. The shortest is chosen and copied to `b`.
func (p *PathData) copyInstruction(b []byte, cmd byte) int {
n := len(p.coords)
if n == 0 {
@@ -191,6 +195,7 @@ func (p *PathData) copyInstruction(b []byte, cmd byte) int {
return j
}
+// shortenCurPosInstruction only minifies the coordinates.
func (p *PathData) shortenCurPosInstruction(cmd byte, coords [][]byte) PathDataState {
state := p.state
p.curBuffer = p.curBuffer[:0]
@@ -202,7 +207,8 @@ func (p *PathData) shortenCurPosInstruction(cmd byte, coords [][]byte) PathDataS
}
for i, coord := range coords {
isFlag := false
- if (cmd == 'A' || cmd == 'a') && (i%7 == 3 || i%7 == 4) {
+ // Arc has boolean flags that can only be 0 or 1. Setting isFlag prevents from adding a dot before a zero (instead of a space). However, when the dot already was there, the command is malformed and could make the path longer than before, introducing bugs.
+ if (cmd == 'A' || cmd == 'a') && (i%7 == 3 || i%7 == 4) && coord[0] != '.' {
isFlag = true
}
@@ -212,6 +218,7 @@ func (p *PathData) shortenCurPosInstruction(cmd byte, coords [][]byte) PathDataS
return state
}
+// shortenAltPosInstruction toggles the command between absolute / relative coordinates and minifies the coordinates.
func (p *PathData) shortenAltPosInstruction(cmd byte, coordFloats []float64, x, y float64) PathDataState {
state := p.state
p.altBuffer = p.altBuffer[:0]
@@ -250,6 +257,7 @@ func (p *PathData) shortenAltPosInstruction(cmd byte, coordFloats []float64, x,
return state
}
+// copyNumber will copy a number to the destination buffer, taking into account space or dot insertion to guarantee the shortest pathdata.
func (state *PathDataState) copyNumber(buffer *[]byte, coord []byte, isFlag bool) {
if state.prevDigit && (coord[0] >= '0' && coord[0] <= '9' || coord[0] == '.' && state.prevDigitIsInt) {
if coord[0] == '0' && !state.prevDigitIsInt {
diff --git a/vendor/github.com/tdewolff/minify/svg/pathdata_test.go b/vendor/github.com/tdewolff/minify/svg/pathdata_test.go
index a975aa0..8d4f4a5 100644
--- a/vendor/github.com/tdewolff/minify/svg/pathdata_test.go
+++ b/vendor/github.com/tdewolff/minify/svg/pathdata_test.go
@@ -28,8 +28,9 @@ func TestPathData(t *testing.T) {
{"M.0.1", "M0 .1"},
{"M200.0.1", "M2e2.1"},
- {"M0 0a3.28 3.28.0.0.0 3.279 3.28", "M0 0a3.28 3.28.0 0 0 3.279 3.28"}, // #114
- {"A1.1.0.0.0.0.2.3", "A1.1.0.0 0 0 .2."}, // bad input (sweep and large-arc are not booleans) gives bad output
+ {"M0 0a3.28 3.28.0.0.0 3.279 3.28", "M0 0a3.28 3.28.0.0.0 3.279 3.28"}, // #114
+ {"A1.1.0.0.0.0.2.3", "A1.1.0.0.0.0.2.3"}, // bad input (sweep and large-arc are not booleans) gives bad output
+ {"A.0.0.4.0.0.0.3", "A0 0 .4.0.0.0.3"}, // bad input, keep dot for booleans
// fuzz
{"", ""},
@@ -37,7 +38,11 @@ func TestPathData(t *testing.T) {
{".8.00c0", ""},
{".1.04h0e6.0e6.0e0.0", "h0 0 0 0"},
{"M.1.0.0.2Z", "M.1.0.0.2z"},
- {"A.0.0.0.0.3.2e3.7.0.0.0.0.0.1.3.0.0.0.0.2.3.2.0.0.0.0.20.2e-10.0.0.0.0.0.0.0.0", "A0 0 0 0 .3 2e2.7.0.0.0 0 0 .1.3 30 0 0 0 .2.3.2 3 20 0 0 .2 2e-1100 11 0 0 0 "}, // bad input (sweep and large-arc are not booleans) gives bad output
+ {"A.0.0.0.0.3.2e3.7.0.0.0.0.0.1.3.0.0.0.0.2.3.2.0.0.0.0.20.2e-10.0.0.0.0.0.0.0.0", "A0 0 0 0 .3 2e2.7.0.0.0.0.0.1.3.0.0.0.0.2.3.2.0.0.0.0.2 2e-11.0.0.0.0.0.0.0.0"}, // bad input (sweep and large-arc are not booleans) gives bad output
+ {
+ "A.0.0.4.0.0.0.3.0.0.0.0.0.4.2.0.0.0.0.2.0.4.0.0.0.4.2.8.2.0.0.0.2.9.28.0.0.0.0.0.2.3.0.0.0.0.0.0.2.3.2.09e-03.0.0.0.0.8.0.0.0.0.0.0.0",
+ "A0 0 .4.0.0.0.3.0.0.0.0.0.4.2.0.0.0.0.2.0.4.0.0.0.4.2.8.2.0.0.0.2.9.28.0.0.0.0.0.2.3.0.0.0.0.0.0.2.3.2 9e-5.0.0.0.0.8.0.0.0.0.0.0.0",
+ },
}
p := NewPathData(&Minifier{Decimals: -1})
diff --git a/vendor/github.com/tdewolff/minify/svg/svg.go b/vendor/github.com/tdewolff/minify/svg/svg.go
index 984544f..83962e9 100644
--- a/vendor/github.com/tdewolff/minify/svg/svg.go
+++ b/vendor/github.com/tdewolff/minify/svg/svg.go
@@ -51,7 +51,6 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
p := NewPathData(o)
minifyBuffer := buffer.NewWriter(make([]byte, 0, 64))
attrByteBuffer := make([]byte, 0, 64)
- gStack := make([]bool, 0)
l := xml.NewLexer(r)
defer l.Restore()
@@ -59,7 +58,6 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
tb := NewTokenBuffer(l)
for {
t := *tb.Shift()
- SWITCH:
switch t.TokenType {
case xml.ErrorToken:
if l.Err() == io.EOF {
@@ -113,29 +111,7 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
}
case xml.StartTagToken:
tag = t.Hash
- if containerTagMap[tag] { // skip empty containers
- i := 0
- for {
- next := tb.Peek(i)
- i++
- if next.TokenType == xml.EndTagToken && next.Hash == tag || next.TokenType == xml.StartTagCloseVoidToken || next.TokenType == xml.ErrorToken {
- for j := 0; j < i; j++ {
- tb.Shift()
- }
- break SWITCH
- } else if next.TokenType != xml.AttributeToken && next.TokenType != xml.StartTagCloseToken {
- break
- }
- }
- if tag == svg.G {
- if tb.Peek(0).TokenType == xml.StartTagCloseToken {
- gStack = append(gStack, false)
- tb.Shift()
- break
- }
- gStack = append(gStack, true)
- }
- } else if tag == svg.Metadata {
+ if tag == svg.Metadata {
skipTag(tb, tag)
break
} else if tag == svg.Line {
@@ -184,7 +160,7 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
}
if tag == svg.Svg && attr == svg.ContentStyleType {
- val = minify.ContentType(val)
+ val = minify.Mediatype(val)
defaultStyleType = val
} else if attr == svg.Style {
minifyBuffer.Reset()
@@ -266,13 +242,6 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
}
case xml.EndTagToken:
tag = 0
- if t.Hash == svg.G && len(gStack) > 0 {
- if !gStack[len(gStack)-1] {
- gStack = gStack[:len(gStack)-1]
- break
- }
- gStack = gStack[:len(gStack)-1]
- }
if len(t.Data) > 3+len(t.Text) {
t.Data[2+len(t.Text)] = '>'
t.Data = t.Data[:3+len(t.Text)]
diff --git a/vendor/github.com/tdewolff/minify/svg/svg_test.go b/vendor/github.com/tdewolff/minify/svg/svg_test.go
index 7d3cfef..bc43b0c 100644
--- a/vendor/github.com/tdewolff/minify/svg/svg_test.go
+++ b/vendor/github.com/tdewolff/minify/svg/svg_test.go
@@ -41,9 +41,9 @@ func TestSVG(t *testing.T) {
{`<path d="M20 20l-10-10z"/>`, `<path d="M20 20 10 10z"/>`},
{`<?xml version="1.0" encoding="utf-8"?>`, ``},
{`<svg viewbox="0 0 16 16"><path/></svg>`, `<svg viewbox="0 0 16 16"><path/></svg>`},
- {`<g></g>`, ``},
- {`<g><path/></g>`, `<path/>`},
- {`<g id="a"><g><path/></g></g>`, `<g id="a"><path/></g>`},
+ {`<g></g>`, `<g/>`},
+ {`<g><path/></g>`, `<g><path/></g>`},
+ {`<g id="a"><g><path/></g></g>`, `<g id="a"><g><path/></g></g>`},
{`<path fill="#ffffff"/>`, `<path fill="#fff"/>`},
{`<path fill="#fff"/>`, `<path fill="#fff"/>`},
{`<path fill="white"/>`, `<path fill="#fff"/>`},
diff --git a/vendor/github.com/tdewolff/minify/svg/table.go b/vendor/github.com/tdewolff/minify/svg/table.go
index 42a1e78..22d6c2b 100644
--- a/vendor/github.com/tdewolff/minify/svg/table.go
+++ b/vendor/github.com/tdewolff/minify/svg/table.go
@@ -2,18 +2,6 @@ package svg // import "github.com/tdewolff/minify/svg"
import "github.com/tdewolff/parse/svg"
-var containerTagMap = map[svg.Hash]bool{
- svg.A: true,
- svg.Defs: true,
- svg.G: true,
- svg.Marker: true,
- svg.Mask: true,
- svg.Missing_Glyph: true,
- svg.Pattern: true,
- svg.Switch: true,
- svg.Symbol: true,
-}
-
var colorAttrMap = map[svg.Hash]bool{
svg.Color: true,
svg.Fill: true,