mirror of
https://github.com/penpot/penpot.git
synced 2026-09-10 14:09:17 +00:00
Merge pull request #8811 from penpot/alotor-fix-position-data
🐛 Fix problem with position data in new render
This commit is contained in:
commit
486a08189e
@ -1643,45 +1643,42 @@
|
|||||||
(+ offset POSITION-DATA-U32-SIZE)))
|
(+ offset POSITION-DATA-U32-SIZE)))
|
||||||
(persistent! result)))
|
(persistent! result)))
|
||||||
|
|
||||||
result
|
content (:content shape)]
|
||||||
(into []
|
|
||||||
(keep
|
|
||||||
(fn [{:keys [paragraph span start-pos end-pos direction x y width height]}]
|
|
||||||
(let [content (:content shape)
|
|
||||||
element (-> content :children
|
|
||||||
(get 0) :children ;; paragraph-set
|
|
||||||
(get paragraph) :children ;; paragraph
|
|
||||||
(get span))
|
|
||||||
element-text (:text element)]
|
|
||||||
|
|
||||||
;; Add comprehensive nil-safety checks
|
|
||||||
(when (and element
|
|
||||||
element-text
|
|
||||||
(>= start-pos 0)
|
|
||||||
(<= end-pos (count element-text))
|
|
||||||
(<= start-pos end-pos))
|
|
||||||
(let [text (subs element-text start-pos end-pos)]
|
|
||||||
(d/patch-object
|
|
||||||
txt/default-text-attrs
|
|
||||||
(d/without-nils
|
|
||||||
{:x x
|
|
||||||
:y (+ y height)
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:direction (dr/translate-direction direction)
|
|
||||||
:font-family (get element :font-family)
|
|
||||||
:font-size (get element :font-size)
|
|
||||||
:font-weight (get element :font-weight)
|
|
||||||
:text-transform (get element :text-transform)
|
|
||||||
:text-decoration (get element :text-decoration)
|
|
||||||
:letter-spacing (get element :letter-spacing)
|
|
||||||
:font-style (get element :font-style)
|
|
||||||
:fills (get element :fills)
|
|
||||||
:text text})))))))
|
|
||||||
result)]
|
|
||||||
(mem/free)
|
(mem/free)
|
||||||
|
|
||||||
result)))
|
(into []
|
||||||
|
(keep
|
||||||
|
(fn [{:keys [paragraph span start-pos end-pos direction x y width height]}]
|
||||||
|
(let [element (-> content :children
|
||||||
|
(get 0) :children ;; paragraph-set
|
||||||
|
(get paragraph) :children ;; paragraph
|
||||||
|
(get span))
|
||||||
|
element-text (:text element)]
|
||||||
|
|
||||||
|
;; Add comprehensive nil-safety checks
|
||||||
|
;; Be aware that for RTL texts `start-pos` can be greatert han `end-pos`
|
||||||
|
(when (and element element-text)
|
||||||
|
(let [text (subs element-text start-pos end-pos)]
|
||||||
|
(d/patch-object
|
||||||
|
txt/default-text-attrs
|
||||||
|
(d/without-nils
|
||||||
|
{:x x
|
||||||
|
:y (+ y height)
|
||||||
|
:width width
|
||||||
|
:height height
|
||||||
|
:direction (dr/translate-direction direction)
|
||||||
|
:font-id (get element :font-id)
|
||||||
|
:font-family (get element :font-family)
|
||||||
|
:font-size (get element :font-size)
|
||||||
|
:font-weight (get element :font-weight)
|
||||||
|
:text-transform (get element :text-transform)
|
||||||
|
:text-decoration (get element :text-decoration)
|
||||||
|
:letter-spacing (get element :letter-spacing)
|
||||||
|
:font-style (get element :font-style)
|
||||||
|
:fills (get element :fills)
|
||||||
|
:text text})))))))
|
||||||
|
result))))
|
||||||
|
|
||||||
(defn apply-canvas-blur
|
(defn apply-canvas-blur
|
||||||
[]
|
[]
|
||||||
|
|||||||
@ -1378,67 +1378,45 @@ pub fn calculate_text_layout_data(
|
|||||||
let current_y = para_layout.y;
|
let current_y = para_layout.y;
|
||||||
let text_paragraph = text_paragraphs.get(paragraph_index);
|
let text_paragraph = text_paragraphs.get(paragraph_index);
|
||||||
if let Some(text_para) = text_paragraph {
|
if let Some(text_para) = text_paragraph {
|
||||||
let mut span_ranges: Vec<(usize, usize, usize, String, String)> = vec![];
|
let mut span_ranges: Vec<(usize, usize, usize)> = vec![];
|
||||||
let mut cur = 0;
|
let mut cur = 0;
|
||||||
for (span_index, span) in text_para.children().iter().enumerate() {
|
for (span_index, span) in text_para.children().iter().enumerate() {
|
||||||
let transformed_text: String = span.apply_text_transform();
|
let text: String = span.apply_text_transform();
|
||||||
let original_text = span.text.clone();
|
let text_len = text.encode_utf16().count();
|
||||||
let text = transformed_text.clone();
|
span_ranges.push((cur, cur + text_len + 1, span_index));
|
||||||
let text_len = text.len();
|
|
||||||
span_ranges.push((cur, cur + text_len, span_index, text, original_text));
|
|
||||||
cur += text_len;
|
cur += text_len;
|
||||||
}
|
}
|
||||||
for (start, end, span_index, transformed_text, original_text) in span_ranges {
|
for (start, end, span_index) in span_ranges {
|
||||||
// Skip empty spans to avoid invalid rect calculations
|
|
||||||
if start >= end {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let rects = para_layout.paragraph.get_rects_for_range(
|
let rects = para_layout.paragraph.get_rects_for_range(
|
||||||
start..end,
|
start..end,
|
||||||
RectHeightStyle::Tight,
|
RectHeightStyle::Tight,
|
||||||
RectWidthStyle::Tight,
|
RectWidthStyle::Tight,
|
||||||
);
|
);
|
||||||
|
|
||||||
for textbox in rects {
|
for textbox in rects {
|
||||||
let direction = textbox.direct;
|
let direction = textbox.direct;
|
||||||
let mut rect = textbox.rect;
|
let mut rect = textbox.rect;
|
||||||
let cy = rect.top + rect.height() / 2.0;
|
let cy = rect.top + rect.height() / 2.0;
|
||||||
|
|
||||||
// Get byte positions from Skia's transformed text layout
|
// Get byte positions from Skia's transformed text layout
|
||||||
let glyph_start = para_layout
|
let start_pos = para_layout
|
||||||
.paragraph
|
.paragraph
|
||||||
.get_glyph_position_at_coordinate((rect.left + 0.1, cy))
|
.get_glyph_position_at_coordinate((rect.left + 0.1, cy))
|
||||||
.position as usize;
|
.position as usize
|
||||||
let glyph_end = para_layout
|
- start;
|
||||||
|
|
||||||
|
let end_pos = para_layout
|
||||||
.paragraph
|
.paragraph
|
||||||
.get_glyph_position_at_coordinate((rect.right - 0.1, cy))
|
.get_glyph_position_at_coordinate((rect.right - 0.1, cy))
|
||||||
.position as usize;
|
.position as usize
|
||||||
|
- start;
|
||||||
// Convert to byte positions relative to this span
|
|
||||||
let byte_start = glyph_start.saturating_sub(start);
|
|
||||||
let byte_end = glyph_end.saturating_sub(start);
|
|
||||||
|
|
||||||
// Convert byte positions to character positions in ORIGINAL text
|
|
||||||
// This handles multi-byte UTF-8 and text transform differences
|
|
||||||
let char_start = transformed_text
|
|
||||||
.char_indices()
|
|
||||||
.position(|(i, _)| i >= byte_start)
|
|
||||||
.unwrap_or(0);
|
|
||||||
let char_end = transformed_text
|
|
||||||
.char_indices()
|
|
||||||
.position(|(i, _)| i >= byte_end)
|
|
||||||
.unwrap_or_else(|| transformed_text.chars().count());
|
|
||||||
|
|
||||||
// Clamp to original text length for safety
|
|
||||||
let original_char_count = original_text.chars().count();
|
|
||||||
let final_start = char_start.min(original_char_count);
|
|
||||||
let final_end = char_end.min(original_char_count);
|
|
||||||
|
|
||||||
rect.offset((x, current_y));
|
rect.offset((x, current_y));
|
||||||
position_data.push(PositionData {
|
position_data.push(PositionData {
|
||||||
paragraph: paragraph_index as u32,
|
paragraph: paragraph_index as u32,
|
||||||
span: span_index as u32,
|
span: span_index as u32,
|
||||||
start_pos: final_start as u32,
|
start_pos: start_pos as u32,
|
||||||
end_pos: final_end as u32,
|
end_pos: end_pos as u32,
|
||||||
x: rect.x(),
|
x: rect.x(),
|
||||||
y: rect.y(),
|
y: rect.y(),
|
||||||
width: rect.width(),
|
width: rect.width(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user