-
Notifications
You must be signed in to change notification settings - Fork 23
Adopt CSS-style drop shadow mask #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 7 files
| #define SHADOW_LUT_Y_LEN (CONFIG_VERTICAL_OFFSET + CONFIG_SHADOW_FADE_TAIL) | ||
|
|
||
| /* Fast lookup: 17-entry approximation of (1 - t^2)^2 * 0.92 + 0.08. */ | ||
| static inline twin_fixed_t shadow_gaussian_weight(twin_fixed_t t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the shadow_gaussian_weight() function has the same effect as twin_stack_blur(). Removing the call to twin_stack_blur() still produces a gradient color effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the shadow_gaussian_weight() function has the same effect as twin_stack_blur().
No, these two functions have completely different purposes and effects.
The purpose of twin_stack_blur:
- Blurs an existing image in-place
- Uses the Stack Blur algorithm (2-pass separable convolution)
- Horizontal scan + vertical scan
- Creates a temporary pixmap for two-directional processing
Complexity: O(2 × width × height × k)
The purpose of shadow_gaussian_weight:
- Looks up a single weight value from a precomputed LUT
- Input: t ∈ [0, 1] (fixed-point format)
- Output: Gaussian weight (16.16 fixed-point)
- Uses formula: (1 - t²)² × 0.92 + 0.08
Complexity: O(1) lookup
Comparisons:
twin_stack_bluris like taking a photograph and applying a Photoshop blur filter to it. You're processing what's already there.shadow_gaussian_weightis like looking up paint opacity values from a chart to paint a gradient from scratch. You're creating something new.
| twin_coord_t bottom_start = win_height; | ||
| if (bottom_start < 0) | ||
| bottom_start = 0; | ||
| twin_coord_t bottom_end = win_height + bottom_extent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
twin_coord_t win_height = shadow->height - shadow->window->shadow_y;
twin_coord_t bottom_extent = shadow->height - win_height;
Therefore, bottom_end == shadow->height
| if (bottom_start < 0) | ||
| bottom_start = 0; | ||
| twin_coord_t bottom_end = win_height + bottom_extent; | ||
| if (bottom_end > shadow->height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to compare.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to compare.
Scenario where bounds check matters:
CONFIG_VERTICAL_OFFSET = 6, FADE_TAIL = 2
∴ lut_y_len = 8
Case 1: shadow_y = 10
→ bottom_extent limited to 8
→ bottom_end = win_height + 8
→ Need bounds check if win_height + 8 > shadow->height
Case 2: shadow_y = 20 (large window)
→ bottom_extent limited to 8
→ bottom_end = win_height + 8 (definitely < shadow->height)
Bounds check is REQUIRED because bottom_extent gets clamped to LUT size.
| if (bottom_width <= 0) | ||
| continue; | ||
|
|
||
| twin_coord_t dist_y = y - win_height; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
twin_coord_t dist_y = y - bottom_start; this is clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
twin_coord_t dist_y = y - bottom_start;this is clearer.
Current implementation is correct for LUT indexing semantics.
- alpha_lut_y is built with indices [0, y_offset)
- LUT entry 0 = maximum alpha (at window edge)
- LUT entry y_offset-1 = minimum alpha (at shadow fade end)
- dist_y must represent distance from window edge (win_height)
- NOT distance from loop start (bottom_start)
|
Only need to keep one variable for the same function. |
This commit generates shadow_gaussian lookup table during the build, so the renderer stops depending on runtime math. It replaces the stack-blur border writes with a lookup-table renderer that matches CSS behavior and stays efficient. For performance considerations, it caches the vertical and bottom falloff tables and rely on memset() or pointer writes to trim per-frame work. It exposes a small configurable fade tail and update defaults plus the API, so it aligns with CSS box-shadow semantics.
This commit generates shadow_gaussian lookup table during the build, so the renderer stops depending on runtime math. It replaces the stack-blur border writes with a lookup-table renderer that matches CSS behavior and stays efficient.
For performance considerations, it caches the vertical and bottom falloff tables and rely on memset() or pointer writes to trim per-frame work. It exposes a small configurable fade tail and update defaults plus the API, so it aligns with CSS box-shadow semantics.
Summary by cubic
Switches drop shadow rendering to a CSS-style box-shadow mask using a precomputed Gaussian LUT. Improves visual match and speeds up rendering while simplifying the shadow API.
New Features
Migration