mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Fix slash char problems for embedded editor
This commit is contained in:
parent
052417cd10
commit
7c46a3f1e0
@ -123,6 +123,9 @@ fn calculate_cursor_rect(
|
||||
.map(|span| span.text.chars().count())
|
||||
.sum();
|
||||
|
||||
let layout_char_pos = para.logical_to_layout_offset(char_pos);
|
||||
let layout_para_count = para.logical_to_layout_offset(para_char_count);
|
||||
|
||||
let (cursor_x, cursor_height) = if para_char_count == 0 {
|
||||
// Empty paragraph - use default height
|
||||
(0.0, laid_out_para.height())
|
||||
@ -139,7 +142,7 @@ fn calculate_cursor_rect(
|
||||
}
|
||||
} else if char_pos >= para_char_count {
|
||||
let rects = laid_out_para.get_rects_for_range(
|
||||
para_char_count.saturating_sub(1)..para_char_count,
|
||||
layout_para_count.saturating_sub(1)..layout_para_count,
|
||||
RectHeightStyle::Max,
|
||||
RectWidthStyle::Tight,
|
||||
);
|
||||
@ -150,7 +153,7 @@ fn calculate_cursor_rect(
|
||||
}
|
||||
} else {
|
||||
let rects = laid_out_para.get_rects_for_range(
|
||||
char_pos..char_pos + 1,
|
||||
layout_char_pos..layout_char_pos + 1,
|
||||
RectHeightStyle::Max,
|
||||
RectWidthStyle::Tight,
|
||||
);
|
||||
@ -221,9 +224,11 @@ fn calculate_selection_rects(
|
||||
};
|
||||
|
||||
if range_start < range_end {
|
||||
let layout_range_start = para.logical_to_layout_offset(range_start);
|
||||
let layout_range_end = para.logical_to_layout_offset(range_end);
|
||||
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
|
||||
let text_boxes = laid_out_para.get_rects_for_range(
|
||||
range_start..range_end,
|
||||
layout_range_start..layout_range_end,
|
||||
RectHeightStyle::Max,
|
||||
RectWidthStyle::Tight,
|
||||
);
|
||||
|
||||
@ -522,10 +522,12 @@ impl TextContent {
|
||||
}
|
||||
}
|
||||
|
||||
let layout_offset = position_with_affinity.position as usize;
|
||||
let logical_offset = paragraph.layout_to_logical_offset(layout_offset);
|
||||
return Some(TextPositionWithAffinity::new(
|
||||
position_with_affinity,
|
||||
paragraph_index,
|
||||
position_with_affinity.position as usize,
|
||||
logical_offset,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -996,6 +998,49 @@ impl Paragraph {
|
||||
.iter_mut()
|
||||
.for_each(|l| l.scale_content(value));
|
||||
}
|
||||
|
||||
/// Convert a logical character offset (based on original span text)
|
||||
/// to a layout offset (as used by Skia). `apply_text_transform` inserts
|
||||
/// a zero-width space after each '/', so the layout text is longer.
|
||||
pub fn logical_to_layout_offset(&self, logical_offset: usize) -> usize {
|
||||
let mut pos = 0;
|
||||
let mut extra = 0;
|
||||
for span in self.children() {
|
||||
for ch in span.text.chars() {
|
||||
if pos >= logical_offset {
|
||||
return logical_offset + extra;
|
||||
}
|
||||
if ch == '/' {
|
||||
extra += 1;
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
logical_offset + extra
|
||||
}
|
||||
|
||||
/// Convert a layout character offset (from Skia, which includes
|
||||
/// zero-width spaces after '/') back to a logical offset.
|
||||
pub fn layout_to_logical_offset(&self, layout_offset: usize) -> usize {
|
||||
let mut logical_pos = 0;
|
||||
let mut layout_pos = 0;
|
||||
for span in self.children() {
|
||||
for ch in span.text.chars() {
|
||||
if layout_pos >= layout_offset {
|
||||
return logical_pos;
|
||||
}
|
||||
logical_pos += 1;
|
||||
layout_pos += 1;
|
||||
if ch == '/' {
|
||||
layout_pos += 1;
|
||||
if layout_pos > layout_offset {
|
||||
return logical_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logical_pos
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
|
||||
@ -851,7 +851,8 @@ fn get_cursor_rect(
|
||||
let mut y_offset = valign_offset;
|
||||
for (idx, laid_out_para) in layout_paragraphs.iter().enumerate() {
|
||||
if idx == cursor.paragraph {
|
||||
let char_pos = cursor.offset;
|
||||
let para = ¶graphs[idx];
|
||||
let char_pos = para.logical_to_layout_offset(cursor.offset);
|
||||
|
||||
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
|
||||
let rects = laid_out_para.get_rects_for_range(
|
||||
@ -938,9 +939,11 @@ fn get_selection_rects(
|
||||
};
|
||||
|
||||
if range_start < range_end {
|
||||
let layout_range_start = para.logical_to_layout_offset(range_start);
|
||||
let layout_range_end = para.logical_to_layout_offset(range_end);
|
||||
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
|
||||
let text_boxes = laid_out_para.get_rects_for_range(
|
||||
range_start..range_end,
|
||||
layout_range_start..layout_range_end,
|
||||
RectHeightStyle::Tight,
|
||||
RectWidthStyle::Tight,
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user