diff --git a/kittens/choose_fonts/backend.py b/kittens/choose_fonts/backend.py index a01eca3f5..791662ab9 100644 --- a/kittens/choose_fonts/backend.py +++ b/kittens/choose_fonts/backend.py @@ -11,7 +11,16 @@ from kitty.cli import create_default_opts from kitty.conf.utils import to_color from kitty.constants import kitten_exe from kitty.fonts import Descriptor -from kitty.fonts.common import face_from_descriptor, get_font_files, get_variable_data_for_descriptor, spec_for_descriptor +from kitty.fonts.common import ( + face_from_descriptor, + get_axis_map, + get_font_files, + get_named_style, + get_variable_data_for_descriptor, + get_variable_data_for_face, + is_variable, + spec_for_descriptor, +) from kitty.fonts.list import create_family_groups from kitty.fonts.render import display_bitmap from kitty.options.types import Options @@ -65,21 +74,32 @@ def opts_from_cmd(cmd: Dict[str, Any]) -> Tuple[Options, FamilyKey, float, float BaseKey = Tuple[FamilyKey, int, int] FaceKey = Tuple[str, BaseKey] +RenderedSample = Tuple[bytes, Dict[str, Any]] +RenderedSampleTransmit = Dict[str, Any] 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) -> bytes: +def render_face_sample(font: Descriptor, opts: Options, dpi_x: float, dpi_y: float, width: int, height: int) -> RenderedSample: face = face_from_descriptor(font) face.set_size(opts.font_size, dpi_x, dpi_y) - return face.render_sample_text(SAMPLE_TEXT, width, height, opts.foreground.rgb) + metadata = { + 'variable_data': get_variable_data_for_face(face), + 'style': font['style'], + } + if is_variable(font): + ns = get_named_style(face) + if ns: + metadata['variable_named_style'] = ns + metadata['variable_axis_map'] = get_axis_map(face) + return face.render_sample_text(SAMPLE_TEXT, width, height, opts.foreground.rgb), metadata 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]: + cache: Dict[FaceKey, RenderedSampleTransmit] +) -> Dict[str, RenderedSampleTransmit]: base_key: BaseKey = family_key, width, height - ans: Dict[str, str] = {} + ans: Dict[str, RenderedSampleTransmit] = {} font_files = get_font_files(opts) for x in family_key: key: FaceKey = getattr(opts, x).created_from_string, base_key @@ -96,9 +116,10 @@ def render_family_sample( ans[x] = cached else: with tempfile.NamedTemporaryFile(delete=False, suffix='.rgba', dir=output_dir) as tf: - bitmap = render_face_sample(desc, opts, dpi_x, dpi_y, width, height) + bitmap, metadata = render_face_sample(desc, opts, dpi_x, dpi_y, width, height) tf.write(bitmap) - cache[key] = ans[x] = tf.name + metadata['path'] = tf.name + cache[key] = ans[x] = metadata return ans @@ -119,7 +140,7 @@ def resolved_faces(opts: Options) -> Dict[OptNames, ResolvedFace]: def main() -> None: - cache: Dict[FaceKey, str] = {} + cache: Dict[FaceKey, RenderedSampleTransmit] = {} for line in sys.stdin.buffer: cmd = json.loads(line) action = cmd.get('action', '') @@ -160,5 +181,5 @@ def showcase(family: str) -> None: ss = screen_size_function()() width = ss.cell_width * ss.cols height = 5 * ss.cell_height - bitmap = render_face_sample(desc, opts, float(q['dpi_x']), float(q['dpi_y']), width, height) + bitmap = render_face_sample(desc, opts, float(q['dpi_x']), float(q['dpi_y']), width, height)[0] display_bitmap(bitmap, width, height) diff --git a/kittens/choose_fonts/faces.go b/kittens/choose_fonts/faces.go index c83213e53..d16b65ff7 100644 --- a/kittens/choose_fonts/faces.go +++ b/kittens/choose_fonts/faces.go @@ -25,7 +25,7 @@ type faces struct { family string settings faces_settings - preview_cache map[faces_preview_key]map[string]string + preview_cache map[faces_preview_key]map[string]RenderedSampleTransmit preview_cache_mutex sync.Mutex } @@ -48,12 +48,11 @@ func (self *faces) draw_screen() (err error) { key := faces_preview_key{settings: self.settings, width: int(sz.WidthCells * sz.CellWidth), height: int(sz.CellHeight) * num_lines} self.preview_cache_mutex.Lock() defer self.preview_cache_mutex.Unlock() - previews := self.preview_cache[key] - if previews == nil { - self.preview_cache[key] = make(map[string]string) - self.preview_cache[key]["in_flight"] = "yes" + previews, found := self.preview_cache[key] + if !found { + self.preview_cache[key] = make(map[string]RenderedSampleTransmit) go func() { - var r map[string]string + var r map[string]RenderedSampleTransmit s := key.settings self.handler.set_worker_error(kitty_font_backend.query("render_family_samples", map[string]any{ "text_style": self.handler.text_style, "font_family": s.font_family, @@ -62,13 +61,12 @@ func (self *faces) draw_screen() (err error) { }, &r)) self.preview_cache_mutex.Lock() defer self.preview_cache_mutex.Unlock() - r["in_flight"] = "no" self.preview_cache[key] = r self.handler.lp.WakeupMainThread() }() return } - if previews["in_flight"] == "yes" { + if len(previews) < 4 { return } @@ -82,7 +80,7 @@ func (self *faces) draw_screen() (err error) { lp.QueueWriteString(str) if y+num_lines < int(sz.HeightCells) { lp.MoveCursorTo(1, y+1) - self.handler.graphics_manager.display_image(slot, previews[setting], key.width, key.height) + self.handler.graphics_manager.display_image(slot, previews[setting].Path, key.width, key.height) slot++ y += num_lines + 1 } @@ -97,7 +95,7 @@ func (self *faces) draw_screen() (err error) { func (self *faces) initialize(h *handler) (err error) { self.handler = h - self.preview_cache = make(map[faces_preview_key]map[string]string) + self.preview_cache = make(map[faces_preview_key]map[string]RenderedSampleTransmit) return } diff --git a/kittens/choose_fonts/list.go b/kittens/choose_fonts/list.go index e2149c516..83e79d2ab 100644 --- a/kittens/choose_fonts/list.go +++ b/kittens/choose_fonts/list.go @@ -142,14 +142,14 @@ func (self *FontList) draw_preview(x, y int, sz loop.ScreenSize) (err error) { case "": self.preview_cache[key] = "requested" go func() { - var r map[string]string + var r map[string]RenderedSampleTransmit self.handler.set_worker_error(kitty_font_backend.query("render_family_samples", map[string]any{ "text_style": self.handler.text_style, "font_family": key.family, "width": key.width, "height": key.height, "output_dir": self.handler.temp_dir, }, &r)) self.preview_cache_mutex.Lock() defer self.preview_cache_mutex.Unlock() - self.preview_cache[key] = r["font_family"] + self.preview_cache[key] = r["font_family"].Path self.handler.lp.WakeupMainThread() }() return diff --git a/kittens/choose_fonts/types.go b/kittens/choose_fonts/types.go index e64efee57..c3edac8b8 100644 --- a/kittens/choose_fonts/types.go +++ b/kittens/choose_fonts/types.go @@ -86,6 +86,14 @@ type ListResult struct { Resolved_faces ResolvedFaces `json:"resolved_faces"` } +type RenderedSampleTransmit struct { + Path string `json:"path"` + Variable_data VariableData `json:"variable_data"` + Style string `json:"style"` + Variable_named_style NamedStyle `json:"variable_named_style"` + Variable_axis_map map[string]float64 `json:"variable_axis_map"` +} + var variable_data_cache map[string]VariableData var variable_data_cache_mutex sync.Mutex