svg_img: Embed the font file (#401)

<img width="644" alt="image"
src="https://github.com/user-attachments/assets/7acaff6c-0913-402a-8759-2660d2977ce5">
This commit is contained in:
Floyd Wang 2024-11-08 15:45:00 +08:00 committed by GitHub
parent 5aad0bf340
commit df54c7b2fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 35 additions and 19 deletions

1
Cargo.lock generated
View file

@ -5533,6 +5533,7 @@ dependencies = [
"paste", "paste",
"regex", "regex",
"resvg", "resvg",
"rust-embed",
"rust-i18n", "rust-i18n",
"serde", "serde",
"serde_json", "serde_json",

View file

@ -1,6 +1,6 @@
{ {
"border_radius": 8, "border_radius": 8,
"font_family": "sans-serif", "font_family": "Noto Sans",
"height": 400, "height": 400,
"inner_radius": 30, "inner_radius": 30,
"legend_margin": { "legend_margin": {

View file

@ -9,13 +9,11 @@ version = "0.1.0"
doctest = false doctest = false
[dependencies] [dependencies]
anyhow = "1"
gpui.workspace = true gpui.workspace = true
itertools = "0.13.0"
serde = "1.0.203"
serde_json = "1"
anyhow = "1"
image = "0.25.1" image = "0.25.1"
itertools = "0.13.0"
once_cell = "1.19.0" once_cell = "1.19.0"
paste = "1" paste = "1"
regex = "1" regex = "1"
@ -23,7 +21,10 @@ resvg = { version = "0.44.0", default-features = false, features = [
"system-fonts", "system-fonts",
"text", "text",
] } ] }
rust-embed = "8.5.0"
rust-i18n = "3" rust-i18n = "3"
serde = "1.0.203"
serde_json = "1"
smallvec = "1.13.2" smallvec = "1.13.2"
smol = "1" smol = "1"
unicode-segmentation = "1.11.0" unicode-segmentation = "1.11.0"

Binary file not shown.

View file

@ -2,15 +2,13 @@ use std::{cell::RefCell, rc::Rc};
use gpui::{ use gpui::{
anchored, deferred, div, prelude::FluentBuilder, px, relative, AnchorCorner, AnyElement, anchored, deferred, div, prelude::FluentBuilder, px, relative, AnchorCorner, AnyElement,
AppContext, DismissEvent, DispatchPhase, Element, ElementId, Focusable, GlobalElementId, DismissEvent, DispatchPhase, Element, ElementId, Focusable, GlobalElementId,
InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, ParentElement, Pixels, Point,
Position, Stateful, Style, View, ViewContext, WindowContext, Position, Stateful, Style, View, ViewContext, WindowContext,
}; };
use crate::popup_menu::PopupMenu; use crate::popup_menu::PopupMenu;
pub fn init(_cx: &mut AppContext) {}
pub trait ContextMenuExt: ParentElement + Sized { pub trait ContextMenuExt: ParentElement + Sized {
fn context_menu( fn context_menu(
self, self,

View file

@ -61,15 +61,22 @@ pub use svg_img::*;
use std::ops::Deref; use std::ops::Deref;
use rust_embed::RustEmbed;
rust_i18n::i18n!("locales", fallback = "en"); rust_i18n::i18n!("locales", fallback = "en");
#[derive(RustEmbed)]
#[folder = "./assets"]
#[include = "fonts/**/*"]
#[exclude = "*.DS_Store"]
pub struct Assets;
/// Initialize the UI module. /// Initialize the UI module.
/// ///
/// This must be called before using any of the UI components. /// This must be called before using any of the UI components.
/// You can initialize the UI module at your application's entry point. /// You can initialize the UI module at your application's entry point.
pub fn init(cx: &mut gpui::AppContext) { pub fn init(cx: &mut gpui::AppContext) {
theme::init(cx); theme::init(cx);
context_menu::init(cx);
date_picker::init(cx); date_picker::init(cx);
dock::init(cx); dock::init(cx);
drawer::init(cx); drawer::init(cx);
@ -80,7 +87,6 @@ pub fn init(cx: &mut gpui::AppContext) {
popover::init(cx); popover::init(cx);
popup_menu::init(cx); popup_menu::init(cx);
table::init(cx); table::init(cx);
webview::init(cx);
} }
pub fn locale() -> impl Deref<Target = str> { pub fn locale() -> impl Deref<Target = str> {

View file

@ -1,4 +1,8 @@
use std::{hash::Hash, ops::Deref, sync::Arc}; use std::{
hash::Hash,
ops::Deref,
sync::{Arc, LazyLock},
};
use gpui::{ use gpui::{
px, size, AppContext, Asset, Bounds, Element, Hitbox, ImageCacheError, InteractiveElement, px, size, AppContext, Asset, Bounds, Element, Hitbox, ImageCacheError, InteractiveElement,
@ -10,6 +14,17 @@ use smallvec::SmallVec;
use image::ImageBuffer; use image::ImageBuffer;
use crate::Assets;
const FONT_PATH: &str = "fonts/NotoSans-Regular.ttf";
static OPTIONS: LazyLock<usvg::Options> = LazyLock::new(|| {
let mut options = usvg::Options::default();
if let Some(font_data) = Assets::get(FONT_PATH).map(|f| f.data) {
options.fontdb_mut().load_font_data(font_data.into());
}
options
});
#[derive(Debug, Clone, Hash)] #[derive(Debug, Clone, Hash)]
pub enum SvgSource { pub enum SvgSource {
/// A svg bytes /// A svg bytes
@ -103,10 +118,7 @@ impl Asset for Image {
} }
}; };
let mut options = usvg::Options::default(); let tree = usvg::Tree::from_data(&bytes, &OPTIONS)?;
options.fontdb_mut().load_system_fonts();
let tree = usvg::Tree::from_data(&bytes, &options)?;
let mut pixmap = let mut pixmap =
resvg::tiny_skia::Pixmap::new(size.width.0 as u32, size.height.0 as u32) resvg::tiny_skia::Pixmap::new(size.width.0 as u32, size.height.0 as u32)

View file

@ -6,14 +6,12 @@ use wry::{
}; };
use gpui::{ use gpui::{
div, AppContext, Bounds, ContentMask, DismissEvent, Element, ElementId, EventEmitter, div, Bounds, ContentMask, DismissEvent, Element, ElementId, EventEmitter, FocusHandle,
FocusHandle, FocusableView, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, FocusableView, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId,
MouseDownEvent, ParentElement as _, Pixels, Render, Size, Style, Styled as _, View, MouseDownEvent, ParentElement as _, Pixels, Render, Size, Style, Styled as _, View,
WindowContext, WindowContext,
}; };
pub fn init(_cx: &AppContext) {}
pub struct WebView { pub struct WebView {
focus_handle: FocusHandle, focus_handle: FocusHandle,
webview: Rc<wry::WebView>, webview: Rc<wry::WebView>,