mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
Merge pull request #7698 from penpot/elenatorro-fix-word-breaking-different-browsers
🔧 Fix cross-browser text issues
This commit is contained in:
@@ -95,7 +95,6 @@ macro_rules! with_state_mut_current_shape {
|
||||
};
|
||||
}
|
||||
|
||||
/// This is called from JS after the WebGL context has been created.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init(width: i32, height: i32) {
|
||||
let state_box = Box::new(State::new(width, height));
|
||||
@@ -104,6 +103,13 @@ pub extern "C" fn init(width: i32, height: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_browser(browser: u8) {
|
||||
with_state_mut!(state, {
|
||||
state.set_browser(browser);
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn clean_up() {
|
||||
with_state_mut!(state, {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
math::{Bounds, Matrix, Rect},
|
||||
render::{default_font, DEFAULT_EMOJI_FONT},
|
||||
utils::Browser,
|
||||
};
|
||||
|
||||
use core::f32;
|
||||
@@ -19,6 +20,7 @@ use crate::math::Point;
|
||||
use crate::shapes::{self, merge_fills, Shape, VerticalAlign};
|
||||
use crate::utils::{get_fallback_fonts, get_font_collection};
|
||||
use crate::Uuid;
|
||||
use crate::STATE;
|
||||
|
||||
// TODO: maybe move this to the wasm module?
|
||||
pub type ParagraphBuilderGroup = Vec<ParagraphBuilder>;
|
||||
@@ -607,6 +609,7 @@ impl Paragraph {
|
||||
style.set_text_align(self.text_align);
|
||||
style.set_text_direction(self.text_direction);
|
||||
style.set_replace_tab_characters(true);
|
||||
style.set_apply_rounding_hack(true);
|
||||
style.set_text_height_behavior(skia::textlayout::TextHeightBehavior::All);
|
||||
style
|
||||
}
|
||||
@@ -711,7 +714,7 @@ impl TextSpan {
|
||||
style.set_font_families(&font_families);
|
||||
style.set_font_size(self.font_size);
|
||||
style.set_letter_spacing(self.letter_spacing);
|
||||
style.set_half_leading(false);
|
||||
style.set_half_leading(true);
|
||||
|
||||
style
|
||||
}
|
||||
@@ -753,15 +756,26 @@ impl TextSpan {
|
||||
format!("{}", self.font_family)
|
||||
}
|
||||
|
||||
fn remove_ignored_chars(text: &str) -> String {
|
||||
fn process_ignored_chars(text: &str, browser: u8) -> String {
|
||||
text.chars()
|
||||
.filter(|&c| c >= '\u{0020}' && c != '\u{2028}' && c != '\u{2029}')
|
||||
.filter_map(|c| {
|
||||
if c < '\u{0020}' || c == '\u{2028}' || c == '\u{2029}' {
|
||||
if browser == Browser::Firefox as u8 {
|
||||
None
|
||||
} else {
|
||||
Some(' ')
|
||||
}
|
||||
} else {
|
||||
Some(c)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn apply_text_transform(&self) -> String {
|
||||
let text = Self::remove_ignored_chars(&self.text);
|
||||
match self.text_transform {
|
||||
let browser = crate::with_state!(state, { state.current_browser });
|
||||
let text = Self::process_ignored_chars(&self.text, browser);
|
||||
let transformed_text = match self.text_transform {
|
||||
Some(TextTransform::Uppercase) => text.to_uppercase(),
|
||||
Some(TextTransform::Lowercase) => text.to_lowercase(),
|
||||
Some(TextTransform::Capitalize) => text
|
||||
@@ -776,7 +790,9 @@ impl TextSpan {
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
None => text,
|
||||
}
|
||||
};
|
||||
|
||||
transformed_text.replace("/", "/\u{200B}")
|
||||
}
|
||||
|
||||
pub fn scale_content(&mut self, value: f32) {
|
||||
|
||||
@@ -22,6 +22,7 @@ pub(crate) struct State<'a> {
|
||||
pub render_state: RenderState,
|
||||
pub text_editor_state: TextEditorState,
|
||||
pub current_id: Option<Uuid>,
|
||||
pub current_browser: u8,
|
||||
pub shapes: ShapesPool<'a>,
|
||||
}
|
||||
|
||||
@@ -31,6 +32,7 @@ impl<'a> State<'a> {
|
||||
render_state: RenderState::new(width, height),
|
||||
text_editor_state: TextEditorState::new(),
|
||||
current_id: None,
|
||||
current_browser: 0,
|
||||
shapes: ShapesPool::new(),
|
||||
}
|
||||
}
|
||||
@@ -124,6 +126,10 @@ impl<'a> State<'a> {
|
||||
self.render_state.set_background_color(color);
|
||||
}
|
||||
|
||||
pub fn set_browser(&mut self, browser: u8) {
|
||||
self.current_browser = browser;
|
||||
}
|
||||
|
||||
/// Sets the parent for the current shape and updates the parent's extended rectangle
|
||||
///
|
||||
/// When a shape is assigned a new parent, the parent's extended rectangle needs to be
|
||||
|
||||
@@ -36,3 +36,25 @@ pub fn get_fallback_fonts() -> &'static HashSet<String> {
|
||||
pub fn get_font_collection() -> &'static FontCollection {
|
||||
with_state_mut!(state, { state.font_collection() })
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum Browser {
|
||||
Firefox = 0,
|
||||
Chrome = 1,
|
||||
Safari = 2,
|
||||
Edge = 3,
|
||||
Unknown = 4,
|
||||
}
|
||||
|
||||
impl From<u8> for Browser {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Browser::Firefox,
|
||||
1 => Browser::Chrome,
|
||||
2 => Browser::Safari,
|
||||
3 => Browser::Edge,
|
||||
_ => Browser::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user