fidl_fuchsia_fonts_ext/
lib.rsuse fidl_fuchsia_fonts::{
self as fonts, CacheMissPolicy, FallbackGroup, FamilyName, FontFamilyInfo, GenericFontFamily,
Style2, TypefaceQuery, TypefaceRequest, TypefaceRequestFlags, TypefaceResponse, Width,
};
use fidl_fuchsia_intl as intl;
pub trait FallbackGroupExt {
fn to_generic_font_family(&self) -> Option<GenericFontFamily>;
}
impl FallbackGroupExt for FallbackGroup {
fn to_generic_font_family(&self) -> Option<GenericFontFamily> {
match self {
FallbackGroup::None => None,
FallbackGroup::Serif => Some(GenericFontFamily::Serif),
FallbackGroup::SansSerif => Some(GenericFontFamily::SansSerif),
FallbackGroup::Monospace => Some(GenericFontFamily::Monospace),
FallbackGroup::Cursive => Some(GenericFontFamily::Cursive),
FallbackGroup::Fantasy => Some(GenericFontFamily::Fantasy),
}
}
}
pub trait RequestExt {
fn into_typeface_request(self) -> TypefaceRequest;
}
impl RequestExt for fonts::Request {
fn into_typeface_request(self) -> TypefaceRequest {
let family: Option<FamilyName> = match self.family {
Some(family) => Some(FamilyName { name: family }),
None => None,
};
let style: Option<Style2> = Some(Style2 {
weight: Some(self.weight as u16),
slant: Some(self.slant),
width: Width::from_primitive(self.width),
..Default::default()
});
let languages: Option<Vec<intl::LocaleId>> = self.language.map(|languages| {
languages.iter().map(|lang_code| intl::LocaleId { id: lang_code.to_string() }).collect()
});
let mut flags = TypefaceRequestFlags::empty();
if (self.flags & fonts::REQUEST_FLAG_NO_FALLBACK) != 0 {
flags |= TypefaceRequestFlags::EXACT_FAMILY;
}
if (self.flags & fonts::REQUEST_FLAG_EXACT_MATCH) != 0 {
flags |= TypefaceRequestFlags::EXACT_STYLE;
}
TypefaceRequest {
query: Some(TypefaceQuery {
family,
style,
languages,
code_points: match self.character {
ch if ch > 0 => Some(vec![ch]),
_ => None,
},
fallback_family: self.fallback_group.to_generic_font_family(),
..Default::default()
}),
flags: Some(flags),
cache_miss_policy: None,
..Default::default()
}
}
}
pub trait TypefaceRequestExt {
fn exact_family(&self) -> bool;
fn exact_style(&self) -> bool;
fn cache_miss_policy(&self) -> CacheMissPolicy;
}
impl TypefaceRequestExt for TypefaceRequest {
fn exact_family(&self) -> bool {
self.flags.map_or(false, |flags| flags.contains(fonts::TypefaceRequestFlags::EXACT_FAMILY))
}
fn exact_style(&self) -> bool {
self.flags.map_or(false, |flags| flags.contains(fonts::TypefaceRequestFlags::EXACT_STYLE))
}
fn cache_miss_policy(&self) -> CacheMissPolicy {
self.cache_miss_policy.unwrap_or(CacheMissPolicy::BlockUntilDownloaded)
}
}
pub trait TypefaceResponseExt {
fn into_font_response(self) -> Option<fonts::Response>;
}
impl TypefaceResponseExt for TypefaceResponse {
fn into_font_response(self) -> Option<fonts::Response> {
if self == Self::default() {
None
} else {
Some(fonts::Response {
buffer: self.buffer.unwrap(),
buffer_id: self.buffer_id.unwrap(),
font_index: self.font_index.unwrap(),
})
}
}
}
pub trait FontFamilyInfoExt {
fn into_family_info(self) -> Option<fonts::FamilyInfo>;
}
impl FontFamilyInfoExt for FontFamilyInfo {
fn into_family_info(self) -> Option<fonts::FamilyInfo> {
if self == Self::default() {
None
} else {
Some(fonts::FamilyInfo {
name: self.name.unwrap().name,
styles: self
.styles
.unwrap()
.into_iter()
.flat_map(|style2| style2.into_style())
.collect(),
})
}
}
}
pub trait Style2Ext {
fn into_style(self) -> Option<fonts::Style>;
}
impl Style2Ext for Style2 {
fn into_style(self) -> Option<fonts::Style> {
if self == Self::default() {
None
} else {
Some(fonts::Style {
weight: self.weight.unwrap() as u32, width: self.width.unwrap().into_primitive(),
slant: self.slant.unwrap(),
})
}
}
}