Separate WrappedLines from ShapedLines
ShapedLines are never wrapped, whereas WrappedLines are optionally wrapped if they are associated with a wrap width. I tried to combine everything because wrapping is inherently optional for the Text element, but we have a bunch of APIs that don't make sense on a line that may wrap, so we need a distinct type for that case.
This commit is contained in:
parent
e5ada92b7b
commit
9558da8681
12 changed files with 563 additions and 330 deletions
|
@ -13,7 +13,8 @@ pub use block_map::{BlockMap, BlockPoint};
|
|||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use fold_map::FoldMap;
|
||||
use gpui::{
|
||||
Font, FontId, HighlightStyle, Hsla, Line, Model, ModelContext, Pixels, TextRun, UnderlineStyle,
|
||||
Font, FontId, HighlightStyle, Hsla, LineLayout, Model, ModelContext, Pixels, ShapedLine,
|
||||
TextRun, UnderlineStyle, WrappedLine,
|
||||
};
|
||||
use inlay_map::InlayMap;
|
||||
use language::{
|
||||
|
@ -561,7 +562,7 @@ impl DisplaySnapshot {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn lay_out_line_for_row(
|
||||
pub fn layout_row(
|
||||
&self,
|
||||
display_row: u32,
|
||||
TextLayoutDetails {
|
||||
|
@ -569,7 +570,7 @@ impl DisplaySnapshot {
|
|||
editor_style,
|
||||
rem_size,
|
||||
}: &TextLayoutDetails,
|
||||
) -> Line {
|
||||
) -> Arc<LineLayout> {
|
||||
let mut runs = Vec::new();
|
||||
let mut line = String::new();
|
||||
|
||||
|
@ -598,29 +599,27 @@ impl DisplaySnapshot {
|
|||
|
||||
let font_size = editor_style.text.font_size.to_pixels(*rem_size);
|
||||
text_system
|
||||
.layout_text(&line, font_size, &runs, None)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.layout_line(&line, font_size, &runs)
|
||||
.expect("we expect the font to be loaded because it's rendered by the editor")
|
||||
}
|
||||
|
||||
pub fn x_for_point(
|
||||
pub fn x_for_display_point(
|
||||
&self,
|
||||
display_point: DisplayPoint,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> Pixels {
|
||||
let layout_line = self.lay_out_line_for_row(display_point.row(), text_layout_details);
|
||||
layout_line.x_for_index(display_point.column() as usize)
|
||||
let line = self.layout_row(display_point.row(), text_layout_details);
|
||||
line.x_for_index(display_point.column() as usize)
|
||||
}
|
||||
|
||||
pub fn column_for_x(
|
||||
pub fn display_column_for_x(
|
||||
&self,
|
||||
display_row: u32,
|
||||
x_coordinate: Pixels,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
x: Pixels,
|
||||
details: &TextLayoutDetails,
|
||||
) -> u32 {
|
||||
let layout_line = self.lay_out_line_for_row(display_row, text_layout_details);
|
||||
layout_line.closest_index_for_x(x_coordinate) as u32
|
||||
let layout_line = self.layout_row(display_row, details);
|
||||
layout_line.closest_index_for_x(x) as u32
|
||||
}
|
||||
|
||||
pub fn chars_at(
|
||||
|
|
|
@ -5445,7 +5445,9 @@ impl Editor {
|
|||
*head.column_mut() += 1;
|
||||
head = display_map.clip_point(head, Bias::Right);
|
||||
let goal = SelectionGoal::HorizontalPosition(
|
||||
display_map.x_for_point(head, &text_layout_details).into(),
|
||||
display_map
|
||||
.x_for_display_point(head, &text_layout_details)
|
||||
.into(),
|
||||
);
|
||||
selection.collapse_to(head, goal);
|
||||
|
||||
|
@ -6391,8 +6393,8 @@ impl Editor {
|
|||
let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
|
||||
let range = oldest_selection.display_range(&display_map).sorted();
|
||||
|
||||
let start_x = display_map.x_for_point(range.start, &text_layout_details);
|
||||
let end_x = display_map.x_for_point(range.end, &text_layout_details);
|
||||
let start_x = display_map.x_for_display_point(range.start, &text_layout_details);
|
||||
let end_x = display_map.x_for_display_point(range.end, &text_layout_details);
|
||||
let positions = start_x.min(end_x)..start_x.max(end_x);
|
||||
|
||||
selections.clear();
|
||||
|
@ -6431,15 +6433,16 @@ impl Editor {
|
|||
let range = selection.display_range(&display_map).sorted();
|
||||
debug_assert_eq!(range.start.row(), range.end.row());
|
||||
let mut row = range.start.row();
|
||||
let positions = if let SelectionGoal::HorizontalRange { start, end } =
|
||||
selection.goal
|
||||
{
|
||||
px(start)..px(end)
|
||||
} else {
|
||||
let start_x = display_map.x_for_point(range.start, &text_layout_details);
|
||||
let end_x = display_map.x_for_point(range.end, &text_layout_details);
|
||||
start_x.min(end_x)..start_x.max(end_x)
|
||||
};
|
||||
let positions =
|
||||
if let SelectionGoal::HorizontalRange { start, end } = selection.goal {
|
||||
px(start)..px(end)
|
||||
} else {
|
||||
let start_x =
|
||||
display_map.x_for_display_point(range.start, &text_layout_details);
|
||||
let end_x =
|
||||
display_map.x_for_display_point(range.end, &text_layout_details);
|
||||
start_x.min(end_x)..start_x.max(end_x)
|
||||
};
|
||||
|
||||
while row != end_row {
|
||||
if above {
|
||||
|
@ -6992,7 +6995,7 @@ impl Editor {
|
|||
let display_point = point.to_display_point(display_snapshot);
|
||||
let goal = SelectionGoal::HorizontalPosition(
|
||||
display_snapshot
|
||||
.x_for_point(display_point, &text_layout_details)
|
||||
.x_for_display_point(display_point, &text_layout_details)
|
||||
.into(),
|
||||
);
|
||||
(display_point, goal)
|
||||
|
@ -9755,7 +9758,8 @@ impl InputHandler for Editor {
|
|||
let scroll_left = scroll_position.x * em_width;
|
||||
|
||||
let start = OffsetUtf16(range_utf16.start).to_display_point(&snapshot);
|
||||
let x = snapshot.x_for_point(start, &text_layout_details) - scroll_left + self.gutter_width;
|
||||
let x = snapshot.x_for_display_point(start, &text_layout_details) - scroll_left
|
||||
+ self.gutter_width;
|
||||
let y = line_height * (start.row() as f32 - scroll_position.y);
|
||||
|
||||
Some(Bounds {
|
||||
|
|
|
@ -20,10 +20,10 @@ use collections::{BTreeMap, HashMap};
|
|||
use gpui::{
|
||||
div, point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace,
|
||||
BorrowWindow, Bounds, Component, ContentMask, Corners, DispatchPhase, Edges, Element,
|
||||
ElementId, ElementInputHandler, Entity, EntityId, Hsla, InteractiveComponent, Line,
|
||||
ElementId, ElementInputHandler, Entity, EntityId, Hsla, InteractiveComponent, LineLayout,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentComponent, Pixels,
|
||||
ScrollWheelEvent, Size, StatefulInteractiveComponent, Style, Styled, TextRun, TextStyle, View,
|
||||
ViewContext, WindowContext,
|
||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveComponent, Style, Styled,
|
||||
TextRun, TextStyle, View, ViewContext, WindowContext, WrappedLine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::language_settings::ShowWhitespaceSetting;
|
||||
|
@ -476,7 +476,7 @@ impl EditorElement {
|
|||
Self::paint_diff_hunks(bounds, layout, cx);
|
||||
}
|
||||
|
||||
for (ix, line) in layout.line_number_layouts.iter().enumerate() {
|
||||
for (ix, line) in layout.line_numbers.iter().enumerate() {
|
||||
if let Some(line) = line {
|
||||
let line_origin = bounds.origin
|
||||
+ point(
|
||||
|
@ -775,21 +775,21 @@ impl EditorElement {
|
|||
.chars_at(cursor_position)
|
||||
.next()
|
||||
.and_then(|(character, _)| {
|
||||
let text = character.to_string();
|
||||
let text = SharedString::from(character.to_string());
|
||||
let len = text.len();
|
||||
cx.text_system()
|
||||
.layout_text(
|
||||
&text,
|
||||
.shape_line(
|
||||
text,
|
||||
cursor_row_layout.font_size,
|
||||
&[TextRun {
|
||||
len: text.len(),
|
||||
len,
|
||||
font: self.style.text.font(),
|
||||
color: self.style.background,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.log_err()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
@ -1244,20 +1244,20 @@ impl EditorElement {
|
|||
let font_size = style.text.font_size.to_pixels(cx.rem_size());
|
||||
let layout = cx
|
||||
.text_system()
|
||||
.layout_text(
|
||||
" ".repeat(column).as_str(),
|
||||
.shape_line(
|
||||
SharedString::from(" ".repeat(column)),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: column,
|
||||
font: style.text.font(),
|
||||
color: Hsla::default(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
layout[0].width
|
||||
layout.width
|
||||
}
|
||||
|
||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &ViewContext<Editor>) -> Pixels {
|
||||
|
@ -1338,7 +1338,7 @@ impl EditorElement {
|
|||
relative_rows
|
||||
}
|
||||
|
||||
fn layout_line_numbers(
|
||||
fn shape_line_numbers(
|
||||
&self,
|
||||
rows: Range<u32>,
|
||||
active_rows: &BTreeMap<u32, bool>,
|
||||
|
@ -1347,12 +1347,12 @@ impl EditorElement {
|
|||
snapshot: &EditorSnapshot,
|
||||
cx: &ViewContext<Editor>,
|
||||
) -> (
|
||||
Vec<Option<gpui::Line>>,
|
||||
Vec<Option<ShapedLine>>,
|
||||
Vec<Option<(FoldStatus, BufferRow, bool)>>,
|
||||
) {
|
||||
let font_size = self.style.text.font_size.to_pixels(cx.rem_size());
|
||||
let include_line_numbers = snapshot.mode == EditorMode::Full;
|
||||
let mut line_number_layouts = Vec::with_capacity(rows.len());
|
||||
let mut shaped_line_numbers = Vec::with_capacity(rows.len());
|
||||
let mut fold_statuses = Vec::with_capacity(rows.len());
|
||||
let mut line_number = String::new();
|
||||
let is_relative = EditorSettings::get_global(cx).relative_line_numbers;
|
||||
|
@ -1387,15 +1387,14 @@ impl EditorElement {
|
|||
len: line_number.len(),
|
||||
font: self.style.text.font(),
|
||||
color,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
};
|
||||
let layout = cx
|
||||
let shaped_line = cx
|
||||
.text_system()
|
||||
.layout_text(&line_number, font_size, &[run], None)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.shape_line(line_number.clone().into(), font_size, &[run])
|
||||
.unwrap();
|
||||
line_number_layouts.push(Some(layout));
|
||||
shaped_line_numbers.push(Some(shaped_line));
|
||||
fold_statuses.push(
|
||||
is_singleton
|
||||
.then(|| {
|
||||
|
@ -1408,17 +1407,17 @@ impl EditorElement {
|
|||
}
|
||||
} else {
|
||||
fold_statuses.push(None);
|
||||
line_number_layouts.push(None);
|
||||
shaped_line_numbers.push(None);
|
||||
}
|
||||
}
|
||||
|
||||
(line_number_layouts, fold_statuses)
|
||||
(shaped_line_numbers, fold_statuses)
|
||||
}
|
||||
|
||||
fn layout_lines(
|
||||
&mut self,
|
||||
rows: Range<u32>,
|
||||
line_number_layouts: &[Option<Line>],
|
||||
line_number_layouts: &[Option<ShapedLine>],
|
||||
snapshot: &EditorSnapshot,
|
||||
cx: &ViewContext<Editor>,
|
||||
) -> Vec<LineWithInvisibles> {
|
||||
|
@ -1439,18 +1438,17 @@ impl EditorElement {
|
|||
.chain(iter::repeat(""))
|
||||
.take(rows.len());
|
||||
placeholder_lines
|
||||
.map(|line| {
|
||||
.filter_map(move |line| {
|
||||
let run = TextRun {
|
||||
len: line.len(),
|
||||
font: self.style.text.font(),
|
||||
color: placeholder_color,
|
||||
background_color: None,
|
||||
underline: Default::default(),
|
||||
};
|
||||
cx.text_system()
|
||||
.layout_text(line, font_size, &[run], None)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.shape_line(line.to_string().into(), font_size, &[run])
|
||||
.log_err()
|
||||
})
|
||||
.map(|line| LineWithInvisibles {
|
||||
line,
|
||||
|
@ -1726,7 +1724,7 @@ impl EditorElement {
|
|||
.head
|
||||
});
|
||||
|
||||
let (line_number_layouts, fold_statuses) = self.layout_line_numbers(
|
||||
let (line_numbers, fold_statuses) = self.shape_line_numbers(
|
||||
start_row..end_row,
|
||||
&active_rows,
|
||||
head_for_relative,
|
||||
|
@ -1740,8 +1738,7 @@ impl EditorElement {
|
|||
let scrollbar_row_range = scroll_position.y..(scroll_position.y + height_in_lines);
|
||||
|
||||
let mut max_visible_line_width = Pixels::ZERO;
|
||||
let line_layouts =
|
||||
self.layout_lines(start_row..end_row, &line_number_layouts, &snapshot, cx);
|
||||
let line_layouts = self.layout_lines(start_row..end_row, &line_numbers, &snapshot, cx);
|
||||
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;
|
||||
|
@ -1879,35 +1876,31 @@ impl EditorElement {
|
|||
let invisible_symbol_font_size = font_size / 2.;
|
||||
let tab_invisible = cx
|
||||
.text_system()
|
||||
.layout_text(
|
||||
"→",
|
||||
.shape_line(
|
||||
"→".into(),
|
||||
invisible_symbol_font_size,
|
||||
&[TextRun {
|
||||
len: "→".len(),
|
||||
font: self.style.text.font(),
|
||||
color: cx.theme().colors().editor_invisible,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap();
|
||||
let space_invisible = cx
|
||||
.text_system()
|
||||
.layout_text(
|
||||
"•",
|
||||
.shape_line(
|
||||
"•".into(),
|
||||
invisible_symbol_font_size,
|
||||
&[TextRun {
|
||||
len: "•".len(),
|
||||
font: self.style.text.font(),
|
||||
color: cx.theme().colors().editor_invisible,
|
||||
background_color: None,
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap();
|
||||
|
||||
LayoutState {
|
||||
|
@ -1939,7 +1932,7 @@ impl EditorElement {
|
|||
active_rows,
|
||||
highlighted_rows,
|
||||
highlighted_ranges,
|
||||
line_number_layouts,
|
||||
line_numbers,
|
||||
display_hunks,
|
||||
blocks,
|
||||
selections,
|
||||
|
@ -2199,7 +2192,7 @@ impl EditorElement {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct LineWithInvisibles {
|
||||
pub line: Line,
|
||||
pub line: ShapedLine,
|
||||
invisibles: Vec<Invisible>,
|
||||
}
|
||||
|
||||
|
@ -2209,7 +2202,7 @@ impl LineWithInvisibles {
|
|||
text_style: &TextStyle,
|
||||
max_line_len: usize,
|
||||
max_line_count: usize,
|
||||
line_number_layouts: &[Option<Line>],
|
||||
line_number_layouts: &[Option<ShapedLine>],
|
||||
editor_mode: EditorMode,
|
||||
cx: &WindowContext,
|
||||
) -> Vec<Self> {
|
||||
|
@ -2229,11 +2222,12 @@ impl LineWithInvisibles {
|
|||
}]) {
|
||||
for (ix, mut line_chunk) in highlighted_chunk.chunk.split('\n').enumerate() {
|
||||
if ix > 0 {
|
||||
let layout = cx
|
||||
let shaped_line = cx
|
||||
.text_system()
|
||||
.layout_text(&line, font_size, &styles, None);
|
||||
.shape_line(line.clone().into(), font_size, &styles)
|
||||
.unwrap();
|
||||
layouts.push(Self {
|
||||
line: layout.unwrap().pop().unwrap(),
|
||||
line: shaped_line,
|
||||
invisibles: invisibles.drain(..).collect(),
|
||||
});
|
||||
|
||||
|
@ -2267,6 +2261,7 @@ impl LineWithInvisibles {
|
|||
len: line_chunk.len(),
|
||||
font: text_style.font(),
|
||||
color: text_style.color,
|
||||
background_color: None,
|
||||
underline: text_style.underline,
|
||||
});
|
||||
|
||||
|
@ -3087,7 +3082,7 @@ pub struct LayoutState {
|
|||
visible_display_row_range: Range<u32>,
|
||||
active_rows: BTreeMap<u32, bool>,
|
||||
highlighted_rows: Option<Range<u32>>,
|
||||
line_number_layouts: Vec<Option<gpui::Line>>,
|
||||
line_numbers: Vec<Option<ShapedLine>>,
|
||||
display_hunks: Vec<DisplayDiffHunk>,
|
||||
blocks: Vec<BlockLayout>,
|
||||
highlighted_ranges: Vec<(Range<DisplayPoint>, Hsla)>,
|
||||
|
@ -3100,8 +3095,8 @@ pub struct LayoutState {
|
|||
code_actions_indicator: Option<CodeActionsIndicator>,
|
||||
// hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>,
|
||||
fold_indicators: Vec<Option<AnyElement<Editor>>>,
|
||||
tab_invisible: Line,
|
||||
space_invisible: Line,
|
||||
tab_invisible: ShapedLine,
|
||||
space_invisible: ShapedLine,
|
||||
}
|
||||
|
||||
struct CodeActionsIndicator {
|
||||
|
@ -3201,7 +3196,7 @@ fn layout_line(
|
|||
snapshot: &EditorSnapshot,
|
||||
style: &EditorStyle,
|
||||
cx: &WindowContext,
|
||||
) -> Result<Line> {
|
||||
) -> Result<ShapedLine> {
|
||||
let mut line = snapshot.line(row);
|
||||
|
||||
if line.len() > MAX_LINE_LEN {
|
||||
|
@ -3213,21 +3208,17 @@ fn layout_line(
|
|||
line.truncate(len);
|
||||
}
|
||||
|
||||
Ok(cx
|
||||
.text_system()
|
||||
.layout_text(
|
||||
&line,
|
||||
style.text.font_size.to_pixels(cx.rem_size()),
|
||||
&[TextRun {
|
||||
len: snapshot.line_len(row) as usize,
|
||||
font: style.text.font(),
|
||||
color: Hsla::default(),
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
)?
|
||||
.pop()
|
||||
.unwrap())
|
||||
cx.text_system().shape_line(
|
||||
line.into(),
|
||||
style.text.font_size.to_pixels(cx.rem_size()),
|
||||
&[TextRun {
|
||||
len: snapshot.line_len(row) as usize,
|
||||
font: style.text.font(),
|
||||
color: Hsla::default(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
}],
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -3237,7 +3228,7 @@ pub struct Cursor {
|
|||
line_height: Pixels,
|
||||
color: Hsla,
|
||||
shape: CursorShape,
|
||||
block_text: Option<Line>,
|
||||
block_text: Option<ShapedLine>,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
|
@ -3247,7 +3238,7 @@ impl Cursor {
|
|||
line_height: Pixels,
|
||||
color: Hsla,
|
||||
shape: CursorShape,
|
||||
block_text: Option<Line>,
|
||||
block_text: Option<ShapedLine>,
|
||||
) -> Cursor {
|
||||
Cursor {
|
||||
origin,
|
||||
|
|
|
@ -98,7 +98,7 @@ pub fn up_by_rows(
|
|||
SelectionGoal::HorizontalPosition(x) => x.into(), // todo!("Can the fields in SelectionGoal by Pixels? We should extract a geometry crate and depend on that.")
|
||||
SelectionGoal::WrappedHorizontalPosition((_, x)) => x.into(),
|
||||
SelectionGoal::HorizontalRange { end, .. } => end.into(),
|
||||
_ => map.x_for_point(start, text_layout_details),
|
||||
_ => map.x_for_display_point(start, text_layout_details),
|
||||
};
|
||||
|
||||
let prev_row = start.row().saturating_sub(row_count);
|
||||
|
@ -107,7 +107,7 @@ pub fn up_by_rows(
|
|||
Bias::Left,
|
||||
);
|
||||
if point.row() < start.row() {
|
||||
*point.column_mut() = map.column_for_x(point.row(), goal_x, text_layout_details)
|
||||
*point.column_mut() = map.display_column_for_x(point.row(), goal_x, text_layout_details)
|
||||
} else if preserve_column_at_start {
|
||||
return (start, goal);
|
||||
} else {
|
||||
|
@ -137,18 +137,18 @@ pub fn down_by_rows(
|
|||
SelectionGoal::HorizontalPosition(x) => x.into(),
|
||||
SelectionGoal::WrappedHorizontalPosition((_, x)) => x.into(),
|
||||
SelectionGoal::HorizontalRange { end, .. } => end.into(),
|
||||
_ => map.x_for_point(start, text_layout_details),
|
||||
_ => map.x_for_display_point(start, text_layout_details),
|
||||
};
|
||||
|
||||
let new_row = start.row() + row_count;
|
||||
let mut point = map.clip_point(DisplayPoint::new(new_row, 0), Bias::Right);
|
||||
if point.row() > start.row() {
|
||||
*point.column_mut() = map.column_for_x(point.row(), goal_x, text_layout_details)
|
||||
*point.column_mut() = map.display_column_for_x(point.row(), goal_x, text_layout_details)
|
||||
} else if preserve_column_at_end {
|
||||
return (start, goal);
|
||||
} else {
|
||||
point = map.max_point();
|
||||
goal_x = map.x_for_point(point, text_layout_details)
|
||||
goal_x = map.x_for_display_point(point, text_layout_details)
|
||||
}
|
||||
|
||||
let mut clipped_point = map.clip_point(point, Bias::Right);
|
||||
|
|
|
@ -313,14 +313,14 @@ impl SelectionsCollection {
|
|||
let is_empty = positions.start == positions.end;
|
||||
let line_len = display_map.line_len(row);
|
||||
|
||||
let layed_out_line = display_map.lay_out_line_for_row(row, &text_layout_details);
|
||||
let line = display_map.layout_row(row, &text_layout_details);
|
||||
|
||||
dbg!("****START COL****");
|
||||
let start_col = layed_out_line.closest_index_for_x(positions.start) as u32;
|
||||
if start_col < line_len || (is_empty && positions.start == layed_out_line.width) {
|
||||
let start_col = line.closest_index_for_x(positions.start) as u32;
|
||||
if start_col < line_len || (is_empty && positions.start == line.width) {
|
||||
let start = DisplayPoint::new(row, start_col);
|
||||
dbg!("****END COL****");
|
||||
let end_col = layed_out_line.closest_index_for_x(positions.end) as u32;
|
||||
let end_col = line.closest_index_for_x(positions.end) as u32;
|
||||
let end = DisplayPoint::new(row, end_col);
|
||||
dbg!(start_col, end_col);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue