diff options
author | bptato <nincsnevem662@gmail.com> | 2023-07-29 01:04:38 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-07-29 01:16:29 +0200 |
commit | f646b6caf0661ab2bee5abb4489267438de27c55 (patch) | |
tree | fca88782d420787a64da9eeaf86547854c7af218 | |
parent | 4ffd835674870434dd820f8778b5eeeee615723c (diff) | |
download | chawan-f646b6caf0661ab2bee5abb4489267438de27c55.tar.gz |
Add default background/foreground color override
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | doc/config.md | 12 | ||||
-rw-r--r-- | res/config.toml | 2 | ||||
-rw-r--r-- | src/config/config.nim | 11 | ||||
-rw-r--r-- | src/display/term.nim | 77 | ||||
-rw-r--r-- | todo | 6 |
6 files changed, 82 insertions, 39 deletions
diff --git a/README.md b/README.md index 130fa10b..0b2b6a01 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,19 @@ want to try more established ones: ## FAQ +### Why does Chawan use strange/incorrect/ugly colors? + +Chawan assumes the terminal's default background/foreground colors are +black and white. If this is not true for your terminal, make sure to set +the display.default-background-color and display.default-foreground-color +properties in your Chawan configuration file. + +Also, by default, Chawan uses the eight ANSI colors to display colored +text. To use true colors, either export COLORTERM=truecolor or set the +display.color-mode to "24bit". To use 256 colors, set display.color-mode to +"8bit" instead. (You can also turn off colors and/or styling altogether in +the configuration; please consult [doc/config.md](doc/config.md) for details.) + ### Why write another web browser? I've found other text-based web browsers insufficient for my needs, so diff --git a/doc/config.md b/doc/config.md index ca62dd88..fabe9820 100644 --- a/doc/config.md +++ b/doc/config.md @@ -282,6 +282,18 @@ black background, etc).</td> <td>Set the terminal emulator's window title to that of the current page.</td> </tr> +<tr> +<td>default-background-color</td> +<td>color</td> +<td>Sets the assumed background color of the terminal.</td> +</tr> + +<tr> +<td>default-foreground-color</td> +<td>color</td> +<td>Sets the assumed foreground color of the terminal.</td> +</tr> + </table> ## Omnirule diff --git a/res/config.toml b/res/config.toml index 4e319652..c12c10ff 100644 --- a/res/config.toml +++ b/res/config.toml @@ -30,6 +30,8 @@ double-width-ambiguous = false minimum-contrast = 100 force-clear = false set-title = true +default-background-color = "#000000" +default-foreground-color = "#FFFFFF" [[omnirule]] match = '^ddg:' diff --git a/src/config/config.nim b/src/config/config.nim index dfcb63c4..f379cb3b 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -96,6 +96,8 @@ type minimum_contrast*: int32 force_clear*: bool set_title*: bool + default_background_color*: RGBColor + default_foreground_color*: RGBColor #TODO: add JS wrappers for objects Config* = ref ConfigObj @@ -321,6 +323,7 @@ proc parseConfigValue(x: var Opt[ColorMode], v: TomlValue, k: string) proc parseConfigValue(x: var Opt[FormatMode], v: TomlValue, k: string) proc parseConfigValue(x: var FormatMode, v: TomlValue, k: string) proc parseConfigValue(x: var RGBAColor, v: TomlValue, k: string) +proc parseConfigValue(x: var RGBColor, v: TomlValue, k: string) proc parseConfigValue[T](x: var Opt[T], v: TomlValue, k: string) proc parseConfigValue(x: var ActionMap, v: TomlValue, k: string) proc parseConfigValue(x: var CSSConfig, v: TomlValue, k: string) @@ -429,6 +432,14 @@ proc parseConfigValue(x: var RGBAColor, v: TomlValue, k: string) = "' for key " & k) x = c.get +proc parseConfigValue(x: var RGBColor, v: TomlValue, k: string) = + typeCheck(v, VALUE_STRING, k) + let c = parseLegacyColor(v.s) + if c.isNone: + raise newException(ValueError, "invalid color '" & v.s & + "' for key " & k) + x = c.get + proc parseConfigValue[T](x: var Opt[T], v: TomlValue, k: string) = if v.vt == VALUE_STRING and v.s == "auto": x.err() diff --git a/src/display/term.nim b/src/display/term.nim index 0aa7daa9..a2112ee5 100644 --- a/src/display/term.nim +++ b/src/display/term.nim @@ -51,7 +51,6 @@ type canvas*: FixedGrid pcanvas: FixedGrid attrs*: WindowAttributes - mincontrast: int colormode: ColorMode formatmode: FormatMode smcup: bool @@ -201,26 +200,33 @@ proc disableAltScreen(term: Terminal): string = else: return RMCUP() +func defaultBackground(term: Terminal): RGBColor = + return term.config.display.default_background_color + +func defaultForeground(term: Terminal): RGBColor = + return term.config.display.default_foreground_color + +func mincontrast(term: Terminal): int32 = + return term.config.display.minimum_contrast + proc getRGB(a: CellColor, bg: bool): RGBColor = if a.rgb: return a.rgbcolor - elif a == defaultColor: - if bg: - return ColorsRGB["black"] - else: - return ColorsRGB["white"] elif a.color >= 16: return eightBitToRGB(EightBitColor(a.color)) - return ANSIColorMap[a.color mod 10] + return ANSIColorMap[a.color] # Use euclidian distance to quantize RGB colors. -proc approximateANSIColor(rgb: RGBColor): ANSIColor = +proc approximateANSIColor(rgb, termDefault: RGBColor): CellColor = var a = 0i32 var n = -1 - for i in 0 .. ANSIColorMap.high: - let color = ANSIColorMap[i] + for i in -1 .. ANSIColorMap.high: + let color = if i > 0: + ANSIColorMap[i] + else: + termDefault if color == rgb: - return ANSIColor(i) + return if i == -1: defaultColor else: cellColor(ANSIColor(i)) let x = int32(color.r) - int32(rgb.r) let y = int32(color.g) - int32(rgb.g) let z = int32(color.b) - int32(rgb.b) @@ -231,14 +237,20 @@ proc approximateANSIColor(rgb: RGBColor): ANSIColor = if n == -1 or b < a: n = i a = b - return ANSIColor(n) + return if n == -1: defaultColor else: cellColor(ANSIColor(n)) -# Return a fgcolor contrasted to the background by contrast. -proc correctContrast(bgcolor, fgcolor: CellColor, contrast: int, - colormode: ColorMode): CellColor = +# Return a fgcolor contrasted to the background by term.mincontrast. +proc correctContrast(term: Terminal, bgcolor, fgcolor: CellColor): CellColor = + let contrast = term.mincontrast let cfgcolor = fgcolor - let bgcolor = getRGB(bgcolor, true) - let fgcolor = getRGB(fgcolor, false) + let bgcolor = if bgcolor == defaultColor: + term.defaultBackground + else: + getRGB(bgcolor, true) + let fgcolor = if fgcolor == defaultColor: + term.defaultForeground + else: + getRGB(fgcolor, false) let bgY = int(bgcolor.Y) var fgY = int(fgcolor.Y) let diff = abs(bgY - fgY) @@ -256,11 +268,11 @@ proc correctContrast(bgcolor, fgcolor: CellColor, contrast: int, if fgY < 0: fgY = 255 let newrgb = YUV(cast[uint8](fgY), fgcolor.U, fgcolor.V) - case colormode + case term.colormode of TRUECOLOR: return cellColor(newrgb) of ANSI: - return cellColor(approximateANSIColor(newrgb)) + return approximateANSIColor(newrgb, term.defaultForeground) of EIGHT_BIT: return cellColor(rgbToEightBit(newrgb)) of MONOCHROME: @@ -283,25 +295,16 @@ proc processFormat*(term: Terminal, format: var Format, cellf: Format): string = let color = cellf.fgcolor.eightbit cellf.fgcolor = cellColor(eightBitToRGB(color)) if cellf.bgcolor.rgb: - let color = approximateANSIColor(cellf.bgcolor.rgbcolor) - if color == ANSI_BLACK: - cellf.bgcolor = defaultColor - else: - cellf.bgcolor = cellColor(color) + cellf.bgcolor = approximateANSIColor(cellf.bgcolor.rgbcolor, + term.defaultBackground) if cellf.fgcolor.rgb: if cellf.bgcolor == defaultColor: - var color = approximateANSIColor(cellf.fgcolor.rgbcolor) - if color == ANSI_BLACK: - color = ANSI_WHITE - if color == ANSI_WHITE: - cellf.fgcolor = defaultColor - else: - cellf.fgcolor = cellColor(color) + cellf.fgcolor = approximateANSIColor(cellf.fgcolor.rgbcolor, + term.defaultForeground) else: - cellf.fgcolor = if cellf.bgcolor.color < 4: - defaultColor - else: - cellColor(ANSI_WHITE) # white + # ANSI non-default fgcolor AND bgcolor at the same time is assumed + # to be broken. + cellf.fgcolor = defaultColor of EIGHT_BIT: if cellf.bgcolor.rgb: cellf.bgcolor = cellColor(rgbToEightBit(cellf.bgcolor.rgbcolor)) @@ -313,8 +316,7 @@ proc processFormat*(term: Terminal, format: var Format, cellf: Format): string = of TRUE_COLOR: discard if term.colormode != MONOCHROME: - cellf.fgcolor = correctContrast(cellf.bgcolor, cellf.fgcolor, - term.mincontrast, term.colormode) + cellf.fgcolor = term.correctContrast(cellf.bgcolor, cellf.fgcolor) if cellf.fgcolor != format.fgcolor and cellf.fgcolor == defaultColor or cellf.bgcolor != format.bgcolor and cellf.bgcolor == defaultColor: result &= term.resetFormat() @@ -520,7 +522,6 @@ proc applyConfig(term: Terminal) = if term.config.display.alt_screen.isSome: term.smcup = term.config.display.alt_screen.get term.set_title = term.config.display.set_title - term.mincontrast = term.config.display.minimum_contrast if term.config.encoding.display_charset.isSome: term.cs = term.config.encoding.display_charset.get else: diff --git a/todo b/todo index c4e6e260..79e5fb2e 100644 --- a/todo +++ b/todo @@ -14,8 +14,12 @@ display: - important: buffer list * either a buffer list buffer, or a buffer list popup menu. ideally both. -- configurable default background color - dark mode (basically max Y) +- do not assume default background color + * instead, add an "override-default-color" option that is set to + true by default and replaces default bgcolor/fgcolor with + default-background/foreground-color +- allow overriding ansi colors config: - important: config editor - working js interface |