Resolve variations on fallback faces
This commit is contained in:
1 parent
3dc4014589
commit
178102799d
4 files changed
+398
-89
No files matched your search
Vendored
+38
@@ -331,6 +331,14 @@ pub struct Attrs<'a> {
|
||||
/// A specific database face selected by the caller. Font fallback remains
|
||||
/// available when that face does not contain a requested glyph.
|
||||
pub font_id_opt: Option<fontdb::ID>,
|
||||
/// High-level CSS `font-weight` coordinate, applied only when the actual
|
||||
/// shaped face provides a `wght` axis.
|
||||
pub font_weight_axis_opt: Option<VariationValue>,
|
||||
/// Automatic optical-size coordinate derived from the used font size.
|
||||
/// `None` represents `font-optical-sizing: none`.
|
||||
pub font_optical_size_opt: Option<VariationValue>,
|
||||
/// Whether high-level font style requests an italic variable instance.
|
||||
pub font_italic_axis: bool,
|
||||
pub stretch: Stretch,
|
||||
pub style: Style,
|
||||
pub weight: Weight,
|
||||
@@ -352,6 +360,9 @@ impl<'a> Attrs<'a> {
|
||||
color_opt: None,
|
||||
family: Family::SansSerif,
|
||||
font_id_opt: None,
|
||||
font_weight_axis_opt: None,
|
||||
font_optical_size_opt: None,
|
||||
font_italic_axis: false,
|
||||
stretch: Stretch::Normal,
|
||||
style: Style::Normal,
|
||||
weight: Weight::NORMAL,
|
||||
@@ -382,6 +393,21 @@ impl<'a> Attrs<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn font_weight_axis(mut self, value: f32) -> Self {
|
||||
self.font_weight_axis_opt = Some(VariationValue(value));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn font_optical_size(mut self, value: f32) -> Self {
|
||||
self.font_optical_size_opt = Some(VariationValue(value));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn font_italic_axis(mut self, italic: bool) -> Self {
|
||||
self.font_italic_axis = italic;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set [Stretch]
|
||||
pub fn stretch(mut self, stretch: Stretch) -> Self {
|
||||
self.stretch = stretch;
|
||||
@@ -453,6 +479,9 @@ impl<'a> Attrs<'a> {
|
||||
pub fn compatible(&self, other: &Self) -> bool {
|
||||
self.family == other.family
|
||||
&& self.font_id_opt == other.font_id_opt
|
||||
&& self.font_weight_axis_opt == other.font_weight_axis_opt
|
||||
&& self.font_optical_size_opt == other.font_optical_size_opt
|
||||
&& self.font_italic_axis == other.font_italic_axis
|
||||
&& self.stretch == other.stretch
|
||||
&& self.style == other.style
|
||||
&& self.weight == other.weight
|
||||
@@ -487,6 +516,9 @@ pub struct AttrsOwned {
|
||||
pub color_opt: Option<Color>,
|
||||
pub family_owned: FamilyOwned,
|
||||
pub font_id_opt: Option<fontdb::ID>,
|
||||
pub font_weight_axis_opt: Option<VariationValue>,
|
||||
pub font_optical_size_opt: Option<VariationValue>,
|
||||
pub font_italic_axis: bool,
|
||||
pub stretch: Stretch,
|
||||
pub style: Style,
|
||||
pub weight: Weight,
|
||||
@@ -505,6 +537,9 @@ impl AttrsOwned {
|
||||
color_opt: attrs.color_opt,
|
||||
family_owned: FamilyOwned::new(attrs.family),
|
||||
font_id_opt: attrs.font_id_opt,
|
||||
font_weight_axis_opt: attrs.font_weight_axis_opt,
|
||||
font_optical_size_opt: attrs.font_optical_size_opt,
|
||||
font_italic_axis: attrs.font_italic_axis,
|
||||
stretch: attrs.stretch,
|
||||
style: attrs.style,
|
||||
weight: attrs.weight,
|
||||
@@ -522,6 +557,9 @@ impl AttrsOwned {
|
||||
color_opt: self.color_opt,
|
||||
family: self.family_owned.as_family(),
|
||||
font_id_opt: self.font_id_opt,
|
||||
font_weight_axis_opt: self.font_weight_axis_opt,
|
||||
font_optical_size_opt: self.font_optical_size_opt,
|
||||
font_italic_axis: self.font_italic_axis,
|
||||
stretch: self.stretch,
|
||||
style: self.style,
|
||||
weight: self.weight,
|
||||
|
||||
Vendored
+8
@@ -22,6 +22,14 @@ pub struct LayoutGlyph {
|
||||
pub font_id: fontdb::ID,
|
||||
/// Font id of the glyph
|
||||
pub glyph_id: u16,
|
||||
/// Whether the selected font face has variation axes.
|
||||
pub font_is_variable: bool,
|
||||
/// Automatic `wght` axis value requested by the span.
|
||||
pub font_weight_axis_opt: Option<f32>,
|
||||
/// Automatic `opsz` axis value requested by the span.
|
||||
pub font_optical_size_opt: Option<f32>,
|
||||
/// Whether the span requests an italic variation axis.
|
||||
pub font_italic_axis: bool,
|
||||
/// X offset of hitbox
|
||||
pub x: f32,
|
||||
/// Y offset of hitbox
|
||||
|
||||
Vendored
+49
-1
@@ -144,10 +144,41 @@ fn shape_fallback(
|
||||
// requests non-default variation coordinates, then use the varied face for
|
||||
// metrics, plan construction, and shaping so advances and glyph selection
|
||||
// are derived from the same instance.
|
||||
let varied_face = if attrs.font_variations.is_empty() {
|
||||
let varied_face = if !font.rustybuzz().is_variable()
|
||||
|| (attrs.font_variations.is_empty()
|
||||
&& attrs.font_weight_axis_opt.is_none()
|
||||
&& attrs.font_optical_size_opt.is_none()
|
||||
&& !attrs.font_italic_axis)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
let mut face = font.rustybuzz().clone();
|
||||
if let Some(value) = attrs
|
||||
.font_weight_axis_opt
|
||||
.map(|value| value.0)
|
||||
.filter(|value| value.is_finite())
|
||||
{
|
||||
let _ = face.set_variation(rustybuzz::ttf_parser::Tag::from_bytes(b"wght"), value);
|
||||
}
|
||||
if let Some(value) = attrs
|
||||
.font_optical_size_opt
|
||||
.map(|value| value.0)
|
||||
.filter(|value| value.is_finite())
|
||||
{
|
||||
let _ = face.set_variation(rustybuzz::ttf_parser::Tag::from_bytes(b"opsz"), value);
|
||||
}
|
||||
if attrs.font_italic_axis {
|
||||
let italic = rustybuzz::ttf_parser::Tag::from_bytes(b"ital");
|
||||
if face
|
||||
.variation_axes()
|
||||
.into_iter()
|
||||
.any(|axis| axis.tag == italic)
|
||||
{
|
||||
let _ = face.set_variation(italic, 1.0);
|
||||
} else {
|
||||
let _ = face.set_variation(rustybuzz::ttf_parser::Tag::from_bytes(b"slnt"), -14.0);
|
||||
}
|
||||
}
|
||||
for variation in attrs
|
||||
.font_variations
|
||||
.iter()
|
||||
@@ -257,6 +288,10 @@ fn shape_fallback(
|
||||
font_monospace_em_width: font.monospace_em_width(),
|
||||
font_id: font.id(),
|
||||
glyph_id: info.glyph_id.try_into().expect("failed to cast glyph ID"),
|
||||
font_is_variable: face.is_variable(),
|
||||
font_weight_axis_opt: attrs.font_weight_axis_opt.map(|value| value.0),
|
||||
font_optical_size_opt: attrs.font_optical_size_opt.map(|value| value.0),
|
||||
font_italic_axis: attrs.font_italic_axis,
|
||||
//TODO: color should not be related to shaping
|
||||
color_opt: attrs.color_opt,
|
||||
metadata: attrs.metadata,
|
||||
@@ -539,6 +574,7 @@ fn shape_skip(
|
||||
.expect("no default font found");
|
||||
let font_id = font.id();
|
||||
let font_monospace_em_width = font.monospace_em_width();
|
||||
let font_is_variable = font.rustybuzz().is_variable();
|
||||
let font = font.as_swash();
|
||||
|
||||
let charmap = font.charmap();
|
||||
@@ -569,6 +605,10 @@ fn shape_skip(
|
||||
font_monospace_em_width,
|
||||
font_id,
|
||||
glyph_id,
|
||||
font_is_variable,
|
||||
font_weight_axis_opt: attrs.font_weight_axis_opt.map(|value| value.0),
|
||||
font_optical_size_opt: attrs.font_optical_size_opt.map(|value| value.0),
|
||||
font_italic_axis: attrs.font_italic_axis,
|
||||
color_opt: attrs.color_opt,
|
||||
metadata: attrs.metadata,
|
||||
cache_key_flags: attrs.cache_key_flags,
|
||||
@@ -592,6 +632,10 @@ pub struct ShapeGlyph {
|
||||
pub font_monospace_em_width: Option<f32>,
|
||||
pub font_id: fontdb::ID,
|
||||
pub glyph_id: u16,
|
||||
pub font_is_variable: bool,
|
||||
pub font_weight_axis_opt: Option<f32>,
|
||||
pub font_optical_size_opt: Option<f32>,
|
||||
pub font_italic_axis: bool,
|
||||
pub color_opt: Option<Color>,
|
||||
pub metadata: usize,
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
@@ -615,6 +659,10 @@ impl ShapeGlyph {
|
||||
line_height_opt,
|
||||
font_id: self.font_id,
|
||||
glyph_id: self.glyph_id,
|
||||
font_is_variable: self.font_is_variable,
|
||||
font_weight_axis_opt: self.font_weight_axis_opt,
|
||||
font_optical_size_opt: self.font_optical_size_opt,
|
||||
font_italic_axis: self.font_italic_axis,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
|
||||
Reference in new issue
Block a user