in shiny/iconvg/upgrade.go [216:335]
func upgradeStyling(u *upgrader, v1 buffer, v0 buffer) (uf upgradeFunc, newV1 buffer, newV0 buffer, retErr error) {
for len(v0) > 0 {
switch opcode := v0[0]; {
case opcode < 0x80: // "Set CSEL/NSEL"
if opcode < 0x40 {
u.csel = uint32(opcode & 63)
} else {
u.nsel = uint32(opcode & 63)
}
v0 = v0[1:]
case opcode < 0xa8: // "Set CREG[etc] to an etc color"
adj := uint32(opcode & 7)
if adj == 7 {
adj = 0
}
index := (u.csel - adj) & 63
v0 = v0[1:]
c, n := Color{}, 0
switch (opcode - 0x80) >> 3 {
case 0:
c, n = v0.decodeColor1()
case 1:
c, n = v0.decodeColor2()
case 2:
c, n = v0.decodeColor3Direct()
case 3:
c, n = v0.decodeColor4()
case 4:
c, n = v0.decodeColor3Indirect()
}
if n == 0 {
return nil, nil, nil, errInvalidColor
}
u.creg[index], retErr = u.resolve(c, false)
if retErr != nil {
return nil, nil, nil, retErr
}
v0 = v0[n:]
if (opcode & 7) == 7 {
u.csel = (u.csel + 1) & 63
}
case opcode < 0xc0: // "Set NREG[etc] to a real number"
adj := uint32(opcode & 7)
if adj == 7 {
adj = 0
}
index := (u.nsel - adj) & 63
v0 = v0[1:]
f, n := float32(0), 0
switch (opcode - 0x80) >> 3 {
case 5:
f, n = v0.decodeReal()
case 6:
f, n = v0.decodeCoordinate()
case 7:
f, n = v0.decodeZeroToOne()
}
if n == 0 {
return nil, nil, nil, errInvalidNumber
}
u.nreg[index] = f
v0 = v0[n:]
if (opcode & 7) == 7 {
u.nsel = (u.nsel + 1) & 63
}
case opcode < 0xc7: // Start path.
adj := uint32(opcode & 7)
u.fill = (u.csel - adj) & 63
v1 = append(v1, 0x35) // FFV1 MoveTo.
v0 = v0[1:]
return upgradeDrawing, v1, v0, nil
case opcode == 0xc7: // "Set LOD"
if u.calculatingJumpLOD {
u.calculatingJumpLOD = false
return nil, v1, v0, errCalculatingJumpLOD
}
v0 = v0[1:]
lod := [2]float32{}
for i := range lod {
f, n := v0.decodeReal()
if n == 0 {
return nil, nil, nil, errInvalidNumber
}
lod[i] = f
v0 = v0[n:]
}
if (lod[0] == 0) && math.IsInf(float64(lod[1]), +1) {
break
}
u.calculatingJumpLOD = true
ifTrue := []byte(nil)
if ifTrue, v0, retErr = u.upgradeBytecode(nil, v0); retErr != nil {
return nil, nil, nil, retErr
}
nInstructions := countFFV1Instructions(ifTrue)
if nInstructions >= (1 << 30) {
return nil, nil, nil, errUnsupportedUpgrade
}
v1 = append(v1, 0x3a) // FFV1 JumpLOD.
v1.encodeNaturalFFV1(uint32(nInstructions))
v1.encodeCoordinateFFV1(lod[0])
v1.encodeCoordinateFFV1(lod[1])
v1 = append(v1, ifTrue...)
default:
return nil, nil, nil, errUnsupportedStylingOpcode
}
}
return upgradeStyling, v1, v0, nil
}