Skip to content

Commit 7d5afc9

Browse files
authored
Try to load font by path (#79)
1 parent e43f9a1 commit 7d5afc9

File tree

4 files changed

+40
-22
lines changed

4 files changed

+40
-22
lines changed

src/config/params.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
use raqote::SolidSource;
24

35
use super::{Color, Config};
@@ -126,7 +128,13 @@ fn default_font_color() -> SolidSource {
126128
}
127129

128130
fn font_by_name(name: String) -> Font {
129-
Font::font_by_name(name.as_str()).unwrap_or_else(|e| panic!("cannot find font {}: {}", name, e))
131+
let path = Path::new(name.as_str());
132+
if path.is_absolute() && path.exists() {
133+
Font::font_by_path(path)
134+
} else {
135+
Font::font_by_name(name.as_str())
136+
}
137+
.unwrap_or_else(|e| panic!("cannot find font {}: {}", name, e))
130138
}
131139

132140
fn color_to_solid_source(x: Color) -> SolidSource {

src/font.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
use anyhow::Result;
24
use raqote::{AntialiasMode, DrawOptions, DrawTarget, Point, SolidSource};
35

@@ -28,6 +30,8 @@ pub trait FontBackend: Sized {
2830

2931
fn font_by_name(name: &str) -> Result<Self>;
3032

33+
fn font_by_path(path: &Path) -> Result<Self>;
34+
3135
fn draw(
3236
&self,
3337
dt: &mut DrawTarget,

src/font/fdue.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::cell::RefCell;
22
use std::collections::BinaryHeap;
3+
use std::path::Path;
34

45
use anyhow::Context;
56
use fontdue::layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle, VerticalAlign};
@@ -10,35 +11,27 @@ use rust_fontconfig::{FcFontCache, FcFontPath, FcPattern};
1011

1112
use super::{FontBackend, FontColor, Result};
1213

13-
static FONTCONFIG: Lazy<FontConfig> = Lazy::new(FontConfig::new);
14+
static FONTCONFIG_CACHE: Lazy<FcFontCache> = Lazy::new(FcFontCache::build);
1415
const BUF_SIZE: usize = 256 * 256;
1516

1617
pub struct Font {
1718
inner: fontdue::Font,
18-
}
19-
20-
// Because Font is re-created on every `draw` call method we cached dynamic allocations
21-
struct FontConfig {
22-
cache: FcFontCache,
2319
// Layout in fontdue uses allocations, so we're reusing it for reduce memory allocations
2420
layout: RefCell<Layout>,
2521
// Move buffer to heap, because it is very big for stack; only one allocation happens
2622
buffer: RefCell<Vec<u32>>,
2723
}
2824

29-
impl FontConfig {
30-
fn new() -> Self {
25+
impl Font {
26+
fn with_font(inner: fontdue::Font) -> Self {
3127
Self {
32-
cache: FcFontCache::build(),
28+
inner,
3329
layout: RefCell::new(Layout::new(CoordinateSystem::PositiveYDown)),
3430
buffer: RefCell::new(vec![0; BUF_SIZE]),
3531
}
3632
}
3733
}
3834

39-
//SAFETY: We do not use multiple threads, so it never happens that the & is posted to another thread
40-
unsafe impl Sync for FontConfig {}
41-
4235
#[derive(Eq)]
4336
struct FuzzyResult<'a> {
4437
text: &'a str,
@@ -75,14 +68,13 @@ impl Font {
7568
)
7669
.map_err(|e| anyhow::anyhow!("{}", e))?;
7770

78-
Ok(Font { inner })
71+
Ok(Font::with_font(inner))
7972
}
8073

8174
fn try_find_best_font(name: &str) -> Vec<String> {
8275
const COUNT_MATCHES: usize = 5;
8376

84-
FONTCONFIG
85-
.cache
77+
FONTCONFIG_CACHE
8678
.list()
8779
.keys()
8880
.filter_map(|font| {
@@ -103,17 +95,15 @@ impl Font {
10395

10496
impl FontBackend for Font {
10597
fn default() -> Self {
106-
FONTCONFIG
107-
.cache
98+
FONTCONFIG_CACHE
10899
.query(&FcPattern::default())
109100
.map(Font::from_fc_path)
110101
.unwrap()
111102
.unwrap()
112103
}
113104

114105
fn font_by_name(name: &str) -> Result<Self> {
115-
FONTCONFIG
116-
.cache
106+
FONTCONFIG_CACHE
117107
.query(&FcPattern {
118108
name: Some(name.to_string()),
119109
..Default::default()
@@ -130,6 +120,16 @@ impl FontBackend for Font {
130120
})?
131121
}
132122

123+
fn font_by_path(path: &Path) -> Result<Self> {
124+
Font::from_fc_path(&FcFontPath {
125+
path: path
126+
.to_str()
127+
.ok_or_else(|| anyhow::anyhow!("Invalid path"))?
128+
.to_owned(),
129+
font_index: 0,
130+
})
131+
}
132+
133133
fn draw(
134134
&self,
135135
dt: &mut DrawTarget,
@@ -139,8 +139,8 @@ impl FontBackend for Font {
139139
color: FontColor,
140140
opts: &DrawOptions,
141141
) {
142-
let mut buf = FONTCONFIG.buffer.borrow_mut();
143-
let mut layout = FONTCONFIG.layout.borrow_mut();
142+
let mut buf = self.buffer.borrow_mut();
143+
let mut layout = self.layout.borrow_mut();
144144

145145
layout.reset(&LayoutSettings {
146146
x: start_pos.x,

src/font/fontkit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
use font_kit::family_name::FamilyName;
24
pub use font_kit::loaders::freetype::Font;
35
use font_kit::properties::Properties;
@@ -22,6 +24,10 @@ impl FontBackend for Font {
2224
.map_err(Into::into)
2325
}
2426

27+
fn font_by_path(path: &Path) -> Result<Self> {
28+
Font::from_path(path, 0).map_err(Into::into)
29+
}
30+
2531
fn draw(
2632
&self,
2733
dt: &mut DrawTarget,

0 commit comments

Comments
 (0)