Skip to content

Commit

Permalink
feat: Configurable contrast and gamma (#2510)
Browse files Browse the repository at this point in the history
* Configurable text contrast and gamma

* Explicitly specify the colorspace to use

* Change default hinting to slight

Full hinting is a bit too aggressive, especially with fractional font sizes

* Update the documentation

* Cargo fmt

* Set font hinting none as default

---------

Co-authored-by: Kaylee Simmons <[email protected]>
  • Loading branch information
fredizzimo and Kethku committed May 11, 2024
1 parent f5bab65 commit 866e3c2
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/renderer/fonts/font_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,10 @@ impl FontEdging {

#[derive(Clone, Debug, Hash, PartialEq, Eq, Default)]
pub enum FontHinting {
#[default]
Full,
Normal,
Slight,
#[default]
None,
}

Expand Down
4 changes: 4 additions & 0 deletions src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ pub struct RendererSettings {
debug_renderer: bool,
profiler: bool,
underline_stroke_scale: f32,
text_gamma: f32,
text_contrast: f32,
}

impl Default for RendererSettings {
Expand All @@ -115,6 +117,8 @@ impl Default for RendererSettings {
debug_renderer: false,
profiler: false,
underline_stroke_scale: 1.,
text_gamma: 0.0,
text_contrast: 0.5,
}
}
}
Expand Down
25 changes: 19 additions & 6 deletions src/renderer/opengl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use skia_safe::{
backend_render_targets::make_gl, gl::FramebufferInfo, surfaces::wrap_backend_render_target,
DirectContext, SurfaceOrigin,
},
ColorType,
ColorSpace, ColorType, PixelGeometry, SurfaceProps, SurfacePropsFlags,
};
use winit::{
dpi::PhysicalSize,
Expand All @@ -37,9 +37,9 @@ pub use super::vsync::VSyncWinDwm;
#[cfg(target_os = "macos")]
pub use super::vsync::VSyncMacos;

use super::{SkiaRenderer, VSync, WindowConfig, WindowConfigType};
use super::{RendererSettings, SkiaRenderer, VSync, WindowConfig, WindowConfigType};

use crate::{profiling::tracy_gpu_zone, window::UserEvent};
use crate::{profiling::tracy_gpu_zone, settings::SETTINGS, window::UserEvent};

#[cfg(feature = "gpu_profiling")]
use crate::profiling::{opengl::create_opengl_gpu_context, GpuCtx};
Expand Down Expand Up @@ -276,13 +276,26 @@ fn create_surface(
let width = NonZeroU32::new(size.width).unwrap();
let height = NonZeroU32::new(size.height).unwrap();
GlSurface::resize(window_surface, context, width, height);

let render_settings = SETTINGS.get::<RendererSettings>();

let surface_props = SurfaceProps::new_with_text_properties(
SurfacePropsFlags::default(),
PixelGeometry::default(),
render_settings.text_contrast,
render_settings.text_gamma,
);

// NOTE: It would be much better to render using a linear gamma format, and SRGB backbuffer
// format But currently the Skia glyph atlas uses a 32-bit linear format texture, so some color
// precision is lost, and the font colors will be slightly off.
wrap_backend_render_target(
gr_context,
&backend_render_target,
SurfaceOrigin::BottomLeft,
ColorType::RGBA8888,
None,
None,
ColorSpace::new_srgb(),
Some(surface_props).as_ref(),
)
.expect("Could not create skia surface")
.expect("Could not create skia backend render target")
}
18 changes: 17 additions & 1 deletion src/window/window_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use crate::windows_utils::{register_right_click, unregister_right_click};
use crate::{
bridge::{send_ui, ParallelCommand, SerialCommand},
profiling::{tracy_frame, tracy_gpu_collect, tracy_gpu_zone, tracy_plot, tracy_zone},
renderer::{create_skia_renderer, DrawCommand, Renderer, SkiaRenderer, VSync, WindowConfig},
renderer::{
create_skia_renderer, DrawCommand, Renderer, RendererSettingsChanged, SkiaRenderer, VSync,
WindowConfig,
},
settings::{
clamped_grid_size, FontSettings, HotReloadConfigs, SettingsChanged, DEFAULT_GRID_SIZE,
MIN_GRID_SIZE, SETTINGS,
Expand Down Expand Up @@ -276,6 +279,16 @@ impl WinitWindowWrapper {
self.macos_feature.handle_settings_changed(changed_setting);
}

fn handle_render_settings_changed(&mut self, changed_setting: RendererSettingsChanged) {
match changed_setting {
RendererSettingsChanged::TextGamma(..) | RendererSettingsChanged::TextContrast(..) => {
self.skia_renderer.resize();
self.font_changed_last_frame = true;
}
_ => {}
}
}

pub fn handle_title_changed(&mut self, new_title: String) {
self.title = new_title;
self.skia_renderer.window().set_title(&self.title);
Expand Down Expand Up @@ -399,6 +412,9 @@ impl WinitWindowWrapper {
Event::UserEvent(UserEvent::SettingsChanged(SettingsChanged::Window(e))) => {
self.handle_window_settings_changed(e);
}
Event::UserEvent(UserEvent::SettingsChanged(SettingsChanged::Renderer(e))) => {
self.handle_render_settings_changed(e);
}
Event::UserEvent(UserEvent::ConfigsChanged(config)) => {
self.handle_config_changed(*config);
}
Expand Down
30 changes: 28 additions & 2 deletions website/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ as such it's also documented in `:h guifont`. But to sum it up and also add Neov
- alias
- `#h-X` (available since 0.10.2) - Sets level of glyph outline adjustment, while `X` is
a type of hinting:
- full (default)
- full
- normal
- slight
- none
- none (default)
- Some examples:
- `Hack,Noto_Color_Emoji:h12:b` — Hack at size 12 in bold, with Noto Color Emoji as fallback
should Hack fail to contain any glyph.
Expand Down Expand Up @@ -119,6 +119,32 @@ this][scale-runtime] for a nice recipe to bind this to a hotkey.

[scale-runtime]: faq.md#how-can-i-dynamically-change-the-scale-at-runtime

#### Text Gamma and Contrast

VimScript:

```vim
let g:neovide_text_gamma = 0.0
let g:neovide_text_contrast = 0.5
```

Lua:

```lua
vim.g.neovide_text_gamma = 0.0
vim.g.neovide_text_contrast = 0.5
```

**Unreleased yet.**

You can fine tune the gamma and contrast of the text to your liking. The defaults is a good
compromise that gives readable text on all backgrounds and an accurate color representation. But if
that doesn't suit you, and you want to emulate the Alacritty font rendering for example you can use
a gamma of 0.8 and a contrast of 0.1.

Note a gamma of 0.0, means standard sRGB gamma or 2.2. Also note that these settings don't
necessarily apply immediately due to caching of the fonts.

#### Padding

VimScript:
Expand Down

0 comments on commit 866e3c2

Please sign in to comment.