Skip to content

Commit

Permalink
feat: 支持解析字体
Browse files Browse the repository at this point in the history
  • Loading branch information
luckyadam committed Aug 12, 2024
1 parent c9bed43 commit e15d053
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 4 deletions.
2 changes: 1 addition & 1 deletion __test__/index.spec.mjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Generated by [AVA](https://avajs.dev).

> Snapshot 1
'{"keyframes":[],"medias":[],"styles":[{"declarations":[[66,100],[69,"100px"],[67,"100px"],[68,"100px"]],"media":0,"selector":["px"]}]}'
'{"fonts":[],"keyframes":[],"medias":[],"styles":[{"declarations":[[66,100],[69,"100px"],[67,"100px"],[68,"100px"]],"media":0,"selector":["px"]}]}'
Binary file modified __test__/index.spec.mjs.snap
Binary file not shown.
26 changes: 25 additions & 1 deletion src/json_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use swc_core::ecma::ast::*;
use crate::constants::{Pseudo, SUPPORT_PSEUDO_KEYS};
use crate::style_propetries::style_value_type::StyleValueType;

use crate::style_parser::KeyFrameItem;
use crate::style_parser::{FontFaceItem, KeyFrameItem};
use crate::style_propetries::style_media::StyleMedia;
use crate::style_propetries::unit::Platform;
use crate::visitor::parse_style_values;
Expand All @@ -16,18 +16,21 @@ pub struct JsonWriter {
styles: IndexMap<(u32, String), Vec<StyleValueType>>,
keyframes: IndexMap<(u32, String), Vec<KeyFrameItem>>,
medias: Vec<StyleMedia>,
fonts: Vec<FontFaceItem>,
}

impl JsonWriter {
pub fn new(
styles: IndexMap<(u32, String), Vec<StyleValueType>>,
keyframes: IndexMap<(u32, String), Vec<KeyFrameItem>>,
medias: Vec<StyleMedia>,
fonts: Vec<FontFaceItem>,
) -> Self {
Self {
styles,
keyframes,
medias,
fonts,
}
}

Expand Down Expand Up @@ -203,6 +206,8 @@ impl JsonWriter {
})
.collect();

// fonts

let json_value = expr_to_json(&Expr::Object(ObjectLit {
span: DUMMY_SP,
props: vec![
Expand Down Expand Up @@ -255,6 +260,25 @@ impl JsonWriter {
.collect(),
})),
}))),
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
key: PropName::Ident(Ident::new("fonts".into(), DUMMY_SP)),
value: Box::new(Expr::Array(ArrayLit {
span: DUMMY_SP,
elems: self
.fonts
.iter()
.map(|font| {
Some(ExprOrSpread {
spread: None,
expr: Box::new(Expr::Object(ObjectLit {
span: DUMMY_SP,
props: font.clone().to_expr(),
})),
})
})
.collect(),
})),
}))),
],
}));

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub fn parse(styles: Vec<String>, options: ParseOptions) -> ParseResult {
style_data.all_style.borrow().clone(),
style_data.all_keyframes.borrow().clone(),
style_data.all_medias.borrow().clone(),
style_data.all_fonts.borrow().clone(),
);

ParseResult {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub fn main() {
style_data.all_style.borrow().clone(),
style_data.all_keyframes.borrow().clone(),
style_data.all_medias.borrow().clone(),
style_data.all_fonts.borrow().clone(),
);

print!("{}", style_map.to_json());
Expand Down
105 changes: 103 additions & 2 deletions src/style_parser.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
use std::{cell::RefCell, convert::Infallible, rc::Rc};

use super::parse_style_properties::parse_style_properties;
use crate::{generate_expr_enum, generate_expr_lit_str};
use crate::style_propetries::font_weight::{self, FontWeight};
use crate::style_propetries::style_property_enum::ArkUI_FontWeight;
use crate::style_propetries::traits::ToExpr;
use crate::visitor::parse_style_values;
use crate::{
style_propetries::{style_value_type::StyleValueType, unit::Platform},
utils::to_camel_case,
};
use indexmap::IndexMap;
use lightningcss::properties::font::FontFamily;
use lightningcss::rules::font_face::{FontFaceProperty, Source};
use lightningcss::{
declaration::DeclarationBlock,
properties::Property,
properties::{Property, font::{FontWeight as FontWeightProperty, AbsoluteFontWeight}},
rules::{keyframes::KeyframeSelector, CssRule},
stylesheet::{ParserOptions, PrinterOptions, StyleSheet},
traits::ToCss,
Expand All @@ -27,6 +33,7 @@ pub struct StyleData {
pub all_style: Rc<RefCell<IndexMap<(u32, String), StyleValue>>>,
pub all_keyframes: Rc<RefCell<IndexMap<(u32, String), Vec<KeyFrameItem>>>>,
pub all_medias: Rc<RefCell<Vec<StyleMedia>>>,
pub all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
}

pub struct KeyFramesData {
Expand Down Expand Up @@ -57,6 +64,36 @@ impl KeyFrameItem {
return arr_keyframe_items;
}
}

#[derive(Debug, Clone)]
pub struct FontFaceItem {
pub font_family: String,
pub src: String,
pub font_weight: Option<ArkUI_FontWeight>,
}

impl FontFaceItem {
pub fn to_expr(&self) -> Vec<PropOrSpread> {
let mut result = vec![
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
key: PropName::Ident(Ident::new("fontFamily".into(), DUMMY_SP)),
value: Box::new(generate_expr_lit_str!(self.font_family.clone())),
}))),
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
key: PropName::Ident(Ident::new("src".into(), DUMMY_SP)),
value: Box::new(generate_expr_lit_str!(self.src.clone())),
}))),
];
if let Some(font_weight) = self.font_weight {
result.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
key: PropName::Ident(Ident::new("fontWeight".into(), DUMMY_SP)),
value: Box::new(generate_expr_enum!(font_weight)),
}))));
}
return result;
}
}

#[derive(Debug, Clone)]
pub struct StyleDeclaration<'i> {
pub specificity: u32,
Expand All @@ -66,6 +103,7 @@ pub struct StyleDeclaration<'i> {
struct StyleVisitor<'i> {
all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
medias: Rc<RefCell<Vec<StyleMedia>>>,
media_index: u32,
}
Expand All @@ -74,12 +112,14 @@ impl<'i> StyleVisitor<'i> {
pub fn new(
all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
medias: Rc<RefCell<Vec<StyleMedia>>>,
media_index: u32,
) -> Self {
StyleVisitor {
all_style,
keyframes,
all_fonts,
medias,
media_index,
}
Expand Down Expand Up @@ -190,7 +230,64 @@ impl<'i> Visitor<'i> for StyleVisitor<'i> {
keyframe_data.name,
keyframe_data.keyframes,
));
}
},
// 字体收集
CssRule::FontFace(font_face_rule) => {
let mut font_face = FontFaceItem {
font_family: "".to_string(),
src: "".to_string(),
font_weight: None,
};
font_face_rule.properties.iter().for_each(|property| {
match property {
FontFaceProperty::FontFamily(value) => {
font_face.font_family = value.to_css_string(PrinterOptions::default()).unwrap();
},
FontFaceProperty::Source(source) => {
// src 只取第一个
if let Some(next) = source.iter().next() {
match next {
Source::Url(value) => {
font_face.src = value.url.to_css_string(PrinterOptions::default()).unwrap();
},
_ => {}
}
}
},
FontFaceProperty::FontWeight(font_weight) => {
font_face.font_weight = Some(match &font_weight.0 {
FontWeightProperty::Bolder => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_BOLDER,
FontWeightProperty::Lighter => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_LIGHTER,
FontWeightProperty::Absolute(val) => {
match val {
AbsoluteFontWeight::Bold => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_BOLD,
AbsoluteFontWeight::Normal => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_NORMAL,
AbsoluteFontWeight::Weight(num) => {
let new_num = ((num / 100.0).ceil() * 100.0) as i32;
match new_num {
100 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W100,
200 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W200,
300 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W300,
400 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W400,
500 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W500,
600 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W600,
700 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W700,
800 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W800,
900 => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_W900,
_ => ArkUI_FontWeight::ARKUI_FONT_WEIGHT_NORMAL,
}
},
}
},
});
},
_ => {}
};
if !font_face.font_family.is_empty() && !font_face.src.is_empty() {
self.all_fonts.borrow_mut().push(font_face.clone());
}
});
},
_ => {}
}
Ok(())
Expand All @@ -205,6 +302,7 @@ pub struct StyleParser<'i> {
pub all_style: Rc<RefCell<Vec<(u32, String, Vec<StyleDeclaration<'i>>)>>>,
pub all_keyframes: Rc<RefCell<Vec<(u32, String, Vec<KeyFrameItem>)>>>,
pub all_medias: Rc<RefCell<Vec<StyleMedia>>>,
pub all_fonts: Rc<RefCell<Vec<FontFaceItem>>>,
}

impl<'i> StyleParser<'i> {
Expand All @@ -213,6 +311,7 @@ impl<'i> StyleParser<'i> {
all_style: Rc::new(RefCell::new(vec![])),
all_keyframes: Rc::new(RefCell::new(vec![])),
all_medias: Rc::new(RefCell::new(vec![])),
all_fonts: Rc::new(RefCell::new(vec![])),
}
}

Expand All @@ -221,6 +320,7 @@ impl<'i> StyleParser<'i> {
let mut style_visitor = StyleVisitor::new(
Rc::clone(&self.all_style),
Rc::clone(&self.all_keyframes),
Rc::clone(&self.all_fonts),
Rc::clone(&self.all_medias),
0,
);
Expand Down Expand Up @@ -287,6 +387,7 @@ impl<'i> StyleParser<'i> {
all_style: Rc::new(RefCell::new(final_all_style)),
all_keyframes: Rc::new(RefCell::new(final_all_keyframes)),
all_medias: self.all_medias.clone(),
all_fonts: self.all_fonts.clone(),
};
}

Expand Down

0 comments on commit e15d053

Please sign in to comment.