mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-17 22:08:39 +00:00

Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / node_test (macos-14) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.85) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.85) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_test_driver (macos-14) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.85) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
CI / material-components (push) Blocked by required conditions
* Parlay init * Start on femtovg * Cargo fmt * Decimate fonts.rs * Use fill_glyphs * [autofix.ci] apply automated fixes * Use positioned_glyphs instead * Clean up a little * Format * [autofix.ci] apply automated fixes * Few fixes * [autofix.ci] apply automated fixes * More small changes * Clean up * [autofix.ci] apply automated fixes * Display text cursor * Handle text_input_cursor_rect_for_byte_offset * stoke glyphs * Handle text selections * Stroke selection as well * Fix wierd cargo.toml padding * Move selection and stroking to brush settings * Removed commented out code * [autofix.ci] apply automated fixes * Cursor sizing * [autofix.ci] apply automated fixes * Mark unused variables * _scale -> scale * Handle a lot more layout options * Use the parley cursor * Removed unused PhysicalPoint * Start combining stuff WIP * Move things into i_slint_core::textlayout::sharedparley * [autofix.ci] apply automated fixes * Go back to splitting paragraphs correctly * Handle font_metrics via ttf_parser * Move (lack of) overflow handling to sharedparley * [autofix.ci] apply automated fixes * impl Deref for Layout * Be more explit about the width passed to layout being physical * Cargo fmt, rename fonts to font_cache * Use a thread local for layout context * Use parley selection * fix femtovg wgpu * Switch femtovg branch * max_physical_width -> max_width * Box contexts * [autofix.ci] apply automated fixes * Fallback to GenericFamily::SansSerif if no font is set * Add paint.set_font_size * Use max_physical_height * Fix text_size to return correct logical sizes * Use femtovg from crates.io * Fix C++ build The `sharedparley` module declares a public `Layout` struct, which clashes with the `Layout` struct we use in the C++ API. The former however is entirely internal to Rust, so we can instruct cbindgen to ignore the module. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Simon Hausmann <simon.hausmann@slint.dev>
138 lines
4.1 KiB
Rust
138 lines
4.1 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
|
|
pub use fontique;
|
|
pub use ttf_parser;
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
|
|
pub static COLLECTION: std::sync::LazyLock<Collection> = std::sync::LazyLock::new(|| {
|
|
let mut collection = fontique::Collection::new(fontique::CollectionOptions {
|
|
shared: true,
|
|
..Default::default()
|
|
});
|
|
|
|
let mut source_cache = fontique::SourceCache::new_shared();
|
|
|
|
let mut default_fonts: HashMap<std::path::PathBuf, fontique::QueryFont> = Default::default();
|
|
|
|
let mut add_font_from_path = |path: std::path::PathBuf| {
|
|
if let Ok(bytes) = std::fs::read(&path) {
|
|
// just use the first font of the first family in the file.
|
|
if let Some(font) =
|
|
collection.register_fonts(bytes.into(), None).first().and_then(|(id, infos)| {
|
|
let info = infos.first()?;
|
|
get_font_for_info(&mut collection, &mut source_cache, *id, &info)
|
|
})
|
|
{
|
|
default_fonts.insert(path, font);
|
|
}
|
|
}
|
|
};
|
|
|
|
if let Some(path) = std::env::var_os("SLINT_DEFAULT_FONT") {
|
|
let path = std::path::Path::new(&path);
|
|
if path.extension().is_some() {
|
|
add_font_from_path(path.to_owned());
|
|
} else {
|
|
if let Ok(dir) = std::fs::read_dir(path) {
|
|
for file in dir {
|
|
if let Ok(file) = file {
|
|
add_font_from_path(file.path());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Collection { inner: collection, source_cache, default_fonts: Arc::new(default_fonts) }
|
|
});
|
|
|
|
pub fn get_collection() -> Collection {
|
|
COLLECTION.clone()
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Collection {
|
|
pub inner: fontique::Collection,
|
|
pub source_cache: fontique::SourceCache,
|
|
pub default_fonts: Arc<HashMap<std::path::PathBuf, fontique::QueryFont>>,
|
|
}
|
|
|
|
impl Collection {
|
|
pub fn query<'a>(&'a mut self) -> fontique::Query<'a> {
|
|
self.inner.query(&mut self.source_cache)
|
|
}
|
|
|
|
pub fn get_font_for_info(
|
|
&mut self,
|
|
family_id: fontique::FamilyId,
|
|
info: &fontique::FontInfo,
|
|
) -> Option<fontique::QueryFont> {
|
|
get_font_for_info(&mut self.inner, &mut self.source_cache, family_id, info)
|
|
}
|
|
}
|
|
|
|
fn get_font_for_info(
|
|
collection: &mut fontique::Collection,
|
|
source_cache: &mut fontique::SourceCache,
|
|
family_id: fontique::FamilyId,
|
|
info: &fontique::FontInfo,
|
|
) -> Option<fontique::QueryFont> {
|
|
let mut query = collection.query(source_cache);
|
|
query.set_families(std::iter::once(fontique::QueryFamily::from(family_id)));
|
|
query.set_attributes(fontique::Attributes {
|
|
weight: info.weight(),
|
|
style: info.style(),
|
|
width: info.width(),
|
|
});
|
|
let mut font = None;
|
|
query.matches_with(|queried_font| {
|
|
font = Some(queried_font.clone());
|
|
fontique::QueryStatus::Stop
|
|
});
|
|
font
|
|
}
|
|
|
|
impl std::ops::Deref for Collection {
|
|
type Target = fontique::Collection;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.inner
|
|
}
|
|
}
|
|
|
|
impl std::ops::DerefMut for Collection {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.inner
|
|
}
|
|
}
|
|
|
|
/// Font metrics in design space. Scale with desired pixel size and divided by units_per_em
|
|
/// to obtain pixel metrics.
|
|
#[derive(Clone)]
|
|
pub struct DesignFontMetrics {
|
|
pub ascent: f32,
|
|
pub descent: f32,
|
|
pub x_height: f32,
|
|
pub cap_height: f32,
|
|
pub units_per_em: f32,
|
|
}
|
|
|
|
impl DesignFontMetrics {
|
|
pub fn new(font: &fontique::QueryFont) -> Self {
|
|
let face = ttf_parser::Face::parse(font.blob.data(), font.index).unwrap();
|
|
Self::new_from_face(&face)
|
|
}
|
|
|
|
pub fn new_from_face(face: &ttf_parser::Face) -> Self {
|
|
Self {
|
|
ascent: face.ascender() as f32,
|
|
descent: face.descender() as f32,
|
|
x_height: face.x_height().unwrap_or_default() as f32,
|
|
cap_height: face.capital_height().unwrap_or_default() as f32,
|
|
units_per_em: face.units_per_em() as f32,
|
|
}
|
|
}
|
|
}
|