URI: 
       color.go - hugo - [fork] hugo port for 9front
  HTML git clone https://git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       color.go (4592B)
       ---
            1 // Copyright 2019 The Hugo Authors. All rights reserved.
            2 //
            3 // Licensed under the Apache License, Version 2.0 (the "License");
            4 // you may not use this file except in compliance with the License.
            5 // You may obtain a copy of the License at
            6 // http://www.apache.org/licenses/LICENSE-2.0
            7 //
            8 // Unless required by applicable law or agreed to in writing, software
            9 // distributed under the License is distributed on an "AS IS" BASIS,
           10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           11 // See the License for the specific language governing permissions and
           12 // limitations under the License.
           13 
           14 package images
           15 
           16 import (
           17         "encoding/hex"
           18         "fmt"
           19         "hash/fnv"
           20         "image/color"
           21         "math"
           22         "strings"
           23 
           24         "github.com/gohugoio/hugo/common/hstrings"
           25         "slices"
           26 )
           27 
           28 type colorGoProvider interface {
           29         ColorGo() color.Color
           30 }
           31 
           32 type Color struct {
           33         // The color.
           34         color color.Color
           35 
           36         // The color prefixed with a #.
           37         hex string
           38 
           39         // The relative luminance of the color.
           40         luminance float64
           41 }
           42 
           43 // Luminance as defined by w3.org.
           44 // See https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
           45 func (c Color) Luminance() float64 {
           46         return c.luminance
           47 }
           48 
           49 // ColorGo returns the color as a color.Color.
           50 // For internal use only.
           51 func (c Color) ColorGo() color.Color {
           52         return c.color
           53 }
           54 
           55 // ColorHex returns the color as a hex string  prefixed with a #.
           56 func (c Color) ColorHex() string {
           57         return c.hex
           58 }
           59 
           60 // String returns the color as a hex string prefixed with a #.
           61 func (c Color) String() string {
           62         return c.hex
           63 }
           64 
           65 // For hashstructure. This struct is used in template func options
           66 // that needs to be able to hash a Color.
           67 // For internal use only.
           68 func (c Color) Hash() (uint64, error) {
           69         h := fnv.New64a()
           70         h.Write([]byte(c.hex))
           71         return h.Sum64(), nil
           72 }
           73 
           74 func (c *Color) init() error {
           75         c.hex = ColorGoToHexString(c.color)
           76         r, g, b, _ := c.color.RGBA()
           77         c.luminance = 0.2126*c.toSRGB(uint8(r)) + 0.7152*c.toSRGB(uint8(g)) + 0.0722*c.toSRGB(uint8(b))
           78         return nil
           79 }
           80 
           81 func (c Color) toSRGB(i uint8) float64 {
           82         v := float64(i) / 255
           83         if v <= 0.04045 {
           84                 return v / 12.92
           85         } else {
           86                 return math.Pow((v+0.055)/1.055, 2.4)
           87         }
           88 }
           89 
           90 // AddColorToPalette adds c as the first color in p if not already there.
           91 // Note that it does no additional checks, so callers must make sure
           92 // that the palette is valid for the relevant format.
           93 func AddColorToPalette(c color.Color, p color.Palette) color.Palette {
           94         var found bool
           95         if slices.Contains(p, c) {
           96                 found = true
           97         }
           98 
           99         if !found {
          100                 p = append(color.Palette{c}, p...)
          101         }
          102 
          103         return p
          104 }
          105 
          106 // ReplaceColorInPalette will replace the color in palette p closest to c in Euclidean
          107 // R,G,B,A space with c.
          108 func ReplaceColorInPalette(c color.Color, p color.Palette) {
          109         p[p.Index(c)] = c
          110 }
          111 
          112 // ColorGoToHexString converts a color.Color to a hex string.
          113 func ColorGoToHexString(c color.Color) string {
          114         r, g, b, a := c.RGBA()
          115         rgba := color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
          116         if rgba.A == 0xff {
          117                 return fmt.Sprintf("#%.2x%.2x%.2x", rgba.R, rgba.G, rgba.B)
          118         }
          119         return fmt.Sprintf("#%.2x%.2x%.2x%.2x", rgba.R, rgba.G, rgba.B, rgba.A)
          120 }
          121 
          122 // ColorGoToColor converts a color.Color to a Color.
          123 func ColorGoToColor(c color.Color) Color {
          124         cc := Color{color: c}
          125         if err := cc.init(); err != nil {
          126                 panic(err)
          127         }
          128         return cc
          129 }
          130 
          131 func hexStringToColor(s string) Color {
          132         c, err := hexStringToColorGo(s)
          133         if err != nil {
          134                 panic(err)
          135         }
          136         return ColorGoToColor(c)
          137 }
          138 
          139 // HexStringsToColors converts a slice of hex strings to a slice of Colors.
          140 func HexStringsToColors(s ...string) []Color {
          141         var colors []Color
          142         for _, v := range s {
          143                 colors = append(colors, hexStringToColor(v))
          144         }
          145         return colors
          146 }
          147 
          148 func toColorGo(v any) (color.Color, bool, error) {
          149         switch vv := v.(type) {
          150         case colorGoProvider:
          151                 return vv.ColorGo(), true, nil
          152         default:
          153                 s, ok := hstrings.ToString(v)
          154                 if !ok {
          155                         return nil, false, nil
          156                 }
          157                 c, err := hexStringToColorGo(s)
          158                 if err != nil {
          159                         return nil, false, err
          160                 }
          161                 return c, true, nil
          162         }
          163 }
          164 
          165 func hexStringToColorGo(s string) (color.Color, error) {
          166         s = strings.TrimPrefix(s, "#")
          167 
          168         if len(s) != 3 && len(s) != 4 && len(s) != 6 && len(s) != 8 {
          169                 return nil, fmt.Errorf("invalid color code: %q", s)
          170         }
          171 
          172         s = strings.ToLower(s)
          173 
          174         if len(s) == 3 || len(s) == 4 {
          175                 var v string
          176                 for _, r := range s {
          177                         v += string(r) + string(r)
          178                 }
          179                 s = v
          180         }
          181 
          182         // Standard colors.
          183         if s == "ffffff" {
          184                 return color.White, nil
          185         }
          186 
          187         if s == "000000" {
          188                 return color.Black, nil
          189         }
          190 
          191         // Set Alfa to white.
          192         if len(s) == 6 {
          193                 s += "ff"
          194         }
          195 
          196         b, err := hex.DecodeString(s)
          197         if err != nil {
          198                 return nil, err
          199         }
          200 
          201         return color.RGBA{b[0], b[1], b[2], b[3]}, nil
          202 }