Skip to content

Commit

Permalink
CoWify style types
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Oct 9, 2024
1 parent a05a6f1 commit ca8cdc6
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 36 deletions.
5 changes: 3 additions & 2 deletions examples/swash_render/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use parley::layout::{Alignment, Glyph, GlyphRun, Layout, PositionedLayoutItem};
use parley::style::{FontStack, FontWeight, StyleProperty, TextStyle};
use parley::{FontContext, InlineBox, LayoutContext};
use peniko::Color;
use std::borrow::Cow;
use std::fs::File;
use swash::scale::image::Content;
use swash::scale::{Render, ScaleContext, Scaler, Source, StrikeWith};
Expand Down Expand Up @@ -46,8 +47,8 @@ fn main() {

// Setup some Parley text styles
let brush_style = StyleProperty::Brush(text_color);
let font_stack = FontStack::Source("system-ui");
let font_stack_style: StyleProperty<Color> = StyleProperty::FontStack(font_stack);
let font_stack = FontStack::Source(Cow::Borrowed("system-ui"));
let font_stack_style: StyleProperty<Color> = StyleProperty::FontStack(font_stack.clone());
let bold = FontWeight::new(600.0);
let bold_style = StyleProperty::FontWeight(bold);

Expand Down
4 changes: 3 additions & 1 deletion examples/tiny_skia_render/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//! Note: Emoji rendering is not currently implemented in this example. See the swash example
//! if you need emoji rendering.

use std::borrow::Cow;

use parley::layout::{Alignment, GlyphRun, Layout, PositionedLayoutItem};
use parley::style::{FontStack, FontWeight, StyleProperty};
use parley::{FontContext, InlineBox, LayoutContext};
Expand Down Expand Up @@ -53,7 +55,7 @@ fn main() {
builder.push_default(&brush_style);

// Set default font family
let font_stack = FontStack::Source("system-ui");
let font_stack = FontStack::Source(Cow::Borrowed("system-ui"));
let font_stack_style = StyleProperty::FontStack(font_stack);
builder.push_default(&font_stack_style);
builder.push_default(&StyleProperty::LineHeight(1.3));
Expand Down
3 changes: 2 additions & 1 deletion examples/vello_editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use anyhow::Result;
use std::borrow::Cow;
use std::num::NonZeroUsize;
use std::sync::Arc;
use vello::peniko::Color;
Expand Down Expand Up @@ -135,7 +136,7 @@ impl ApplicationHandler for SimpleVelloApp<'_> {
parley::style::StyleProperty::FontSize(32.0),
parley::style::StyleProperty::LineHeight(1.2),
parley::style::StyleProperty::FontStack(parley::style::FontStack::Source(
"system-ui",
Cow::Borrowed("system-ui"),
)),
])),
]);
Expand Down
28 changes: 17 additions & 11 deletions parley/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::font::FontContext;
use crate::layout;
use crate::style::TextStyle;
use crate::util::nearly_eq;
use core::borrow::Borrow;
use core::ops::Range;
use fontique::FamilyId;
use swash::text::Language;
Expand Down Expand Up @@ -134,13 +135,13 @@ impl ResolveContext {
) -> ResolvedProperty<B> {
use ResolvedProperty::*;
match property {
StyleProperty::FontStack(value) => FontStack(self.resolve_stack(fcx, *value)),
StyleProperty::FontStack(value) => FontStack(self.resolve_stack(fcx, value)),
StyleProperty::FontSize(value) => FontSize(*value * scale),
StyleProperty::FontStretch(value) => FontStretch(*value),
StyleProperty::FontStyle(value) => FontStyle(*value),
StyleProperty::FontWeight(value) => FontWeight(*value),
StyleProperty::FontVariations(value) => FontVariations(self.resolve_variations(*value)),
StyleProperty::FontFeatures(value) => FontFeatures(self.resolve_features(*value)),
StyleProperty::FontVariations(value) => FontVariations(self.resolve_variations(value)),
StyleProperty::FontFeatures(value) => FontFeatures(self.resolve_features(value)),
StyleProperty::Locale(value) => Locale(value.map(Language::parse).flatten()),
StyleProperty::Brush(value) => Brush(value.clone()),
StyleProperty::Underline(value) => Underline(*value),
Expand All @@ -166,13 +167,13 @@ impl ResolveContext {
scale: f32,
) -> ResolvedStyle<B> {
ResolvedStyle {
font_stack: self.resolve_stack(fcx, raw_style.font_stack),
font_stack: self.resolve_stack(fcx, &raw_style.font_stack),
font_size: raw_style.font_size * scale,
font_stretch: raw_style.font_stretch,
font_style: raw_style.font_style,
font_weight: raw_style.font_weight,
font_variations: self.resolve_variations(raw_style.font_variations),
font_features: self.resolve_features(raw_style.font_features),
font_variations: self.resolve_variations(&raw_style.font_variations),
font_features: self.resolve_features(&raw_style.font_features),
locale: raw_style.locale.and_then(Language::parse),
brush: raw_style.brush.clone(),
underline: ResolvedDecoration {
Expand All @@ -194,14 +195,18 @@ impl ResolveContext {
}

/// Resolves a font stack.
pub fn resolve_stack(&mut self, fcx: &mut FontContext, stack: FontStack) -> Resolved<FamilyId> {
pub fn resolve_stack(
&mut self,
fcx: &mut FontContext,
stack: &FontStack,
) -> Resolved<FamilyId> {
self.tmp_families.clear();
match stack {
FontStack::Source(source) => {
for family in FontFamily::parse_list(source) {
match family {
FontFamily::Named(name) => {
if let Some(family) = fcx.collection.family_by_name(name) {
if let Some(family) = fcx.collection.family_by_name(&name) {
self.tmp_families.push(family.id());
}
}
Expand All @@ -220,10 +225,11 @@ impl ResolveContext {
}
FontFamily::Generic(family) => {
self.tmp_families
.extend(fcx.collection.generic_families(family));
.extend(fcx.collection.generic_families(*family));
}
},
FontStack::List(families) => {
let families: &[FontFamily<'_>] = families.borrow();
for family in families {
match family {
FontFamily::Named(name) => {
Expand All @@ -247,7 +253,7 @@ impl ResolveContext {
/// Resolves font variation settings.
pub fn resolve_variations(
&mut self,
variations: FontSettings<FontVariation>,
variations: &FontSettings<FontVariation>,
) -> Resolved<Setting<f32>> {
match variations {
FontSettings::Source(source) => {
Expand All @@ -272,7 +278,7 @@ impl ResolveContext {
/// Resolves font feature settings.
pub fn resolve_features(
&mut self,
features: FontSettings<FontFeature>,
features: &FontSettings<FontFeature>,
) -> Resolved<Setting<u16>> {
match features {
FontSettings::Source(source) => {
Expand Down
50 changes: 32 additions & 18 deletions parley/src/style/font.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2021 the Parley Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT

use alloc::borrow::Cow;
use alloc::borrow::ToOwned;
use core::fmt;

pub use fontique::{
Expand All @@ -16,23 +18,23 @@ pub type FontFeature = swash::Setting<u16>;
/// Prioritized sequence of font families.
///
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/font-family>
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum FontStack<'a> {
/// Font family list in CSS format.
Source(&'a str),
Source(Cow<'a, str>),
/// Single font family.
Single(FontFamily<'a>),
/// Ordered list of font families.
List(&'a [FontFamily<'a>]),
List(Cow<'a, [FontFamily<'a>]>),
}

/// Named or generic font family.
///
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/font-family>
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum FontFamily<'a> {
/// Named font family.
Named(&'a str),
Named(Cow<'a, str>),
/// Generic font family.
Generic(GenericFamily),
}
Expand Down Expand Up @@ -125,20 +127,20 @@ impl<'a> Iterator for ParseList<'a> {
while pos < self.len {
if self.source[pos] == quote {
self.pos = pos + 1;
return Some(FontFamily::Named(
return Some(FontFamily::Named(Cow::Borrowed(
core::str::from_utf8(self.source.get(start..pos)?)
.ok()?
.trim(),
));
)));
}
pos += 1;
}
self.pos = pos;
return Some(FontFamily::Named(
return Some(FontFamily::Named(Cow::Borrowed(
core::str::from_utf8(self.source.get(start..pos)?)
.ok()?
.trim(),
));
)));
}
let mut end = start;
while pos < self.len {
Expand All @@ -155,29 +157,41 @@ impl<'a> Iterator for ParseList<'a> {
.trim();
Some(match GenericFamily::parse(name) {
Some(family) => FontFamily::Generic(family),
_ => FontFamily::Named(name),
_ => FontFamily::Named(Cow::Borrowed(name)),
})
}
}

/// Font settings that can be supplied as a raw source string or
/// a parsed slice.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum FontSettings<'a, T> {
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum FontSettings<'a, T>
where
[T]: ToOwned,
<[T] as ToOwned>::Owned: fmt::Debug + Eq + Clone,
{
/// Setting source in CSS format.
Source(&'a str),
Source(Cow<'a, str>),
/// List of settings.
List(&'a [T]),
List(Cow<'a, [T]>),
}

impl<'a, T> From<&'a str> for FontSettings<'a, T> {
impl<'a, T> From<&'a str> for FontSettings<'a, T>
where
[T]: ToOwned,
<[T] as ToOwned>::Owned: fmt::Debug + Eq + Clone,
{
fn from(value: &'a str) -> Self {
Self::Source(value)
Self::Source(Cow::Borrowed(value))
}
}

impl<'a, T> From<&'a [T]> for FontSettings<'a, T> {
impl<'a, T> From<&'a [T]> for FontSettings<'a, T>
where
[T]: ToOwned,
<[T] as ToOwned>::Owned: fmt::Debug + Eq + Clone,
{
fn from(value: &'a [T]) -> Self {
Self::List(value)
Self::List(Cow::Borrowed(value))
}
}
8 changes: 5 additions & 3 deletions parley/src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
mod brush;
mod font;

use alloc::borrow::Cow;

pub use brush::*;
pub use font::{
FontFamily, FontFeature, FontSettings, FontStack, FontStretch, FontStyle, FontVariation,
Expand Down Expand Up @@ -111,13 +113,13 @@ pub struct TextStyle<'a, B: Brush> {
impl<B: Brush> Default for TextStyle<'_, B> {
fn default() -> Self {
TextStyle {
font_stack: FontStack::Source("sans-serif"),
font_stack: FontStack::Source(Cow::Borrowed("sans-serif")),
font_size: 16.0,
font_stretch: Default::default(),
font_style: Default::default(),
font_weight: Default::default(),
font_variations: FontSettings::List(&[]),
font_features: FontSettings::List(&[]),
font_variations: FontSettings::List(Cow::Borrowed(&[])),
font_features: FontSettings::List(Cow::Borrowed(&[])),
locale: Default::default(),
brush: Default::default(),
has_underline: Default::default(),
Expand Down

0 comments on commit ca8cdc6

Please sign in to comment.