in shiny/iconvg/decode.go [435:640]
func decodeDrawing(dst Destination, p printer, src buffer) (mf modeFunc, src1 buffer, err error) {
var coords [6]float32
switch opcode := src[0]; {
case opcode < 0xe0:
op, nCoords, nReps := "", 0, 1+int(opcode&0x0f)
switch opcode >> 4 {
case 0x00, 0x01:
op = "L (absolute lineTo)"
nCoords = 2
nReps = 1 + int(opcode&0x1f)
case 0x02, 0x03:
op = "l (relative lineTo)"
nCoords = 2
nReps = 1 + int(opcode&0x1f)
case 0x04:
op = "T (absolute smooth quadTo)"
nCoords = 2
case 0x05:
op = "t (relative smooth quadTo)"
nCoords = 2
case 0x06:
op = "Q (absolute quadTo)"
nCoords = 4
case 0x07:
op = "q (relative quadTo)"
nCoords = 4
case 0x08:
op = "S (absolute smooth cubeTo)"
nCoords = 4
case 0x09:
op = "s (relative smooth cubeTo)"
nCoords = 4
case 0x0a:
op = "C (absolute cubeTo)"
nCoords = 6
case 0x0b:
op = "c (relative cubeTo)"
nCoords = 6
case 0x0c:
op = "A (absolute arcTo)"
nCoords = 0
case 0x0d:
op = "a (relative arcTo)"
nCoords = 0
}
if p != nil {
p(src[:1], "%s, %d reps\n", op, nReps)
}
src = src[1:]
for i := 0; i < nReps; i++ {
if p != nil && i != 0 {
p(nil, "%s, implicit\n", op)
}
var largeArc, sweep bool
if op[0] != 'A' && op[0] != 'a' {
src, err = decodeCoordinates(coords[:nCoords], p, src)
if err != nil {
return nil, nil, err
}
} else {
// We have an absolute or relative arcTo.
src, err = decodeCoordinates(coords[:2], p, src)
if err != nil {
return nil, nil, err
}
coords[2], src, err = decodeAngle(p, src)
if err != nil {
return nil, nil, err
}
largeArc, sweep, src, err = decodeArcToFlags(p, src)
if err != nil {
return nil, nil, err
}
src, err = decodeCoordinates(coords[4:6], p, src)
if err != nil {
return nil, nil, err
}
}
if dst == nil {
continue
}
switch op[0] {
case 'L':
dst.AbsLineTo(coords[0], coords[1])
case 'l':
dst.RelLineTo(coords[0], coords[1])
case 'T':
dst.AbsSmoothQuadTo(coords[0], coords[1])
case 't':
dst.RelSmoothQuadTo(coords[0], coords[1])
case 'Q':
dst.AbsQuadTo(coords[0], coords[1], coords[2], coords[3])
case 'q':
dst.RelQuadTo(coords[0], coords[1], coords[2], coords[3])
case 'S':
dst.AbsSmoothCubeTo(coords[0], coords[1], coords[2], coords[3])
case 's':
dst.RelSmoothCubeTo(coords[0], coords[1], coords[2], coords[3])
case 'C':
dst.AbsCubeTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5])
case 'c':
dst.RelCubeTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5])
case 'A':
dst.AbsArcTo(coords[0], coords[1], coords[2], largeArc, sweep, coords[4], coords[5])
case 'a':
dst.RelArcTo(coords[0], coords[1], coords[2], largeArc, sweep, coords[4], coords[5])
}
}
case opcode == 0xe1:
if p != nil {
p(src[:1], "z (closePath); end path\n")
}
src = src[1:]
if dst != nil {
dst.ClosePathEndPath()
}
return decodeStyling, src, nil
case opcode == 0xe2:
if p != nil {
p(src[:1], "z (closePath); M (absolute moveTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:2], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.ClosePathAbsMoveTo(coords[0], coords[1])
}
case opcode == 0xe3:
if p != nil {
p(src[:1], "z (closePath); m (relative moveTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:2], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.ClosePathRelMoveTo(coords[0], coords[1])
}
case opcode == 0xe6:
if p != nil {
p(src[:1], "H (absolute horizontal lineTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:1], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.AbsHLineTo(coords[0])
}
case opcode == 0xe7:
if p != nil {
p(src[:1], "h (relative horizontal lineTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:1], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.RelHLineTo(coords[0])
}
case opcode == 0xe8:
if p != nil {
p(src[:1], "V (absolute vertical lineTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:1], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.AbsVLineTo(coords[0])
}
case opcode == 0xe9:
if p != nil {
p(src[:1], "v (relative vertical lineTo)\n")
}
src = src[1:]
src, err = decodeCoordinates(coords[:1], p, src)
if err != nil {
return nil, nil, err
}
if dst != nil {
dst.RelVLineTo(coords[0])
}
default:
return nil, nil, errUnsupportedDrawingOpcode
}
return decodeDrawing, src, nil
}