hdim_render/view.rs
1//! Viewport definition and calculation logic.
2//!
3//! This module defines the [View] struct, which maps a source image region
4//! to a target terminal area, handling coordinate mapping and scaling calculations.
5
6/// Defines the mapping between a rectangular area of the source image
7/// and the target rendering area in the terminal.
8///
9/// The `View` struct is used to determine which pixels from the source image
10/// correspond to which character cells in the terminal output.
11#[derive(Debug, Clone, Copy)]
12pub struct View {
13 /// The top-left X coordinate of the view on the source image (in pixels).
14 pub source_x: u32,
15 /// The top-left Y coordinate of the view on the source image (in pixels).
16 pub source_y: u32,
17 /// The width of the view on the source image (in pixels).
18 pub source_width: u32,
19 /// The height of the view on the source image (in pixels).
20 pub source_height: u32,
21 /// The width of the target render area (in terminal columns).
22 pub target_width: u32,
23 /// The height of the target render area (in terminal rows).
24 pub target_height: u32,
25}
26
27impl View {
28 /// Calculates the scaling ratios between source and target dimensions.
29 ///
30 /// # Returns
31 ///
32 /// A tuple `(x_ratio, y_ratio)` representing source pixels per terminal cell.
33 pub fn calculate_scaling(&self) -> (f32, f32) {
34 let x_ratio = self.source_width as f32 / self.target_width as f32;
35 let y_ratio = self.source_height as f32 / self.target_height as f32;
36 (x_ratio, y_ratio)
37 }
38
39 /// Maps a terminal cell coordinate (x, y) to the corresponding source image coordinates.
40 ///
41 /// # Arguments
42 ///
43 /// * `x` - The terminal column index.
44 /// * `y` - The terminal row index.
45 /// * `x_ratio` - Source pixels per column.
46 /// * `y_ratio` - Source pixels per row.
47 ///
48 /// # Returns
49 ///
50 /// A tuple `(source_x, source_y_top, source_y_bottom)` representing the starting
51 /// pixel coordinates for the top and bottom halves of the character block.
52 pub fn map_to_source(&self, x: u32, y: u32, x_ratio: f32, y_ratio: f32) -> (u32, u32, u32) {
53 let source_pixel_x = self.source_x + (x as f32 * x_ratio) as u32;
54 let source_pixel_y_top = self.source_y + (y as f32 * y_ratio) as u32;
55 let source_pixel_y_bottom = source_pixel_y_top + (y_ratio / 2.0).round().max(1.0) as u32;
56 (source_pixel_x, source_pixel_y_top, source_pixel_y_bottom)
57 }
58
59 /// Calculates the block dimensions for averaging colors.
60 ///
61 /// # Arguments
62 ///
63 /// * `x_ratio` - Source pixels per column.
64 /// * `y_ratio` - Source pixels per row.
65 ///
66 /// # Returns
67 ///
68 /// A tuple `(block_width, block_height)` representing the size of the pixel block
69 /// to sample for each half-character.
70 pub fn calculate_block_size(&self, x_ratio: f32, y_ratio: f32) -> (u32, u32) {
71 let block_width = x_ratio.round().max(1.0) as u32;
72 let block_height = (y_ratio / 2.0).round().max(1.0) as u32;
73 (block_width, block_height)
74 }
75}