fix(13e6): pre-rotate LANDSCAPE diagram for CCW-to-landscape rotation
The user rotates the frame 90° CCW into landscape (not CW as the previous comment block assumed), so the LANDSCAPE orientation diagram needs to be pre-rotated the opposite direction to land upright. - Previous: ribbon on bottom edge, LEFT arrow, label rotated 90° CCW on the diagram's left side (matched CW user rotation; rendered upside- down once the user actually rotates CCW into landscape). - Now: ribbon on top edge, RIGHT arrow, label rotated 90° CW down the diagram's right side. After the user's 90° CCW rotation it lands as wide rect, ribbon-left, up-arrow — correct upright landscape. Adds right_arrow() helper as the mirror of left_arrow(). Regenerated all three setup-screen .bins. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 248 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 248 KiB |
+30
-20
@@ -281,6 +281,15 @@ def left_arrow(draw, cx, cy, half_h=18, w=34, color=BK):
|
|||||||
], fill=color)
|
], fill=color)
|
||||||
|
|
||||||
|
|
||||||
|
def right_arrow(draw, cx, cy, half_h=18, w=34, color=BK):
|
||||||
|
"""Solid filled triangle pointing right, centered on (cx, cy)."""
|
||||||
|
draw.polygon([
|
||||||
|
(cx + w // 2, cy),
|
||||||
|
(cx - w // 2, cy - half_h),
|
||||||
|
(cx - w // 2, cy + half_h),
|
||||||
|
], fill=color)
|
||||||
|
|
||||||
|
|
||||||
def paste_rotated_text(img, text, font, fill, anchor_xy, ccw_degrees=90):
|
def paste_rotated_text(img, text, font, fill, anchor_xy, ccw_degrees=90):
|
||||||
"""
|
"""
|
||||||
Render `text` horizontally onto a transparent overlay, rotate ccw, and
|
Render `text` horizontally onto a transparent overlay, rotate ccw, and
|
||||||
@@ -304,17 +313,17 @@ def orientation_diagrams(img, cx, top_y, label_color=None, compact=False):
|
|||||||
|
|
||||||
PORTRAIT = upright tall rect, ribbon along the bottom short edge,
|
PORTRAIT = upright tall rect, ribbon along the bottom short edge,
|
||||||
up-arrow inside.
|
up-arrow inside.
|
||||||
LANDSCAPE = pre-rotated 90° CCW from upright landscape. The frame
|
LANDSCAPE = pre-rotated 90° CW from upright landscape. The frame
|
||||||
rotation portrait→landscape is 90° CW (ribbon moves
|
rotation portrait→landscape is 90° CCW (ribbon moves
|
||||||
bottom→left as viewed by the user); the CCW pre-rotation
|
top→left as viewed by the user); the CW pre-rotation
|
||||||
cancels that, so when the user picks the frame up and
|
cancels that, so when the user picks the frame up and
|
||||||
rotates it 90° CW into landscape the diagram lands
|
rotates it 90° CCW into landscape the diagram lands
|
||||||
upright (wide rect, ribbon-left, up-arrow).
|
upright (wide rect, ribbon-left, up-arrow).
|
||||||
In the portrait rendering that means: tall rect, ribbon
|
In the portrait rendering that means: tall rect, ribbon
|
||||||
along bottom edge (was the LEFT edge upright), LEFT-
|
along TOP edge (was the LEFT edge upright), RIGHT-
|
||||||
pointing arrow (was UP upright), and the "LANDSCAPE"
|
pointing arrow (was UP upright), and the "LANDSCAPE"
|
||||||
label rotated 90° CCW so it runs up the long edge —
|
label rotated 90° CW so it runs DOWN the right long edge
|
||||||
reads horizontally once the frame is mounted landscape.
|
— reads horizontally once the frame is mounted landscape.
|
||||||
"""
|
"""
|
||||||
if label_color is None:
|
if label_color is None:
|
||||||
label_color = BK
|
label_color = BK
|
||||||
@@ -355,28 +364,29 @@ def orientation_diagrams(img, cx, top_y, label_color=None, compact=False):
|
|||||||
pt_y + (diag_h - ribbon_thick) // 2)
|
pt_y + (diag_h - ribbon_thick) // 2)
|
||||||
text_center(draw, pt_x + diag_w // 2, diag_bottom + 14, "PORTRAIT", F_TINY, BK)
|
text_center(draw, pt_x + diag_w // 2, diag_bottom + 14, "PORTRAIT", F_TINY, BK)
|
||||||
|
|
||||||
# LANDSCAPE — pre-rotated 90° CCW from upright.
|
# LANDSCAPE — pre-rotated 90° CW from upright (the user rotates 90° CCW
|
||||||
|
# into landscape; the CW pre-rotation cancels that so it lands upright).
|
||||||
# Upright landscape: wide rect, ribbon along LEFT long edge, UP arrow.
|
# Upright landscape: wide rect, ribbon along LEFT long edge, UP arrow.
|
||||||
# After 90° CCW (in portrait rendering): tall rect, ribbon along BOTTOM
|
# After 90° CW (in portrait rendering): tall rect, ribbon along TOP
|
||||||
# short edge, LEFT-pointing arrow. Label runs up the LEFT long edge,
|
# short edge, RIGHT-pointing arrow. Label runs DOWN the RIGHT long edge,
|
||||||
# rotated 90° CCW so it reads L→R once the frame is rotated to landscape.
|
# rotated 90° CW so it reads L→R once the frame is rotated to landscape.
|
||||||
draw.rectangle([ls_x, ls_y, ls_x + diag_w - 1, ls_y + diag_h - 1],
|
draw.rectangle([ls_x, ls_y, ls_x + diag_w - 1, ls_y + diag_h - 1],
|
||||||
outline=BK, width=3)
|
outline=BK, width=3)
|
||||||
draw.rectangle([ls_x, ls_y + diag_h - ribbon_thick,
|
draw.rectangle([ls_x, ls_y,
|
||||||
ls_x + diag_w - 1, ls_y + diag_h - 1], fill=BK)
|
ls_x + diag_w - 1, ls_y + ribbon_thick - 1], fill=BK)
|
||||||
left_arrow(draw, ls_x + diag_w // 2,
|
right_arrow(draw, ls_x + diag_w // 2,
|
||||||
ls_y + (diag_h - ribbon_thick) // 2)
|
ls_y + ribbon_thick + (diag_h - ribbon_thick) // 2)
|
||||||
# Rotated label, anchored just left of the diagram's left long edge.
|
# Rotated label, anchored just right of the diagram's right long edge.
|
||||||
label_text = "LANDSCAPE"
|
label_text = "LANDSCAPE"
|
||||||
bb = F_TINY.getbbox(label_text)
|
bb = F_TINY.getbbox(label_text)
|
||||||
label_w = bb[2] - bb[0]
|
label_w = bb[2] - bb[0]
|
||||||
label_h = bb[3] - bb[1]
|
label_h = bb[3] - bb[1]
|
||||||
# Rotated label is `label_w` tall, `label_h` wide. Centred vertically
|
# Rotated 90° CW: label is `label_w` tall, `label_h` wide. Centred
|
||||||
# against the rect, sitting just to its left.
|
# vertically against the rect, sitting just to its right.
|
||||||
rotated_x = ls_x - label_h - 16
|
rotated_x = ls_x + diag_w + 16
|
||||||
rotated_y = ls_y + (diag_h - label_w) // 2
|
rotated_y = ls_y + (diag_h - label_w) // 2
|
||||||
paste_rotated_text(img, label_text, F_TINY, BK, (rotated_x, rotated_y),
|
paste_rotated_text(img, label_text, F_TINY, BK, (rotated_x, rotated_y),
|
||||||
ccw_degrees=90)
|
ccw_degrees=-90)
|
||||||
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user