Checks
Problem Description
ImageLoader.LoadSvgImage scales an SVG by its drawing bounds and sizes the output bitmap to those scaled bounds, but it never translates the drawing by the bounds' origin. When Drawing.Bounds.X/Y are non-zero — i.e. any SVG with padding between the viewBox and the artwork — the content is drawn at that offset inside a bitmap that is only as large as the content itself, so the right and bottom edges fall outside the bitmap and are cut off.
In Flow.Launcher.Infrastructure/Image/ImageLoader.cs:
var scale = desiredHeight / drawingBounds.Height;
...
drawingContext.PushTransform(new ScaleTransform(scale, scale));
drawingContext.DrawDrawing(drawing); // drawn at drawingBounds.X/Y, but the bitmap starts at 0,0
This affects any icon set with an inset viewBox. GitHub's Octicons, for example, use a 24x24 viewBox whose artwork spans (1,1)-(23,23), so every icon loses ~1px off two edges. SVGs whose artwork touches (0,0) — such as one with a full-bleed background rect — render correctly, which is why the bug is easy to miss.
Suggested fix — translate the drawing back to the origin before rendering:
drawingContext.PushTransform(new ScaleTransform(scale, scale));
drawingContext.PushTransform(new TranslateTransform(-drawingBounds.X, -drawingBounds.Y));
drawingContext.DrawDrawing(drawing);
A plugin-side workaround is to add a full-bleed transparent rect to anchor the bounds at the origin: <rect width="24" height="24" fill="#000000" fill-opacity="0"/>. Note that fill="none" does not work, as it contributes no bounds.
To Reproduce
-
Point a plugin's IcoPath (or a result's IcoPath) at an SVG whose artwork is inset from the viewBox, e.g.:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="11" fill="#1A7F37"/>
</svg>
Its drawing bounds are (1,1) 22x22.
-
Query the plugin so the icon is shown.
-
The icon's right and bottom edges are clipped. Adding <rect width="24" height="24" fill="#000000" fill-opacity="0"/> as the first child makes the bounds (0,0) 24x24 and the icon renders in full.
Screenshots
The same SVGs rendered through LoadSvgImage, before and after adding the translate. The thin box is the bitmap the loader produces; ink touching the box is ink falling outside it. Bounds reported by the loader: circle (1,1) 22x22, issue (1,1) 22x22, pull-request (1,0) 23x22, alert (1,1) 23x20.
Flow Launcher Version
2.1.3
Windows Build Number
10.0.26200.7462
Error Log
Not applicable — nothing is logged; the icon is silently clipped.
Checks
Problem Description
ImageLoader.LoadSvgImagescales an SVG by its drawing bounds and sizes the output bitmap to those scaled bounds, but it never translates the drawing by the bounds' origin. WhenDrawing.Bounds.X/Yare non-zero — i.e. any SVG with padding between the viewBox and the artwork — the content is drawn at that offset inside a bitmap that is only as large as the content itself, so the right and bottom edges fall outside the bitmap and are cut off.In
Flow.Launcher.Infrastructure/Image/ImageLoader.cs:This affects any icon set with an inset viewBox. GitHub's Octicons, for example, use a 24x24 viewBox whose artwork spans (1,1)-(23,23), so every icon loses ~1px off two edges. SVGs whose artwork touches (0,0) — such as one with a full-bleed background rect — render correctly, which is why the bug is easy to miss.
Suggested fix — translate the drawing back to the origin before rendering:
A plugin-side workaround is to add a full-bleed transparent rect to anchor the bounds at the origin:
<rect width="24" height="24" fill="#000000" fill-opacity="0"/>. Note thatfill="none"does not work, as it contributes no bounds.To Reproduce
Point a plugin's
IcoPath(or a result'sIcoPath) at an SVG whose artwork is inset from the viewBox, e.g.:Its drawing bounds are (1,1) 22x22.
Query the plugin so the icon is shown.
The icon's right and bottom edges are clipped. Adding
<rect width="24" height="24" fill="#000000" fill-opacity="0"/>as the first child makes the bounds (0,0) 24x24 and the icon renders in full.Screenshots
The same SVGs rendered through
LoadSvgImage, before and after adding the translate. The thin box is the bitmap the loader produces; ink touching the box is ink falling outside it. Bounds reported by the loader: circle(1,1) 22x22, issue(1,1) 22x22, pull-request(1,0) 23x22, alert(1,1) 23x20.Flow Launcher Version
2.1.3
Windows Build Number
10.0.26200.7462
Error Log
Not applicable — nothing is logged; the icon is silently clipped.