skia_safe/core/
font_metrics.rs

1use crate::{prelude::*, scalar};
2use skia_bindings::{self as sb, SkFontMetrics};
3
4bitflags! {
5    #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6    pub struct Flags: u32 {
7        const UNDERLINE_THICKNESS_IS_VALID = sb::SkFontMetrics_FontMetricsFlags_kUnderlineThicknessIsValid_Flag as _;
8        const UNDERLINE_POSITION_IS_VALID = sb::SkFontMetrics_FontMetricsFlags_kUnderlinePositionIsValid_Flag as _;
9        const STRIKEOUT_THICKNESS_IS_VALID = sb::SkFontMetrics_FontMetricsFlags_kStrikeoutThicknessIsValid_Flag as _;
10        const STRIKEOUT_POSITION_IS_VALID = sb::SkFontMetrics_FontMetricsFlags_kStrikeoutPositionIsValid_Flag as _;
11        const BOUNDS_INVALID = sb::SkFontMetrics_FontMetricsFlags_kBoundsInvalid_Flag as _;
12    }
13}
14
15#[repr(C)]
16#[derive(Copy, Clone, PartialEq, Default, Debug)]
17pub struct FontMetrics {
18    flags: Flags,
19    pub top: scalar,
20    pub ascent: scalar,
21    pub descent: scalar,
22    pub bottom: scalar,
23    pub leading: scalar,
24    pub avg_char_width: scalar,
25    pub max_char_width: scalar,
26    pub x_min: scalar,
27    pub x_max: scalar,
28    pub x_height: scalar,
29    pub cap_height: scalar,
30    underline_thickness: scalar,
31    underline_position: scalar,
32    strikeout_thickness: scalar,
33    strikeout_position: scalar,
34}
35
36native_transmutable!(SkFontMetrics, FontMetrics, font_metrics_layout);
37
38impl FontMetrics {
39    pub fn underline_thickness(&self) -> Option<scalar> {
40        self.if_valid(
41            Flags::UNDERLINE_THICKNESS_IS_VALID,
42            self.underline_thickness,
43        )
44    }
45
46    pub fn underline_position(&self) -> Option<scalar> {
47        self.if_valid(Flags::UNDERLINE_POSITION_IS_VALID, self.underline_position)
48    }
49
50    pub fn strikeout_thickness(&self) -> Option<scalar> {
51        self.if_valid(
52            Flags::STRIKEOUT_THICKNESS_IS_VALID,
53            self.strikeout_thickness,
54        )
55    }
56
57    pub fn strikeout_position(&self) -> Option<scalar> {
58        self.if_valid(Flags::STRIKEOUT_POSITION_IS_VALID, self.strikeout_position)
59    }
60
61    fn if_valid(&self, flag: self::Flags, value: scalar) -> Option<scalar> {
62        self.flags.contains(flag).if_true_some(value)
63    }
64
65    pub fn has_bounds(&self) -> bool {
66        !self.flags.contains(Flags::BOUNDS_INVALID)
67    }
68}