Flow-Launcher / Flow-Launcher/Flow.Launcher

BUG: SVG icons are clipped when the artwork does not start at the viewBox origin

Open Beginner friendly
#4,574 0 comments 1 reaction 0 assignees View on GitHub
bug kind/ui
Dominant language
C#
Stars
15.6k
Forks
644
Avg merge
16h 51m
Merged PRs (30d)
3

Description

### Checks

- [x] I have checked that this issue has not already been reported.
- [x] I am using the latest version of Flow Launcher.
- [ ] I am using the prerelease version of Flow Launcher.

### 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`:

```csharp
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:

```csharp
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: ``. Note that `fill="none"` does not work, as it contributes no bounds.

### To Reproduce

1. Point a plugin's `IcoPath` (or a result's `IcoPath`) at an SVG whose artwork is inset from the viewBox, e.g.:

```xml

```

Its drawing bounds are (1,1) 22x22.

2. Query the plugin so the icon is shown.

3. The icon's right and bottom edges are clipped. Adding `` 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`.

Image

### 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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in Flow.Launcher.Infrastructure/Image/ImageLoader.cs at ImageLoader.LoadSvgImage and inspect how drawing bounds are used during SVG rendering. Reproduce the issue with the inset 24x24 circle SVG from the report, then verify that the rendered bitmap contains the complete artwork without clipping at the right or bottom edges.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.