Skip to content

Conversation

@Kezii
Copy link

@Kezii Kezii commented Jan 3, 2026

Add support for non-square pixels, using fractional numbers

for example, the display I'm working rn has a 2:3 pixel aspect ratio, this makes the simulator realistic to the device

@rfuest
Copy link
Member

rfuest commented Jan 4, 2026

Thanks for the PR. This is a useful addition, but I would like to change the way it is implemented.

If this setting is named pixel aspect ratio I would expect pixel_aspect_ratio(2, 1) and pixel_aspect_ratio(4, 2) to behave the same. An alternative would be to add a pub fn scale_non_square(mut self, scale: Size) -> Self method to the output settings builder and change the type of OutputSettings::scale to Size. This should have the same functionality without having two interacting settings that determine the output pixel size.

@Kezii Kezii force-pushed the master branch 2 times, most recently from d42ebfd to c513b3a Compare January 26, 2026 14:41
@Kezii
Copy link
Author

Kezii commented Jan 26, 2026

Hello,
I edited the code as requested

Copy link
Member

@rfuest rfuest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's better. Some of the code can be simplified by using the component wise methods that Point and Size implement.

src/display.rs Outdated
Comment on lines 105 to 113
let width = self.size.width.saturating_mul(output_settings.scale.width)
+ self.size.width.saturating_sub(1) * output_settings.pixel_spacing;
let height = self
.size
.height
.saturating_mul(output_settings.scale.height)
+ self.size.height.saturating_sub(1) * output_settings.pixel_spacing;

Size::new(width, height)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified by using Size::component_mul:

Suggested change
let width = self.size.width.saturating_mul(output_settings.scale.width)
+ self.size.width.saturating_sub(1) * output_settings.pixel_spacing;
let height = self
.size
.height
.saturating_mul(output_settings.scale.height)
+ self.size.height.saturating_sub(1) * output_settings.pixel_spacing;
Size::new(width, height)
self.size.component_mul(output_settings.scale)
+ self.size.saturating_sub(Size::new_equal(1)) * output_settings.pixel_spacing

.unwrap();

if output_settings.scale == 1 {
if output_settings.scale == Size::new(1, 1) && output_settings.pixel_spacing == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

Comment on lines 81 to 82
let pitch_x = (output_settings.scale.width + output_settings.pixel_spacing) as i32;
let pitch_y = (output_settings.scale.height + output_settings.pixel_spacing) as i32;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've added a getter for the pitch:

Suggested change
let pitch_x = (output_settings.scale.width + output_settings.pixel_spacing) as i32;
let pitch_y = (output_settings.scale.height + output_settings.pixel_spacing) as i32;
let pitch = output_settings.pixel_pitch();

self.fill_solid(
&Rectangle::new(p * pixel_pitch + position, pixel_size),
&Rectangle::new(
Point::new(p.x * pitch_x, p.y * pitch_y) + position,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Point::new(p.x * pitch_x, p.y * pitch_y) + position,
p.component_mul(pitch) + position,

Comment on lines 100 to 106
/// Sets the pixel scale to a non-square value. This is useful for displaying
/// non-square pixels.
///
/// # Panics
///
/// Panics if `width` or `height` is `0`.
pub fn scale_non_square(mut self, width: u32, height: u32) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In embedded-graphics related crates it's preferred to take a Size argument instead of separate width and height. The doc comment should start with a single sentence.

Suggested change
/// Sets the pixel scale to a non-square value. This is useful for displaying
/// non-square pixels.
///
/// # Panics
///
/// Panics if `width` or `height` is `0`.
pub fn scale_non_square(mut self, width: u32, height: u32) -> Self {
/// Sets a non-square pixel scale.
///
/// This is useful for simulating a display with a non-square pixel aspect ratio.
///
/// # Panics
///
/// Panics if `width` or `height` is `0`.
pub fn scale_non_square(mut self, scale: Size) -> Self {

Comment on lines 100 to 106
/// Sets the pixel scale to a non-square value. This is useful for displaying
/// non-square pixels.
///
/// # Panics
///
/// Panics if `width` or `height` is `0`.
pub fn scale_non_square(mut self, width: u32, height: u32) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this function up to be directly below scale.

Comment on lines 9 to 16
### Added

- Added support for non-square pixels

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Added
- Added support for non-square pixels
### Added
- **(breaking)** [#71](https://github.com/embedded-graphics/simulator/pull/71) Added support for non-square pixels.
### Fixed
- [#71](https://github.com/embedded-graphics/simulator/pull/71) Fixed pixel spacing for unscaled outputs.

@Kezii
Copy link
Author

Kezii commented Jan 28, 2026

Hello,
Thank you for your answer

I applied the required changes

Copy link
Member

@rfuest rfuest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately CI isn't happy with one of the suggestions I made.

pub theme: BinaryColorTheme,
}

#[cfg(feature = "with-sdl")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribute causes the build without the with-sdl flag to fail, because pixel_pitch is now used with and without SDL support enabled. I would suggest to just remove the cfg attribute, and instead add an #[allow(unused)] attribute to output_to_display method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants