Skip to content

Commit 17f4e9f

Browse files
authored
Make StyleProperty::FontStack more ergonomic. (#129)
1 parent d4dcf36 commit 17f4e9f

File tree

9 files changed

+97
-44
lines changed

9 files changed

+97
-44
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This release has an [MSRV] of 1.75.
2525
- An example with Vello on Winit which shows a basic text editor ([#106] by [@dfrg])
2626
- `PlainEditor`, a basic action-based text editor based on Parley `Selection` and `Cursor` ([#126] by [@xorgy])
2727
- Tree style builder ([#76] by [@nicoburns])
28+
- Conversions for `FontFamily`, `FontStack`, and `StyleProperty` to make styling more ergonomic ([#129] by [@xorgy])
2829

2930
### Changed
3031

@@ -35,6 +36,7 @@ This release has an [MSRV] of 1.75.
3536
#### Parley
3637

3738
- Emoji clusters now get an Emoji family added by default ([#56] by [@dfrg])
39+
- Style builders now accept `Into<StyleProperty<'a, B: Brush>>` so you can push a `GenericFamily` or `FontStack` directly. ([#129] by [@xorgy])
3840

3941
#### Fontique
4042

@@ -78,6 +80,7 @@ This release has an [MSRV] of 1.70.
7880
[#85]: https://github.com/linebender/parley/pull/85
7981
[#106]: https://github.com/linebender/parley/pull/106
8082
[#126]: https://github.com/linebender/parley/pull/126
83+
[#129]: https://github.com/linebender/parley/pull/129
8184

8285
[Unreleased]: https://github.com/linebender/parley/compare/v0.1.0...HEAD
8386
[0.1.0]: https://github.com/linebender/parley/releases/tag/v0.1.0

examples/swash_render/src/main.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use parley::layout::{Alignment, Glyph, GlyphRun, Layout, PositionedLayoutItem};
1010
use parley::style::{FontStack, FontWeight, StyleProperty, TextStyle};
1111
use parley::{FontContext, InlineBox, LayoutContext};
1212
use peniko::Color;
13-
use std::borrow::Cow;
1413
use std::fs::File;
1514
use swash::scale::image::Content;
1615
use swash::scale::{Render, ScaleContext, Scaler, Source, StrikeWith};
@@ -47,10 +46,8 @@ fn main() {
4746

4847
// Setup some Parley text styles
4948
let brush_style = StyleProperty::Brush(text_color);
50-
let font_stack = FontStack::Source(Cow::Borrowed("system-ui"));
51-
let font_stack_style: StyleProperty<Color> = StyleProperty::FontStack(font_stack.clone());
52-
let bold = FontWeight::new(600.0);
53-
let bold_style = StyleProperty::FontWeight(bold);
49+
let font_stack = FontStack::from("system-ui");
50+
let bold_style = StyleProperty::FontWeight(FontWeight::new(600.0));
5451

5552
let mut layout = if std::env::args().any(|arg| arg == "--tree") {
5653
// TREE BUILDER
@@ -104,15 +101,15 @@ fn main() {
104101
let mut builder = layout_cx.ranged_builder(&mut font_cx, &text, display_scale);
105102

106103
// Set default text colour styles (set foreground text color)
107-
builder.push_default(&brush_style);
104+
builder.push_default(brush_style);
108105

109106
// Set default font family
110-
builder.push_default(&font_stack_style);
111-
builder.push_default(&StyleProperty::LineHeight(1.3));
112-
builder.push_default(&StyleProperty::FontSize(16.0));
107+
builder.push_default(font_stack);
108+
builder.push_default(StyleProperty::LineHeight(1.3));
109+
builder.push_default(StyleProperty::FontSize(16.0));
113110

114111
// Set the first 4 characters to bold
115-
builder.push(&bold_style, 0..4);
112+
builder.push(bold_style, 0..4);
116113

117114
builder.push_inline_box(InlineBox {
118115
id: 0,

examples/tiny_skia_render/src/main.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
//! Note: Emoji rendering is not currently implemented in this example. See the swash example
88
//! if you need emoji rendering.
99
10-
use std::borrow::Cow;
11-
12-
use parley::layout::{Alignment, GlyphRun, Layout, PositionedLayoutItem};
13-
use parley::style::{FontStack, FontWeight, StyleProperty};
14-
use parley::{FontContext, InlineBox, LayoutContext};
10+
use parley::{
11+
Alignment, FontContext, FontWeight, GenericFamily, GlyphRun, InlineBox, Layout, LayoutContext,
12+
PositionedLayoutItem, StyleProperty,
13+
};
1514
use peniko::Color as PenikoColor;
16-
use skrifa::instance::{LocationRef, NormalizedCoord, Size};
17-
use skrifa::outline::{DrawSettings, OutlinePen};
18-
use skrifa::raw::FontRef as ReadFontsRef;
19-
use skrifa::{GlyphId, MetadataProvider, OutlineGlyph};
15+
use skrifa::{
16+
instance::{LocationRef, NormalizedCoord, Size},
17+
outline::{DrawSettings, OutlinePen},
18+
raw::FontRef as ReadFontsRef,
19+
GlyphId, MetadataProvider, OutlineGlyph,
20+
};
2021
use tiny_skia::{
2122
Color as TinySkiaColor, FillRule, Paint, PathBuilder, Pixmap, PixmapMut, Rect, Transform,
2223
};
@@ -52,19 +53,16 @@ fn main() {
5253

5354
// Set default text colour styles (set foreground text color)
5455
let brush_style = StyleProperty::Brush(foreground_color);
55-
builder.push_default(&brush_style);
56+
builder.push_default(brush_style);
5657

5758
// Set default font family
58-
let font_stack = FontStack::Source(Cow::Borrowed("system-ui"));
59-
let font_stack_style = StyleProperty::FontStack(font_stack);
60-
builder.push_default(&font_stack_style);
61-
builder.push_default(&StyleProperty::LineHeight(1.3));
62-
builder.push_default(&StyleProperty::FontSize(16.0));
59+
builder.push_default(GenericFamily::SystemUi);
60+
builder.push_default(StyleProperty::LineHeight(1.3));
61+
builder.push_default(StyleProperty::FontSize(16.0));
6362

6463
// Set the first 4 characters to bold
6564
let bold = FontWeight::new(600.0);
66-
let bold_style = StyleProperty::FontWeight(bold);
67-
builder.push(&bold_style, 0..4);
65+
builder.push(StyleProperty::FontWeight(bold), 0..4);
6866

6967
builder.push_inline_box(InlineBox {
7068
id: 0,

examples/vello_editor/src/main.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

44
use anyhow::Result;
5-
use std::borrow::Cow;
65
use std::num::NonZeroUsize;
76
use std::sync::Arc;
87
use vello::peniko::Color;
@@ -17,7 +16,7 @@ use winit::window::Window;
1716

1817
// #[path = "text2.rs"]
1918
mod text;
20-
use parley::layout::editor::PlainEditorOp;
19+
use parley::{GenericFamily, PlainEditorOp, StyleProperty};
2120

2221
// Simple struct to hold the state of the renderer
2322
pub struct ActiveRenderState<'s> {
@@ -133,11 +132,9 @@ impl ApplicationHandler for SimpleVelloApp<'_> {
133132
PlainEditorOp::SetScale(1.0),
134133
PlainEditorOp::SetWidth(size.width as f32 - 2f32 * text::INSET),
135134
PlainEditorOp::SetDefaultStyle(Arc::new([
136-
parley::style::StyleProperty::FontSize(32.0),
137-
parley::style::StyleProperty::LineHeight(1.2),
138-
parley::style::StyleProperty::FontStack(parley::style::FontStack::Source(
139-
Cow::Borrowed("system-ui"),
140-
)),
135+
StyleProperty::FontSize(32.0),
136+
StyleProperty::LineHeight(1.2),
137+
GenericFamily::SystemUi.into(),
141138
])),
142139
]);
143140
}

parley/src/builder.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,23 @@ pub struct RangedBuilder<'a, B: Brush> {
2222
}
2323

2424
impl<B: Brush> RangedBuilder<'_, B> {
25-
pub fn push_default(&mut self, property: &StyleProperty<B>) {
25+
pub fn push_default<'a>(&mut self, property: impl Into<StyleProperty<'a, B>>) {
2626
let resolved = self
2727
.lcx
2828
.rcx
29-
.resolve_property(self.fcx, property, self.scale);
29+
.resolve_property(self.fcx, &property.into(), self.scale);
3030
self.lcx.ranged_style_builder.push_default(resolved);
3131
}
3232

33-
pub fn push(&mut self, property: &StyleProperty<B>, range: impl RangeBounds<usize>) {
33+
pub fn push<'a>(
34+
&mut self,
35+
property: impl Into<StyleProperty<'a, B>>,
36+
range: impl RangeBounds<usize>,
37+
) {
3438
let resolved = self
3539
.lcx
3640
.rcx
37-
.resolve_property(self.fcx, property, self.scale);
41+
.resolve_property(self.fcx, &property.into(), self.scale);
3842
self.lcx.ranged_style_builder.push(resolved, range);
3943
}
4044

parley/src/layout/editor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ where
445445
fn update_layout(&mut self, font_cx: &mut FontContext, layout_cx: &mut LayoutContext<T>) {
446446
let mut builder = layout_cx.ranged_builder(font_cx, &self.buffer, self.scale);
447447
for prop in self.default_style.iter() {
448-
builder.push_default(prop);
448+
builder.push_default(prop.to_owned());
449449
}
450450
builder.build_into(&mut self.layout, &self.buffer);
451451
self.layout.break_all_lines(Some(self.width));

parley/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
//! - [`RangedBuilder`] and [`TreeBuilder`] which are builders for creating a [`Layout`].
1111
//! - [`RangedBuilder`] allows styles to be specified as a flat `Vec` of spans
1212
//! - [`TreeBuilder`] allows styles to be specified as a tree of spans
13-
//!
13+
//!
1414
//! They are constructed using the [`ranged_builder`](LayoutContext::ranged_builder) and [`tree_builder`](LayoutContext::ranged_builder) methods on [`LayoutContext`].
1515
//! - [`Layout`] which represents styled paragraph(s) of text and can perform shaping, line-breaking, bidi-reordering, and alignment of that text.
16-
//!
16+
//!
1717
//! `Layout` supports re-linebreaking and re-aligning many times (in case the width at which wrapping should occur changes). But if the text content or
1818
//! the styles applied to that content change then a new `Layout` must be created using a new `RangedBuilder` or `TreeBuilder`.
1919
//!
@@ -38,11 +38,11 @@
3838
//! let mut builder = layout_cx.ranged_builder(&mut font_cx, &TEXT, DISPLAY_SCALE);
3939
//!
4040
//! // Set default styles that apply to the entire layout
41-
//! builder.push_default(&StyleProperty::LineHeight(1.3));
42-
//! builder.push_default(&StyleProperty::FontSize(16.0));
41+
//! builder.push_default(StyleProperty::LineHeight(1.3));
42+
//! builder.push_default(StyleProperty::FontSize(16.0));
4343
//!
4444
//! // Set a style that applies to the first 4 characters
45-
//! builder.push(&StyleProperty::FontWeight(FontWeight::new(600.0)), 0..4);
45+
//! builder.push(StyleProperty::FontWeight(FontWeight::new(600.0)), 0..4);
4646
//!
4747
//! // Add a box to be laid out inline with the text
4848
//! builder.push_inline_box(InlineBox { id: 0, index: 5, width: 50.0, height: 50.0 });

parley/src/style/font.rs

+30
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,36 @@ impl<'a> FontFamily<'a> {
8383
}
8484
}
8585

86+
impl<'a> From<GenericFamily> for FontFamily<'a> {
87+
fn from(f: GenericFamily) -> Self {
88+
FontFamily::Generic(f)
89+
}
90+
}
91+
92+
impl<'a> From<GenericFamily> for FontStack<'a> {
93+
fn from(f: GenericFamily) -> Self {
94+
FontStack::Single(f.into())
95+
}
96+
}
97+
98+
impl<'a> From<FontFamily<'a>> for FontStack<'a> {
99+
fn from(f: FontFamily<'a>) -> Self {
100+
FontStack::Single(f)
101+
}
102+
}
103+
104+
impl<'a> From<&'a str> for FontStack<'a> {
105+
fn from(s: &'a str) -> Self {
106+
FontStack::Source(Cow::Borrowed(s))
107+
}
108+
}
109+
110+
impl<'a> From<&'a [FontFamily<'a>]> for FontStack<'a> {
111+
fn from(fs: &'a [FontFamily<'a>]) -> Self {
112+
FontStack::List(Cow::Borrowed(fs))
113+
}
114+
}
115+
86116
impl fmt::Display for FontFamily<'_> {
87117
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88118
match self {

parley/src/style/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,27 @@ impl<B: Brush> Default for TextStyle<'_, B> {
136136
}
137137
}
138138
}
139+
140+
impl<'a, B: Brush> From<FontStack<'a>> for StyleProperty<'a, B> {
141+
fn from(fs: FontStack<'a>) -> Self {
142+
StyleProperty::FontStack(fs)
143+
}
144+
}
145+
146+
impl<'a, B: Brush> From<&'a [FontFamily<'a>]> for StyleProperty<'a, B> {
147+
fn from(fs: &'a [FontFamily<'a>]) -> Self {
148+
StyleProperty::FontStack(fs.into())
149+
}
150+
}
151+
152+
impl<'a, B: Brush> From<FontFamily<'a>> for StyleProperty<'a, B> {
153+
fn from(f: FontFamily<'a>) -> Self {
154+
StyleProperty::FontStack(FontStack::from(f))
155+
}
156+
}
157+
158+
impl<'a, B: Brush> From<GenericFamily> for StyleProperty<'a, B> {
159+
fn from(f: GenericFamily) -> Self {
160+
StyleProperty::FontStack(f.into())
161+
}
162+
}

0 commit comments

Comments
 (0)