mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 02:48:34 +00:00
Draw tabs with svg icons in editor code only
This commit is contained in:
parent
f0a88b3337
commit
2d8c88ad73
4 changed files with 186 additions and 104 deletions
|
@ -21,7 +21,7 @@ use git::diff::DiffHunkStatus;
|
|||
use gpui::{
|
||||
color::Color,
|
||||
elements::*,
|
||||
fonts::{HighlightStyle, Underline},
|
||||
fonts::{HighlightStyle, TextStyle, Underline},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
|
@ -29,17 +29,18 @@ use gpui::{
|
|||
},
|
||||
json::{self, ToJson},
|
||||
platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent},
|
||||
text_layout::{self, Line, RunStyle, TextLayoutCache},
|
||||
AnyElement, Axis, Border, CursorRegion, Element, EventContext, LayoutContext, MouseRegion,
|
||||
Quad, SceneBuilder, SizeConstraint, ViewContext, WindowContext,
|
||||
text_layout::{self, Invisible, Line, RunStyle, TextLayoutCache},
|
||||
AnyElement, Axis, Border, CursorRegion, Element, EventContext, FontCache, LayoutContext,
|
||||
MouseRegion, Quad, SceneBuilder, SizeConstraint, ViewContext, WindowContext,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use json::json;
|
||||
use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Selection};
|
||||
use project::ProjectPath;
|
||||
use settings::{GitGutter, Settings};
|
||||
use settings::{GitGutter, Settings, ShowInvisibles};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{self, Ordering},
|
||||
fmt::Write,
|
||||
iter,
|
||||
|
@ -808,7 +809,8 @@ impl EditorElement {
|
|||
.contains(&cursor_position.row())
|
||||
{
|
||||
let cursor_row_layout = &layout.position_map.line_layouts
|
||||
[(cursor_position.row() - start_row) as usize];
|
||||
[(cursor_position.row() - start_row) as usize]
|
||||
.line;
|
||||
let cursor_column = cursor_position.column() as usize;
|
||||
|
||||
let cursor_character_x = cursor_row_layout.x_for_index(cursor_column);
|
||||
|
@ -863,9 +865,9 @@ impl EditorElement {
|
|||
|
||||
if let Some(visible_text_bounds) = bounds.intersection(visible_bounds) {
|
||||
// Draw glyphs
|
||||
for (ix, line) in layout.position_map.line_layouts.iter().enumerate() {
|
||||
for (ix, line_with_invisibles) in layout.position_map.line_layouts.iter().enumerate() {
|
||||
let row = start_row + ix as u32;
|
||||
line.paint(
|
||||
line_with_invisibles.line.paint(
|
||||
scene,
|
||||
content_origin
|
||||
+ vec2f(
|
||||
|
@ -876,6 +878,53 @@ impl EditorElement {
|
|||
layout.position_map.line_height,
|
||||
cx,
|
||||
);
|
||||
|
||||
let settings = cx.global::<Settings>();
|
||||
match settings
|
||||
.editor_overrides
|
||||
.show_invisibles
|
||||
.or(settings.editor_defaults.show_invisibles)
|
||||
.unwrap_or_default()
|
||||
{
|
||||
ShowInvisibles::None => {}
|
||||
ShowInvisibles::All => {
|
||||
for invisible in &line_with_invisibles.invisibles {
|
||||
match invisible {
|
||||
Invisible::Tab { line_start_offset } => {
|
||||
// TODO kb cache, deduplicate
|
||||
let x_offset =
|
||||
line_with_invisibles.line.x_for_index(*line_start_offset);
|
||||
let font_size = line_with_invisibles.line.font_size();
|
||||
let max_size = vec2f(font_size, font_size);
|
||||
let origin = content_origin
|
||||
+ vec2f(
|
||||
-scroll_left + x_offset,
|
||||
row as f32 * layout.position_map.line_height
|
||||
- scroll_top,
|
||||
);
|
||||
|
||||
let mut test_svg = Svg::new("icons/arrow_right_16.svg")
|
||||
.with_color(Color::red());
|
||||
let (_, mut layout_state) = test_svg.layout(
|
||||
SizeConstraint::new(origin, max_size),
|
||||
editor,
|
||||
cx,
|
||||
);
|
||||
test_svg.paint(
|
||||
scene,
|
||||
RectF::new(origin, max_size),
|
||||
visible_bounds,
|
||||
&mut layout_state,
|
||||
editor,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
// TODO kb draw whitespaces too
|
||||
Invisible::Whitespace { .. } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -888,7 +937,7 @@ impl EditorElement {
|
|||
if let Some((position, context_menu)) = layout.context_menu.as_mut() {
|
||||
scene.push_stacking_context(None, None);
|
||||
let cursor_row_layout =
|
||||
&layout.position_map.line_layouts[(position.row() - start_row) as usize];
|
||||
&layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
|
||||
let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
|
||||
let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top;
|
||||
let mut list_origin = content_origin + vec2f(x, y);
|
||||
|
@ -921,7 +970,7 @@ impl EditorElement {
|
|||
|
||||
// This is safe because we check on layout whether the required row is available
|
||||
let hovered_row_layout =
|
||||
&layout.position_map.line_layouts[(position.row() - start_row) as usize];
|
||||
&layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
|
||||
|
||||
// Minimum required size: Take the first popover, and add 1.5 times the minimum popover
|
||||
// height. This is the size we will use to decide whether to render popovers above or below
|
||||
|
@ -1118,7 +1167,7 @@ impl EditorElement {
|
|||
.into_iter()
|
||||
.map(|row| {
|
||||
let line_layout =
|
||||
&layout.position_map.line_layouts[(row - start_row) as usize];
|
||||
&layout.position_map.line_layouts[(row - start_row) as usize].line;
|
||||
HighlightedRangeLine {
|
||||
start_x: if row == range.start.row() {
|
||||
content_origin.x()
|
||||
|
@ -1282,7 +1331,7 @@ impl EditorElement {
|
|||
rows: Range<u32>,
|
||||
snapshot: &EditorSnapshot,
|
||||
cx: &ViewContext<Editor>,
|
||||
) -> Vec<text_layout::Line> {
|
||||
) -> Vec<LineWithInvisibles> {
|
||||
if rows.start >= rows.end {
|
||||
return Vec::new();
|
||||
}
|
||||
|
@ -1317,6 +1366,10 @@ impl EditorElement {
|
|||
)],
|
||||
)
|
||||
})
|
||||
.map(|line| LineWithInvisibles {
|
||||
line,
|
||||
invisibles: Vec::new(),
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
let style = &self.style;
|
||||
|
@ -1366,13 +1419,6 @@ impl EditorElement {
|
|||
}
|
||||
});
|
||||
|
||||
let settings = cx.global::<Settings>();
|
||||
let show_invisibles = settings
|
||||
.editor_overrides
|
||||
.show_invisibles
|
||||
.or(settings.editor_defaults.show_invisibles)
|
||||
.unwrap_or_default()
|
||||
== settings::ShowInvisibles::All;
|
||||
layout_highlighted_chunks(
|
||||
chunks,
|
||||
&style.text,
|
||||
|
@ -1380,7 +1426,6 @@ impl EditorElement {
|
|||
cx.font_cache(),
|
||||
MAX_LINE_LEN,
|
||||
rows.len() as usize,
|
||||
show_invisibles,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1398,7 +1443,7 @@ impl EditorElement {
|
|||
text_x: f32,
|
||||
line_height: f32,
|
||||
style: &EditorStyle,
|
||||
line_layouts: &[text_layout::Line],
|
||||
line_layouts: &[LineWithInvisibles],
|
||||
include_root: bool,
|
||||
editor: &mut Editor,
|
||||
cx: &mut LayoutContext<Editor>,
|
||||
|
@ -1421,6 +1466,7 @@ impl EditorElement {
|
|||
let anchor_x = text_x
|
||||
+ if rows.contains(&align_to.row()) {
|
||||
line_layouts[(align_to.row() - rows.start) as usize]
|
||||
.line
|
||||
.x_for_index(align_to.column() as usize)
|
||||
} else {
|
||||
layout_line(align_to.row(), snapshot, style, cx.text_layout_cache())
|
||||
|
@ -1599,6 +1645,93 @@ impl EditorElement {
|
|||
}
|
||||
}
|
||||
|
||||
struct HighlightedChunk<'a> {
|
||||
chunk: &'a str,
|
||||
style: Option<HighlightStyle>,
|
||||
is_tab: bool,
|
||||
}
|
||||
|
||||
pub struct LineWithInvisibles {
|
||||
pub line: Line,
|
||||
invisibles: Vec<Invisible>,
|
||||
}
|
||||
|
||||
fn layout_highlighted_chunks<'a>(
|
||||
chunks: impl Iterator<Item = HighlightedChunk<'a>>,
|
||||
text_style: &TextStyle,
|
||||
text_layout_cache: &TextLayoutCache,
|
||||
font_cache: &Arc<FontCache>,
|
||||
max_line_len: usize,
|
||||
max_line_count: usize,
|
||||
) -> Vec<LineWithInvisibles> {
|
||||
let mut layouts = Vec::with_capacity(max_line_count);
|
||||
let mut line = String::new();
|
||||
let mut invisibles = Vec::new();
|
||||
let mut styles = Vec::new();
|
||||
let mut row = 0;
|
||||
let mut line_exceeded_max_len = false;
|
||||
for highlighted_chunk in chunks.chain([HighlightedChunk {
|
||||
chunk: "\n",
|
||||
style: None,
|
||||
is_tab: false,
|
||||
}]) {
|
||||
for (ix, mut line_chunk) in highlighted_chunk.chunk.split('\n').enumerate() {
|
||||
if ix > 0 {
|
||||
layouts.push(LineWithInvisibles {
|
||||
line: text_layout_cache.layout_str(&line, text_style.font_size, &styles),
|
||||
invisibles: invisibles.drain(..).collect(),
|
||||
});
|
||||
|
||||
line.clear();
|
||||
styles.clear();
|
||||
row += 1;
|
||||
line_exceeded_max_len = false;
|
||||
if row == max_line_count {
|
||||
return layouts;
|
||||
}
|
||||
}
|
||||
|
||||
if !line_chunk.is_empty() && !line_exceeded_max_len {
|
||||
let text_style = if let Some(style) = highlighted_chunk.style {
|
||||
text_style
|
||||
.clone()
|
||||
.highlight(style, font_cache)
|
||||
.map(Cow::Owned)
|
||||
.unwrap_or_else(|_| Cow::Borrowed(text_style))
|
||||
} else {
|
||||
Cow::Borrowed(text_style)
|
||||
};
|
||||
|
||||
if line.len() + line_chunk.len() > max_line_len {
|
||||
let mut chunk_len = max_line_len - line.len();
|
||||
while !line_chunk.is_char_boundary(chunk_len) {
|
||||
chunk_len -= 1;
|
||||
}
|
||||
line_chunk = &line_chunk[..chunk_len];
|
||||
line_exceeded_max_len = true;
|
||||
}
|
||||
|
||||
styles.push((
|
||||
line_chunk.len(),
|
||||
RunStyle {
|
||||
font_id: text_style.font_id,
|
||||
color: text_style.color,
|
||||
underline: text_style.underline,
|
||||
},
|
||||
));
|
||||
if highlighted_chunk.is_tab {
|
||||
invisibles.push(Invisible::Tab {
|
||||
line_start_offset: line.len(),
|
||||
});
|
||||
}
|
||||
line.push_str(line_chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layouts
|
||||
}
|
||||
|
||||
impl Element<Editor> for EditorElement {
|
||||
type LayoutState = LayoutState;
|
||||
type PaintState = ();
|
||||
|
@ -1825,9 +1958,9 @@ impl Element<Editor> for EditorElement {
|
|||
|
||||
let mut max_visible_line_width = 0.0;
|
||||
let line_layouts = self.layout_lines(start_row..end_row, &snapshot, cx);
|
||||
for line in &line_layouts {
|
||||
if line.width() > max_visible_line_width {
|
||||
max_visible_line_width = line.width();
|
||||
for line_with_invisibles in &line_layouts {
|
||||
if line_with_invisibles.line.width() > max_visible_line_width {
|
||||
max_visible_line_width = line_with_invisibles.line.width();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2087,10 +2220,11 @@ impl Element<Editor> for EditorElement {
|
|||
return None;
|
||||
}
|
||||
|
||||
let line = layout
|
||||
let line = &layout
|
||||
.position_map
|
||||
.line_layouts
|
||||
.get((range_start.row() - start_row) as usize)?;
|
||||
.get((range_start.row() - start_row) as usize)?
|
||||
.line;
|
||||
let range_start_x = line.x_for_index(range_start.column() as usize);
|
||||
let range_start_y = range_start.row() as f32 * layout.position_map.line_height;
|
||||
Some(RectF::new(
|
||||
|
@ -2149,13 +2283,13 @@ pub struct LayoutState {
|
|||
fold_indicators: Vec<Option<AnyElement<Editor>>>,
|
||||
}
|
||||
|
||||
pub struct PositionMap {
|
||||
struct PositionMap {
|
||||
size: Vector2F,
|
||||
line_height: f32,
|
||||
scroll_max: Vector2F,
|
||||
em_width: f32,
|
||||
em_advance: f32,
|
||||
line_layouts: Vec<text_layout::Line>,
|
||||
line_layouts: Vec<LineWithInvisibles>,
|
||||
snapshot: EditorSnapshot,
|
||||
}
|
||||
|
||||
|
@ -2177,6 +2311,7 @@ impl PositionMap {
|
|||
let (column, x_overshoot) = if let Some(line) = self
|
||||
.line_layouts
|
||||
.get(row as usize - scroll_position.y() as usize)
|
||||
.map(|line_with_spaces| &line_with_spaces.line)
|
||||
{
|
||||
if let Some(ix) = line.index_for_x(x) {
|
||||
(ix as u32, 0.0)
|
||||
|
@ -2445,7 +2580,7 @@ impl HighlightedRange {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn position_to_display_point(
|
||||
fn position_to_display_point(
|
||||
position: Vector2F,
|
||||
text_bounds: RectF,
|
||||
position_map: &PositionMap,
|
||||
|
@ -2462,7 +2597,7 @@ pub fn position_to_display_point(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn range_to_bounds(
|
||||
fn range_to_bounds(
|
||||
range: &Range<DisplayPoint>,
|
||||
content_origin: Vector2F,
|
||||
scroll_left: f32,
|
||||
|
@ -2490,7 +2625,7 @@ pub fn range_to_bounds(
|
|||
content_origin.y() + row_range.start as f32 * position_map.line_height - scroll_top;
|
||||
|
||||
for (idx, row) in row_range.enumerate() {
|
||||
let line_layout = &position_map.line_layouts[(row - start_row) as usize];
|
||||
let line_layout = &position_map.line_layouts[(row - start_row) as usize].line;
|
||||
|
||||
let start_x = if row == range.start.row() {
|
||||
content_origin.x() + line_layout.x_for_index(range.start.column() as usize)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::cmp;
|
||||
|
||||
use gpui::{text_layout, ViewContext};
|
||||
use gpui::ViewContext;
|
||||
use language::Point;
|
||||
|
||||
use crate::{display_map::ToDisplayPoint, Editor, EditorMode};
|
||||
use crate::{display_map::ToDisplayPoint, Editor, EditorMode, LineWithInvisibles};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum Autoscroll {
|
||||
|
@ -172,7 +172,7 @@ impl Editor {
|
|||
viewport_width: f32,
|
||||
scroll_width: f32,
|
||||
max_glyph_width: f32,
|
||||
layouts: &[text_layout::Line],
|
||||
layouts: &[LineWithInvisibles],
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> bool {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
|
@ -194,10 +194,13 @@ impl Editor {
|
|||
let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
|
||||
target_left = target_left.min(
|
||||
layouts[(head.row() - start_row) as usize]
|
||||
.line
|
||||
.x_for_index(start_column as usize),
|
||||
);
|
||||
target_right = target_right.max(
|
||||
layouts[(head.row() - start_row) as usize].x_for_index(end_column as usize)
|
||||
layouts[(head.row() - start_row) as usize]
|
||||
.line
|
||||
.x_for_index(end_column as usize)
|
||||
+ max_glyph_width,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
json::{ToJson, Value},
|
||||
text_layout::{Invisible, Line, RunStyle, ShapedBoundary},
|
||||
text_layout::{Line, RunStyle, ShapedBoundary},
|
||||
AppContext, Element, FontCache, LayoutContext, SceneBuilder, SizeConstraint, TextLayoutCache,
|
||||
View, ViewContext,
|
||||
};
|
||||
|
@ -114,11 +114,7 @@ impl<V: View> Element<V> for Text {
|
|||
} else {
|
||||
result = None;
|
||||
}
|
||||
result.map(|(chunk, style)| HighlightedChunk {
|
||||
chunk,
|
||||
style,
|
||||
is_tab: false,
|
||||
})
|
||||
result
|
||||
});
|
||||
|
||||
// Perform shaping on these highlighted chunks
|
||||
|
@ -129,7 +125,6 @@ impl<V: View> Element<V> for Text {
|
|||
&cx.font_cache,
|
||||
usize::MAX,
|
||||
self.text.matches('\n').count() + 1,
|
||||
false,
|
||||
);
|
||||
|
||||
// If line wrapping is enabled, wrap each of the shaped lines.
|
||||
|
@ -342,45 +337,24 @@ impl<V: View> Element<V> for Text {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct HighlightedChunk<'a> {
|
||||
pub chunk: &'a str,
|
||||
pub style: Option<HighlightStyle>,
|
||||
pub is_tab: bool,
|
||||
}
|
||||
|
||||
impl<'a> HighlightedChunk<'a> {
|
||||
fn plain_str(str_symbols: &'a str) -> Self {
|
||||
Self {
|
||||
chunk: str_symbols,
|
||||
style: None,
|
||||
is_tab: str_symbols == "\t",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform text layout on a series of highlighted chunks of text.
|
||||
pub fn layout_highlighted_chunks<'a>(
|
||||
chunks: impl Iterator<Item = HighlightedChunk<'a>>,
|
||||
fn layout_highlighted_chunks<'a>(
|
||||
chunks: impl Iterator<Item = (&'a str, Option<HighlightStyle>)>,
|
||||
text_style: &TextStyle,
|
||||
text_layout_cache: &TextLayoutCache,
|
||||
font_cache: &Arc<FontCache>,
|
||||
max_line_len: usize,
|
||||
max_line_count: usize,
|
||||
show_invisibles: bool,
|
||||
) -> Vec<Line> {
|
||||
let mut layouts = Vec::with_capacity(max_line_count);
|
||||
let mut line = String::new();
|
||||
let mut invisibles = Vec::new();
|
||||
let mut styles = Vec::new();
|
||||
let mut row = 0;
|
||||
let mut line_exceeded_max_len = false;
|
||||
for highlighted_chunk in chunks.chain(std::iter::once(HighlightedChunk::plain_str("\n"))) {
|
||||
for (ix, mut line_chunk) in highlighted_chunk.chunk.split('\n').enumerate() {
|
||||
for (chunk, highlight_style) in chunks.chain([("\n", Default::default())]) {
|
||||
for (ix, mut line_chunk) in chunk.split('\n').enumerate() {
|
||||
if ix > 0 {
|
||||
let mut laid_out_line =
|
||||
text_layout_cache.layout_str(&line, text_style.font_size, &styles);
|
||||
laid_out_line.invisibles.extend(invisibles.drain(..));
|
||||
layouts.push(laid_out_line);
|
||||
layouts.push(text_layout_cache.layout_str(&line, text_style.font_size, &styles));
|
||||
line.clear();
|
||||
styles.clear();
|
||||
row += 1;
|
||||
|
@ -391,7 +365,7 @@ pub fn layout_highlighted_chunks<'a>(
|
|||
}
|
||||
|
||||
if !line_chunk.is_empty() && !line_exceeded_max_len {
|
||||
let text_style = if let Some(style) = highlighted_chunk.style {
|
||||
let text_style = if let Some(style) = highlight_style {
|
||||
text_style
|
||||
.clone()
|
||||
.highlight(style, font_cache)
|
||||
|
@ -410,6 +384,7 @@ pub fn layout_highlighted_chunks<'a>(
|
|||
line_exceeded_max_len = true;
|
||||
}
|
||||
|
||||
line.push_str(line_chunk);
|
||||
styles.push((
|
||||
line_chunk.len(),
|
||||
RunStyle {
|
||||
|
@ -418,12 +393,6 @@ pub fn layout_highlighted_chunks<'a>(
|
|||
underline: text_style.underline,
|
||||
},
|
||||
));
|
||||
if show_invisibles && highlighted_chunk.is_tab {
|
||||
invisibles.push(Invisible::Tab {
|
||||
range: line.len()..line.len() + line_chunk.len(),
|
||||
});
|
||||
}
|
||||
line.push_str(line_chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use crate::{
|
|||
window::WindowContext,
|
||||
SceneBuilder,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use ordered_float::OrderedFloat;
|
||||
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
|
||||
use smallvec::SmallVec;
|
||||
|
@ -179,7 +178,6 @@ impl<'a> Hash for CacheKeyRef<'a> {
|
|||
pub struct Line {
|
||||
layout: Arc<LineLayout>,
|
||||
style_runs: SmallVec<[StyleRun; 32]>,
|
||||
pub invisibles: SmallVec<[Invisible; 32]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -215,8 +213,8 @@ pub struct Glyph {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Invisible {
|
||||
Tab { range: std::ops::Range<usize> },
|
||||
Whitespace { range: std::ops::Range<usize> },
|
||||
Tab { line_start_offset: usize },
|
||||
Whitespace { line_range: std::ops::Range<usize> },
|
||||
}
|
||||
|
||||
impl Line {
|
||||
|
@ -229,11 +227,7 @@ impl Line {
|
|||
underline: style.underline,
|
||||
});
|
||||
}
|
||||
Self {
|
||||
layout,
|
||||
style_runs,
|
||||
invisibles: SmallVec::new(),
|
||||
}
|
||||
Self { layout, style_runs }
|
||||
}
|
||||
|
||||
pub fn runs(&self) -> &[Run] {
|
||||
|
@ -310,16 +304,6 @@ impl Line {
|
|||
let mut color = Color::black();
|
||||
let mut underline = None;
|
||||
|
||||
let tab_ranges = self
|
||||
.invisibles
|
||||
.iter()
|
||||
.filter_map(|invisible| match invisible {
|
||||
Invisible::Tab { range } => Some(range),
|
||||
Invisible::Whitespace { .. } => None,
|
||||
})
|
||||
.sorted_by(|tab_range_1, tab_range_2| tab_range_1.start.cmp(&tab_range_2.start))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for run in &self.layout.runs {
|
||||
let max_glyph_width = cx
|
||||
.font_cache
|
||||
|
@ -386,19 +370,10 @@ impl Line {
|
|||
origin: glyph_origin,
|
||||
});
|
||||
} else {
|
||||
let id = if tab_ranges.iter().any(|tab_range| {
|
||||
tab_range.start <= glyph.index && glyph.index < tab_range.end
|
||||
}) {
|
||||
// TODO kb get a proper (cached) glyph
|
||||
glyph.id + 100
|
||||
} else {
|
||||
glyph.id
|
||||
};
|
||||
|
||||
scene.push_glyph(scene::Glyph {
|
||||
font_id: run.font_id,
|
||||
font_size: self.layout.font_size,
|
||||
id,
|
||||
id: glyph.id,
|
||||
origin: glyph_origin,
|
||||
color,
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue