mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-13 02:26:37 +00:00
fix(display): size the preview after orientation and pixel mappers
display_geometry.physical_size claimed to give DisplayManager's answer but only computed cols*chain x rows*parallel. RGBMatrix.width/height are measured after the library's pixel mappers, so a Rotate:90 / orientation 90 chain previewed 128x32 for a 32x128 panel and a U-mapper chain of four 256x32 for 128x64. Model the built-in mappers' size effect as the pinned lib/pixel-mapper.cc does (Rotate, U-mapper, V-mapper, StackToRow, Remap; Mirror and unknown names leave it alone), and move the orientation composition here so DisplayManager and the preview share it. The module docstring no longer claims the sync handshake uses it; that imports only DEFAULT_CHAIN_LENGTH. Audit finding F18. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -142,3 +142,54 @@ def test_preview_callers_do_not_rederive_the_size():
|
||||
assert "get('chain_length', 1)" not in source, rel
|
||||
assert 'get("chain_length", 1)' not in source, rel
|
||||
assert 'cols * chain_length' not in source, rel
|
||||
|
||||
|
||||
# --- Pixel mappers ----------------------------------------------------------
|
||||
# RGBMatrix.width/height are measured after the library's pixel mappers
|
||||
# (lib/pixel-mapper.cc), so the preview has to apply them too. This used to
|
||||
# report 128x32 for a Rotate:90 chain the panel drew at 32x128.
|
||||
|
||||
@pytest.mark.parametrize('hardware,expected', [
|
||||
({'pixel_mapper_config': 'Rotate:90'}, (32, 128)),
|
||||
({'pixel_mapper_config': 'Rotate:270'}, (32, 128)),
|
||||
({'pixel_mapper_config': 'Rotate:-90'}, (32, 128)),
|
||||
({'pixel_mapper_config': 'Rotate:180'}, (128, 32)),
|
||||
({'orientation': '90'}, (32, 128)),
|
||||
({'orientation': '270'}, (32, 128)),
|
||||
({'orientation': '180'}, (128, 32)),
|
||||
# Two quarter turns cancel out.
|
||||
({'pixel_mapper_config': 'Rotate:90', 'orientation': '270'}, (128, 32)),
|
||||
# U-mapper folds a chain of 4 into two rows: (256 / 64) * 32 by 2 * 32.
|
||||
({'chain_length': 4, 'pixel_mapper_config': 'U-mapper'}, (128, 64)),
|
||||
({'chain_length': 4, 'pixel_mapper_config': 'u-mapper;Rotate:90'}, (64, 128)),
|
||||
# U-mapper needs an even chain of at least 2, or the library skips it.
|
||||
({'chain_length': 3, 'pixel_mapper_config': 'U-mapper'}, (192, 32)),
|
||||
({'cols': 32, 'chain_length': 4, 'pixel_mapper_config': 'V-mapper'}, (32, 128)),
|
||||
({'chain_length': 1, 'parallel': 2, 'pixel_mapper_config': 'StackToRow:Z'}, (128, 32)),
|
||||
({'pixel_mapper_config': 'Remap:64,64|0,0n|0,32n'}, (64, 64)),
|
||||
# A Remap panel entirely outside the visible area: the library skips it.
|
||||
({'pixel_mapper_config': 'Remap:64,64|0,0n|0,99n'}, (128, 32)),
|
||||
({'pixel_mapper_config': 'Mirror:H'}, (128, 32)),
|
||||
# Unknown or unusable mappers are skipped by the library.
|
||||
({'pixel_mapper_config': 'Bogus;Rotate:45;Rotate:ninety'}, (128, 32)),
|
||||
])
|
||||
def test_pixel_mappers_change_the_size_as_the_library_does(hardware, expected):
|
||||
hw = {'rows': 32, 'cols': 64, 'chain_length': 2, 'parallel': 1}
|
||||
hw.update(hardware)
|
||||
assert physical_size(_config(hw)) == expected
|
||||
assert logical_size(_config(hw)) == expected
|
||||
|
||||
|
||||
def test_double_sided_splits_the_mapped_size():
|
||||
cfg = _config({'rows': 32, 'cols': 64, 'chain_length': 2, 'parallel': 1, 'orientation': '90'},
|
||||
{'enabled': True, 'copies': 2, 'axis': 'vertical'})
|
||||
assert logical_size(cfg) == (32, 64)
|
||||
|
||||
|
||||
def test_display_manager_composes_the_mapper_config_it_sizes_from():
|
||||
from src.display_geometry import compose_pixel_mapper_config
|
||||
assert compose_pixel_mapper_config({}) == ''
|
||||
assert compose_pixel_mapper_config({'orientation': '90'}) == 'Rotate:90'
|
||||
assert compose_pixel_mapper_config(
|
||||
{'pixel_mapper_config': ' U-mapper ', 'orientation': '180'}) == 'U-mapper;Rotate:180'
|
||||
assert compose_pixel_mapper_config({'orientation': 'sideways'}) == ''
|
||||
|
||||
Reference in New Issue
Block a user