Skip to content

Commit 792f262

Browse files
committed
Fix Text tool font choice style turning to "-" on font that doesn't support previous style
1 parent 46ec336 commit 792f262

File tree

3 files changed

+51
-84
lines changed

3 files changed

+51
-84
lines changed

editor/src/messages/portfolio/document/node_graph/node_properties.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -789,12 +789,7 @@ pub fn font_inputs(parameter_widgets_info: ParameterWidgetsInfo) -> (Vec<WidgetI
789789
.map(|family| {
790790
MenuListEntry::new(family.name.clone())
791791
.label(family.name.clone())
792-
.font({
793-
// Get the URL for the stylesheet of a subsetted font preview for the font style closest to weight 400
794-
let preview_name = family.name.replace(' ', "+");
795-
let preview_weight = family.closest_style(400, false).weight;
796-
format!("https://fonts.googleapis.com/css2?display=swap&family={preview_name}:wght@{preview_weight}&text={preview_name}")
797-
})
792+
.font(family.closest_style(400, false).preview_url(&family.name))
798793
.on_update({
799794
// Construct the new font using the new family and the initial or previous style, although this style might not exist in the catalog
800795
let mut new_font = Font::new(family.name.clone(), font.font_style_to_restore.clone().unwrap_or_else(|| font.font_style.clone()));

editor/src/messages/portfolio/utility_types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ impl FontCatalogStyle {
7272
let italic = named_style.contains("Italic (");
7373
FontCatalogStyle { weight, italic, url: url.into() }
7474
}
75+
76+
/// Get the URL for the stylesheet for loading a font preview for this style of the given family name, subsetted to only the letters in the family name.
77+
pub fn preview_url(&self, family: impl Into<String>) -> String {
78+
let name = family.into().replace(' ', "+");
79+
let italic = if self.italic { "ital," } else { "" };
80+
let weight = self.weight;
81+
format!("https://fonts.googleapis.com/css2?display=swap&family={name}:{italic}wght@{weight}&text={name}")
82+
}
7583
}
7684

7785
#[derive(PartialEq, Eq, Clone, Copy, Default, Debug, serde::Serialize, serde::Deserialize)]

editor/src/messages/tool/tool_messages/text_tool.rs

Lines changed: 42 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ pub struct TextOptions {
3333
font_size: f64,
3434
line_height_ratio: f64,
3535
character_spacing: f64,
36-
font_name: String,
37-
font_style: String,
36+
font: Font,
3837
fill: ToolColorOptions,
3938
tilt: f64,
4039
align: TextAlign,
@@ -46,8 +45,7 @@ impl Default for TextOptions {
4645
font_size: 24.,
4746
line_height_ratio: 1.2,
4847
character_spacing: 0.,
49-
font_name: graphene_std::consts::DEFAULT_FONT_FAMILY.into(),
50-
font_style: graphene_std::consts::DEFAULT_FONT_STYLE.into(),
48+
font: Font::new(graphene_std::consts::DEFAULT_FONT_FAMILY.into(), graphene_std::consts::DEFAULT_FONT_STYLE.into()),
5149
fill: ToolColorOptions::new_primary(),
5250
tilt: 0.,
5351
align: TextAlign::default(),
@@ -80,7 +78,7 @@ pub enum TextToolMessage {
8078
pub enum TextOptionsUpdate {
8179
FillColor(Option<Color>),
8280
FillColorType(ToolColorType),
83-
Font { family: String, style: String },
81+
Font { font: Font },
8482
FontSize(f64),
8583
LineHeightRatio(f64),
8684
Align(TextAlign),
@@ -100,92 +98,57 @@ impl ToolMetadata for TextTool {
10098
}
10199

102100
fn create_text_widgets(tool: &TextTool, font_catalog: &FontCatalog) -> Vec<WidgetInstance> {
101+
fn update_options(font: Font, commit_style: Option<String>) -> impl Fn(&()) -> Message + Clone {
102+
let mut font = font;
103+
if let Some(style) = commit_style {
104+
font.font_style = style;
105+
}
106+
107+
move |_| {
108+
TextToolMessage::UpdateOptions {
109+
options: TextOptionsUpdate::Font { font: font.clone() },
110+
}
111+
.into()
112+
}
113+
}
114+
103115
let font = DropdownInput::new(vec![
104116
font_catalog
105117
.0
106118
.iter()
107119
.map(|family| {
120+
let font = Font::new(family.name.clone(), tool.options.font.font_style.clone());
121+
let commit_style = font_catalog.find_font_style_in_catalog(&tool.options.font).map(|style| style.to_named_style());
122+
let update = update_options(font.clone(), None);
123+
let commit = update_options(font, commit_style);
124+
108125
MenuListEntry::new(family.name.clone())
109126
.label(family.name.clone())
110-
.font({
111-
// Get the URL for the stylesheet of a subsetted font preview for the font style closest to weight 400
112-
let preview_name = family.name.replace(' ', "+");
113-
let preview_weight = family.closest_style(400, false).weight;
114-
format!("https://fonts.googleapis.com/css2?display=swap&family={preview_name}:wght@{preview_weight}&text={preview_name}")
115-
})
116-
.on_update({
117-
let family = family.name.clone();
118-
let style = tool.options.font_style.clone();
119-
move |_| {
120-
TextToolMessage::UpdateOptions {
121-
options: TextOptionsUpdate::Font {
122-
family: family.clone(),
123-
style: style.clone(),
124-
},
125-
}
126-
.into()
127-
}
128-
})
129-
.on_commit({
130-
let family = family.name.clone();
131-
let style = tool.options.font_style.clone();
132-
move |_| {
133-
TextToolMessage::UpdateOptions {
134-
options: TextOptionsUpdate::Font {
135-
family: family.clone(),
136-
style: style.clone(),
137-
},
138-
}
139-
.into()
140-
}
141-
})
127+
.font(family.closest_style(400, false).preview_url(&family.name))
128+
.on_update(update)
129+
.on_commit(commit)
142130
})
143131
.collect::<Vec<_>>(),
144132
])
145-
.selected_index(font_catalog.0.iter().position(|family| family.name == tool.options.font_name).map(|i| i as u32))
133+
.selected_index(font_catalog.0.iter().position(|family| family.name == tool.options.font.font_family).map(|i| i as u32))
146134
.virtual_scrolling(true)
147135
.widget_instance();
148136

149137
let style = DropdownInput::new({
150138
font_catalog
151139
.0
152140
.iter()
153-
.find(|family| family.name == tool.options.font_name)
141+
.find(|family| family.name == tool.options.font.font_family)
154142
.map(|family| {
155143
let build_entry = |style: &FontCatalogStyle| {
156144
let font_style = style.to_named_style();
157-
MenuListEntry::new(font_style.clone())
158-
.on_update({
159-
// Keep the existing family
160-
let font_family = tool.options.font_name.clone();
161-
// Use the new style
162-
let font_style = font_style.clone();
163-
move |_| {
164-
TextToolMessage::UpdateOptions {
165-
options: TextOptionsUpdate::Font {
166-
family: font_family.clone(),
167-
style: font_style.clone(),
168-
},
169-
}
170-
.into()
171-
}
172-
})
173-
.on_commit({
174-
// Keep the existing family
175-
let font_family = tool.options.font_name.clone();
176-
// Use the new style
177-
let font_style = font_style.clone();
178-
move |_| {
179-
TextToolMessage::UpdateOptions {
180-
options: TextOptionsUpdate::Font {
181-
family: font_family.clone(),
182-
style: font_style.clone(),
183-
},
184-
}
185-
.into()
186-
}
187-
})
188-
.label(font_style)
145+
146+
let font = Font::new(tool.options.font.font_family.clone(), font_style.clone());
147+
let commit_style = font_catalog.find_font_style_in_catalog(&tool.options.font).map(|style| style.to_named_style());
148+
let update = update_options(font.clone(), None);
149+
let commit = update_options(font, commit_style);
150+
151+
MenuListEntry::new(font_style.clone()).on_update(update).on_commit(commit).label(font_style)
189152
};
190153

191154
vec![
@@ -200,11 +163,13 @@ fn create_text_widgets(tool: &TextTool, font_catalog: &FontCatalog) -> Vec<Widge
200163
font_catalog
201164
.0
202165
.iter()
203-
.find(|family| family.name == tool.options.font_name)
166+
.find(|family| family.name == tool.options.font.font_family)
204167
.and_then(|family| {
205168
let not_italic = family.styles.iter().filter(|style| !style.italic);
206169
let italic = family.styles.iter().filter(|style| style.italic);
207-
not_italic.chain(italic).position(|style| style.to_named_style() == tool.options.font_style)
170+
not_italic
171+
.chain(italic)
172+
.position(|style| Some(style) == font_catalog.find_font_style_in_catalog(&tool.options.font).as_ref())
208173
})
209174
.map(|i| i as u32),
210175
)
@@ -317,9 +282,8 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionMessageContext<'a>> for Text
317282
return;
318283
};
319284
match options {
320-
TextOptionsUpdate::Font { family, style } => {
321-
self.options.font_name = family;
322-
self.options.font_style = style;
285+
TextOptionsUpdate::Font { font } => {
286+
self.options.font = font;
323287
}
324288
TextOptionsUpdate::FontSize(font_size) => self.options.font_size = font_size,
325289
TextOptionsUpdate::LineHeightRatio(line_height_ratio) => self.options.line_height_ratio = line_height_ratio,
@@ -930,7 +894,7 @@ impl Fsm for TextToolFsmState {
930894
tilt: tool_options.tilt,
931895
align: tool_options.align,
932896
},
933-
font: Font::new(tool_options.font_name.clone(), tool_options.font_style.clone()),
897+
font: Font::new(tool_options.font.font_family.clone(), tool_options.font.font_style.clone()),
934898
color: tool_options.fill.active_color(),
935899
};
936900
tool_data.new_text(document, editing_text, font_cache, responses);
@@ -956,7 +920,7 @@ impl Fsm for TextToolFsmState {
956920
TextToolFsmState::Ready
957921
}
958922
(TextToolFsmState::Editing, TextToolMessage::RefreshEditingFontData) => {
959-
let font = Font::new(tool_options.font_name.clone(), tool_options.font_style.clone());
923+
let font = Font::new(tool_options.font.font_family.clone(), tool_options.font.font_style.clone());
960924
responses.add(FrontendMessage::DisplayEditableTextboxUpdateFontData {
961925
font_data: font_cache.get(&font).map(|(data, _)| data.clone()).unwrap_or_default(),
962926
});

0 commit comments

Comments
 (0)