Text and the SVG button images are mixed on screen, so they now share
UIDropShadowParams (3 UI units of blur, 0.66 intensity, no offset, the
atlas's existing look) instead of the text having its own.
draw_text.cpp included <windows.h> directly, whose min/max macros broke
the std::max calls added here. Include CommonWindows.h instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CompositeDropShadow in Common/Render/DropShadow.cpp blurs a premultiplied
RGBA image's alpha (with an optional offset) and composites the image
over it. The atlas's AddDropShadow and TextDrawer::AddDropShadow are now
thin wrappers that pick the parameters.
The blur scatters only the non-transparent texels, which makes atlas
shadows 3-7x faster than the old gather-with-clamping version. Atlas
output is unchanged apart from rounding (alpha differs by at most 1).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
nanosvg walks every scanline of the target for each visible shape, so
rasterizing the whole SVG and cropping the images out of it cost
shapes * canvas area. Each image is now rasterized into a buffer the size
of its bounding box, from a list of copies of its own shapes, so the
images can be rasterized on the thread pool.
Atlas generation on a Redmi 9A (32-bit) goes from about 165 ms to about
95 ms, and on a desktop from about 10 ms to 6 ms. Parsing the SVG is now
the largest part. The atlas layout is unchanged; a few edge pixels differ
by at most 2/255 from the different subpixel offsets.
Also copy whole rows in Image::copyfrom, and fix a leak of the SVG file
data when parsing fails.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>