Skip to content

Commit

Permalink
allow custom font scaling using span attrs
Browse files Browse the repository at this point in the history
fixes pop-os#64
  • Loading branch information
conradludgate committed Apr 1, 2023
1 parent f244598 commit b836d46
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 9 deletions.
110 changes: 107 additions & 3 deletions src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::ops::Range;
use core::{hash::Hash, ops::Range};

pub use fontdb::{Family, Stretch, Style, Weight};
use rangemap::RangeMap;
Expand Down Expand Up @@ -88,17 +88,64 @@ impl FamilyOwned {
}

/// Text attributes
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[derive(Clone, Copy, Debug)]
pub struct Attrs<'a> {
//TODO: should this be an option?
pub color_opt: Option<Color>,
pub family: Family<'a>,
pub stretch: Stretch,
pub style: Style,
pub weight: Weight,
pub scaling: f32,
pub metadata: usize,
}

impl PartialEq for Attrs<'_> {
fn eq(&self, other: &Self) -> bool {
// compile error if new fields are added
let Self {
color_opt,
family,
stretch,
style,
weight,
scaling,
metadata,
} = self;

*color_opt == other.color_opt
&& *family == other.family
&& *stretch == other.stretch
&& *style == other.style
&& *weight == other.weight
&& f32::total_cmp(scaling, &other.scaling).is_eq()
&& *metadata == other.metadata
}
}
impl Eq for Attrs<'_> {}
impl Hash for Attrs<'_> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
// compile error if new fields are added
let Self {
color_opt,
family,
stretch,
style,
weight,
scaling,
metadata,
} = self;

color_opt.hash(state);
family.hash(state);
stretch.hash(state);
style.hash(state);
weight.hash(state);
scaling.to_bits().hash(state);
metadata.hash(state);
}
}

impl<'a> Attrs<'a> {
/// Create a new set of attributes with sane defaults
///
Expand All @@ -110,6 +157,7 @@ impl<'a> Attrs<'a> {
stretch: Stretch::Normal,
style: Style::Normal,
weight: Weight::NORMAL,
scaling: 1.0,
metadata: 0,
}
}
Expand Down Expand Up @@ -144,6 +192,12 @@ impl<'a> Attrs<'a> {
self
}

/// Set scaling
pub fn scaling(mut self, scaling: f32) -> Self {
self.scaling = scaling;
self
}

/// Set metadata
pub fn metadata(mut self, metadata: usize) -> Self {
self.metadata = metadata;
Expand All @@ -165,18 +219,20 @@ impl<'a> Attrs<'a> {
&& self.stretch == other.stretch
&& self.style == other.style
&& self.weight == other.weight
&& self.scaling.total_cmp(&other.scaling).is_eq()
}
}

/// An owned version of [`Attrs`]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[derive(Clone, Debug)]
pub struct AttrsOwned {
//TODO: should this be an option?
pub color_opt: Option<Color>,
pub family_owned: FamilyOwned,
pub stretch: Stretch,
pub style: Style,
pub weight: Weight,
pub scaling: f32,
pub metadata: usize,
}

Expand All @@ -188,6 +244,7 @@ impl AttrsOwned {
stretch: attrs.stretch,
style: attrs.style,
weight: attrs.weight,
scaling: attrs.scaling,
metadata: attrs.metadata,
}
}
Expand All @@ -199,11 +256,58 @@ impl AttrsOwned {
stretch: self.stretch,
style: self.style,
weight: self.weight,
scaling: self.scaling,
metadata: self.metadata,
}
}
}

impl PartialEq for AttrsOwned {
fn eq(&self, other: &Self) -> bool {
// compile error if new fields are added
let Self {
color_opt,
family_owned,
stretch,
style,
weight,
scaling,
metadata,
} = self;

*color_opt == other.color_opt
&& *family_owned == other.family_owned
&& *stretch == other.stretch
&& *style == other.style
&& *weight == other.weight
&& f32::total_cmp(scaling, &other.scaling).is_eq()
&& *metadata == other.metadata
}
}
impl Eq for AttrsOwned {}
impl Hash for AttrsOwned {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
// compile error if new fields are added
let Self {
color_opt,
family_owned,
stretch,
style,
weight,
scaling,
metadata,
} = self;

color_opt.hash(state);
family_owned.hash(state);
stretch.hash(state);
style.hash(state);
weight.hash(state);
scaling.to_bits().hash(state);
metadata.hash(state);
}
}

/// List of text attributes to apply to a line
//TODO: have this clean up the spans when changes are made
#[derive(Eq, PartialEq)]
Expand Down
12 changes: 6 additions & 6 deletions src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ fn shape_fallback(
let mut missing = Vec::new();
let mut glyphs = Vec::with_capacity(glyph_infos.len());
for (info, pos) in glyph_infos.iter().zip(glyph_positions.iter()) {
let x_advance = pos.x_advance as f32 / font_scale;
let y_advance = pos.y_advance as f32 / font_scale;
let x_offset = pos.x_offset as f32 / font_scale;
let y_offset = pos.y_offset as f32 / font_scale;

let start_glyph = start_run + info.cluster as usize;
let attrs = attrs_list.get_span(start_glyph);

let x_advance = pos.x_advance as f32 / font_scale * attrs.scaling;
let y_advance = pos.y_advance as f32 / font_scale * attrs.scaling;
let x_offset = pos.x_offset as f32 / font_scale * attrs.scaling;
let y_offset = pos.y_offset as f32 / font_scale * attrs.scaling;

if info.glyph_id == 0 {
missing.push(start_glyph);
}

let attrs = attrs_list.get_span(start_glyph);
glyphs.push(ShapeGlyph {
start: start_glyph,
end: end_run, // Set later
Expand Down

0 comments on commit b836d46

Please sign in to comment.