prehnite_core/widget/
font.rs

1#![doc = "フォント設定を使用するテキストウィジェット"]
2use crate::widget::text::TextBuilder;
3use iced::widget::text::Rich;
4use iced::widget::Text;
5use iced::{widget, Font};
6use std::sync::{LazyLock, OnceLock, RwLock};
7use tracing::error;
8use tracing_unwrap::{OptionExt, ResultExt};
9
10static DEFAULT_FONT: OnceLock<Font> = OnceLock::new();
11
12#[tracing::instrument]
13/// デフォルトフォントを初期化します。
14pub fn init_default_font(font: Font) {
15    DEFAULT_FONT
16        .set(font)
17        .inspect_err(|_| error!("set_default_font was called twice."))
18        .ok_or_log();
19}
20
21/// デフォルトフォントを取得します。
22///
23/// # Panics
24/// デフォルトフォントが初期化されていない場合
25pub fn get_default_font() -> Font {
26    DEFAULT_FONT
27        .get()
28        .expect_or_log("DEFAULT_FONT not initialized.")
29        .clone()
30}
31
32static CURRENT_FONT_FAMILY: LazyLock<RwLock<Option<Font>>> = LazyLock::new(|| RwLock::new(None));
33
34#[tracing::instrument]
35/// 使用するフォントを設定します。
36///
37/// # Panics
38/// 現在のフォントファミリーの読み込み時にLockPoisoningが発生した場合
39pub fn set_font(font_family: Option<&'static String>) {
40    *CURRENT_FONT_FAMILY.write().unwrap_or_log() = font_family.map(|v| Font::with_name(v.as_str()));
41}
42
43/// 使用するフォントを取得します。
44///
45/// # Panics
46/// 現在のフォントファミリーの読み込み時にLockPoisoningが発生した場合
47pub fn get_font_opt() -> Option<Font> {
48    CURRENT_FONT_FAMILY.read().unwrap_or_log().clone()
49}
50
51/// 使用するフォントを取得します。設定されていない場合は、デフォルトフォントを使用します。
52///
53/// # Panics
54/// 現在のフォントファミリーの読み込み時にLockPoisoningが発生した場合
55pub fn get_font() -> Font {
56    CURRENT_FONT_FAMILY
57        .read()
58        .unwrap_or_log()
59        .clone()
60        .unwrap_or(get_default_font())
61}
62
63/// フォント設定が適用された[`Text`]
64#[inline]
65pub fn ftext<'a>(text: impl widget::text::IntoFragment<'a>) -> Text<'a> {
66    TextBuilder::with_font().text(text)
67}
68
69/// フォント設定が適用された[`Rich`]
70#[inline]
71pub fn frich_text<'a, Link, Message>(
72    spans: impl AsRef<[widget::text::Span<'a, Link, Font>]> + 'a,
73) -> Rich<'a, Link, Message>
74where
75    Link: Clone + 'static,
76{
77    TextBuilder::with_font().rich(spans)
78}