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}
69