mirror of
https://github.com/penpot/penpot.git
synced 2025-07-11 01:17:19 +02:00
🔧 Add vertical alignment for text shapes
This commit is contained in:
parent
0010d61ae2
commit
134fb1ab4c
8 changed files with 2436 additions and 1 deletions
2365
frontend/playwright/data/render-wasm/get-file-text-align.json
Normal file
2365
frontend/playwright/data/render-wasm/get-file-text-align.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -162,3 +162,16 @@ test("Renders a file with multiple emoji", async ({ page }) => {
|
|||
await workspace.waitForFirstRender();
|
||||
await expect(workspace.canvas).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("Renders a file with texts with different alignments", async ({ page }) => {
|
||||
const workspace = new WasmWorkspacePage(page);
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("render-wasm/get-file-text-align.json");
|
||||
|
||||
await workspace.goToWorkspace({
|
||||
id: "692f368b-63ca-8141-8006-62925640b827",
|
||||
pageId: "692f368b-63ca-8141-8006-62925640b828",
|
||||
});
|
||||
await workspace.waitForFirstRender();
|
||||
await expect(workspace.canvas).toHaveScreenshot();
|
||||
});
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
|
@ -236,6 +236,7 @@
|
|||
|
||||
(defn set-shape-text-images
|
||||
[shape-id content]
|
||||
|
||||
(let [paragraph-set (first (get content :children))
|
||||
paragraphs (get paragraph-set :children)]
|
||||
(->> paragraphs
|
||||
|
@ -357,6 +358,10 @@
|
|||
;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html
|
||||
(h/call wasm/internal-module "_set_shape_blend_mode" (sr/translate-blend-mode blend-mode)))
|
||||
|
||||
(defn set-shape-vertical-align
|
||||
[vertical-align]
|
||||
(h/call wasm/internal-module "_set_shape_vertical_align" (sr/serialize-vertical-align vertical-align)))
|
||||
|
||||
(defn set-shape-opacity
|
||||
[opacity]
|
||||
(h/call wasm/internal-module "_set_shape_opacity" (or opacity 1)))
|
||||
|
@ -630,6 +635,8 @@
|
|||
(defn set-shape-text-content
|
||||
[shape-id content]
|
||||
(h/call wasm/internal-module "_clear_shape_text")
|
||||
(set-shape-vertical-align (dm/get-prop content :vertical-align))
|
||||
|
||||
(let [paragraph-set (first (dm/get-prop content :children))
|
||||
paragraphs (dm/get-prop paragraph-set :children)
|
||||
fonts (fonts/get-content-fonts content)
|
||||
|
@ -752,6 +759,7 @@
|
|||
(when (some? shadows) (set-shape-shadows shadows))
|
||||
(when (= type :text)
|
||||
(set-shape-grow-type grow-type))
|
||||
|
||||
(when (or (ctl/any-layout? shape)
|
||||
(ctl/any-layout-immediate-child? objects shape))
|
||||
(set-layout-child shape))
|
||||
|
|
|
@ -295,6 +295,10 @@
|
|||
[value enum-map]
|
||||
(get enum-map value 0))
|
||||
|
||||
(defn serialize-vertical-align
|
||||
[vertical-align]
|
||||
(serialize-enum vertical-align {"top" 0 "center" 1 "bottom" 2}))
|
||||
|
||||
(defn serialize-text-align
|
||||
[text-align]
|
||||
(serialize-enum text-align {"left" 0 "center" 1 "right" 2 "justify" 3}))
|
||||
|
|
|
@ -19,6 +19,7 @@ use math::{Bounds, Matrix};
|
|||
use mem::SerializableResult;
|
||||
use shapes::{
|
||||
BoolType, ConstraintH, ConstraintV, StructureEntry, StructureEntryType, TransformEntry, Type,
|
||||
VerticalAlign,
|
||||
};
|
||||
use skia_safe as skia;
|
||||
use state::State;
|
||||
|
@ -346,6 +347,13 @@ pub extern "C" fn set_shape_blend_mode(mode: i32) {
|
|||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_shape_vertical_align(align: u8) {
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
shape.set_vertical_align(VerticalAlign::from(align));
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_shape_opacity(opacity: f32) {
|
||||
with_current_shape!(state, |shape: &mut Shape| {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{RenderState, Shape, SurfaceId};
|
||||
use crate::shapes::VerticalAlign;
|
||||
use skia_safe::{textlayout::Paragraph, Paint, Path};
|
||||
|
||||
pub fn render(
|
||||
|
@ -11,8 +12,16 @@ pub fn render(
|
|||
.surfaces
|
||||
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
||||
|
||||
let container_height = shape.selrect().height();
|
||||
for group in paragraphs {
|
||||
let mut offset_y = 0.0;
|
||||
let total_paragraphs_height: f32 = group.iter().map(|p| p.height()).sum();
|
||||
|
||||
let mut offset_y = match shape.vertical_align() {
|
||||
VerticalAlign::Center => (container_height - total_paragraphs_height) / 2.0,
|
||||
VerticalAlign::Bottom => container_height - total_paragraphs_height,
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
for skia_paragraph in group {
|
||||
let xy = (shape.selrect().x(), shape.selrect.y() + offset_y);
|
||||
skia_paragraph.paint(canvas, xy);
|
||||
|
|
|
@ -156,6 +156,24 @@ impl ConstraintH {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
pub enum VerticalAlign {
|
||||
Top,
|
||||
Center,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
impl VerticalAlign {
|
||||
pub fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Self::Top,
|
||||
1 => Self::Center,
|
||||
2 => Self::Bottom,
|
||||
_ => Self::Top,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
pub enum ConstraintV {
|
||||
Top,
|
||||
|
@ -195,6 +213,7 @@ pub struct Shape {
|
|||
pub fills: Vec<Fill>,
|
||||
pub strokes: Vec<Stroke>,
|
||||
pub blend_mode: BlendMode,
|
||||
pub vertical_align: VerticalAlign,
|
||||
pub blur: Blur,
|
||||
pub opacity: f32,
|
||||
pub hidden: bool,
|
||||
|
@ -221,6 +240,7 @@ impl Shape {
|
|||
fills: Vec::with_capacity(1),
|
||||
strokes: Vec::with_capacity(1),
|
||||
blend_mode: BlendMode::default(),
|
||||
vertical_align: VerticalAlign::Top,
|
||||
opacity: 1.,
|
||||
hidden: false,
|
||||
blur: Blur::default(),
|
||||
|
@ -312,6 +332,14 @@ impl Shape {
|
|||
self.opacity = opacity;
|
||||
}
|
||||
|
||||
pub fn set_vertical_align(&mut self, align: VerticalAlign) {
|
||||
self.vertical_align = align;
|
||||
}
|
||||
|
||||
pub fn vertical_align(&self) -> VerticalAlign {
|
||||
self.vertical_align
|
||||
}
|
||||
|
||||
pub fn set_constraint_h(&mut self, constraint: Option<ConstraintH>) {
|
||||
self.constraint_h = constraint;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue