Skip to content

Commit e15d053

Browse files
committed
feat: 支持解析字体
1 parent c9bed43 commit e15d053

File tree

6 files changed

+131
-4
lines changed

6 files changed

+131
-4
lines changed

__test__/index.spec.mjs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Generated by [AVA](https://avajs.dev).
88

99
> Snapshot 1
1010
11-
'{"keyframes":[],"medias":[],"styles":[{"declarations":[[66,100],[69,"100px"],[67,"100px"],[68,"100px"]],"media":0,"selector":["px"]}]}'
11+
'{"fonts":[],"keyframes":[],"medias":[],"styles":[{"declarations":[[66,100],[69,"100px"],[67,"100px"],[68,"100px"]],"media":0,"selector":["px"]}]}'

__test__/index.spec.mjs.snap

3 Bytes
Binary file not shown.

src/json_writer.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use swc_core::ecma::ast::*;
66
use crate::constants::{Pseudo, SUPPORT_PSEUDO_KEYS};
77
use crate::style_propetries::style_value_type::StyleValueType;
88

9-
use crate::style_parser::KeyFrameItem;
9+
use crate::style_parser::{FontFaceItem, KeyFrameItem};
1010
use crate::style_propetries::style_media::StyleMedia;
1111
use crate::style_propetries::unit::Platform;
1212
use crate::visitor::parse_style_values;
@@ -16,18 +16,21 @@ pub struct JsonWriter {
1616
styles: IndexMap<(u32, String), Vec<StyleValueType>>,
1717
keyframes: IndexMap<(u32, String), Vec<KeyFrameItem>>,
1818
medias: Vec<StyleMedia>,
19+
fonts: Vec<FontFaceItem>,
1920
}
2021

2122
impl JsonWriter {
2223
pub fn new(
2324
styles: IndexMap<(u32, String), Vec<StyleValueType>>,
2425
keyframes: IndexMap<(u32, String), Vec<KeyFrameItem>>,
2526
medias: Vec<StyleMedia>,
27+
fonts: Vec<FontFaceItem>,
2628
) -> Self {
2729
Self {
2830
styles,
2931
keyframes,
3032
medias,
33+
fonts,
3134
}
3235
}
3336

@@ -203,6 +206,8 @@ impl JsonWriter {
203206
})
204207
.collect();
205208

209+
// fonts
210+
206211
let json_value = expr_to_json(&Expr::Object(ObjectLit {
207212
span: DUMMY_SP,
208213
props: vec![
@@ -255,6 +260,25 @@ impl JsonWriter {
255260
.collect(),
256261
})),
257262
}))),
263+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
264+
key: PropName::Ident(Ident::new("fonts".into(), DUMMY_SP)),
265+
value: Box::new(Expr::Array(ArrayLit {
266+
span: DUMMY_SP,
267+
elems: self
268+
.fonts
269+
.iter()
270+
.map(|font| {
271+
Some(ExprOrSpread {
272+
spread: None,
273+
expr: Box::new(Expr::Object(ObjectLit {
274+
span: DUMMY_SP,
275+
props: font.clone().to_expr(),
276+
})),
277+
})
278+
})
279+
.collect(),
280+
})),
281+
}))),
258282
],
259283
}));
260284

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub fn parse(styles: Vec<String>, options: ParseOptions) -> ParseResult {
5252
style_data.all_style.borrow().clone(),
5353
style_data.all_keyframes.borrow().clone(),
5454
style_data.all_medias.borrow().clone(),
55+
style_data.all_fonts.borrow().clone(),
5556
);
5657

5758
ParseResult {

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn main() {
2929
style_data.all_style.borrow().clone(),
3030
style_data.all_keyframes.borrow().clone(),
3131
style_data.all_medias.borrow().clone(),
32+
style_data.all_fonts.borrow().clone(),
3233
);
3334

3435
print!("{}", style_map.to_json());

src/style_parser.rs

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use std::{cell::RefCell, convert::Infallible, rc::Rc};
22

33
use super::parse_style_properties::parse_style_properties;
4+
use crate::{generate_expr_enum, generate_expr_lit_str};
5+
use crate::style_propetries::font_weight::{self, FontWeight};
6+
use crate::style_propetries::style_property_enum::ArkUI_FontWeight;
7+
use crate::style_propetries::traits::ToExpr;
48
use crate::visitor::parse_style_values;
59
use crate::{
610
style_propetries::{style_value_type::StyleValueType, unit::Platform},
711
utils::to_camel_case,
812
};
913
use indexmap::IndexMap;
14+
use lightningcss::properties::font::FontFamily;
15+
use lightningcss::rules::font_face::{FontFaceProperty, Source};
1016
use lightningcss::{
1117
declaration::DeclarationBlock,
12-
properties::Property,
18+
properties::{Property, font::{FontWeight as FontWeightProperty, AbsoluteFontWeight}},
1319
rules::{keyframes::KeyframeSelector, CssRule},
1420
stylesheet::{ParserOptions, PrinterOptions, StyleSheet},
1521
traits::ToCss,
@@ -27,6 +33,7 @@ pub struct StyleData {
2733
pub all_style: Rc<RefCell<IndexMap<(u32, String), StyleValue>>>,
2834
pub all_keyframes: Rc<RefCell<IndexMap<(u32, String), Vec<KeyFrameItem>>>>,
2935
pub all_medias: Rc<RefCell<Vec<StyleMedia>>>,
36+
pub all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
3037
}
3138

3239
pub struct KeyFramesData {
@@ -57,6 +64,36 @@ impl KeyFrameItem {
5764
return arr_keyframe_items;
5865
}
5966
}
67+
68+
#[derive(Debug, Clone)]
69+
pub struct FontFaceItem {
70+
pub font_family: String,
71+
pub src: String,
72+
pub font_weight: Option<ArkUI_FontWeight>,
73+
}
74+
75+
impl FontFaceItem {
76+
pub fn to_expr(&self) -> Vec<PropOrSpread> {
77+
let mut result = vec![
78+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
79+
key: PropName::Ident(Ident::new("fontFamily".into(), DUMMY_SP)),
80+
value: Box::new(generate_expr_lit_str!(self.font_family.clone())),
81+
}))),
82+
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
83+
key: PropName::Ident(Ident::new("src".into(), DUMMY_SP)),
84+
value: Box::new(generate_expr_lit_str!(self.src.clone())),
85+
}))),
86+
];
87+
if let Some(font_weight) = self.font_weight {
88+
result.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
89+
key: PropName::Ident(Ident::new("fontWeight".into(), DUMMY_SP)),
90+
value: Box::new(generate_expr_enum!(font_weight)),
91+
}))));
92+
}
93+
return result;
94+
}
95+
}
96+
6097
#[derive(Debug, Clone)]
6198
pub struct StyleDeclaration<'i> {
6299
pub specificity: u32,
@@ -66,6 +103,7 @@ pub struct StyleDeclaration<'i> {
66103
struct StyleVisitor<'i> {
67104
all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
68105
keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
106+
all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
69107
medias: Rc<RefCell<Vec<StyleMedia>>>,
70108
media_index: u32,
71109
}
@@ -74,12 +112,14 @@ impl<'i> StyleVisitor<'i> {
74112
pub fn new(
75113
all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
76114
keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
115+
all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
77116
medias: Rc<RefCell<Vec<StyleMedia>>>,
78117
media_index: u32,
79118
) -> Self {
80119
StyleVisitor {
81120
all_style,
82121
keyframes,
122+
all_fonts,
83123
medias,
84124
media_index,
85125
}
@@ -190,7 +230,64 @@ impl<'i> Visitor<'i> for StyleVisitor<'i> {
190230
keyframe_data.name,
191231
keyframe_data.keyframes,
192232
));
193-
}
233+
},
234+
// 字体收集
235+
CssRule::FontFace(font_face_rule) => {
236+
let mut font_face = FontFaceItem {
237+
font_family: "".to_string(),
238+
src: "".to_string(),
239+
font_weight: None,
240+
};
241+
font_face_rule.properties.iter().for_each(|property| {
242+
match property {
243+
FontFaceProperty::FontFamily(value) => {
244+
font_face.font_family = value.to_css_string(PrinterOptions::default()).unwrap();
245+
},
246+
FontFaceProperty::Source(source) => {
247+
// src 只取第一个
248+
if let Some(next) = source.iter().next() {
249+
match next {
250+
Source::Url(value) => {
251+
font_face.src = value.url.to_css_string(PrinterOptions::default()).unwrap();
252+
},
253+
_ => {}
254+
}
255+
}
256+
},
257+
FontFaceProperty::FontWeight(font_weight) => {
258+
font_face.font_weight = Some(match &font_weight.0 {
259+
FontWeightProperty::Bolder => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_BOLDER,
260+
FontWeightProperty::Lighter => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_LIGHTER,
261+
FontWeightProperty::Absolute(val) => {
262+
match val {
263+
AbsoluteFontWeight::Bold => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_BOLD,
264+
AbsoluteFontWeight::Normal => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_NORMAL,
265+
AbsoluteFontWeight::Weight(num) => {
266+
let new_num = ((num / 100.0).ceil() * 100.0) as i32;
267+
match new_num {
268+
100 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W100,
269+
200 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W200,
270+
300 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W300,
271+
400 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W400,
272+
500 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W500,
273+
600 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W600,
274+
700 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W700,
275+
800 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W800,
276+
900 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W900,
277+
_ => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_NORMAL,
278+
}
279+
},
280+
}
281+
},
282+
});
283+
},
284+
_ => {}
285+
};
286+
if !font_face.font_family.is_empty() && !font_face.src.is_empty() {
287+
self.all_fonts.borrow_mut().push(font_face.clone());
288+
}
289+
});
290+
},
194291
_ => {}
195292
}
196293
Ok(())
@@ -205,6 +302,7 @@ pub struct StyleParser<'i> {
205302
pub all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
206303
pub all_keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
207304
pub all_medias: Rc<RefCell<Vec<StyleMedia>>>,
305+
pub all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
208306
}
209307

210308
impl<'i> StyleParser<'i> {
@@ -213,6 +311,7 @@ impl<'i> StyleParser<'i> {
213311
all_style: Rc::new(RefCell::new(vec![])),
214312
all_keyframes: Rc::new(RefCell::new(vec![])),
215313
all_medias: Rc::new(RefCell::new(vec![])),
314+
all_fonts: Rc::new(RefCell::new(vec![])),
216315
}
217316
}
218317

@@ -221,6 +320,7 @@ impl<'i> StyleParser<'i> {
221320
let mut style_visitor = StyleVisitor::new(
222321
Rc::clone(&self.all_style),
223322
Rc::clone(&self.all_keyframes),
323+
Rc::clone(&self.all_fonts),
224324
Rc::clone(&self.all_medias),
225325
0,
226326
);
@@ -287,6 +387,7 @@ impl<'i> StyleParser<'i> {
287387
all_style: Rc::new(RefCell::new(final_all_style)),
288388
all_keyframes: Rc::new(RefCell::new(final_all_keyframes)),
289389
all_medias: self.all_medias.clone(),
390+
all_fonts: self.all_fonts.clone(),
290391
};
291392
}
292393

0 commit comments

Comments
 (0)