Skip to content

Commit

Permalink
Add support for italic text in the software renderer's bitmap font path
Browse files Browse the repository at this point in the history
In the screenshot tests this works by setting SLINT_DEFAULT_FONT to
pointer to a directory, instead of a file. We then load all fonts in
that directory and consider their families the default unless a family
is specified. This way for "Noto Sans" a regular as well as an italic
version is registered in fontdb and returned in the list of font
fallback ids. embed_glyphs in the compiler then embeds those variants
and we find them at run-time.
  • Loading branch information
tronical committed May 30, 2023
1 parent f1621c5 commit af54cee
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 135 deletions.
Binary file added examples/printerdemo/ui/fonts/NotoSans-Italic.ttf
Binary file not shown.
3 changes: 3 additions & 0 deletions examples/printerdemo/ui/fonts/NotoSans-Italic.ttf.license
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Google Inc. <https://fonts.google.com/noto/specimen/Noto+Sans/about>

SPDX-License-Identifier: OFL-1.1-RFN
1 change: 1 addition & 0 deletions examples/printerdemo/ui/fonts/convert.sh
Expand Up @@ -13,3 +13,4 @@ cp NotoSans-unhinted/LICENSE_OFL.txt .
for weight in Light Regular Bold; do
pyftsubset NotoSans-unhinted/NotoSans-$weight.ttf --unicodes="U+0020-007F,U+2026" --output-file=NotoSans-$weight.ttf
done
pyftsubset NotoSans-unhinted/NotoSans-Italic.ttf --unicodes="U+0020-007F,U+2026" --output-file=NotoSans-Italic.ttf
72 changes: 46 additions & 26 deletions internal/common/sharedfontdb.rs
Expand Up @@ -18,7 +18,9 @@ pub struct FontDatabase {
)))]
pub fontconfig_fallback_families: Vec<String>,
// Default font famiilies to use instead of SansSerif when SLINT_DEFAULT_FONT env var is set.
default_font_families: Vec<String>,
pub default_font_family_ids: Vec<fontdb::ID>,
// Same as default_font_families but reduced to unique family names
default_font_family_names: Vec<String>,
}

impl FontDatabase {
Expand All @@ -33,12 +35,12 @@ impl FontDatabase {
query.families = &single_family;
self.db.query(&query)
} else {
if self.default_font_families.is_empty() {
if self.default_font_family_ids.is_empty() {
query.families = &[fontdb::Family::SansSerif];
self.db.query(&query)
} else {
let family_storage = self
.default_font_families
.default_font_family_names
.iter()
.map(|name| fontdb::Family::Name(name))
.collect::<Vec<_>>();
Expand All @@ -65,29 +67,46 @@ fn init_fontdb() -> FontDatabase {
let mut font_db = fontdb::Database::new();

#[cfg(not(target_arch = "wasm32"))]
let default_font_families = std::env::var_os("SLINT_DEFAULT_FONT").and_then(|maybe_font_path| {
let path = std::path::Path::new(&maybe_font_path);
if path.extension().is_some() {
match font_db.load_font_file(path) {
Ok(()) => {
Some(font_db.faces().flat_map(|face_info| face_info.families.first().map(|(name, _)| name.clone())).collect())
},
Err(err) => {
eprintln!(
"Could not load the font set via `SLINT_DEFAULT_FONT`: {}: {}", path.display(), err,
);
None
},
}
} else {
eprintln!(
"The environment variable `SLINT_DEFAULT_FONT` is set, but its value is not referring to a file",
);
None
}
}).unwrap_or_default();
let (default_font_family_ids, default_font_family_names) =
std::env::var_os("SLINT_DEFAULT_FONT")
.and_then(|maybe_font_path| {
let path = std::path::Path::new(&maybe_font_path);
match if path.extension().is_some() {
font_db.load_font_file(path)
} else {
font_db.load_fonts_dir(path);
Ok(())
} {
Ok(_) => {
let mut family_ids = Vec::new();
let mut family_names = Vec::new();

for face_info in font_db.faces() {
family_ids.push(face_info.id);

let family_name = &face_info.families[0].0;
if let Err(insert_pos) = family_names.binary_search(family_name) {
family_names.insert(insert_pos, family_name.clone());
}
}

Some((family_ids, family_names))
}
Err(err) => {
eprintln!(
"Could not load the font set via `SLINT_DEFAULT_FONT`: {}: {}",
path.display(),
err,
);
None
}
}
})
.unwrap_or_default();

#[cfg(target_arch = "wasm32")]
let default_font_families = Vec::default();
let (default_font_family_ids, default_font_family_names) =
(Default::default(), Default::default());

#[cfg(not(any(
target_family = "windows",
Expand Down Expand Up @@ -136,7 +155,8 @@ fn init_fontdb() -> FontDatabase {
target_arch = "wasm32"
)))]
fontconfig_fallback_families,
default_font_families,
default_font_family_ids,
default_font_family_names,
}
}

Expand Down
2 changes: 2 additions & 0 deletions internal/compiler/embedded_resources.rs
Expand Up @@ -79,6 +79,8 @@ pub struct BitmapFont {
pub ascent: f32,
pub descent: f32,
pub glyphs: Vec<BitmapGlyphs>,
pub weight: u16,
pub italic: bool,
}

#[derive(Debug, Clone)]
Expand Down
6 changes: 4 additions & 2 deletions internal/compiler/generator/rust.rs
Expand Up @@ -228,7 +228,7 @@ pub fn generate(doc: &Document) -> TokenStream {
)
},
#[cfg(feature = "software-renderer")]
crate::embedded_resources::EmbeddedResourcesKind::BitmapFontData(crate::embedded_resources::BitmapFont { family_name, character_map, units_per_em, ascent, descent, glyphs }) => {
crate::embedded_resources::EmbeddedResourcesKind::BitmapFontData(crate::embedded_resources::BitmapFont { family_name, character_map, units_per_em, ascent, descent, glyphs, weight, italic }) => {

let character_map_size = character_map.len();

Expand Down Expand Up @@ -285,7 +285,9 @@ pub fn generate(doc: &Document) -> TokenStream {
#link_section
static GLYPHS : [slint::private_unstable_api::re_exports::BitmapGlyphs; #glyphs_size] = [#(#glyphs),*];
&GLYPHS
})
}),
weight: #weight,
italic: #italic,
};
)
},
Expand Down

0 comments on commit af54cee

Please sign in to comment.