gpui: Fix blending of colors in HighlightStyle::highlight (#37666)
Whilst looking into adding support for RainbowBrackes, we stumbled upon this: Whereas for all properties during this blending, we take the value of `other` if it is set, for the color we actually take `self.color` instead of `other.color` if `self.color` is at full opacity. `Hsla::blend` returns the latter color if it is at full opacity, which seems wrong for this case. Hence, this PR swaps these. Will not merge before the next release, to ensure that we don't break something somewhere unexpected. Release Notes: - N/A
This commit is contained in:
@@ -703,9 +703,8 @@ impl<'a> HighlightedChunk<'a> {
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
let invisible_style = if let Some(mut style) = style {
|
||||
style.highlight(invisible_highlight);
|
||||
style
|
||||
let invisible_style = if let Some(style) = style {
|
||||
style.highlight(invisible_highlight)
|
||||
} else {
|
||||
invisible_highlight
|
||||
};
|
||||
@@ -726,9 +725,8 @@ impl<'a> HighlightedChunk<'a> {
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
let invisible_style = if let Some(mut style) = style {
|
||||
style.highlight(invisible_highlight);
|
||||
style
|
||||
let invisible_style = if let Some(style) = style {
|
||||
style.highlight(invisible_highlight)
|
||||
} else {
|
||||
invisible_highlight
|
||||
};
|
||||
@@ -962,62 +960,59 @@ impl DisplaySnapshot {
|
||||
},
|
||||
)
|
||||
.flat_map(|chunk| {
|
||||
let mut highlight_style = chunk
|
||||
let highlight_style = chunk
|
||||
.syntax_highlight_id
|
||||
.and_then(|id| id.style(&editor_style.syntax));
|
||||
|
||||
if let Some(chunk_highlight) = chunk.highlight_style {
|
||||
// For color inlays, blend the color with the editor background
|
||||
let mut processed_highlight = chunk_highlight;
|
||||
if chunk.is_inlay
|
||||
&& let Some(inlay_color) = chunk_highlight.color
|
||||
{
|
||||
// Only blend if the color has transparency (alpha < 1.0)
|
||||
if inlay_color.a < 1.0 {
|
||||
let blended_color = editor_style.background.blend(inlay_color);
|
||||
processed_highlight.color = Some(blended_color);
|
||||
}
|
||||
let chunk_highlight = chunk.highlight_style.map(|chunk_highlight| {
|
||||
HighlightStyle {
|
||||
// For color inlays, blend the color with the editor background
|
||||
// if the color has transparency (alpha < 1.0)
|
||||
color: chunk_highlight.color.map(|color| {
|
||||
if chunk.is_inlay && !color.is_opaque() {
|
||||
editor_style.background.blend(color)
|
||||
} else {
|
||||
color
|
||||
}
|
||||
}),
|
||||
..chunk_highlight
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(highlight_style) = highlight_style.as_mut() {
|
||||
highlight_style.highlight(processed_highlight);
|
||||
} else {
|
||||
highlight_style = Some(processed_highlight);
|
||||
}
|
||||
}
|
||||
let diagnostic_highlight = chunk
|
||||
.diagnostic_severity
|
||||
.filter(|severity| {
|
||||
self.diagnostics_max_severity
|
||||
.into_lsp()
|
||||
.is_some_and(|max_severity| severity <= &max_severity)
|
||||
})
|
||||
.map(|severity| HighlightStyle {
|
||||
fade_out: chunk
|
||||
.is_unnecessary
|
||||
.then_some(editor_style.unnecessary_code_fade),
|
||||
underline: (chunk.underline
|
||||
&& editor_style.show_underlines
|
||||
&& !(chunk.is_unnecessary && severity > lsp::DiagnosticSeverity::WARNING))
|
||||
.then(|| {
|
||||
let diagnostic_color =
|
||||
super::diagnostic_style(severity, &editor_style.status);
|
||||
UnderlineStyle {
|
||||
color: Some(diagnostic_color),
|
||||
thickness: 1.0.into(),
|
||||
wavy: true,
|
||||
}
|
||||
}),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let mut diagnostic_highlight = HighlightStyle::default();
|
||||
|
||||
if let Some(severity) = chunk.diagnostic_severity.filter(|severity| {
|
||||
self.diagnostics_max_severity
|
||||
.into_lsp()
|
||||
.is_some_and(|max_severity| severity <= &max_severity)
|
||||
}) {
|
||||
if chunk.is_unnecessary {
|
||||
diagnostic_highlight.fade_out = Some(editor_style.unnecessary_code_fade);
|
||||
}
|
||||
if chunk.underline
|
||||
&& editor_style.show_underlines
|
||||
&& !(chunk.is_unnecessary && severity > lsp::DiagnosticSeverity::WARNING)
|
||||
{
|
||||
let diagnostic_color = super::diagnostic_style(severity, &editor_style.status);
|
||||
diagnostic_highlight.underline = Some(UnderlineStyle {
|
||||
color: Some(diagnostic_color),
|
||||
thickness: 1.0.into(),
|
||||
wavy: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(highlight_style) = highlight_style.as_mut() {
|
||||
highlight_style.highlight(diagnostic_highlight);
|
||||
} else {
|
||||
highlight_style = Some(diagnostic_highlight);
|
||||
}
|
||||
let style = [highlight_style, chunk_highlight, diagnostic_highlight]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.reduce(|acc, highlight| acc.highlight(highlight));
|
||||
|
||||
HighlightedChunk {
|
||||
text: chunk.text,
|
||||
style: highlight_style,
|
||||
style,
|
||||
is_tab: chunk.is_tab,
|
||||
is_inlay: chunk.is_inlay,
|
||||
replacement: chunk.renderer.map(ChunkReplacement::Renderer),
|
||||
|
||||
@@ -150,11 +150,11 @@ impl<'a> Iterator for CustomHighlightsChunks<'a> {
|
||||
..chunk.clone()
|
||||
};
|
||||
if !self.active_highlights.is_empty() {
|
||||
let mut highlight_style = HighlightStyle::default();
|
||||
for active_highlight in self.active_highlights.values() {
|
||||
highlight_style.highlight(*active_highlight);
|
||||
}
|
||||
prefix.highlight_style = Some(highlight_style);
|
||||
prefix.highlight_style = self
|
||||
.active_highlights
|
||||
.values()
|
||||
.copied()
|
||||
.reduce(|acc, active_highlight| acc.highlight(active_highlight));
|
||||
}
|
||||
Some(prefix)
|
||||
}
|
||||
|
||||
@@ -385,9 +385,9 @@ impl<'a> Iterator for InlayChunks<'a> {
|
||||
next_inlay_highlight_endpoint = usize::MAX;
|
||||
} else {
|
||||
next_inlay_highlight_endpoint = range.end - offset_in_inlay.0;
|
||||
highlight_style
|
||||
.get_or_insert_with(Default::default)
|
||||
.highlight(*style);
|
||||
highlight_style = highlight_style
|
||||
.map(|highlight| highlight.highlight(*style))
|
||||
.or_else(|| Some(*style));
|
||||
}
|
||||
} else {
|
||||
next_inlay_highlight_endpoint = usize::MAX;
|
||||
|
||||
@@ -23817,8 +23817,7 @@ pub fn styled_runs_for_code_label<'a>(
|
||||
} else {
|
||||
return Default::default();
|
||||
};
|
||||
let mut muted_style = style;
|
||||
muted_style.highlight(fade_out);
|
||||
let muted_style = style.highlight(fade_out);
|
||||
|
||||
let mut runs = SmallVec::<[(Range<usize>, HighlightStyle); 3]>::new();
|
||||
if range.start >= label.filter_range.end {
|
||||
|
||||
Reference in New Issue
Block a user