HatchLing-TuneBox / sizes.py
taellinglin's picture
Enhanced choreography, screen and device sizes, orientation, key and piano roll positions
3ba3768 verified
Raw History Blame Contribute Delete
3.54 kB
"""Sheet sizes: paper in millimetres, and common screen, phone, tablet and projector resolutions in pixels.
A screen size keeps its exact shape (aspect ratio) but is drawn on a sheet whose long side is SCREEN_LONG_MM, so line weights and lettering
look the same as on paper; its SVG is then given the real pixel size as its width and height, so it shows at 1:1 on that screen.
"""
SCREEN_LONG_MM = 297.0
# key -> (label, width, height) in millimetres; as the thing is held: portrait for paper
PAPERS = {
'a5': ('A5 (148 x 210 mm)', 148.0, 210.0),
'a4': ('A4 (210 x 297 mm)', 210.0, 297.0),
'a3': ('A3 (297 x 420 mm)', 297.0, 420.0),
'a2': ('A2 (420 x 594 mm)', 420.0, 594.0),
'a1': ('A1 (594 x 841 mm)', 594.0, 841.0),
'letter': ('US Letter (8.5 x 11 in)', 215.9, 279.4),
'tabloid': ('US Tabloid (11 x 17 in)', 279.4, 431.8),
}
# key -> (label, width, height) in pixels, in the shape the device is usually used in
SCREENS = {
'phone-ios': ('Phone: iPhone 15 / 16 (1179 x 2556)', 1179, 2556),
'phone-ios-max': ('Phone: iPhone Pro Max (1290 x 2796)', 1290, 2796),
'phone-android': ('Phone: Android FHD+ (1080 x 2400)', 1080, 2400),
'phone-android-qhd': ('Phone: Android QHD+ (1440 x 3200)', 1440, 3200),
'tablet-ipad': ('Tablet: iPad 10.9 in (1640 x 2360)', 1640, 2360),
'tablet-ipad-pro': ('Tablet: iPad Pro 12.9 in (2048 x 2732)', 2048, 2732),
'tablet-android': ('Tablet: Android (1200 x 1920)', 1200, 1920),
'laptop-768': ('Laptop: 1366 x 768', 1366, 768),
'laptop-mba': ('Laptop: MacBook Air 13 in (2560 x 1664)', 2560, 1664),
'laptop-mbp': ('Laptop: MacBook Pro 14 in (3024 x 1964)', 3024, 1964),
'hd': ('Screen: HD 720p (1280 x 720)', 1280, 720),
'fhd': ('Screen: Full HD 1080p (1920 x 1080)', 1920, 1080),
'wuxga': ('Screen: WUXGA (1920 x 1200)', 1920, 1200),
'qhd': ('Screen: QHD 1440p (2560 x 1440)', 2560, 1440),
'uwqhd': ('Screen: Ultrawide 21:9 (3440 x 1440)', 3440, 1440),
'uhd': ('Screen: 4K UHD (3840 x 2160)', 3840, 2160),
'uhd8k': ('Screen: 8K UHD (7680 x 4320)', 7680, 4320),
'proj-xga': ('Projector: XGA 4:3 (1024 x 768)', 1024, 768),
'proj-wxga': ('Projector: WXGA 16:10 (1280 x 800)', 1280, 800),
'proj-1080': ('Projector: 1080p 16:9 (1920 x 1080)', 1920, 1080),
'proj-4k': ('Projector: DCI 4K cinema (4096 x 2160)', 4096, 2160),
'social-square': ('Social: square post (1080 x 1080)', 1080, 1080),
'social-story': ('Social: story / reel (1080 x 1920)', 1080, 1920),
}
CHOICES = [(v[0], k) for k, v in PAPERS.items()] + [(v[0], k) for k, v in SCREENS.items()]
ORIENTATIONS = ['auto', 'portrait', 'landscape']
def is_screen(key: str) -> bool:
return key in SCREENS
def _oriented(w, h, orientation):
if orientation == 'portrait': return (min(w, h), max(w, h))
if orientation == 'landscape': return (max(w, h), min(w, h))
return (w, h)
def size_mm(key: str, orientation: str = 'auto') -> tuple:
"""-> (width, height) of the sheet in millimetres. 'auto' keeps the shape the paper or device is usually held in."""
if key in SCREENS:
_, w, h = SCREENS[key]; s = SCREEN_LONG_MM / max(w, h)
return _oriented(w * s, h * s, orientation)
_, w, h = PAPERS.get(key, PAPERS['a4'])
return _oriented(w, h, orientation)
def size_px(key: str, orientation: str = 'auto'):
"""-> (width, height) in pixels for a screen size, or None for paper."""
if key not in SCREENS: return None
_, w, h = SCREENS[key]
return _oriented(w, h, orientation)