Skip to content

Support arbitrary icon sources and per-device LCD geometry - #6

Open
nanderss wants to merge 3 commits into
okoker:mainfrom
nanderss:icon-scaling-lcd-geometry
Open

Support arbitrary icon sources and per-device LCD geometry#6
nanderss wants to merge 3 commits into
okoker:mainfrom
nanderss:icon-scaling-lcd-geometry

Conversation

@nanderss

Copy link
Copy Markdown

Two related limits meant button icons only really worked with square .icns files on the exact panel the render geometry was calibrated for.

Icons had to be square and ≤1024px

Sources larger than 1024px were rejected outright with image too large, and the draw rect was a fixed square, so anything not already square was stretched to fill it. Between them, the .png / .jpg support the README advertises didn't really hold up.

Oversized sources are now downscaled while decoding via CGImageSourceCreateThumbnailAtIndex, which also resamples in one step and picks the best-matching representation inside a multi-size .icns — so it costs less than the full-size decode it replaces, not more. Non-square images are fitted and centered, with the unused axis left black to match the LCD background.

Verified with a 3000x1200 source: previously rejected and the key left blank, now scaled and letterboxed correctly on the hardware.

The render geometry is not the same on every clone

size, shiftX and shiftY were constants, commented as empirically calibrated to center on the physical LCD. That calibration is per-panel. On an AJAZZ AKP03 the 85x85 render is cropped by the panel, and because the offsets are asymmetric it's cropped unevenly — icons keep their rounded corners on two sides and have them sliced flat on the other two. That's a confusing symptom, because it reads as a rendering artifact rather than clipping.

That model wants 72x72 with no offset, which is also what this README describes the LCD keys as.

Swapping one hardcoded calibration for another would just break the N3 the same way, so this moves the three values into an optional lcd config section. Defaults are unchanged, so existing setups keep the current behaviour without touching their config:

"lcd": { "size": 72, "shift_x": 0, "shift_y": 0 }   // AJAZZ AKP03

Verified on an AKP03: renders correctly, and produces byte-identical JPEGs to the hardcoded values it replaces.

Notes

The two changes are sent together because they're coupled in practice — arbitrary-size scaling is only useful once the geometry is right for the panel, and the geometry work is what established the 72x72.

README updated, since unlike my other PRs this one adds config surface. Covers the lcd section, the uneven-cropping symptom, and the AKP03 values.

This is a second way these clones differ beyond the USB IDs in #1, which may be worth knowing about generally — I'd guess the other listed rebrands need checking too, though I only have the one device to test with.

Tested on an AJAZZ AKP03, macOS 26.5, Apple Silicon. I don't have an N3 to confirm the defaults still behave identically, but they're unchanged and the code path is the same when lcd is absent.

nanderss and others added 3 commits August 19, 2026 14:56
Two limits meant only square images of 1024px or less worked as button
icons, which in practice meant .icns files and little else.

Sources larger than 1024px were rejected outright with "image too
large". They are now downscaled while decoding, via
CGImageSourceCreateThumbnailAtIndex. This also resamples in a single
step and picks the best-matching representation inside a multi-size
.icns, so it costs less than the full-size decode it replaces, not
more.

The draw rect was a fixed square, so any source that was not already
square was stretched to fill it. Fit the image to the square instead
and center it, leaving the unused axis black to match the LCD
background.

Verified with a 3000x1200 source: previously rejected and the key was
left blank, now scaled and letterboxed correctly on the hardware.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The render size and viewport offsets were constants calibrated for the
TreasLin N3. They are not right for every clone: on an AJAZZ AKP03 the
85x85 render is cropped by the panel, and because the offsets are
asymmetric it is cropped unevenly -- icons lose the rounded corners on
two sides while keeping them on the other two.

That model wants 72x72 with no offset, which is also what the README
describes the LCD keys as. Rather than swap one hardcoded calibration
for another and break the N3, move size, shift_x and shift_y into an
optional "lcd" config section. Defaults are unchanged, so existing
setups keep the N3 behaviour without touching their config.

Verified on an AKP03: {"size": 72, "shift_x": 0, "shift_y": 0} renders
correctly, and produces byte-identical JPEGs to the hardcoded values it
replaces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Covers the new optional "lcd" section in the config reference, the
symptom that indicates a mismatch, and the AJAZZ AKP03 values. Also
notes that icons may now be any size or aspect ratio.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant