Skip to content

Commit 52eeb2c

Browse files
Move FontConfig conversion to styled_text
This also adds additional cases for the stretch conversion and a note in the doc comments about where these values have come from.
1 parent 0e54031 commit 52eeb2c

File tree

2 files changed

+80
-56
lines changed

2 files changed

+80
-56
lines changed

fontique/src/backend/fontconfig/cache.rs

+3-56
Original file line numberDiff line numberDiff line change
@@ -6,59 +6,6 @@ use std::io::Read;
66
use std::path::PathBuf;
77
use styled_text::{Stretch, Style, Weight};
88

9-
// FIXME(style): There's an argument for putting this into styled_text
10-
fn stretch_from_fc(width: i32) -> Stretch {
11-
match width {
12-
63 => Stretch::EXTRA_CONDENSED,
13-
87 => Stretch::SEMI_CONDENSED,
14-
113 => Stretch::SEMI_EXPANDED,
15-
_ => Stretch::from_ratio(width as f32 / 100.0),
16-
}
17-
}
18-
19-
// FIXME(style): There's an argument for putting this into styled_text
20-
fn style_from_fc(slant: i32) -> Style {
21-
match slant {
22-
100 => Style::Italic,
23-
110 => Style::Oblique(None),
24-
_ => Style::Normal,
25-
}
26-
}
27-
28-
// FIXME(style): There's an argument for putting this into styled_text
29-
fn weight_from_fc(weight: i32) -> Weight {
30-
const MAP: &[(i32, i32)] = &[
31-
(0, 0),
32-
(100, 0),
33-
(200, 40),
34-
(300, 50),
35-
(350, 55),
36-
(380, 75),
37-
(400, 80),
38-
(500, 100),
39-
(600, 180),
40-
(700, 200),
41-
(800, 205),
42-
(900, 210),
43-
(950, 215),
44-
];
45-
for (i, (ot, fc)) in MAP.iter().skip(1).enumerate() {
46-
if weight == *fc {
47-
return Weight::new(*ot as f32);
48-
}
49-
if weight < *fc {
50-
let weight = weight as f32;
51-
let fc_a = MAP[i - 1].1 as f32;
52-
let fc_b = *fc as f32;
53-
let ot_a = MAP[i - 1].1 as f32;
54-
let ot_b = *ot as f32;
55-
let t = (fc_a - fc_b) / (weight - fc_a);
56-
return Weight::new(ot_a + (ot_b - ot_a) * t);
57-
}
58-
}
59-
Weight::EXTRA_BLACK
60-
}
61-
629
#[derive(Default)]
6310
pub struct CachedFont {
6411
pub family: Vec<String>,
@@ -153,21 +100,21 @@ fn parse_font(
153100
Object::Slant => {
154101
for val in elt.values().ok()? {
155102
if let Value::Int(i) = val.ok()? {
156-
font.style = style_from_fc(i as _);
103+
font.style = Style::from_fontconfig(i as _);
157104
}
158105
}
159106
}
160107
Object::Weight => {
161108
for val in elt.values().ok()? {
162109
if let Value::Int(i) = val.ok()? {
163-
font.weight = weight_from_fc(i as _);
110+
font.weight = Weight::from_fontconfig(i as _);
164111
}
165112
}
166113
}
167114
Object::Width => {
168115
for val in elt.values().ok()? {
169116
if let Value::Int(i) = val.ok()? {
170-
font.stretch = stretch_from_fc(i as _);
117+
font.stretch = Stretch::from_fontconfig(i as _);
171118
}
172119
}
173120
}

styled_text/src/attributes.rs

+77
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ impl Stretch {
156156
}
157157
}
158158

159+
impl Stretch {
160+
/// Creates a new stretch attribute with the given value from Fontconfig.
161+
///
162+
/// The values are determined based on the [fonts.conf documentation].
163+
///
164+
/// [fonts.conf documentation]: https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
165+
pub fn from_fontconfig(width: i32) -> Stretch {
166+
match width {
167+
50 => Self::ULTRA_CONDENSED,
168+
63 => Self::EXTRA_CONDENSED,
169+
75 => Self::CONDENSED,
170+
87 => Self::SEMI_CONDENSED,
171+
100 => Self::NORMAL,
172+
113 => Self::SEMI_EXPANDED,
173+
125 => Self::EXPANDED,
174+
150 => Self::EXTRA_EXPANDED,
175+
200 => Self::ULTRA_EXPANDED,
176+
_ => Self::from_ratio(width as f32 / 100.0),
177+
}
178+
}
179+
}
180+
159181
impl fmt::Display for Stretch {
160182
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161183
let value = self.0 * 1000.0;
@@ -268,6 +290,46 @@ impl Weight {
268290
}
269291
}
270292

293+
impl Weight {
294+
/// Creates a new weight attribute with the given value from Fontconfig.
295+
///
296+
/// The values are determined based on the [fonts.conf documentation].
297+
///
298+
/// [fonts.conf documentation]: https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
299+
pub fn from_fontconfig(weight: i32) -> Self {
300+
const MAP: &[(i32, i32)] = &[
301+
(0, 0),
302+
(100, 0),
303+
(200, 40),
304+
(300, 50),
305+
(350, 55),
306+
(380, 75),
307+
(400, 80),
308+
(500, 100),
309+
(600, 180),
310+
(700, 200),
311+
(800, 205),
312+
(900, 210),
313+
(950, 215),
314+
];
315+
for (i, (ot, fc)) in MAP.iter().skip(1).enumerate() {
316+
if weight == *fc {
317+
return Self::new(*ot as f32);
318+
}
319+
if weight < *fc {
320+
let weight = weight as f32;
321+
let fc_a = MAP[i - 1].1 as f32;
322+
let fc_b = *fc as f32;
323+
let ot_a = MAP[i - 1].1 as f32;
324+
let ot_b = *ot as f32;
325+
let t = (fc_a - fc_b) / (weight - fc_a);
326+
return Self::new(ot_a + (ot_b - ot_a) * t);
327+
}
328+
}
329+
Self::EXTRA_BLACK
330+
}
331+
}
332+
271333
impl Default for Weight {
272334
fn default() -> Self {
273335
Self::NORMAL
@@ -362,6 +424,21 @@ impl Style {
362424
}
363425
}
364426

427+
impl Style {
428+
/// Creates a new style attribute with the given value from Fontconfig.
429+
///
430+
/// The values are determined based on the [fonts.conf documentation].
431+
///
432+
/// [fonts.conf documentation]: https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
433+
pub fn from_fontconfig(slant: i32) -> Self {
434+
match slant {
435+
100 => Self::Italic,
436+
110 => Self::Oblique(None),
437+
_ => Self::Normal,
438+
}
439+
}
440+
}
441+
365442
impl fmt::Display for Style {
366443
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367444
let value = match self {

0 commit comments

Comments
 (0)