From af707c512bae89250ff2f5f80960be9c56c4651c Mon Sep 17 00:00:00 2001
From: "gcp-cherry-pick-bot[bot]"
<98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com>
Date: Wed, 5 Feb 2025 20:41:46 -0500
Subject: [PATCH] gpui: Render SVGs at 2x size when rendered in an `img`
(cherry-pick #24332) (#24337)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cherry-picked gpui: Render SVGs at 2x size when rendered in an `img`
(#24332)
This PR adjusts the rendering of SVGs when used with the `img` element
such that they are rendered at 2x their displayed size.
This results in much crisper icons for icons loaded by icon themes:
Release Notes:
- Improved the resolution of icons rendered by icon themes.
Co-authored-by: Marshall Bowers
---
crates/gpui/src/elements/img.rs | 3 ++-
crates/gpui/src/svg_renderer.rs | 3 +++
crates/gpui/src/window.rs | 9 ++++-----
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/crates/gpui/src/elements/img.rs b/crates/gpui/src/elements/img.rs
index 3dbca87ea2488e11c7d8b98af70037bc2682d1d9..879ad7aa763554fb8057a671397fda50b3e83d93 100644
--- a/crates/gpui/src/elements/img.rs
+++ b/crates/gpui/src/elements/img.rs
@@ -3,6 +3,7 @@ use crate::{
DefiniteLength, Element, ElementId, GlobalElementId, Hitbox, Image, InteractiveElement,
Interactivity, IntoElement, LayoutId, Length, ObjectFit, Pixels, RenderImage, Resource,
SharedString, SharedUri, StyleRefinement, Styled, SvgSize, Task, Window,
+ SMOOTH_SVG_SCALE_FACTOR,
};
use anyhow::{anyhow, Result};
@@ -610,7 +611,7 @@ impl Asset for ImageAssetLoader {
} else {
let pixmap =
// TODO: Can we make svgs always rescale?
- svg_renderer.render_pixmap(&bytes, SvgSize::ScaleFactor(1.0))?;
+ svg_renderer.render_pixmap(&bytes, SvgSize::ScaleFactor(SMOOTH_SVG_SCALE_FACTOR))?;
let mut buffer =
ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take()).unwrap();
diff --git a/crates/gpui/src/svg_renderer.rs b/crates/gpui/src/svg_renderer.rs
index f99880ec5e31cc947047f8027ae73f590571fd55..306f8ed6518157f9bc6de6721da94e9befaaac6c 100644
--- a/crates/gpui/src/svg_renderer.rs
+++ b/crates/gpui/src/svg_renderer.rs
@@ -3,6 +3,9 @@ use anyhow::anyhow;
use resvg::tiny_skia::Pixmap;
use std::{hash::Hash, sync::Arc};
+/// When rendering SVGs, we render them at twice the size to get a higher-quality result.
+pub const SMOOTH_SVG_SCALE_FACTOR: f32 = 2.;
+
#[derive(Clone, PartialEq, Hash, Eq)]
pub(crate) struct RenderSvgParams {
pub(crate) path: SharedString,
diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs
index 7e0fae8cc4b2a8c3dde73bb80b62f18ca498d534..305b5e477ff825a19219f405916f36b8eb515a06 100644
--- a/crates/gpui/src/window.rs
+++ b/crates/gpui/src/window.rs
@@ -13,7 +13,7 @@ use crate::{
Subscription, TaffyLayoutEngine, Task, TextStyle, TextStyleRefinement, TransformationMatrix,
Underline, UnderlineStyle, WindowAppearance, WindowBackgroundAppearance, WindowBounds,
WindowControls, WindowDecorations, WindowOptions, WindowParams, WindowTextSystem,
- SUBPIXEL_VARIANTS,
+ SMOOTH_SVG_SCALE_FACTOR, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Context as _, Result};
use collections::{FxHashMap, FxHashSet};
@@ -2567,12 +2567,11 @@ impl Window {
let element_opacity = self.element_opacity();
let scale_factor = self.scale_factor();
let bounds = bounds.scale(scale_factor);
- // Render the SVG at twice the size to get a higher quality result.
let params = RenderSvgParams {
path,
- size: bounds
- .size
- .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
+ size: bounds.size.map(|pixels| {
+ DevicePixels::from((pixels.0 * SMOOTH_SVG_SCALE_FACTOR).ceil() as i32)
+ }),
};
let Some(tile) =