main
Raw Download raw file
  1package ansi
  2
  3import (
  4	"image/color"
  5	"strconv"
  6	"strings"
  7)
  8
  9// ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets
 10// all attributes.
 11// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
 12const ResetStyle = "\x1b[m"
 13
 14// Attr is a SGR (Select Graphic Rendition) style attribute.
 15type Attr = int
 16
 17// Style represents an ANSI SGR (Select Graphic Rendition) style.
 18type Style []string
 19
 20// String returns the ANSI SGR (Select Graphic Rendition) style sequence for
 21// the given style.
 22func (s Style) String() string {
 23	if len(s) == 0 {
 24		return ResetStyle
 25	}
 26	return "\x1b[" + strings.Join(s, ";") + "m"
 27}
 28
 29// Styled returns a styled string with the given style applied.
 30func (s Style) Styled(str string) string {
 31	if len(s) == 0 {
 32		return str
 33	}
 34	return s.String() + str + ResetStyle
 35}
 36
 37// Reset appends the reset style attribute to the style.
 38func (s Style) Reset() Style {
 39	return append(s, resetAttr)
 40}
 41
 42// Bold appends the bold style attribute to the style.
 43func (s Style) Bold() Style {
 44	return append(s, boldAttr)
 45}
 46
 47// Faint appends the faint style attribute to the style.
 48func (s Style) Faint() Style {
 49	return append(s, faintAttr)
 50}
 51
 52// Italic appends the italic style attribute to the style.
 53func (s Style) Italic() Style {
 54	return append(s, italicAttr)
 55}
 56
 57// Underline appends the underline style attribute to the style.
 58func (s Style) Underline() Style {
 59	return append(s, underlineAttr)
 60}
 61
 62// UnderlineStyle appends the underline style attribute to the style.
 63func (s Style) UnderlineStyle(u UnderlineStyle) Style {
 64	switch u {
 65	case NoUnderlineStyle:
 66		return s.NoUnderline()
 67	case SingleUnderlineStyle:
 68		return s.Underline()
 69	case DoubleUnderlineStyle:
 70		return append(s, doubleUnderlineStyle)
 71	case CurlyUnderlineStyle:
 72		return append(s, curlyUnderlineStyle)
 73	case DottedUnderlineStyle:
 74		return append(s, dottedUnderlineStyle)
 75	case DashedUnderlineStyle:
 76		return append(s, dashedUnderlineStyle)
 77	}
 78	return s
 79}
 80
 81// DoubleUnderline appends the double underline style attribute to the style.
 82// This is a convenience method for UnderlineStyle(DoubleUnderlineStyle).
 83func (s Style) DoubleUnderline() Style {
 84	return s.UnderlineStyle(DoubleUnderlineStyle)
 85}
 86
 87// CurlyUnderline appends the curly underline style attribute to the style.
 88// This is a convenience method for UnderlineStyle(CurlyUnderlineStyle).
 89func (s Style) CurlyUnderline() Style {
 90	return s.UnderlineStyle(CurlyUnderlineStyle)
 91}
 92
 93// DottedUnderline appends the dotted underline style attribute to the style.
 94// This is a convenience method for UnderlineStyle(DottedUnderlineStyle).
 95func (s Style) DottedUnderline() Style {
 96	return s.UnderlineStyle(DottedUnderlineStyle)
 97}
 98
 99// DashedUnderline appends the dashed underline style attribute to the style.
100// This is a convenience method for UnderlineStyle(DashedUnderlineStyle).
101func (s Style) DashedUnderline() Style {
102	return s.UnderlineStyle(DashedUnderlineStyle)
103}
104
105// SlowBlink appends the slow blink style attribute to the style.
106func (s Style) SlowBlink() Style {
107	return append(s, slowBlinkAttr)
108}
109
110// RapidBlink appends the rapid blink style attribute to the style.
111func (s Style) RapidBlink() Style {
112	return append(s, rapidBlinkAttr)
113}
114
115// Reverse appends the reverse style attribute to the style.
116func (s Style) Reverse() Style {
117	return append(s, reverseAttr)
118}
119
120// Conceal appends the conceal style attribute to the style.
121func (s Style) Conceal() Style {
122	return append(s, concealAttr)
123}
124
125// Strikethrough appends the strikethrough style attribute to the style.
126func (s Style) Strikethrough() Style {
127	return append(s, strikethroughAttr)
128}
129
130// NoBold appends the no bold style attribute to the style.
131func (s Style) NoBold() Style {
132	return append(s, noBoldAttr)
133}
134
135// NormalIntensity appends the normal intensity style attribute to the style.
136func (s Style) NormalIntensity() Style {
137	return append(s, normalIntensityAttr)
138}
139
140// NoItalic appends the no italic style attribute to the style.
141func (s Style) NoItalic() Style {
142	return append(s, noItalicAttr)
143}
144
145// NoUnderline appends the no underline style attribute to the style.
146func (s Style) NoUnderline() Style {
147	return append(s, noUnderlineAttr)
148}
149
150// NoBlink appends the no blink style attribute to the style.
151func (s Style) NoBlink() Style {
152	return append(s, noBlinkAttr)
153}
154
155// NoReverse appends the no reverse style attribute to the style.
156func (s Style) NoReverse() Style {
157	return append(s, noReverseAttr)
158}
159
160// NoConceal appends the no conceal style attribute to the style.
161func (s Style) NoConceal() Style {
162	return append(s, noConcealAttr)
163}
164
165// NoStrikethrough appends the no strikethrough style attribute to the style.
166func (s Style) NoStrikethrough() Style {
167	return append(s, noStrikethroughAttr)
168}
169
170// DefaultForegroundColor appends the default foreground color style attribute to the style.
171func (s Style) DefaultForegroundColor() Style {
172	return append(s, defaultForegroundColorAttr)
173}
174
175// DefaultBackgroundColor appends the default background color style attribute to the style.
176func (s Style) DefaultBackgroundColor() Style {
177	return append(s, defaultBackgroundColorAttr)
178}
179
180// DefaultUnderlineColor appends the default underline color style attribute to the style.
181func (s Style) DefaultUnderlineColor() Style {
182	return append(s, defaultUnderlineColorAttr)
183}
184
185// ForegroundColor appends the foreground color style attribute to the style.
186func (s Style) ForegroundColor(c Color) Style {
187	return append(s, foregroundColorString(c))
188}
189
190// BackgroundColor appends the background color style attribute to the style.
191func (s Style) BackgroundColor(c Color) Style {
192	return append(s, backgroundColorString(c))
193}
194
195// UnderlineColor appends the underline color style attribute to the style.
196func (s Style) UnderlineColor(c Color) Style {
197	return append(s, underlineColorString(c))
198}
199
200// UnderlineStyle represents an ANSI SGR (Select Graphic Rendition) underline
201// style.
202type UnderlineStyle = byte
203
204const (
205	doubleUnderlineStyle = "4:2"
206	curlyUnderlineStyle  = "4:3"
207	dottedUnderlineStyle = "4:4"
208	dashedUnderlineStyle = "4:5"
209)
210
211const (
212	// NoUnderlineStyle is the default underline style.
213	NoUnderlineStyle UnderlineStyle = iota
214	// SingleUnderlineStyle is a single underline style.
215	SingleUnderlineStyle
216	// DoubleUnderlineStyle is a double underline style.
217	DoubleUnderlineStyle
218	// CurlyUnderlineStyle is a curly underline style.
219	CurlyUnderlineStyle
220	// DottedUnderlineStyle is a dotted underline style.
221	DottedUnderlineStyle
222	// DashedUnderlineStyle is a dashed underline style.
223	DashedUnderlineStyle
224)
225
226// SGR (Select Graphic Rendition) style attributes.
227// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
228const (
229	ResetAttr                        Attr = 0
230	BoldAttr                         Attr = 1
231	FaintAttr                        Attr = 2
232	ItalicAttr                       Attr = 3
233	UnderlineAttr                    Attr = 4
234	SlowBlinkAttr                    Attr = 5
235	RapidBlinkAttr                   Attr = 6
236	ReverseAttr                      Attr = 7
237	ConcealAttr                      Attr = 8
238	StrikethroughAttr                Attr = 9
239	NoBoldAttr                       Attr = 21 // Some terminals treat this as double underline.
240	NormalIntensityAttr              Attr = 22
241	NoItalicAttr                     Attr = 23
242	NoUnderlineAttr                  Attr = 24
243	NoBlinkAttr                      Attr = 25
244	NoReverseAttr                    Attr = 27
245	NoConcealAttr                    Attr = 28
246	NoStrikethroughAttr              Attr = 29
247	BlackForegroundColorAttr         Attr = 30
248	RedForegroundColorAttr           Attr = 31
249	GreenForegroundColorAttr         Attr = 32
250	YellowForegroundColorAttr        Attr = 33
251	BlueForegroundColorAttr          Attr = 34
252	MagentaForegroundColorAttr       Attr = 35
253	CyanForegroundColorAttr          Attr = 36
254	WhiteForegroundColorAttr         Attr = 37
255	ExtendedForegroundColorAttr      Attr = 38
256	DefaultForegroundColorAttr       Attr = 39
257	BlackBackgroundColorAttr         Attr = 40
258	RedBackgroundColorAttr           Attr = 41
259	GreenBackgroundColorAttr         Attr = 42
260	YellowBackgroundColorAttr        Attr = 43
261	BlueBackgroundColorAttr          Attr = 44
262	MagentaBackgroundColorAttr       Attr = 45
263	CyanBackgroundColorAttr          Attr = 46
264	WhiteBackgroundColorAttr         Attr = 47
265	ExtendedBackgroundColorAttr      Attr = 48
266	DefaultBackgroundColorAttr       Attr = 49
267	ExtendedUnderlineColorAttr       Attr = 58
268	DefaultUnderlineColorAttr        Attr = 59
269	BrightBlackForegroundColorAttr   Attr = 90
270	BrightRedForegroundColorAttr     Attr = 91
271	BrightGreenForegroundColorAttr   Attr = 92
272	BrightYellowForegroundColorAttr  Attr = 93
273	BrightBlueForegroundColorAttr    Attr = 94
274	BrightMagentaForegroundColorAttr Attr = 95
275	BrightCyanForegroundColorAttr    Attr = 96
276	BrightWhiteForegroundColorAttr   Attr = 97
277	BrightBlackBackgroundColorAttr   Attr = 100
278	BrightRedBackgroundColorAttr     Attr = 101
279	BrightGreenBackgroundColorAttr   Attr = 102
280	BrightYellowBackgroundColorAttr  Attr = 103
281	BrightBlueBackgroundColorAttr    Attr = 104
282	BrightMagentaBackgroundColorAttr Attr = 105
283	BrightCyanBackgroundColorAttr    Attr = 106
284	BrightWhiteBackgroundColorAttr   Attr = 107
285
286	RGBColorIntroducerAttr      Attr = 2
287	ExtendedColorIntroducerAttr Attr = 5
288)
289
290const (
291	resetAttr                        = "0"
292	boldAttr                         = "1"
293	faintAttr                        = "2"
294	italicAttr                       = "3"
295	underlineAttr                    = "4"
296	slowBlinkAttr                    = "5"
297	rapidBlinkAttr                   = "6"
298	reverseAttr                      = "7"
299	concealAttr                      = "8"
300	strikethroughAttr                = "9"
301	noBoldAttr                       = "21"
302	normalIntensityAttr              = "22"
303	noItalicAttr                     = "23"
304	noUnderlineAttr                  = "24"
305	noBlinkAttr                      = "25"
306	noReverseAttr                    = "27"
307	noConcealAttr                    = "28"
308	noStrikethroughAttr              = "29"
309	blackForegroundColorAttr         = "30"
310	redForegroundColorAttr           = "31"
311	greenForegroundColorAttr         = "32"
312	yellowForegroundColorAttr        = "33"
313	blueForegroundColorAttr          = "34"
314	magentaForegroundColorAttr       = "35"
315	cyanForegroundColorAttr          = "36"
316	whiteForegroundColorAttr         = "37"
317	extendedForegroundColorAttr      = "38"
318	defaultForegroundColorAttr       = "39"
319	blackBackgroundColorAttr         = "40"
320	redBackgroundColorAttr           = "41"
321	greenBackgroundColorAttr         = "42"
322	yellowBackgroundColorAttr        = "43"
323	blueBackgroundColorAttr          = "44"
324	magentaBackgroundColorAttr       = "45"
325	cyanBackgroundColorAttr          = "46"
326	whiteBackgroundColorAttr         = "47"
327	extendedBackgroundColorAttr      = "48"
328	defaultBackgroundColorAttr       = "49"
329	extendedUnderlineColorAttr       = "58"
330	defaultUnderlineColorAttr        = "59"
331	brightBlackForegroundColorAttr   = "90"
332	brightRedForegroundColorAttr     = "91"
333	brightGreenForegroundColorAttr   = "92"
334	brightYellowForegroundColorAttr  = "93"
335	brightBlueForegroundColorAttr    = "94"
336	brightMagentaForegroundColorAttr = "95"
337	brightCyanForegroundColorAttr    = "96"
338	brightWhiteForegroundColorAttr   = "97"
339	brightBlackBackgroundColorAttr   = "100"
340	brightRedBackgroundColorAttr     = "101"
341	brightGreenBackgroundColorAttr   = "102"
342	brightYellowBackgroundColorAttr  = "103"
343	brightBlueBackgroundColorAttr    = "104"
344	brightMagentaBackgroundColorAttr = "105"
345	brightCyanBackgroundColorAttr    = "106"
346	brightWhiteBackgroundColorAttr   = "107"
347)
348
349// foregroundColorString returns the style SGR attribute for the given
350// foreground color.
351// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
352func foregroundColorString(c Color) string {
353	switch c := c.(type) {
354	case BasicColor:
355		// 3-bit or 4-bit ANSI foreground
356		// "3<n>" or "9<n>" where n is the color number from 0 to 7
357		switch c {
358		case Black:
359			return blackForegroundColorAttr
360		case Red:
361			return redForegroundColorAttr
362		case Green:
363			return greenForegroundColorAttr
364		case Yellow:
365			return yellowForegroundColorAttr
366		case Blue:
367			return blueForegroundColorAttr
368		case Magenta:
369			return magentaForegroundColorAttr
370		case Cyan:
371			return cyanForegroundColorAttr
372		case White:
373			return whiteForegroundColorAttr
374		case BrightBlack:
375			return brightBlackForegroundColorAttr
376		case BrightRed:
377			return brightRedForegroundColorAttr
378		case BrightGreen:
379			return brightGreenForegroundColorAttr
380		case BrightYellow:
381			return brightYellowForegroundColorAttr
382		case BrightBlue:
383			return brightBlueForegroundColorAttr
384		case BrightMagenta:
385			return brightMagentaForegroundColorAttr
386		case BrightCyan:
387			return brightCyanForegroundColorAttr
388		case BrightWhite:
389			return brightWhiteForegroundColorAttr
390		}
391	case ExtendedColor:
392		// 256-color ANSI foreground
393		// "38;5;<n>"
394		return "38;5;" + strconv.FormatUint(uint64(c), 10)
395	case TrueColor, color.Color:
396		// 24-bit "true color" foreground
397		// "38;2;<r>;<g>;<b>"
398		r, g, b, _ := c.RGBA()
399		return "38;2;" +
400			strconv.FormatUint(uint64(shift(r)), 10) + ";" +
401			strconv.FormatUint(uint64(shift(g)), 10) + ";" +
402			strconv.FormatUint(uint64(shift(b)), 10)
403	}
404	return defaultForegroundColorAttr
405}
406
407// backgroundColorString returns the style SGR attribute for the given
408// background color.
409// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
410func backgroundColorString(c Color) string {
411	switch c := c.(type) {
412	case BasicColor:
413		// 3-bit or 4-bit ANSI foreground
414		// "4<n>" or "10<n>" where n is the color number from 0 to 7
415		switch c {
416		case Black:
417			return blackBackgroundColorAttr
418		case Red:
419			return redBackgroundColorAttr
420		case Green:
421			return greenBackgroundColorAttr
422		case Yellow:
423			return yellowBackgroundColorAttr
424		case Blue:
425			return blueBackgroundColorAttr
426		case Magenta:
427			return magentaBackgroundColorAttr
428		case Cyan:
429			return cyanBackgroundColorAttr
430		case White:
431			return whiteBackgroundColorAttr
432		case BrightBlack:
433			return brightBlackBackgroundColorAttr
434		case BrightRed:
435			return brightRedBackgroundColorAttr
436		case BrightGreen:
437			return brightGreenBackgroundColorAttr
438		case BrightYellow:
439			return brightYellowBackgroundColorAttr
440		case BrightBlue:
441			return brightBlueBackgroundColorAttr
442		case BrightMagenta:
443			return brightMagentaBackgroundColorAttr
444		case BrightCyan:
445			return brightCyanBackgroundColorAttr
446		case BrightWhite:
447			return brightWhiteBackgroundColorAttr
448		}
449	case ExtendedColor:
450		// 256-color ANSI foreground
451		// "48;5;<n>"
452		return "48;5;" + strconv.FormatUint(uint64(c), 10)
453	case TrueColor, color.Color:
454		// 24-bit "true color" foreground
455		// "38;2;<r>;<g>;<b>"
456		r, g, b, _ := c.RGBA()
457		return "48;2;" +
458			strconv.FormatUint(uint64(shift(r)), 10) + ";" +
459			strconv.FormatUint(uint64(shift(g)), 10) + ";" +
460			strconv.FormatUint(uint64(shift(b)), 10)
461	}
462	return defaultBackgroundColorAttr
463}
464
465// underlineColorString returns the style SGR attribute for the given underline
466// color.
467// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
468func underlineColorString(c Color) string {
469	switch c := c.(type) {
470	// NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline
471	// color, use 256-color instead.
472	//
473	// 256-color ANSI underline color
474	// "58;5;<n>"
475	case BasicColor:
476		return "58;5;" + strconv.FormatUint(uint64(c), 10)
477	case ExtendedColor:
478		return "58;5;" + strconv.FormatUint(uint64(c), 10)
479	case TrueColor, color.Color:
480		// 24-bit "true color" foreground
481		// "38;2;<r>;<g>;<b>"
482		r, g, b, _ := c.RGBA()
483		return "58;2;" +
484			strconv.FormatUint(uint64(shift(r)), 10) + ";" +
485			strconv.FormatUint(uint64(shift(g)), 10) + ";" +
486			strconv.FormatUint(uint64(shift(b)), 10)
487	}
488	return defaultUnderlineColorAttr
489}
490
491// ReadStyleColor decodes a color from a slice of parameters. It returns the
492// number of parameters read and the color. This function is used to read SGR
493// color parameters following the ITU T.416 standard.
494//
495// It supports reading the following color types:
496//   - 0: implementation defined
497//   - 1: transparent
498//   - 2: RGB direct color
499//   - 3: CMY direct color
500//   - 4: CMYK direct color
501//   - 5: indexed color
502//   - 6: RGBA direct color (WezTerm extension)
503//
504// The parameters can be separated by semicolons (;) or colons (:). Mixing
505// separators is not allowed.
506//
507// The specs supports defining a color space id, a color tolerance value, and a
508// tolerance color space id. However, these values have no effect on the
509// returned color and will be ignored.
510//
511// This implementation includes a few modifications to the specs:
512//  1. Support for legacy color values separated by semicolons (;) with respect to RGB, and indexed colors
513//  2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors
514//  3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors
515//  4. Support reading RGBA colors
516func ReadStyleColor(params Params, co *color.Color) (n int) {
517	if len(params) < 2 { // Need at least SGR type and color type
518		return 0
519	}
520
521	// First parameter indicates one of 38, 48, or 58 (foreground, background, or underline)
522	s := params[0]
523	p := params[1]
524	colorType := p.Param(0)
525	n = 2
526
527	paramsfn := func() (p1, p2, p3, p4 int) {
528		// Where should we start reading the color?
529		switch {
530		case s.HasMore() && p.HasMore() && len(params) > 8 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore() && params[7].HasMore():
531			// We have color space id, a 6th parameter, a tolerance value, and a tolerance color space
532			n += 7
533			return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
534		case s.HasMore() && p.HasMore() && len(params) > 7 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore():
535			// We have color space id, a 6th parameter, and a tolerance value
536			n += 6
537			return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
538		case s.HasMore() && p.HasMore() && len(params) > 6 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore():
539			// We have color space id and a 6th parameter
540			// 48 : 4 : : 1 : 2 : 3 :4
541			n += 5
542			return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
543		case s.HasMore() && p.HasMore() && len(params) > 5 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && !params[5].HasMore():
544			// We have color space
545			// 48 : 3 : : 1 : 2 : 3
546			n += 4
547			return params[3].Param(0), params[4].Param(0), params[5].Param(0), -1
548		case s.HasMore() && p.HasMore() && p.Param(0) == 2 && params[2].HasMore() && params[3].HasMore() && !params[4].HasMore():
549			// We have color values separated by colons (:)
550			// 48 : 2 : 1 : 2 : 3
551			fallthrough
552		case !s.HasMore() && !p.HasMore() && p.Param(0) == 2 && !params[2].HasMore() && !params[3].HasMore() && !params[4].HasMore():
553			// Support legacy color values separated by semicolons (;)
554			// 48 ; 2 ; 1 ; 2 ; 3
555			n += 3
556			return params[2].Param(0), params[3].Param(0), params[4].Param(0), -1
557		}
558		// Ambiguous SGR color
559		return -1, -1, -1, -1
560	}
561
562	switch colorType {
563	case 0: // implementation defined
564		return 2
565	case 1: // transparent
566		*co = color.Transparent
567		return 2
568	case 2: // RGB direct color
569		if len(params) < 5 {
570			return 0
571		}
572
573		r, g, b, _ := paramsfn()
574		if r == -1 || g == -1 || b == -1 {
575			return 0
576		}
577
578		*co = color.RGBA{
579			R: uint8(r), //nolint:gosec
580			G: uint8(g), //nolint:gosec
581			B: uint8(b), //nolint:gosec
582			A: 0xff,
583		}
584		return
585
586	case 3: // CMY direct color
587		if len(params) < 5 {
588			return 0
589		}
590
591		c, m, y, _ := paramsfn()
592		if c == -1 || m == -1 || y == -1 {
593			return 0
594		}
595
596		*co = color.CMYK{
597			C: uint8(c), //nolint:gosec
598			M: uint8(m), //nolint:gosec
599			Y: uint8(y), //nolint:gosec
600			K: 0,
601		}
602		return
603
604	case 4: // CMYK direct color
605		if len(params) < 6 {
606			return 0
607		}
608
609		c, m, y, k := paramsfn()
610		if c == -1 || m == -1 || y == -1 || k == -1 {
611			return 0
612		}
613
614		*co = color.CMYK{
615			C: uint8(c), //nolint:gosec
616			M: uint8(m), //nolint:gosec
617			Y: uint8(y), //nolint:gosec
618			K: uint8(k), //nolint:gosec
619		}
620		return
621
622	case 5: // indexed color
623		if len(params) < 3 {
624			return 0
625		}
626		switch {
627		case s.HasMore() && p.HasMore() && !params[2].HasMore():
628			// Colon separated indexed color
629			// 38 : 5 : 234
630		case !s.HasMore() && !p.HasMore() && !params[2].HasMore():
631			// Legacy semicolon indexed color
632			// 38 ; 5 ; 234
633		default:
634			return 0
635		}
636		*co = ExtendedColor(params[2].Param(0)) //nolint:gosec
637		return 3
638
639	case 6: // RGBA direct color
640		if len(params) < 6 {
641			return 0
642		}
643
644		r, g, b, a := paramsfn()
645		if r == -1 || g == -1 || b == -1 || a == -1 {
646			return 0
647		}
648
649		*co = color.RGBA{
650			R: uint8(r), //nolint:gosec
651			G: uint8(g), //nolint:gosec
652			B: uint8(b), //nolint:gosec
653			A: uint8(a), //nolint:gosec
654		}
655		return
656
657	default:
658		return 0
659	}
660}