在Rust中运行时加载字体

yrwegjxp  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(226)

我正在开发一个使用Iced GUI的Rust桌面应用程序。我使用加载自定义字体以用于Iced小部件:

// fonts module:
use iced::Font;

pub const NOTO_SANS_REGULAR: Font = Font::External {
    name: "noto-sans-regular",
    bytes: include_bytes!("../../../resources/fonts/noto-sans-regular.ttf"),
};

pub const NOTO_SANS_BOLD: Font = Font::External {
    name: "noto-sans-bold",
    bytes: include_bytes!("../../../resources/fonts/noto-sans-bold.ttf"),
};

// usage:
fonts::NOTO_SANS_REGULAR

但现在我尝试在运行时加载这些字体,这样它们就不会被捆绑到可执行文件中并增加其大小。

// fonts module:
use once_cell::sync::OnceCell;
use iced::Font;
use tokio::runtime::Runtime;

pub static NOTO_SANS_REGULAR: OnceCell<Font> = OnceCell::new();
pub static NOTO_SANS_BOLD: OnceCell<Font> = OnceCell::new();

async fn download_font(name: &'static str, url: &str) -> Result<Font, reqwest::Error> {
    let response = reqwest::get(url).await?;
    let bytes = response.bytes().await?;
    let font_data = Box::new(bytes);
    let font = Font::External {
        name: name,
        bytes: &*Box::leak(font_data)
    };
    Ok(font)
}

pub fn load_fonts() {
    let runtime = Runtime::new().unwrap();

    runtime.spawn(async move {
        let noto_sans_regular = download_font("noto-sans-regular", "https://raw.githubusercontent.com/googlefonts/noto-fonts/main/unhinted/ttf/NotoSans/NotoSans-Regular.ttf");
        let noto_sans_bold = download_font("noto-sans-bold", "https://raw.githubusercontent.com/googlefonts/noto-fonts/main/unhinted/ttf/NotoSans/NotoSans-Bold.ttf");

        // Await all font downloads and store them in the OnceCell instances
        if let Ok(noto_sans_regular) = noto_sans_regular.await {
            NOTO_SANS_REGULAR.set(noto_sans_regular).ok();
        }
        if let Ok(noto_sans_bold) = noto_sans_bold.await {
            NOTO_SANS_BOLD.set(noto_sans_bold).ok();
        }
    });
}

// usage:
fonts::NOTO_SANS_REGULAR.get().unwrap_or(&Font::Default).clone()

问题是我在那里收到GET请求的DNS错误,因此我不确定整个事情是否会工作。
下载字体失败:reqwest::Error { kind:请求,url:Url { scheme:“https”,cannot_be_a_base:用户名:“",密码:无,主机:Some(Domain(“raw.githubusercontent.com“)),port:None,path:“/googlefonts/noto-fonts/main/unhinted/ttf/NotoSans/NotoSans-Regular.ttf”,查询:无,碎片:无},来源:hyper::Error(Connect,ConnectError(“dns error”,Custom { kind:中断,错误:JoinError::Cancelled(Id(8))))}

8zzbczxx

8zzbczxx1#

如果你所做的只是创建一个默认的Runtime,然后等待它运行Future完成,这正是tokio::main宏所做的,所以你可以使用它来代替:

#[tokio::main]
pub async fn load_fonts() {
    let noto_sans_regular = download_font("noto-sans-regular", "https://raw.githubusercontent.com/googlefonts/noto-fonts/main/unhinted/ttf/NotoSans/NotoSans-Regular.ttf");
    let noto_sans_bold = download_font("noto-sans-bold", "https://raw.githubusercontent.com/googlefonts/noto-fonts/main/unhinted/ttf/NotoSans/NotoSans-Bold.ttf");

    // Await all font downloads and store them in the OnceCell instances
    if let Ok(noto_sans_regular) = noto_sans_regular.await {
        NOTO_SANS_REGULAR.set(noto_sans_regular).ok();
    }
    if let Ok(noto_sans_bold) = noto_sans_bold.await {
        NOTO_SANS_BOLD.set(noto_sans_bold).ok();
    }
}
e37o9pze

e37o9pze2#

我在Discord上得到了一个提示来回答这个问题。我不得不在我的runtime上使用block_on而不是spawn,这就解决了这个问题!

相关问题