fidl_fuchsia_fonts_ext/
lib.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fidl_fuchsia_fonts::{
6    self as fonts, CacheMissPolicy, FallbackGroup, FamilyName, FontFamilyInfo, GenericFontFamily,
7    Style2, TypefaceQuery, TypefaceRequest, TypefaceRequestFlags, TypefaceResponse, Width,
8};
9use fidl_fuchsia_intl as intl;
10
11/// Extensions for [`FallbackGroup`](fidl_fuchsia_fonts::FallbackGroup).
12pub trait FallbackGroupExt {
13    fn to_generic_font_family(&self) -> Option<GenericFontFamily>;
14}
15
16impl FallbackGroupExt for FallbackGroup {
17    fn to_generic_font_family(&self) -> Option<GenericFontFamily> {
18        match self {
19            FallbackGroup::None => None,
20            FallbackGroup::Serif => Some(GenericFontFamily::Serif),
21            FallbackGroup::SansSerif => Some(GenericFontFamily::SansSerif),
22            FallbackGroup::Monospace => Some(GenericFontFamily::Monospace),
23            FallbackGroup::Cursive => Some(GenericFontFamily::Cursive),
24            FallbackGroup::Fantasy => Some(GenericFontFamily::Fantasy),
25        }
26    }
27}
28
29/// Extensions for [`Request`](fidl_fuchsia_fonts::Request).
30pub trait RequestExt {
31    fn into_typeface_request(self) -> TypefaceRequest;
32}
33
34impl RequestExt for fonts::Request {
35    fn into_typeface_request(self) -> TypefaceRequest {
36        let family: Option<FamilyName> = match self.family {
37            Some(family) => Some(FamilyName { name: family }),
38            None => None,
39        };
40
41        let style: Option<Style2> = Some(Style2 {
42            weight: Some(self.weight as u16),
43            slant: Some(self.slant),
44            width: Width::from_primitive(self.width),
45            ..Default::default()
46        });
47
48        let languages: Option<Vec<intl::LocaleId>> = self.language.map(|languages| {
49            languages.iter().map(|lang_code| intl::LocaleId { id: lang_code.to_string() }).collect()
50        });
51
52        let mut flags = TypefaceRequestFlags::empty();
53        if (self.flags & fonts::REQUEST_FLAG_NO_FALLBACK) != 0 {
54            flags |= TypefaceRequestFlags::EXACT_FAMILY;
55        }
56        if (self.flags & fonts::REQUEST_FLAG_EXACT_MATCH) != 0 {
57            flags |= TypefaceRequestFlags::EXACT_STYLE;
58        }
59
60        TypefaceRequest {
61            query: Some(TypefaceQuery {
62                family,
63                style,
64                languages,
65                code_points: match self.character {
66                    ch if ch > 0 => Some(vec![ch]),
67                    _ => None,
68                },
69                fallback_family: self.fallback_group.to_generic_font_family(),
70                ..Default::default()
71            }),
72            flags: Some(flags),
73            cache_miss_policy: None,
74            ..Default::default()
75        }
76    }
77}
78
79/// Extensions for [`TypefaceRequest`](fidl_fuchsia_fonts::TypefaceRequest).
80pub trait TypefaceRequestExt {
81    /// See [`fidl_fuchsia_fonts::TypefaceRequestFlags::ExactFamily`].
82    fn exact_family(&self) -> bool;
83
84    /// See [`fidl_fuchsia_fonts::TypefaceRequestFlags::ExactStyle`].
85    fn exact_style(&self) -> bool;
86
87    /// See ['fidl_fuchsia_fonts::CacheMissPolicy`].
88    fn cache_miss_policy(&self) -> CacheMissPolicy;
89}
90
91impl TypefaceRequestExt for TypefaceRequest {
92    fn exact_family(&self) -> bool {
93        self.flags.map_or(false, |flags| flags.contains(fonts::TypefaceRequestFlags::EXACT_FAMILY))
94    }
95
96    fn exact_style(&self) -> bool {
97        self.flags.map_or(false, |flags| flags.contains(fonts::TypefaceRequestFlags::EXACT_STYLE))
98    }
99
100    fn cache_miss_policy(&self) -> CacheMissPolicy {
101        self.cache_miss_policy.unwrap_or(CacheMissPolicy::BlockUntilDownloaded)
102    }
103}
104
105/// Extensions for [`TypefaceResponse`](fidl_fuchsia_fonts::TypefaceResponse).
106pub trait TypefaceResponseExt {
107    fn into_font_response(self) -> Option<fonts::Response>;
108}
109
110impl TypefaceResponseExt for TypefaceResponse {
111    fn into_font_response(self) -> Option<fonts::Response> {
112        if self == Self::default() {
113            None
114        } else {
115            Some(fonts::Response {
116                buffer: self.buffer.unwrap(),
117                buffer_id: self.buffer_id.unwrap(),
118                font_index: self.font_index.unwrap(),
119            })
120        }
121    }
122}
123
124/// Extensions for [`FontFamilyInfo`](fidl_fuchsia_fonts::FontFamilyInfo).
125pub trait FontFamilyInfoExt {
126    fn into_family_info(self) -> Option<fonts::FamilyInfo>;
127}
128
129impl FontFamilyInfoExt for FontFamilyInfo {
130    fn into_family_info(self) -> Option<fonts::FamilyInfo> {
131        if self == Self::default() {
132            None
133        } else {
134            Some(fonts::FamilyInfo {
135                name: self.name.unwrap().name,
136                styles: self
137                    .styles
138                    .unwrap()
139                    .into_iter()
140                    .flat_map(|style2| style2.into_style())
141                    .collect(),
142            })
143        }
144    }
145}
146
147/// Extensions for [`Style2`](fidl_fuchsia_fonts::Style2).
148pub trait Style2Ext {
149    fn into_style(self) -> Option<fonts::Style>;
150}
151
152impl Style2Ext for Style2 {
153    fn into_style(self) -> Option<fonts::Style> {
154        if self == Self::default() {
155            None
156        } else {
157            Some(fonts::Style {
158                weight: self.weight.unwrap() as u32, // Expanded from u16
159                width: self.width.unwrap().into_primitive(),
160                slant: self.slant.unwrap(),
161            })
162        }
163    }
164}