mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 05:42:03 +03:00
background: use Dimension for background size
This commit is contained in:
parent
040cd19f88
commit
1360e13f24
@ -1,4 +1,4 @@
|
||||
use crate::{default_one_point_oh, Config, Dimension, HsbTransform, RgbaColor};
|
||||
use crate::{default_one_point_oh, Config, Dimension, HsbTransform, PixelUnit, RgbaColor};
|
||||
use luahelper::impl_lua_conversion_dynamic;
|
||||
use wezterm_dynamic::{FromDynamic, FromDynamicOptions, ToDynamic, Value};
|
||||
|
||||
@ -119,14 +119,14 @@ impl BackgroundLayer {
|
||||
repeat_y_size: None,
|
||||
vertical_align: Default::default(),
|
||||
horizontal_align: Default::default(),
|
||||
width: BackgroundSize::Percent(100),
|
||||
height: BackgroundSize::Percent(100),
|
||||
width: BackgroundSize::Dimension(Dimension::Percent(1.)),
|
||||
height: BackgroundSize::Dimension(Dimension::Percent(1.)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/background-size>
|
||||
#[derive(Debug, Copy, Clone, FromDynamic, ToDynamic)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum BackgroundSize {
|
||||
/// Scales image as large as possible without cropping or stretching.
|
||||
/// If the container is larger than the image, tiles the image unless
|
||||
@ -138,11 +138,45 @@ pub enum BackgroundSize {
|
||||
/// cropped.
|
||||
Cover,
|
||||
/// Stretches the image to the specified length in pixels
|
||||
Length(u32),
|
||||
/// Stretches the image to a percentage of the background size
|
||||
/// as determined by the `origin` property.
|
||||
Percent(u8),
|
||||
// FIXME: Dimension
|
||||
Dimension(Dimension),
|
||||
}
|
||||
|
||||
impl FromDynamic for BackgroundSize {
|
||||
fn from_dynamic(
|
||||
value: &Value,
|
||||
options: FromDynamicOptions,
|
||||
) -> Result<Self, wezterm_dynamic::Error> {
|
||||
match value {
|
||||
Value::String(label) => match label.as_str() {
|
||||
"Contain" => return Ok(Self::Contain),
|
||||
"Cover" => return Ok(Self::Cover),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
match PixelUnit::from_dynamic(value, options) {
|
||||
Ok(pix) => Ok(Self::Dimension(pix.into())),
|
||||
Err(_) => Err(wezterm_dynamic::Error::Message(format!(
|
||||
"expected either 'Contain', 'Cover', \
|
||||
a number, or a string of \
|
||||
the form '123px' where 'px' is a unit and \
|
||||
can be one of 'px', '%', 'pt' or 'cell', \
|
||||
but got {}",
|
||||
value.variant_name()
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDynamic for BackgroundSize {
|
||||
fn to_dynamic(&self) -> Value {
|
||||
let s = match self {
|
||||
Self::Cover => "Cover".to_string(),
|
||||
Self::Contain => "Contain".to_string(),
|
||||
Self::Dimension(d) => return d.to_dynamic(),
|
||||
};
|
||||
Value::String(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BackgroundSize {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::color::LinearRgba;
|
||||
use crate::termwindow::RenderState;
|
||||
use crate::utilsprites::RenderMetrics;
|
||||
use crate::Dimensions;
|
||||
use anyhow::Context;
|
||||
use config::{
|
||||
@ -82,7 +83,19 @@ pub struct LoadedBackgroundLayer {
|
||||
fn load_background_layer(
|
||||
layer: &BackgroundLayer,
|
||||
dimensions: &Dimensions,
|
||||
render_metrics: &RenderMetrics,
|
||||
) -> anyhow::Result<LoadedBackgroundLayer> {
|
||||
let h_context = DimensionContext {
|
||||
dpi: dimensions.dpi as f32,
|
||||
pixel_max: dimensions.pixel_width as f32,
|
||||
pixel_cell: render_metrics.cell_size.width as f32,
|
||||
};
|
||||
let v_context = DimensionContext {
|
||||
dpi: dimensions.dpi as f32,
|
||||
pixel_max: dimensions.pixel_height as f32,
|
||||
pixel_cell: render_metrics.cell_size.height as f32,
|
||||
};
|
||||
|
||||
let data = match &layer.source {
|
||||
BackgroundSource::Gradient(g) => {
|
||||
let grad = g
|
||||
@ -90,15 +103,13 @@ fn load_background_layer(
|
||||
.with_context(|| format!("building gradient {:?}", g))?;
|
||||
|
||||
let mut width = match layer.width {
|
||||
BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_width as u32) / 100,
|
||||
BackgroundSize::Length(u) => u as u32,
|
||||
BackgroundSize::Dimension(d) => d.evaluate_as_pixels(h_context),
|
||||
unsup => anyhow::bail!("{:?} not yet implemented", unsup),
|
||||
};
|
||||
} as u32;
|
||||
let mut height = match layer.height {
|
||||
BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_height as u32) / 100,
|
||||
BackgroundSize::Length(u) => u as u32,
|
||||
BackgroundSize::Dimension(d) => d.evaluate_as_pixels(v_context),
|
||||
unsup => anyhow::bail!("{:?} not yet implemented", unsup),
|
||||
};
|
||||
} as u32;
|
||||
|
||||
if matches!(g.orientation, GradientOrientation::Radial { .. }) {
|
||||
// To simplify the math, we compute a perfect circle
|
||||
@ -215,15 +226,13 @@ fn load_background_layer(
|
||||
// surface.
|
||||
// It's not ideal.
|
||||
let width = match layer.width {
|
||||
BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_width as u32) / 100,
|
||||
BackgroundSize::Length(u) => u as u32,
|
||||
BackgroundSize::Dimension(d) => d.evaluate_as_pixels(h_context),
|
||||
unsup => anyhow::bail!("{:?} not yet implemented", unsup),
|
||||
};
|
||||
} as u32;
|
||||
let height = match layer.height {
|
||||
BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_height as u32) / 100,
|
||||
BackgroundSize::Length(u) => u as u32,
|
||||
BackgroundSize::Dimension(d) => d.evaluate_as_pixels(v_context),
|
||||
unsup => anyhow::bail!("{:?} not yet implemented", unsup),
|
||||
};
|
||||
} as u32;
|
||||
|
||||
let size = width.min(height);
|
||||
|
||||
@ -252,11 +261,12 @@ fn load_background_layer(
|
||||
pub fn load_background_image(
|
||||
config: &ConfigHandle,
|
||||
dimensions: &Dimensions,
|
||||
render_metrics: &RenderMetrics,
|
||||
) -> Vec<LoadedBackgroundLayer> {
|
||||
let mut layers = vec![];
|
||||
for layer in &config.background {
|
||||
let load_start = std::time::Instant::now();
|
||||
match load_background_layer(layer, dimensions) {
|
||||
match load_background_layer(layer, dimensions, render_metrics) {
|
||||
Ok(layer) => {
|
||||
log::trace!("loaded layer in {:?}", load_start.elapsed());
|
||||
layers.push(layer);
|
||||
@ -273,6 +283,7 @@ pub fn reload_background_image(
|
||||
config: &ConfigHandle,
|
||||
existing: &[LoadedBackgroundLayer],
|
||||
dimensions: &Dimensions,
|
||||
render_metrics: &RenderMetrics,
|
||||
) -> Vec<LoadedBackgroundLayer> {
|
||||
// We want to reuse the existing version of the image where possible
|
||||
// so that the textures we may have cached can be re-used and so that
|
||||
@ -284,7 +295,7 @@ pub fn reload_background_image(
|
||||
|
||||
CachedImage::mark();
|
||||
|
||||
let result = load_background_image(config, dimensions)
|
||||
let result = load_background_image(config, dimensions, render_metrics)
|
||||
.into_iter()
|
||||
.map(|mut layer| {
|
||||
let hash = layer.source.hash();
|
||||
@ -395,15 +406,13 @@ impl crate::TermWindow {
|
||||
let width = match layer.def.width {
|
||||
BackgroundSize::Contain => max_aspect_width as f32,
|
||||
BackgroundSize::Cover => min_aspect_width as f32,
|
||||
BackgroundSize::Length(n) => n as f32,
|
||||
BackgroundSize::Percent(p) => (pixel_width * p as f32) / 100.,
|
||||
BackgroundSize::Dimension(n) => n.evaluate_as_pixels(h_context),
|
||||
};
|
||||
|
||||
let height = match layer.def.height {
|
||||
BackgroundSize::Contain => max_aspect_height as f32,
|
||||
BackgroundSize::Cover => min_aspect_height as f32,
|
||||
BackgroundSize::Length(n) => n as f32,
|
||||
BackgroundSize::Percent(p) => (pixel_height * p as f32) / 100.,
|
||||
BackgroundSize::Dimension(n) => n.evaluate_as_pixels(v_context),
|
||||
};
|
||||
let origin_x = pixel_width / -2.;
|
||||
let top_pixel = pixel_height / -2.;
|
||||
|
@ -597,7 +597,7 @@ impl TermWindow {
|
||||
dpi,
|
||||
};
|
||||
|
||||
let window_background = load_background_image(&config, &dimensions);
|
||||
let window_background = load_background_image(&config, &dimensions, &render_metrics);
|
||||
|
||||
log::trace!(
|
||||
"TermWindow::new_window called with mux_window_id {} {:?} {:?}",
|
||||
@ -1332,8 +1332,12 @@ impl TermWindow {
|
||||
self.config = config.clone();
|
||||
self.palette.take();
|
||||
|
||||
self.window_background =
|
||||
reload_background_image(&config, &self.window_background, &self.dimensions);
|
||||
self.window_background = reload_background_image(
|
||||
&config,
|
||||
&self.window_background,
|
||||
&self.dimensions,
|
||||
&self.render_metrics,
|
||||
);
|
||||
|
||||
let mux = Mux::get().unwrap();
|
||||
let window = match mux.get_window(self.mux_window_id) {
|
||||
|
Loading…
Reference in New Issue
Block a user