Skip to content

Commit 6a4fee4

Browse files
committed
refactor(adapter): extract image_area from image_show
Exposing `image_area` separately allows future Lua integration to handle image placement more flexibly, without needing to invoke full rendering. This change promotes modularity and simplifies obtaining image dimensions alone. This refactor provides the foundation for feature PR sxyazi#1897, preparing for easier integration.
1 parent fd8871d commit 6a4fee4

File tree

8 files changed

+67
-30
lines changed

8 files changed

+67
-30
lines changed

yazi-adapter/src/adapter.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ratatui::layout::Rect;
55
use tracing::warn;
66
use yazi_shared::env_exists;
77

8-
use super::{Iip, Kgp, KgpOld};
8+
use super::{Iip, Image, Kgp, KgpOld};
99
use crate::{Chafa, Emulator, SHOWN, Sixel, TMUX, Ueberzug, WSL};
1010

1111
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -36,6 +36,20 @@ impl Display for Adapter {
3636
}
3737

3838
impl Adapter {
39+
pub async fn image_area(self, path: &Path, max: Rect) -> Result<Rect> {
40+
if max.is_empty() {
41+
return Ok(Rect::default());
42+
}
43+
44+
match self {
45+
Self::Kgp | Self::KgpOld | Self::Iip | Self::Sixel => {
46+
Image::image_area(path, max).await.map(|(_img, area)| area)
47+
}
48+
Self::X11 | Self::Wayland => Ueberzug::image_area(path, max).await,
49+
Self::Chafa => Chafa::image_area(path, max).await,
50+
}
51+
}
52+
3953
pub async fn image_show(self, path: &Path, max: Rect) -> Result<Rect> {
4054
if max.is_empty() {
4155
return Ok(Rect::default());

yazi-adapter/src/chafa.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ use crate::{Adapter, Emulator};
1111
pub(super) struct Chafa;
1212

1313
impl Chafa {
14-
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
14+
async fn symbol_bytes_with<F: Fn((Vec<&[u8]>, Rect)) -> Result<Rect>>(
15+
path: &Path,
16+
max: Rect,
17+
cb: F,
18+
) -> Result<Rect> {
1519
let output = Command::new("chafa")
1620
.args([
1721
"-f",
@@ -52,16 +56,26 @@ impl Chafa {
5256
width: first.width() as u16,
5357
height: lines.len() as u16,
5458
};
59+
cb((lines, area))
60+
}
5561

56-
Adapter::Chafa.image_hide()?;
57-
Adapter::shown_store(area);
58-
Emulator::move_lock((max.x, max.y), |stderr| {
59-
for (i, line) in lines.into_iter().enumerate() {
60-
stderr.write_all(line)?;
61-
queue!(stderr, MoveTo(max.x, max.y + i as u16 + 1))?;
62-
}
63-
Ok(area)
62+
pub(super) async fn image_area(path: &Path, max: Rect) -> Result<Rect> {
63+
Self::symbol_bytes_with(path, max, |(_, area)| Ok(area)).await
64+
}
65+
66+
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
67+
Self::symbol_bytes_with(path, max, |(lines, area)| {
68+
Adapter::Chafa.image_hide()?;
69+
Adapter::shown_store(area);
70+
Emulator::move_lock((max.x, max.y), |stderr| {
71+
for (i, line) in lines.into_iter().enumerate() {
72+
stderr.write_all(line)?;
73+
queue!(stderr, MoveTo(max.x, max.y + i as u16 + 1))?;
74+
}
75+
Ok(area)
76+
})
6477
})
78+
.await
6579
}
6680

6781
pub(super) fn image_erase(area: Rect) -> Result<()> {

yazi-adapter/src/iip.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ pub(super) struct Iip;
1414

1515
impl Iip {
1616
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
17-
let img = Image::downscale(path, max).await?;
18-
let area = Image::pixel_area((img.width(), img.height()), max);
17+
let (img, area) = Image::image_area(path, max).await?;
1918
let b = Self::encode(img).await?;
2019

2120
Adapter::Iip.image_hide()?;

yazi-adapter/src/image.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ impl Image {
8484
.unwrap_or(rect)
8585
}
8686

87+
#[inline]
88+
pub(super) async fn image_area(path: &Path, max: Rect) -> Result<(DynamicImage, Rect)> {
89+
let img = Self::downscale(path, max).await?;
90+
let area = Self::pixel_area((img.width(), img.height()), max);
91+
Ok((img, area))
92+
}
93+
8794
#[inline]
8895
fn filter() -> FilterType {
8996
match PREVIEW.image_filter.as_str() {

yazi-adapter/src/kgp.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,7 @@ pub(super) struct Kgp;
314314

315315
impl Kgp {
316316
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
317-
let img = Image::downscale(path, max).await?;
318-
let area = Image::pixel_area((img.width(), img.height()), max);
317+
let (img, area) = Image::image_area(path, max).await?;
319318

320319
let b1 = Self::encode(img).await?;
321320
let b2 = Self::place(&area)?;

yazi-adapter/src/kgp_old.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ pub(super) struct KgpOld;
1313

1414
impl KgpOld {
1515
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
16-
let img = Image::downscale(path, max).await?;
17-
let area = Image::pixel_area((img.width(), img.height()), max);
16+
let (img, area) = Image::image_area(path, max).await?;
1817
let b = Self::encode(img).await?;
1918

2019
Adapter::KgpOld.image_hide()?;

yazi-adapter/src/sixel.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ pub(super) struct Sixel;
1313

1414
impl Sixel {
1515
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
16-
let img = Image::downscale(path, max).await?;
17-
let area = Image::pixel_area((img.width(), img.height()), max);
16+
let (img, area) = Image::image_area(path, max).await?;
1817
let b = Self::encode(img).await?;
1918

2019
Adapter::Sixel.image_hide()?;

yazi-adapter/src/ueberzug.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,29 @@ impl Ueberzug {
4141
DEMON.init(Some(tx))
4242
}
4343

44+
pub(super) async fn image_area(path: &Path, max: Rect) -> Result<Rect> {
45+
let p = path.to_owned();
46+
let ImageSize { width: w, height: h } =
47+
tokio::task::spawn_blocking(move || imagesize::size(p)).await??;
48+
49+
Ok(
50+
Dimension::ratio()
51+
.map(|(r1, r2)| Rect {
52+
x: max.x,
53+
y: max.y,
54+
width: max.width.min((w.min(PREVIEW.max_width as _) as f64 / r1).ceil() as _),
55+
height: max.height.min((h.min(PREVIEW.max_height as _) as f64 / r2).ceil() as _),
56+
})
57+
.unwrap_or(max),
58+
)
59+
}
60+
4461
pub(super) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
4562
let Some(tx) = &*DEMON else {
4663
bail!("uninitialized ueberzugpp");
4764
};
4865

49-
let p = path.to_owned();
50-
let ImageSize { width: w, height: h } =
51-
tokio::task::spawn_blocking(move || imagesize::size(p)).await??;
52-
53-
let area = Dimension::ratio()
54-
.map(|(r1, r2)| Rect {
55-
x: max.x,
56-
y: max.y,
57-
width: max.width.min((w.min(PREVIEW.max_width as _) as f64 / r1).ceil() as _),
58-
height: max.height.min((h.min(PREVIEW.max_height as _) as f64 / r2).ceil() as _),
59-
})
60-
.unwrap_or(max);
66+
let area = Self::image_area(path, max).await?;
6167

6268
tx.send(Some((path.to_owned(), area)))?;
6369
Adapter::shown_store(area);

0 commit comments

Comments
 (0)