func upgradeStyling()

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
}