Skip to main content

gpui_engine/
render.rs

1//! Rendering asset identifiers and raster parameters shared by the engine and
2//! its platform backends.
3
4use gpui_shared_string::SharedString;
5use gpui_types::{DevicePixels, Pixels, Point, Size};
6use std::hash::{Hash, Hasher};
7
8/// An opaque identifier for a specific font.
9#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
10#[repr(C)]
11pub struct FontId(pub usize);
12
13/// An identifier for a specific glyph, as returned by the platform text system.
14#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
15#[repr(C)]
16pub struct GlyphId(pub u32);
17
18/// Parameters for rendering a glyph, used as cache keys for raster bounds.
19///
20/// This struct identifies a specific glyph rendering configuration including
21/// font, size, subpixel positioning, and scale factor. It's used to look up
22/// cached raster bounds and sprite atlas entries.
23#[derive(Clone, Debug, PartialEq)]
24#[expect(missing_docs)]
25pub struct RenderGlyphParams {
26    pub font_id: FontId,
27    pub glyph_id: GlyphId,
28    pub font_size: Pixels,
29    pub subpixel_variant: Point<u8>,
30    pub scale_factor: f32,
31    pub is_emoji: bool,
32    pub subpixel_rendering: bool,
33    pub dilation: u8,
34}
35
36impl Eq for RenderGlyphParams {}
37
38impl Hash for RenderGlyphParams {
39    fn hash<H: Hasher>(&self, state: &mut H) {
40        self.font_id.0.hash(state);
41        self.glyph_id.0.hash(state);
42        self.font_size.0.to_bits().hash(state);
43        self.subpixel_variant.hash(state);
44        self.scale_factor.to_bits().hash(state);
45        self.is_emoji.hash(state);
46        self.subpixel_rendering.hash(state);
47        self.dilation.hash(state);
48    }
49}
50
51/// A unique identifier for the image cache
52#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
53pub struct ImageId(pub usize);
54
55#[derive(PartialEq, Eq, Hash, Clone)]
56#[expect(missing_docs)]
57pub struct RenderImageParams {
58    pub image_id: ImageId,
59    pub frame_index: usize,
60}
61
62#[derive(Clone, PartialEq, Hash, Eq)]
63#[expect(missing_docs)]
64pub struct RenderSvgParams {
65    pub path: SharedString,
66    pub size: Size<DevicePixels>,
67}
68
69// Adapted from https://github.com/microsoft/terminal/blob/1283c0f5b99a2961673249fa77c6b986efb5086c/src/renderer/atlas/dwrite.cpp
70// Copyright (c) Microsoft Corporation.
71// Licensed under the MIT license.
72/// Compute gamma correction ratios for subpixel text rendering.
73#[allow(dead_code)]
74pub fn get_gamma_correction_ratios(gamma: f32) -> [f32; 4] {
75    const GAMMA_INCORRECT_TARGET_RATIOS: [[f32; 4]; 13] = [
76        [0.0000 / 4.0, 0.0000 / 4.0, 0.0000 / 4.0, 0.0000 / 4.0], // gamma = 1.0
77        [0.0166 / 4.0, -0.0807 / 4.0, 0.2227 / 4.0, -0.0751 / 4.0], // gamma = 1.1
78        [0.0350 / 4.0, -0.1760 / 4.0, 0.4325 / 4.0, -0.1370 / 4.0], // gamma = 1.2
79        [0.0543 / 4.0, -0.2821 / 4.0, 0.6302 / 4.0, -0.1876 / 4.0], // gamma = 1.3
80        [0.0739 / 4.0, -0.3963 / 4.0, 0.8167 / 4.0, -0.2287 / 4.0], // gamma = 1.4
81        [0.0933 / 4.0, -0.5161 / 4.0, 0.9926 / 4.0, -0.2616 / 4.0], // gamma = 1.5
82        [0.1121 / 4.0, -0.6395 / 4.0, 1.1588 / 4.0, -0.2877 / 4.0], // gamma = 1.6
83        [0.1300 / 4.0, -0.7649 / 4.0, 1.3159 / 4.0, -0.3080 / 4.0], // gamma = 1.7
84        [0.1469 / 4.0, -0.8911 / 4.0, 1.4644 / 4.0, -0.3234 / 4.0], // gamma = 1.8
85        [0.1627 / 4.0, -1.0170 / 4.0, 1.6051 / 4.0, -0.3347 / 4.0], // gamma = 1.9
86        [0.1773 / 4.0, -1.1420 / 4.0, 1.7385 / 4.0, -0.3426 / 4.0], // gamma = 2.0
87        [0.1908 / 4.0, -1.2652 / 4.0, 1.8650 / 4.0, -0.3476 / 4.0], // gamma = 2.1
88        [0.2031 / 4.0, -1.3864 / 4.0, 1.9851 / 4.0, -0.3501 / 4.0], // gamma = 2.2
89    ];
90
91    const NORM13: f32 = ((0x10000 as f64) / (255.0 * 255.0) * 4.0) as f32;
92    const NORM24: f32 = ((0x100 as f64) / (255.0) * 4.0) as f32;
93
94    let index = ((gamma * 10.0).round() as usize).clamp(10, 22) - 10;
95    let ratios = GAMMA_INCORRECT_TARGET_RATIOS[index];
96
97    [
98        ratios[0] * NORM13,
99        ratios[1] * NORM24,
100        ratios[2] * NORM13,
101        ratios[3] * NORM24,
102    ]
103}