mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-18 22:44:50 +02:00
Work on rendering sample text for a font
This commit is contained in:
@@ -2,11 +2,16 @@
|
||||
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import json
|
||||
import string
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Any, Dict, Tuple, TypedDict
|
||||
|
||||
from kitty.fonts.common import get_variable_data_for_descriptor
|
||||
from kitty.conf.utils import to_color
|
||||
from kitty.fonts import Descriptor
|
||||
from kitty.fonts.common import face_from_descriptor, get_font_files, get_variable_data_for_descriptor
|
||||
from kitty.fonts.list import create_family_groups
|
||||
from kitty.options.types import Options
|
||||
from kitty.options.utils import parse_font_spec
|
||||
|
||||
|
||||
def send_to_kitten(x: Any) -> None:
|
||||
@@ -15,7 +20,77 @@ def send_to_kitten(x: Any) -> None:
|
||||
sys.stdout.buffer.flush()
|
||||
|
||||
|
||||
class TextStyle(TypedDict):
|
||||
font_size: float
|
||||
dpi_x: float
|
||||
dpi_y: float
|
||||
foreground: str
|
||||
background: str
|
||||
|
||||
|
||||
FamilyKey = Tuple[str, ...]
|
||||
|
||||
|
||||
def opts_from_cmd(cmd: Dict[str, Any]) -> Tuple[Options, FamilyKey, float, float]:
|
||||
opts = Options()
|
||||
ts: TextStyle = cmd['text_style']
|
||||
opts.font_size = ts['font_size']
|
||||
opts.foreground = to_color(ts['foreground'])
|
||||
opts.background = to_color(ts['background'])
|
||||
family_key = []
|
||||
if 'font_family' in cmd:
|
||||
opts.font_family = parse_font_spec(cmd['font_family'])
|
||||
family_key.append(cmd['font_family'])
|
||||
if 'bold_font' in cmd:
|
||||
opts.bold_font = parse_font_spec(cmd['bold_font'])
|
||||
family_key.append(cmd['bold_font'])
|
||||
if 'italic_font' in cmd:
|
||||
opts.italic_font = parse_font_spec(cmd['italic_font'])
|
||||
family_key.append(cmd['italic_font'])
|
||||
if 'bold_italic_font' in cmd:
|
||||
opts.bold_italic_font = parse_font_spec(cmd['bold_italic_font'])
|
||||
family_key.append(cmd['bold_italic_font'])
|
||||
return opts, tuple(family_key), ts['dpi_x'], ts['dpi_y']
|
||||
|
||||
|
||||
BaseKey = Tuple[FamilyKey, int, int]
|
||||
FaceKey = Tuple[str, BaseKey]
|
||||
SAMPLE_TEXT = string.ascii_lowercase + string.digits + string.ascii_uppercase + ' ' + string.punctuation
|
||||
|
||||
|
||||
def render_face_sample(font: Descriptor, opts: Options, dpi_x: float, dpi_y: float, width: int, height: int, output_dir: str) -> str:
|
||||
face = face_from_descriptor(font)
|
||||
face.set_size(opts.font_size, dpi_x, dpi_y)
|
||||
face.render_sample_text(SAMPLE_TEXT, width, height, opts.foreground.rgb)
|
||||
|
||||
|
||||
def render_family_sample(
|
||||
opts: Options, family_key: FamilyKey, dpi_x: float, dpi_y: float, width: int, height: int, output_dir: str,
|
||||
cache: Dict[FaceKey, str]
|
||||
) -> Dict[str, str]:
|
||||
base_key: BaseKey = family_key, width, height
|
||||
ans: Dict[str, str] = {}
|
||||
font_files = get_font_files(opts)
|
||||
for x in family_key:
|
||||
key: FaceKey = x, base_key
|
||||
if x == 'font_family':
|
||||
desc = font_files['medium']
|
||||
elif x == 'bold_font':
|
||||
desc = font_files['bold']
|
||||
elif x == 'italic_font':
|
||||
desc = font_files['italic']
|
||||
elif x == 'bold_italic_font':
|
||||
desc = font_files['bi']
|
||||
cached = cache.get(key)
|
||||
if cached is not None:
|
||||
ans[x] = cached
|
||||
else:
|
||||
cache[key] = ans[x] = render_face_sample(desc, opts, dpi_x, dpi_y, width, height, output_dir)
|
||||
return ans
|
||||
|
||||
|
||||
def main() -> None:
|
||||
cache: Dict[FaceKey, str] = {}
|
||||
for line in sys.stdin.buffer:
|
||||
cmd = json.loads(line)
|
||||
action = cmd.get('action', '')
|
||||
@@ -26,5 +101,8 @@ def main() -> None:
|
||||
for descriptor in cmd['descriptors']:
|
||||
ans.append(get_variable_data_for_descriptor(descriptor))
|
||||
send_to_kitten(ans)
|
||||
elif action == 'render_family_samples':
|
||||
opts, family_key, dpi_x, dpi_y = opts_from_cmd(cmd)
|
||||
send_to_kitten(render_family_sample(opts, family_key, dpi_x, dpi_y, cmd['width'], cmd['height'], cmd['output_dir'], cache))
|
||||
else:
|
||||
raise SystemExit(f'Unknown action: {action}')
|
||||
|
||||
@@ -24,6 +24,14 @@ const (
|
||||
CHOOSING_FACES
|
||||
)
|
||||
|
||||
type TextStyle struct {
|
||||
Font_sz float64 `json:"font_size"`
|
||||
Dpi_x float64 `json:"dpi_x"`
|
||||
Dpi_y float64 `json:"dpi_y"`
|
||||
Foreground string `json:"foreground"`
|
||||
Background string `json:"background"`
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
lp *loop.Loop
|
||||
fonts map[string][]ListedFont
|
||||
@@ -33,10 +41,7 @@ type handler struct {
|
||||
mouse_state tui.MouseState
|
||||
render_count uint
|
||||
render_lines tui.RenderLines
|
||||
text_style struct {
|
||||
font_sz, dpi_x, dpi_y float64
|
||||
foreground, background string
|
||||
}
|
||||
text_style TextStyle
|
||||
|
||||
// Listing
|
||||
rl *readline.Readline
|
||||
@@ -295,21 +300,21 @@ func (h *handler) on_query_response(key, val string, valid bool) error {
|
||||
}
|
||||
switch key {
|
||||
case "font_size":
|
||||
if err := set_float(key, val, &h.text_style.font_sz); err != nil {
|
||||
if err := set_float(key, val, &h.text_style.Font_sz); err != nil {
|
||||
return err
|
||||
}
|
||||
case "dpi_x":
|
||||
if err := set_float(key, val, &h.text_style.dpi_x); err != nil {
|
||||
if err := set_float(key, val, &h.text_style.Dpi_x); err != nil {
|
||||
return err
|
||||
}
|
||||
case "dpi_y":
|
||||
if err := set_float(key, val, &h.text_style.dpi_y); err != nil {
|
||||
if err := set_float(key, val, &h.text_style.Dpi_y); err != nil {
|
||||
return err
|
||||
}
|
||||
case "foreground":
|
||||
h.text_style.foreground = val
|
||||
h.text_style.Foreground = val
|
||||
case "background":
|
||||
h.text_style.background = val
|
||||
h.text_style.Background = val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user