style.go 21 KB

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