github.com/gagliardetto/solana-go@v1.11.0/text/rgbterm.go (about)

     1  package text
     2  
     3  // This code is a modified version of the rgbterm package:
     4  // see https://github.com/aybabtme/rgbterm/blob/master/LICENSE
     5  // Original license:
     6  //
     7  // The MIT License
     8  
     9  // Copyright (c) 2014, Antoine Grondin.
    10  
    11  // Permission is hereby granted, free of charge, to any person obtaining a copy
    12  // of this software and associated documentation files (the "Software"), to deal
    13  // in the Software without restriction, including without limitation the rights
    14  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    15  // copies of the Software, and to permit persons to whom the Software is
    16  // furnished to do so, subject to the following conditions:
    17  
    18  // The above copyright notice and this permission notice shall be included in
    19  // all copies or substantial portions of the Software.
    20  
    21  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    22  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    23  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    24  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    25  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    26  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    27  // THE SOFTWARE.
    28  
    29  // > Except for functions HSLtoRGB and RGBtoHSL, under a BSD 2 clause license:
    30  
    31  // Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
    32  
    33  // Redistribution and use in source and binary forms, with or without
    34  // modification, are permitted provided that the following conditions are
    35  // met:
    36  
    37  //      * Redistributions of source code must retain the above copyright
    38  // notice, this list of conditions and the following disclaimer.
    39  //      * Redistributions in binary form must reproduce the above
    40  // copyright notice, this list of conditions and the following disclaimer
    41  // in the documentation and/or other materials provided with the
    42  // distribution.
    43  //      * Neither the name of Google Inc. nor the names of its
    44  // contributors may be used to endorse or promote products derived from
    45  // this software without specific prior written permission.
    46  
    47  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    48  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    49  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    50  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    51  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    52  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    53  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    54  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    55  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    56  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    57  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    58  
    59  var (
    60  	before   = []byte("\033[")
    61  	after    = []byte("m")
    62  	reset    = []byte("\033[0;00m")
    63  	fgcolors = fgTermRGB[16:232]
    64  	bgcolors = bgTermRGB[16:232]
    65  )
    66  
    67  // FgString colorizes the foreground of the input with the terminal color
    68  // that matches the closest the RGB color.
    69  //
    70  // This is simply a helper for Bytes.
    71  func FgString(in string, r, g, b uint8) string {
    72  	return string(FgBytes([]byte(in), r, g, b))
    73  }
    74  
    75  // BgString colorizes the background of the input with the terminal color
    76  // that matches the closest the RGB color.
    77  //
    78  // This is simply a helper for Bytes.
    79  func BgString(in string, r, g, b uint8) string {
    80  	return string(BgBytes([]byte(in), r, g, b))
    81  }
    82  
    83  // Bytes colorizes the foreground with the terminal color that matches
    84  // the closest the RGB color.
    85  func FgBytes(in []byte, r, g, b uint8) []byte {
    86  	return colorize(color_(r, g, b, true), in)
    87  }
    88  
    89  // BgBytes colorizes the background of the input with the terminal color
    90  // that matches the closest the RGB color.
    91  func BgBytes(in []byte, r, g, b uint8) []byte {
    92  	return colorize(color_(r, g, b, false), in)
    93  }
    94  
    95  func colorize(color, in []byte) []byte {
    96  	return append(append(append(append(before, color...), after...), in...), reset...)
    97  }
    98  
    99  func color_(r, g, b uint8, foreground bool) []byte {
   100  	// if all colors are equal, it might be in the grayscale range
   101  	if r == g && g == b {
   102  		color, ok := grayscale(r, foreground)
   103  		if ok {
   104  			return color
   105  		}
   106  	}
   107  
   108  	// the general case approximates RGB by using the closest color.
   109  	r6 := ((uint16(r) * 5) / 255)
   110  	g6 := ((uint16(g) * 5) / 255)
   111  	b6 := ((uint16(b) * 5) / 255)
   112  	i := 36*r6 + 6*g6 + b6
   113  	if foreground {
   114  		return fgcolors[i]
   115  	} else {
   116  		return bgcolors[i]
   117  	}
   118  }
   119  
   120  func grayscale(scale uint8, foreground bool) ([]byte, bool) {
   121  	var source [256][]byte
   122  
   123  	if foreground {
   124  		source = fgTermRGB
   125  	} else {
   126  		source = bgTermRGB
   127  	}
   128  
   129  	switch scale {
   130  	case 0x08:
   131  		return source[232], true
   132  	case 0x12:
   133  		return source[233], true
   134  	case 0x1c:
   135  		return source[234], true
   136  	case 0x26:
   137  		return source[235], true
   138  	case 0x30:
   139  		return source[236], true
   140  	case 0x3a:
   141  		return source[237], true
   142  	case 0x44:
   143  		return source[238], true
   144  	case 0x4e:
   145  		return source[239], true
   146  	case 0x58:
   147  		return source[240], true
   148  	case 0x62:
   149  		return source[241], true
   150  	case 0x6c:
   151  		return source[242], true
   152  	case 0x76:
   153  		return source[243], true
   154  	case 0x80:
   155  		return source[244], true
   156  	case 0x8a:
   157  		return source[245], true
   158  	case 0x94:
   159  		return source[246], true
   160  	case 0x9e:
   161  		return source[247], true
   162  	case 0xa8:
   163  		return source[248], true
   164  	case 0xb2:
   165  		return source[249], true
   166  	case 0xbc:
   167  		return source[250], true
   168  	case 0xc6:
   169  		return source[251], true
   170  	case 0xd0:
   171  		return source[252], true
   172  	case 0xda:
   173  		return source[253], true
   174  	case 0xe4:
   175  		return source[254], true
   176  	case 0xee:
   177  		return source[255], true
   178  	}
   179  	return nil, false
   180  }