1
1
use std:: { cell:: RefCell , convert:: Infallible , rc:: Rc } ;
2
2
3
3
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 ;
4
8
use crate :: visitor:: parse_style_values;
5
9
use crate :: {
6
10
style_propetries:: { style_value_type:: StyleValueType , unit:: Platform } ,
7
11
utils:: to_camel_case,
8
12
} ;
9
13
use indexmap:: IndexMap ;
14
+ use lightningcss:: properties:: font:: FontFamily ;
15
+ use lightningcss:: rules:: font_face:: { FontFaceProperty , Source } ;
10
16
use lightningcss:: {
11
17
declaration:: DeclarationBlock ,
12
- properties:: Property ,
18
+ properties:: { Property , font :: { FontWeight as FontWeightProperty , AbsoluteFontWeight } } ,
13
19
rules:: { keyframes:: KeyframeSelector , CssRule } ,
14
20
stylesheet:: { ParserOptions , PrinterOptions , StyleSheet } ,
15
21
traits:: ToCss ,
@@ -27,6 +33,7 @@ pub struct StyleData {
27
33
pub all_style : Rc < RefCell < IndexMap < ( u32 , String ) , StyleValue > > > ,
28
34
pub all_keyframes : Rc < RefCell < IndexMap < ( u32 , String ) , Vec < KeyFrameItem > > > > ,
29
35
pub all_medias : Rc < RefCell < Vec < StyleMedia > > > ,
36
+ pub all_fonts : Rc < RefCell < Vec < FontFaceItem > > > ,
30
37
}
31
38
32
39
pub struct KeyFramesData {
@@ -57,6 +64,36 @@ impl KeyFrameItem {
57
64
return arr_keyframe_items;
58
65
}
59
66
}
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
+
60
97
#[ derive( Debug , Clone ) ]
61
98
pub struct StyleDeclaration < ' i > {
62
99
pub specificity : u32 ,
@@ -66,6 +103,7 @@ pub struct StyleDeclaration<'i> {
66
103
struct StyleVisitor < ' i > {
67
104
all_style : Rc < RefCell < Vec < ( u32 , String , Vec < StyleDeclaration < ' i > > ) > > > ,
68
105
keyframes : Rc < RefCell < Vec < ( u32 , String , Vec < KeyFrameItem > ) > > > ,
106
+ all_fonts : Rc < RefCell < Vec < FontFaceItem > > > ,
69
107
medias : Rc < RefCell < Vec < StyleMedia > > > ,
70
108
media_index : u32 ,
71
109
}
@@ -74,12 +112,14 @@ impl<'i> StyleVisitor<'i> {
74
112
pub fn new (
75
113
all_style : Rc < RefCell < Vec < ( u32 , String , Vec < StyleDeclaration < ' i > > ) > > > ,
76
114
keyframes : Rc < RefCell < Vec < ( u32 , String , Vec < KeyFrameItem > ) > > > ,
115
+ all_fonts : Rc < RefCell < Vec < FontFaceItem > > > ,
77
116
medias : Rc < RefCell < Vec < StyleMedia > > > ,
78
117
media_index : u32 ,
79
118
) -> Self {
80
119
StyleVisitor {
81
120
all_style,
82
121
keyframes,
122
+ all_fonts,
83
123
medias,
84
124
media_index,
85
125
}
@@ -190,7 +230,64 @@ impl<'i> Visitor<'i> for StyleVisitor<'i> {
190
230
keyframe_data. name ,
191
231
keyframe_data. keyframes ,
192
232
) ) ;
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
+ } ,
194
291
_ => { }
195
292
}
196
293
Ok ( ( ) )
@@ -205,6 +302,7 @@ pub struct StyleParser<'i> {
205
302
pub all_style : Rc < RefCell < Vec < ( u32 , String , Vec < StyleDeclaration < ' i > > ) > > > ,
206
303
pub all_keyframes : Rc < RefCell < Vec < ( u32 , String , Vec < KeyFrameItem > ) > > > ,
207
304
pub all_medias : Rc < RefCell < Vec < StyleMedia > > > ,
305
+ pub all_fonts : Rc < RefCell < Vec < FontFaceItem > > > ,
208
306
}
209
307
210
308
impl < ' i > StyleParser < ' i > {
@@ -213,6 +311,7 @@ impl<'i> StyleParser<'i> {
213
311
all_style : Rc :: new ( RefCell :: new ( vec ! [ ] ) ) ,
214
312
all_keyframes : Rc :: new ( RefCell :: new ( vec ! [ ] ) ) ,
215
313
all_medias : Rc :: new ( RefCell :: new ( vec ! [ ] ) ) ,
314
+ all_fonts : Rc :: new ( RefCell :: new ( vec ! [ ] ) ) ,
216
315
}
217
316
}
218
317
@@ -221,6 +320,7 @@ impl<'i> StyleParser<'i> {
221
320
let mut style_visitor = StyleVisitor :: new (
222
321
Rc :: clone ( & self . all_style ) ,
223
322
Rc :: clone ( & self . all_keyframes ) ,
323
+ Rc :: clone ( & self . all_fonts ) ,
224
324
Rc :: clone ( & self . all_medias ) ,
225
325
0 ,
226
326
) ;
@@ -287,6 +387,7 @@ impl<'i> StyleParser<'i> {
287
387
all_style : Rc :: new ( RefCell :: new ( final_all_style) ) ,
288
388
all_keyframes : Rc :: new ( RefCell :: new ( final_all_keyframes) ) ,
289
389
all_medias : self . all_medias . clone ( ) ,
390
+ all_fonts : self . all_fonts . clone ( ) ,
290
391
} ;
291
392
}
292
393
0 commit comments