mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
Merge pull request #7748 from penpot/elenatorro-12586-fix-offset-y-on-new-lines
🐛 Fix new lines spacing between paragraphs
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -347,6 +347,23 @@ test("Renders a file with texts with with text spans of different sizes", async
|
|||||||
await expect(workspace.canvas).toHaveScreenshot();
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Renders a file with texts with paragraphs and breaking lines", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const workspace = new WasmWorkspacePage(page);
|
||||||
|
await workspace.setupEmptyFile();
|
||||||
|
await workspace.mockGetFile(
|
||||||
|
"render-wasm/get-file-text-paragraph-new-lines.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
await workspace.goToWorkspace({
|
||||||
|
id: "a5f238bd-dd8a-8164-8007-1bc3481eaf05",
|
||||||
|
pageId: "a5f238bd-dd8a-8164-8007-1bc3481eaf06",
|
||||||
|
});
|
||||||
|
await workspace.waitForFirstRender();
|
||||||
|
await expect(workspace.canvas).toHaveScreenshot();
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: enable this test once we use the wasm renderer in the new editor
|
// TODO: enable this test once we use the wasm renderer in the new editor
|
||||||
test.skip("Renders a file with texts with tabs", async ({ page }) => {
|
test.skip("Renders a file with texts with tabs", async ({ page }) => {
|
||||||
const workspace = new WasmWorkspacePage(page);
|
const workspace = new WasmWorkspacePage(page);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
@@ -119,13 +119,6 @@
|
|||||||
[paragraph]
|
[paragraph]
|
||||||
(some #(not= "" (:text % "")) (:children paragraph)))
|
(some #(not= "" (:text % "")) (:children paragraph)))
|
||||||
|
|
||||||
(defn should-filter-empty-paragraph?
|
|
||||||
[paragraphs index]
|
|
||||||
(and (not (has-content? (nth paragraphs index)))
|
|
||||||
(< index (count paragraphs))
|
|
||||||
(some has-content? (drop (inc index) paragraphs))
|
|
||||||
(every? #(not (has-content? %)) (take (inc index) paragraphs))))
|
|
||||||
|
|
||||||
(defn create-inline
|
(defn create-inline
|
||||||
[inline paragraph]
|
[inline paragraph]
|
||||||
(create-element
|
(create-element
|
||||||
@@ -150,7 +143,6 @@
|
|||||||
paragraphs (get-in root [:children 0 :children])
|
paragraphs (get-in root [:children 0 :children])
|
||||||
filtered-paragraphs (->> paragraphs
|
filtered-paragraphs (->> paragraphs
|
||||||
(map-indexed vector)
|
(map-indexed vector)
|
||||||
(remove (fn [[index _]] (should-filter-empty-paragraph? paragraphs index)))
|
|
||||||
(mapv second))]
|
(mapv second))]
|
||||||
(create-element
|
(create-element
|
||||||
"div"
|
"div"
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ fn draw_text(
|
|||||||
|
|
||||||
let layer_rec = SaveLayerRec::default();
|
let layer_rec = SaveLayerRec::default();
|
||||||
canvas.save_layer(&layer_rec);
|
canvas.save_layer(&layer_rec);
|
||||||
|
let mut normalized_line_height = text_content.normalized_line_height();
|
||||||
|
|
||||||
for paragraph_builder_group in paragraph_builder_groups {
|
for paragraph_builder_group in paragraph_builder_groups {
|
||||||
let mut group_offset_y = global_offset_y;
|
let mut group_offset_y = global_offset_y;
|
||||||
@@ -228,8 +229,14 @@ fn draw_text(
|
|||||||
let xy = (shape.selrect().x(), shape.selrect().y() + group_offset_y);
|
let xy = (shape.selrect().x(), shape.selrect().y() + group_offset_y);
|
||||||
paragraph.paint(canvas, xy);
|
paragraph.paint(canvas, xy);
|
||||||
|
|
||||||
|
let line_metrics = paragraph.get_line_metrics();
|
||||||
if paragraph_index == group_len - 1 {
|
if paragraph_index == group_len - 1 {
|
||||||
group_offset_y += paragraph.ideographic_baseline();
|
if line_metrics.is_empty() {
|
||||||
|
group_offset_y += normalized_line_height;
|
||||||
|
} else {
|
||||||
|
normalized_line_height = paragraph.ideographic_baseline();
|
||||||
|
group_offset_y += paragraph.ideographic_baseline() * line_metrics.len() as f32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for line_metrics in paragraph.get_line_metrics().iter() {
|
for line_metrics in paragraph.get_line_metrics().iter() {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ pub struct TextContentSize {
|
|||||||
pub width: f32,
|
pub width: f32,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
pub max_width: f32,
|
pub max_width: f32,
|
||||||
|
pub normalized_line_height: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_TEXT_CONTENT_SIZE: f32 = 0.01;
|
const DEFAULT_TEXT_CONTENT_SIZE: f32 = 0.01;
|
||||||
@@ -48,14 +49,7 @@ impl TextContentSize {
|
|||||||
width: DEFAULT_TEXT_CONTENT_SIZE,
|
width: DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
height: DEFAULT_TEXT_CONTENT_SIZE,
|
height: DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
max_width: DEFAULT_TEXT_CONTENT_SIZE,
|
max_width: DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
}
|
normalized_line_height: 0.0,
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(width: f32, height: f32, max_width: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
max_width,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +58,21 @@ impl TextContentSize {
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
max_width: DEFAULT_TEXT_CONTENT_SIZE,
|
max_width: DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
|
normalized_line_height: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_normalized_line_height(
|
||||||
|
width: f32,
|
||||||
|
height: f32,
|
||||||
|
max_width: f32,
|
||||||
|
normalized_line_height: f32,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
max_width,
|
||||||
|
normalized_line_height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +102,9 @@ impl TextContentSize {
|
|||||||
} else {
|
} else {
|
||||||
self.height = default_height;
|
self.height = default_height;
|
||||||
}
|
}
|
||||||
|
if f32::is_finite(size.normalized_line_height) {
|
||||||
|
self.normalized_line_height = size.normalized_line_height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +244,10 @@ impl TextContent {
|
|||||||
self.size.width
|
self.size.width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn normalized_line_height(&self) -> f32 {
|
||||||
|
self.size.normalized_line_height
|
||||||
|
}
|
||||||
|
|
||||||
pub fn grow_type(&self) -> GrowType {
|
pub fn grow_type(&self) -> GrowType {
|
||||||
self.grow_type
|
self.grow_type
|
||||||
}
|
}
|
||||||
@@ -400,9 +416,33 @@ impl TextContent {
|
|||||||
paragraphs
|
paragraphs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the normalized line height from paragraph builders
|
||||||
|
fn calculate_normalized_line_height(
|
||||||
|
&self,
|
||||||
|
paragraph_builders: &mut [ParagraphBuilderGroup],
|
||||||
|
width: f32,
|
||||||
|
) -> f32 {
|
||||||
|
let mut normalized_line_height = 0.0;
|
||||||
|
for paragraph_builder_group in paragraph_builders.iter_mut() {
|
||||||
|
for paragraph_builder in paragraph_builder_group.iter_mut() {
|
||||||
|
let mut paragraph = paragraph_builder.build();
|
||||||
|
paragraph.layout(width);
|
||||||
|
let baseline = paragraph.ideographic_baseline();
|
||||||
|
if baseline > normalized_line_height {
|
||||||
|
normalized_line_height = baseline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
normalized_line_height
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs an Auto Width text layout.
|
/// Performs an Auto Width text layout.
|
||||||
fn text_layout_auto_width(&self) -> TextContentLayoutResult {
|
fn text_layout_auto_width(&self) -> TextContentLayoutResult {
|
||||||
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
||||||
|
|
||||||
|
let normalized_line_height =
|
||||||
|
self.calculate_normalized_line_height(&mut paragraph_builders, f32::MAX);
|
||||||
|
|
||||||
let paragraphs =
|
let paragraphs =
|
||||||
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, f32::MAX);
|
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, f32::MAX);
|
||||||
|
|
||||||
@@ -417,7 +457,12 @@ impl TextContent {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let size = TextContentSize::new(width.ceil(), height.ceil(), width.ceil());
|
let size = TextContentSize::new_with_normalized_line_height(
|
||||||
|
width.ceil(),
|
||||||
|
height.ceil(),
|
||||||
|
width.ceil(),
|
||||||
|
normalized_line_height,
|
||||||
|
);
|
||||||
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,6 +471,10 @@ impl TextContent {
|
|||||||
fn text_layout_auto_height(&self) -> TextContentLayoutResult {
|
fn text_layout_auto_height(&self) -> TextContentLayoutResult {
|
||||||
let width = self.width();
|
let width = self.width();
|
||||||
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
||||||
|
|
||||||
|
let normalized_line_height =
|
||||||
|
self.calculate_normalized_line_height(&mut paragraph_builders, width);
|
||||||
|
|
||||||
let paragraphs =
|
let paragraphs =
|
||||||
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, width);
|
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, width);
|
||||||
let height = paragraphs
|
let height = paragraphs
|
||||||
@@ -434,7 +483,12 @@ impl TextContent {
|
|||||||
.fold(0.0, |auto_height, paragraph| {
|
.fold(0.0, |auto_height, paragraph| {
|
||||||
auto_height + paragraph.height()
|
auto_height + paragraph.height()
|
||||||
});
|
});
|
||||||
let size = TextContentSize::new_with_size(width.ceil(), height.ceil());
|
let size = TextContentSize::new_with_normalized_line_height(
|
||||||
|
width,
|
||||||
|
height.ceil(),
|
||||||
|
DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
|
normalized_line_height,
|
||||||
|
);
|
||||||
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,6 +496,10 @@ impl TextContent {
|
|||||||
fn text_layout_fixed(&self) -> TextContentLayoutResult {
|
fn text_layout_fixed(&self) -> TextContentLayoutResult {
|
||||||
let width = self.width();
|
let width = self.width();
|
||||||
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
let mut paragraph_builders = self.paragraph_builder_group_from_text(None);
|
||||||
|
|
||||||
|
let normalized_line_height =
|
||||||
|
self.calculate_normalized_line_height(&mut paragraph_builders, width);
|
||||||
|
|
||||||
let paragraphs =
|
let paragraphs =
|
||||||
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, width);
|
self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, width);
|
||||||
let paragraph_height = paragraphs
|
let paragraph_height = paragraphs
|
||||||
@@ -451,7 +509,12 @@ impl TextContent {
|
|||||||
auto_height + paragraph.height()
|
auto_height + paragraph.height()
|
||||||
});
|
});
|
||||||
|
|
||||||
let size = TextContentSize::new_with_size(width.ceil(), paragraph_height.ceil());
|
let size = TextContentSize::new_with_normalized_line_height(
|
||||||
|
width,
|
||||||
|
paragraph_height.ceil(),
|
||||||
|
DEFAULT_TEXT_CONTENT_SIZE,
|
||||||
|
normalized_line_height,
|
||||||
|
);
|
||||||
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
TextContentLayoutResult(paragraph_builders, paragraphs, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user