Improve fractional rendering by finding perfectly scalable size

This commit is contained in:
Jeremy Soller 2024-03-14 20:39:28 -06:00
parent bcc1ad8284
commit 2bfcfdf8b8
No known key found for this signature in database
GPG key ID: D02FD439211AF56F

View file

@ -318,28 +318,46 @@ where
let mut editor = self.editor.lock().unwrap();
let cosmic_theme = theme.cosmic();
let scrollbar_w = cosmic_theme.spacing.space_xxs as i32;
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32)
- self.padding.horizontal() as i32;
- self.padding.horizontal() as i32
- scrollbar_w;
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32)
- self.padding.vertical() as i32;
let scale_factor = style.scale_factor as f32;
let metrics = self.metrics.scale(scale_factor);
let image_w = (view_w as f32 * scale_factor) as i32;
let image_h = (view_h as f32 * scale_factor) as i32;
let calculate_image_scaled = |view: i32| -> (i32, f32) {
// Get smallest set of physical pixels that fit inside the logical pixels
let image = ((view as f32) * scale_factor).floor() as i32;
// Convert that back into logical pixels
let scaled = (image as f32) / scale_factor;
(image, scaled)
};
let calculate_ideal = |view_start: i32| -> (i32, f32) {
// Search for a perfect match within 16 pixels
for i in 0..16 {
let view = view_start - i;
let (image, scaled) = calculate_image_scaled(view);
if view == scaled as i32 {
return (image, scaled);
}
}
let (image, scaled) = calculate_image_scaled(view_start);
(image, scaled)
};
let cosmic_theme = theme.cosmic();
let scrollbar_w = (cosmic_theme.spacing.space_xxs as f32 * scale_factor) as i32;
let (image_w, scaled_w) = calculate_ideal(view_w);
let (image_h, scaled_h) = calculate_ideal(view_h);
if image_w <= scrollbar_w || image_h <= 0 {
if image_w <= 0 || image_h <= 0 {
// Zero sized image
return;
}
// Adjust image width by scrollbar width
let image_w = image_w - scrollbar_w;
// Lock font system (used throughout)
let mut font_system = font_system().write().unwrap();
@ -587,7 +605,7 @@ where
let rect = Rectangle::new(
[image_w as f32 / scale_factor, start_y as f32 / scale_factor].into(),
Size::new(
scrollbar_w as f32 / scale_factor,
scrollbar_w as f32,
(end_y as f32 - start_y as f32) / scale_factor,
),
);
@ -609,17 +627,16 @@ where
let image_position = layout.position() + [self.padding.left, self.padding.top].into();
if let Some(ref handle) = *handle_opt {
let image_size = image::Renderer::dimensions(renderer, handle);
let scaled_size = Size::new(scaled_w as f32, scaled_h as f32);
log::debug!(
"text_box image {:?} scaled {:?} position {:?}",
image_size, scaled_size, image_position
);
image::Renderer::draw(
renderer,
handle.clone(),
image::FilterMethod::Nearest,
Rectangle::new(
image_position,
Size::new(
image_size.width as f32 / scale_factor,
image_size.height as f32 / scale_factor,
),
),
Rectangle::new(image_position, scaled_size),
[0.0; 4],
);
}