readStyle function
Implementation
void readStyle(List<SgrParam> params, StyleState out) {
// Upstream: `third_party/ultraviolet/styled.go` (`ReadStyle`).
if (params.isEmpty) {
out.style = const UvStyle();
return;
}
var style = out.style;
for (var i = 0; i < params.length; i++) {
final p = params[i];
final param = p.value;
switch (param) {
case 0:
style = const UvStyle();
case 1:
style = style.copyWith(attrs: style.attrs | Attr.bold);
case 2:
style = style.copyWith(attrs: style.attrs | Attr.faint);
case 3:
style = style.copyWith(attrs: style.attrs | Attr.italic);
case 4:
// Underline with optional subparameter (4:3 etc).
if (p.hasSub) {
final next = p.sub.first;
style = style.copyWith(
underline: switch (next) {
0 => UnderlineStyle.none,
1 => UnderlineStyle.single,
2 => UnderlineStyle.double,
3 => UnderlineStyle.curly,
4 => UnderlineStyle.dotted,
5 => UnderlineStyle.dashed,
_ => UnderlineStyle.single,
},
);
} else {
style = style.copyWith(underline: UnderlineStyle.single);
}
case 5:
style = style.copyWith(attrs: style.attrs | Attr.blink);
case 6:
style = style.copyWith(attrs: style.attrs | Attr.rapidBlink);
case 7:
style = style.copyWith(attrs: style.attrs | Attr.reverse);
case 8:
style = style.copyWith(attrs: style.attrs | Attr.conceal);
case 9:
style = style.copyWith(attrs: style.attrs | Attr.strikethrough);
// Reset variants used in upstream tests.
case 22:
style = style.copyWith(attrs: style.attrs & ~(Attr.bold | Attr.faint));
case 23:
style = style.copyWith(attrs: style.attrs & ~Attr.italic);
case 24:
style = style.copyWith(underline: UnderlineStyle.none);
case 25:
style = style.copyWith(
attrs: style.attrs & ~(Attr.blink | Attr.rapidBlink),
);
case 27:
style = style.copyWith(attrs: style.attrs & ~Attr.reverse);
case 28:
style = style.copyWith(attrs: style.attrs & ~Attr.conceal);
case 29:
style = style.copyWith(attrs: style.attrs & ~Attr.strikethrough);
// Foreground colors: 30-37, 90-97
case >= 30 && <= 37:
style = style.copyWith(fg: UvColor.basic16(param - 30));
case >= 90 && <= 97:
style = style.copyWith(fg: UvColor.basic16(param - 90, bright: true));
// Background colors: 40-47, 100-107
case >= 40 && <= 47:
style = style.copyWith(bg: UvColor.basic16(param - 40));
case >= 100 && <= 107:
style = style.copyWith(bg: UvColor.basic16(param - 100, bright: true));
// Default colors
case 39:
style = style.copyWith(clearFg: true);
case 49:
style = style.copyWith(clearBg: true);
case 59:
style = style.copyWith(clearUnderlineColor: true);
// Extended colors, semicolon form:
// 38;5;<n>, 48;5;<n>, 38;2;r;g;b, 48;2;r;g;b
// Underline color:
// - 58;5;<n>, 58;2;r;g;b
// - 58:5:<n>, 58:2::r:g:b
case 38 || 48:
final isFg = param == 38;
// Colon form groups (e.g. 38:2::r:g:b) come in as a single param with sub.
if (p.hasSub) {
if (p.sub.isEmpty) break;
final mode = p.sub[0];
if (mode == 5 && p.sub.length >= 2) {
final idx = p.sub[1];
style = isFg
? style.copyWith(fg: UvColor.indexed256(idx))
: style.copyWith(bg: UvColor.indexed256(idx));
} else if (mode == 2 && p.sub.length >= 5) {
// 38:2::<r>:<g>:<b>
final r = p.sub[2];
final g = p.sub[3];
final b = p.sub[4];
style = isFg
? style.copyWith(fg: UvColor.rgb(r, g, b))
: style.copyWith(bg: UvColor.rgb(r, g, b));
}
break;
}
if (i + 1 >= params.length) break;
final mode = params[i + 1].value;
if (mode == 5 && i + 2 < params.length) {
final idx = params[i + 2].value;
style = isFg
? style.copyWith(fg: UvColor.indexed256(idx))
: style.copyWith(bg: UvColor.indexed256(idx));
i += 2;
} else if (mode == 2 && i + 4 < params.length) {
final r = params[i + 2].value;
final g = params[i + 3].value;
final b = params[i + 4].value;
style = isFg
? style.copyWith(fg: UvColor.rgb(r, g, b))
: style.copyWith(bg: UvColor.rgb(r, g, b));
i += 4;
}
case 58:
// Underline color (SGR 58). Supports both semicolon and colon forms.
// - Semicolon: 58;5;<n> or 58;2;r;g;b
// - Colon: 58:5:<n> or 58:2::r:g:b
if (p.hasSub) {
if (p.sub.isEmpty) break;
final mode = p.sub[0];
if (mode == 5 && p.sub.length >= 2) {
style = style.copyWith(
underlineColor: UvColor.indexed256(p.sub[1]),
);
} else if (mode == 2) {
// 58:2::r:g:b -> sub = [2,0,r,g,b]
// 58:2:r:g:b -> sub = [2,r,g,b]
if (p.sub.length >= 5) {
final r = p.sub[2];
final g = p.sub[3];
final b = p.sub[4];
style = style.copyWith(underlineColor: UvColor.rgb(r, g, b));
} else if (p.sub.length >= 4) {
final r = p.sub[1];
final g = p.sub[2];
final b = p.sub[3];
style = style.copyWith(underlineColor: UvColor.rgb(r, g, b));
}
}
break;
}
if (i + 1 >= params.length) break;
final mode = params[i + 1].value;
if (mode == 5 && i + 2 < params.length) {
style = style.copyWith(
underlineColor: UvColor.indexed256(params[i + 2].value),
);
i += 2;
} else if (mode == 2 && i + 4 < params.length) {
final r = params[i + 2].value;
final g = params[i + 3].value;
final b = params[i + 4].value;
style = style.copyWith(underlineColor: UvColor.rgb(r, g, b));
i += 4;
}
}
}
out.style = style;
}