瀏覽代碼

[F] Fix RGB to 8bit conversion

Azalea (on HyDEV-Daisy) 3 年之前
父節點
當前提交
39e14aec90
共有 4 個文件被更改,包括 51 次插入13 次删除
  1. 17 6
      hyfetch/color_util.py
  2. 5 4
      hyfetch/main.py
  3. 3 2
      hyfetch/neofetch_util.py
  4. 26 1
      test.py

+ 17 - 6
hyfetch/color_util.py

@@ -1,5 +1,7 @@
 import colorsys
-from typing import NamedTuple
+from typing import NamedTuple, Literal
+
+AnsiMode = Literal['default', 'ansi', '8bit', 'rgb']
 
 
 def redistribute_rgb(r: int, g: int, b: int) -> tuple[int, int, int]:
@@ -69,26 +71,27 @@ class RGB(NamedTuple):
 
         :return: ANSI 256 escape code like \033[38;5;206m'
         """
-        r, g, b = self
+        r, g, b = self.r, self.g, self.b
 
+        gray_possible = True
         gray = False
         sep = 42.5
 
-        while True:
+        while gray_possible:
             if r < sep or g < sep or b < sep:
                 gray = r < sep and g < sep and b < sep
-                break
+                gray_possible = False
             sep += 42.5
 
         if gray:
             color = 232 + (r + g + b) / 33
         else:
-            color = 16 + (r / 256 * 6) * 36 + (g / 256 * 6) * 6 + (b / 256 * 6)
+            color = 16 + int(r / 256. * 6) * 36 + int(g / 256. * 6) * 6 + int(b / 256. * 6)
 
         c = '38' if foreground else '48'
         return f'\033[{c};5;{int(color)}m'
 
-    def to_ansi_16(self) -> str:
+    def to_ansi_16(self, foreground: bool = True) -> str:
         """
         Convert RGB to ANSI 16 Color Escape Code
 
@@ -96,6 +99,14 @@ class RGB(NamedTuple):
         """
         raise NotImplementedError()
 
+    def to_ansi(self, mode: AnsiMode, foreground: bool = True):
+        if mode == 'rgb':
+            return self.to_ansi_rgb(foreground)
+        if mode == '8bit':
+            return self.to_ansi_8bit(foreground)
+        if mode == 'ansi':
+            return self.to_ansi_16(foreground)
+
     def lighten(self, multiplier: float) -> 'RGB':
         """
         Lighten the color by a multiplier

+ 5 - 4
hyfetch/main.py

@@ -8,6 +8,7 @@ from typing import Literal, Iterable
 
 from hypy_utils import printc, json_stringify, color
 
+from .color_util import AnsiMode
 from .neofetch_util import run_neofetch
 from .presets import PRESETS, ColorProfile
 
@@ -18,7 +19,7 @@ CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
 @dataclass
 class Config:
     preset: str
-    mode: Literal['default', 'ansi', '8bit', 'rgb']
+    mode: AnsiMode
 
     def save(self):
         CONFIG_PATH.write_text(json_stringify(self), 'utf-8')
@@ -95,7 +96,7 @@ def create_config() -> Config:
     # Select color system
     # TODO: Demo of each color system
     color_system = literal_input('Which &acolor &bsystem &rdo you want to use?',
-                                 ['ansi', '8bit', 'rgb'], 'rgb')
+                                 ['8bit', 'rgb'], 'rgb')
 
     # Print preset
     print('Available presets:\n')
@@ -135,7 +136,7 @@ def run():
 
     parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure {hyfetch}'))
     parser.add_argument('-p', '--preset', help=f'Use preset', choices=PRESETS.keys())
-    parser.add_argument('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb'])
+    parser.add_argument('-m', '--mode', help=f'Color mode', choices=['8bit', 'rgb'])
     parser.add_argument('--c-scale', dest='scale', help=f'Lighten colors by a multiplier', type=float)
     parser.add_argument('--c-set-l', dest='light', help=f'Set lightness value of the colors', type=float)
 
@@ -163,4 +164,4 @@ def run():
         preset = ColorProfile([c.set_light(args.light) for c in preset.colors])
 
     # Run
-    run_neofetch(preset)
+    run_neofetch(preset, config.mode)

+ 3 - 2
hyfetch/neofetch_util.py

@@ -6,6 +6,7 @@ from tempfile import TemporaryDirectory
 
 import pkg_resources
 
+from .color_util import AnsiMode
 from .presets import ColorProfile
 
 
@@ -27,7 +28,7 @@ def get_distro_ascii() -> str:
     return check_output([get_command_path(), "print_ascii"]).decode().strip()
 
 
-def run_neofetch(preset: ColorProfile):
+def run_neofetch(preset: ColorProfile, mode: AnsiMode):
     # Get existing ascii
     asc = get_distro_ascii()
 
@@ -37,7 +38,7 @@ def run_neofetch(preset: ColorProfile):
     # Add new colors
     lines = asc.split('\n')
     colors = preset.with_length(len(lines))
-    asc = '\n'.join([colors[i].to_ansi_rgb() + l for i, l in enumerate(lines)])
+    asc = '\n'.join([colors[i].to_ansi(mode) + l for i, l in enumerate(lines)])
 
     # Write temp file
     with TemporaryDirectory() as tmp_dir:

+ 26 - 1
test.py

@@ -1,4 +1,7 @@
+from hypy_utils import printc
+
 from hyfetch.color_util import RGB
+from hyfetch.neofetch_util import get_command_path, run_neofetch
 from hyfetch.presets import PRESETS
 
 
@@ -6,10 +9,32 @@ def print_colors_test(colors: list[RGB]):
     print(''.join(f'{c.to_ansi_rgb()}#' for c in colors))
 
 
-if __name__ == '__main__':
+def test_preset_length():
     p = PRESETS.get('transgender')
     print_colors_test(p.with_length(9))
     print_colors_test(p.with_length(6))
     p = PRESETS.get('nonbinary')
     print_colors_test(p.with_length(7))
     print_colors_test(p.with_length(6))
+
+
+def test_command_path():
+    print(get_command_path())
+
+
+def test_rgb_8bit_conversion():
+    for r in range(0, 255, 16):
+        for g in range(0, 255, 16):
+            print(RGB(r, g, 0).to_ansi_rgb(False), end=' ')
+        printc('&r')
+    print()
+    for r in range(0, 255, 16):
+        for g in range(0, 255, 16):
+            print(RGB(r, g, 0).to_ansi_8bit(False), end=' ')
+        printc('&r')
+    print()
+
+
+
+if __name__ == '__main__':
+    test_rgb_8bit_conversion()