mirror of
https://github.com/penpot/penpot.git
synced 2025-06-27 22:37:02 +02:00
Merge pull request #6573 from penpot/elenatorro-11021-text-fixes
🔧 Fix text parsing and transformation
This commit is contained in:
commit
fe60016124
3 changed files with 52 additions and 17 deletions
|
@ -19,7 +19,7 @@ use options::RenderOptions;
|
||||||
use surfaces::{SurfaceId, Surfaces};
|
use surfaces::{SurfaceId, Surfaces};
|
||||||
|
|
||||||
use crate::performance;
|
use crate::performance;
|
||||||
use crate::shapes::{modified_children_ids, Corners, Shape, StructureEntry, Type};
|
use crate::shapes::{modified_children_ids, Corners, Shape, StrokeKind, StructureEntry, Type};
|
||||||
use crate::tiles::{self, TileRect, TileViewbox, TileWithDistance};
|
use crate::tiles::{self, TileRect, TileViewbox, TileWithDistance};
|
||||||
use crate::uuid::Uuid;
|
use crate::uuid::Uuid;
|
||||||
use crate::view::Viewbox;
|
use crate::view::Viewbox;
|
||||||
|
@ -423,9 +423,17 @@ impl RenderState {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Text(text_content) => {
|
Type::Text(text_content) => {
|
||||||
self.surfaces.apply_mut(&[SurfaceId::Fills], |s| {
|
self.surfaces.apply_mut(
|
||||||
|
&[
|
||||||
|
SurfaceId::Fills,
|
||||||
|
SurfaceId::Strokes,
|
||||||
|
SurfaceId::DropShadows,
|
||||||
|
SurfaceId::InnerShadows,
|
||||||
|
],
|
||||||
|
|s| {
|
||||||
s.canvas().concat(&matrix);
|
s.canvas().concat(&matrix);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let text_content = text_content.new_bounds(shape.selrect());
|
let text_content = text_content.new_bounds(shape.selrect());
|
||||||
let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection());
|
let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection());
|
||||||
|
@ -440,6 +448,13 @@ impl RenderState {
|
||||||
self.fonts.font_collection(),
|
self.fonts.font_collection(),
|
||||||
);
|
);
|
||||||
shadows::render_text_drop_shadows(self, &shape, &stroke_paragraphs, antialias);
|
shadows::render_text_drop_shadows(self, &shape, &stroke_paragraphs, antialias);
|
||||||
|
if stroke.kind == StrokeKind::Inner {
|
||||||
|
// Inner strokes must be rendered on the Fills surface because their blend modes
|
||||||
|
// (e.g., SrcATop, DstOver) rely on the text fill already being present underneath.
|
||||||
|
// Rendering them on a separate surface would break this blending and result in incorrect visuals as
|
||||||
|
// black color background.
|
||||||
|
text::render(self, &shape, &stroke_paragraphs, None, None);
|
||||||
|
} else {
|
||||||
text::render(
|
text::render(
|
||||||
self,
|
self,
|
||||||
&shape,
|
&shape,
|
||||||
|
@ -447,6 +462,7 @@ impl RenderState {
|
||||||
Some(SurfaceId::Strokes),
|
Some(SurfaceId::Strokes),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
shadows::render_text_inner_shadows(self, &shape, &stroke_paragraphs, antialias);
|
shadows::render_text_inner_shadows(self, &shape, &stroke_paragraphs, antialias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,19 @@ pub fn render(
|
||||||
surface_id: Option<SurfaceId>,
|
surface_id: Option<SurfaceId>,
|
||||||
paint: Option<skia::Paint>,
|
paint: Option<skia::Paint>,
|
||||||
) {
|
) {
|
||||||
|
let use_save_layer = paint.is_some();
|
||||||
let mask_paint = paint.unwrap_or_default();
|
let mask_paint = paint.unwrap_or_default();
|
||||||
let mask = SaveLayerRec::default().paint(&mask_paint);
|
let mask = SaveLayerRec::default().paint(&mask_paint);
|
||||||
let canvas = render_state
|
let canvas = render_state
|
||||||
.surfaces
|
.surfaces
|
||||||
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
||||||
|
|
||||||
|
// Skip save_layer when no custom paint is provided to avoid isolating content unnecessarily.
|
||||||
|
// This ensures inner strokes and fills can blend correctly on the same surface.
|
||||||
|
if use_save_layer {
|
||||||
canvas.save_layer(&mask);
|
canvas.save_layer(&mask);
|
||||||
|
}
|
||||||
|
|
||||||
for group in paragraphs {
|
for group in paragraphs {
|
||||||
let mut offset_y = 0.0;
|
let mut offset_y = 0.0;
|
||||||
for skia_paragraph in group {
|
for skia_paragraph in group {
|
||||||
|
@ -23,5 +29,7 @@ pub fn render(
|
||||||
offset_y += skia_paragraph.height();
|
offset_y += skia_paragraph.height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if use_save_layer {
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,8 +197,8 @@ impl Default for TextContent {
|
||||||
pub struct Paragraph {
|
pub struct Paragraph {
|
||||||
num_leaves: u32,
|
num_leaves: u32,
|
||||||
text_align: u8,
|
text_align: u8,
|
||||||
text_decoration: u8,
|
|
||||||
text_direction: u8,
|
text_direction: u8,
|
||||||
|
text_decoration: u8,
|
||||||
text_transform: u8,
|
text_transform: u8,
|
||||||
line_height: f32,
|
line_height: f32,
|
||||||
letter_spacing: f32,
|
letter_spacing: f32,
|
||||||
|
@ -212,8 +212,8 @@ impl Default for Paragraph {
|
||||||
Self {
|
Self {
|
||||||
num_leaves: 0,
|
num_leaves: 0,
|
||||||
text_align: 0,
|
text_align: 0,
|
||||||
text_decoration: 0,
|
|
||||||
text_direction: 0,
|
text_direction: 0,
|
||||||
|
text_decoration: 0,
|
||||||
text_transform: 0,
|
text_transform: 0,
|
||||||
line_height: 1.0,
|
line_height: 1.0,
|
||||||
letter_spacing: 0.0,
|
letter_spacing: 0.0,
|
||||||
|
@ -229,8 +229,8 @@ impl Paragraph {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
num_leaves: u32,
|
num_leaves: u32,
|
||||||
text_align: u8,
|
text_align: u8,
|
||||||
text_decoration: u8,
|
|
||||||
text_direction: u8,
|
text_direction: u8,
|
||||||
|
text_decoration: u8,
|
||||||
text_transform: u8,
|
text_transform: u8,
|
||||||
line_height: f32,
|
line_height: f32,
|
||||||
letter_spacing: f32,
|
letter_spacing: f32,
|
||||||
|
@ -241,8 +241,8 @@ impl Paragraph {
|
||||||
Self {
|
Self {
|
||||||
num_leaves,
|
num_leaves,
|
||||||
text_align,
|
text_align,
|
||||||
text_decoration,
|
|
||||||
text_direction,
|
text_direction,
|
||||||
|
text_decoration,
|
||||||
text_transform,
|
text_transform,
|
||||||
line_height,
|
line_height,
|
||||||
letter_spacing,
|
letter_spacing,
|
||||||
|
@ -352,6 +352,8 @@ impl TextLeaf {
|
||||||
3 => skia::textlayout::TextDecoration::OVERLINE,
|
3 => skia::textlayout::TextDecoration::OVERLINE,
|
||||||
_ => skia::textlayout::TextDecoration::NO_DECORATION,
|
_ => skia::textlayout::TextDecoration::NO_DECORATION,
|
||||||
});
|
});
|
||||||
|
// FIXME
|
||||||
|
style.set_decoration_color(paint.color());
|
||||||
|
|
||||||
style.set_font_families(&[
|
style.set_font_families(&[
|
||||||
self.serialized_font_family(),
|
self.serialized_font_family(),
|
||||||
|
@ -369,6 +371,15 @@ impl TextLeaf {
|
||||||
) -> skia::textlayout::TextStyle {
|
) -> skia::textlayout::TextStyle {
|
||||||
let mut style = self.to_style(paragraph, &Rect::default());
|
let mut style = self.to_style(paragraph, &Rect::default());
|
||||||
style.set_foreground_paint(stroke_paint);
|
style.set_foreground_paint(stroke_paint);
|
||||||
|
style.set_font_size(self.font_size);
|
||||||
|
style.set_letter_spacing(paragraph.letter_spacing);
|
||||||
|
style.set_decoration_type(match paragraph.text_decoration {
|
||||||
|
0 => skia::textlayout::TextDecoration::NO_DECORATION,
|
||||||
|
1 => skia::textlayout::TextDecoration::UNDERLINE,
|
||||||
|
2 => skia::textlayout::TextDecoration::LINE_THROUGH,
|
||||||
|
3 => skia::textlayout::TextDecoration::OVERLINE,
|
||||||
|
_ => skia::textlayout::TextDecoration::NO_DECORATION,
|
||||||
|
});
|
||||||
style
|
style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue