Skip to content

Commit 24a66e2

Browse files
authored
Merge pull request #2 from wechat-miniprogram/feat-gap
feat: impl the gap property
2 parents d9c03a4 + 80edb85 commit 24a66e2

File tree

13 files changed

+456
-107
lines changed

13 files changed

+456
-107
lines changed

float-pigment-css/src/property.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ property_list! (PropertyValueWithGlobal, {
5555
0x28 FlexBasis: LengthType as Initial default Length::Undefined, resolver = Length::resolve_em;
5656
0x29 JustifyItems: JustifyItemsType as Initial default JustifyItems::Stretch;
5757
0x2a Order: NumberType as Initial default Number::I32(0);
58+
0x2b RowGap: GapType as Initial default Gap::Normal;
59+
0x2c ColumnGap: GapType as Initial default Gap::Normal;
5860

5961
// background
6062
0x30 BackgroundColor: ColorType as Initial default Color::Undefined;
@@ -330,6 +332,20 @@ property_value_format! (PropertyValueWithGlobal, {
330332
| "right" => JustifyItems::Right
331333
}};
332334
order: {{ Order = <number> -> |x: Number| Number::I32(x.to_i32()); }};
335+
<gap_repr: Gap>:
336+
"normal" => Gap::Normal
337+
| <non_negative_length> -> |length| Gap::Length(length);
338+
;
339+
column_gap: {{ ColumnGap = <gap_repr> }};
340+
row_gap: {{ RowGap = <gap_repr> }};
341+
gap: {{ (RowGap, ColumnGap)
342+
= [ <gap_repr> <gap_repr>? ] -> |(row_gap, column_gap): (Gap, Option<Gap>)| {
343+
if let Some(column_gap) = column_gap {
344+
return (row_gap, column_gap);
345+
}
346+
return (row_gap.clone(), row_gap);
347+
};
348+
}};
333349
flex_grow: {{ FlexGrow = <number> }};
334350
flex_shrink: {{ FlexShrink = <number> }};
335351
flex_basis: {{ FlexBasis = <length> }};

float-pigment-css/src/typing.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,3 +1785,14 @@ pub struct FeatureTag {
17851785
/// The optional number value in `font-feature-settings`.
17861786
pub value: Number,
17871787
}
1788+
1789+
#[allow(missing_docs)]
1790+
#[repr(C)]
1791+
#[property_value_type(PropertyValueWithGlobal for GapType)]
1792+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
1793+
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
1794+
pub enum Gap {
1795+
Normal,
1796+
#[resolve_font_size(Length::resolve_em_and_ratio)]
1797+
Length(Length),
1798+
}

float-pigment-css/src/typing_stringify.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,3 +2327,12 @@ impl fmt::Display for FontFeatureSettings {
23272327
write!(f, "{}", ret.join(","))
23282328
}
23292329
}
2330+
2331+
impl fmt::Display for Gap {
2332+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2333+
match self {
2334+
Gap::Normal => write!(f, "normal"),
2335+
Gap::Length(length) => write!(f, "{}", length),
2336+
}
2337+
}
2338+
}

float-pigment-css/tests/property.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,6 +2058,42 @@ mod flex {
20582058
test_parse_property!(order, "order", "1", Number::I32(1));
20592059
test_parse_property!(order, "order", "-100", Number::I32(-100));
20602060
}
2061+
// 0x2b
2062+
#[test]
2063+
fn row_gap() {
2064+
test_parse_property!(row_gap, "row-gap", "normal", Gap::Normal);
2065+
test_parse_property!(row_gap, "row-gap", "10px", Gap::Length(Length::Px(10.)));
2066+
}
2067+
2068+
// 0x2c
2069+
#[test]
2070+
fn column_gap() {
2071+
test_parse_property!(column_gap, "column-gap", "normal", Gap::Normal);
2072+
test_parse_property!(column_gap, "column-gap", "-10%", Gap::Normal);
2073+
}
2074+
2075+
#[test]
2076+
fn gap() {
2077+
test_parse_property!(row_gap, "gap", "normal", Gap::Normal);
2078+
test_parse_property!(column_gap, "gap", "normal", Gap::Normal);
2079+
2080+
test_parse_property!(row_gap, "gap", "30px", Gap::Length(Length::Px(30.)));
2081+
test_parse_property!(column_gap, "gap", "20px", Gap::Length(Length::Px(20.)));
2082+
2083+
test_parse_property!(row_gap, "gap", "normal 10px", Gap::Normal);
2084+
test_parse_property!(row_gap, "gap", "10px normal", Gap::Length(Length::Px(10.)));
2085+
test_parse_property!(
2086+
column_gap,
2087+
"gap",
2088+
"normal 10px",
2089+
Gap::Length(Length::Px(10.))
2090+
);
2091+
test_parse_property!(column_gap, "gap", "10px normal", Gap::Normal);
2092+
2093+
test_parse_property!(row_gap, "gap", "30px 40px", Gap::Length(Length::Px(30.)));
2094+
test_parse_property!(column_gap, "gap", "30px 40px", Gap::Length(Length::Px(40.)));
2095+
}
2096+
20612097
#[test]
20622098
fn flex_flow() {
20632099
let mut ssg = StyleSheetGroup::new();

float-pigment-forest/src/ffi.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,71 @@ pub unsafe extern "C" fn NodeStyleSetOrder(node: NodePtr, value: i32) {
742742
node.set_order(value);
743743
}
744744

745+
/// # Safety
746+
///
747+
#[no_mangle]
748+
pub unsafe extern "C" fn NodeStyleSetRowGap(node: NodePtr, value: f32) {
749+
let node = &*(node.ptr as *mut Node);
750+
node.set_row_gap(DefLength::Points(Len::from_f32(value)));
751+
}
752+
753+
/// # Safety
754+
///
755+
#[no_mangle]
756+
pub unsafe extern "C" fn NodeStyleSetRowGapNormal(node: NodePtr) {
757+
let node = &*(node.ptr as *mut Node);
758+
node.set_row_gap(DefLength::Undefined);
759+
}
760+
761+
/// # Safety
762+
///
763+
#[no_mangle]
764+
pub unsafe extern "C" fn NodeStyleSetRowGapPercentage(node: NodePtr, value: f32) {
765+
let node = &*(node.ptr as *mut Node);
766+
node.set_row_gap(DefLength::Percent(value));
767+
}
768+
769+
/// # Safety
770+
///
771+
#[no_mangle]
772+
pub unsafe extern "C" fn NodeStyleSetRowGapCalcHandle(node: NodePtr, calc_handle: i32) {
773+
let node = &*(node.ptr as *mut Node);
774+
node.set_row_gap(DefLength::Custom(calc_handle));
775+
}
776+
777+
/// # Safety
778+
///
779+
#[no_mangle]
780+
781+
pub unsafe extern "C" fn NodeStyleSetColumnGap(node: NodePtr, value: f32) {
782+
let node = &*(node.ptr as *mut Node);
783+
node.set_column_gap(DefLength::Points(Len::from_f32(value)));
784+
}
785+
786+
/// # Safety
787+
///
788+
#[no_mangle]
789+
pub unsafe extern "C" fn NodeStyleSetColumnGapNormal(node: NodePtr) {
790+
let node = &*(node.ptr as *mut Node);
791+
node.set_column_gap(DefLength::Undefined);
792+
}
793+
794+
/// # Safety
795+
///
796+
#[no_mangle]
797+
pub unsafe extern "C" fn NodeStyleSetColumnGapPercentage(node: NodePtr, value: f32) {
798+
let node = &*(node.ptr as *mut Node);
799+
node.set_column_gap(DefLength::Percent(value));
800+
}
801+
802+
/// # Safety
803+
///
804+
#[no_mangle]
805+
pub unsafe extern "C" fn NodeStyleSetColumnGapCalcHandle(node: NodePtr, calc_handle: i32) {
806+
let node = &*(node.ptr as *mut Node);
807+
node.set_column_gap(DefLength::Custom(calc_handle));
808+
}
809+
745810
/// # Safety
746811
///
747812
#[no_mangle]

float-pigment-forest/src/layout/layout_impl.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,4 +685,14 @@ impl LayoutStyle<Len> for Node {
685685
fn text_align(&self) -> TextAlign {
686686
self.style_manager().text_align()
687687
}
688+
689+
#[inline]
690+
fn row_gap(&self) -> Length {
691+
self.style_manager().row_gap()
692+
}
693+
694+
#[inline]
695+
fn column_gap(&self) -> Length {
696+
self.style_manager().column_gap()
697+
}
688698
}

float-pigment-forest/src/node.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ pub trait StyleSetter {
618618
unsafe fn set_aspect_ratio(&self, value: Option<f32>);
619619
unsafe fn set_order(&self, value: i32);
620620
unsafe fn set_text_align(&self, value: TextAlign);
621+
unsafe fn set_row_gap(&self, value: Length);
622+
unsafe fn set_column_gap(&self, value: Length);
621623
}
622624

623625
impl StyleSetter for Node {
@@ -857,6 +859,16 @@ impl StyleSetter for Node {
857859
self.mark_dirty_propagate();
858860
}
859861
}
862+
unsafe fn set_row_gap(&self, value: Length) {
863+
if self.style_manager_mut().set_row_gap(value) {
864+
self.mark_dirty_propagate();
865+
}
866+
}
867+
unsafe fn set_column_gap(&self, value: Length) {
868+
if self.style_manager_mut().set_column_gap(value) {
869+
self.mark_dirty_propagate();
870+
}
871+
}
860872
}
861873

862874
#[cfg(test)]

float-pigment-forest/src/style.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct OtherStyle {
7676
pub overflow_y: Overflow,
7777
pub text_align: TextAlign,
7878
pub aspect_ratio: Option<f32>,
79+
pub row_gap: Length,
80+
pub column_gap: Length,
7981
}
8082

8183
impl Default for OtherStyle {
@@ -87,6 +89,8 @@ impl Default for OtherStyle {
8789
overflow_y: Overflow::Visible,
8890
text_align: TextAlign::Start,
8991
aspect_ratio: None,
92+
row_gap: Length::Undefined,
93+
column_gap: Length::Undefined,
9094
}
9195
}
9296
}
@@ -945,4 +949,30 @@ impl StyleManager {
945949
self.flex_style().flex_basis = value;
946950
true
947951
}
952+
953+
pub(crate) fn row_gap(&self) -> Length {
954+
self.other_style().row_gap.clone()
955+
}
956+
957+
pub(crate) fn set_row_gap(&self, value: Length) -> bool {
958+
if self.other_style().row_gap == value {
959+
return false;
960+
}
961+
self.clone_style(StyleBit::Other);
962+
self.other_style().row_gap = value;
963+
true
964+
}
965+
966+
pub(crate) fn column_gap(&self) -> Length {
967+
self.other_style().column_gap.clone()
968+
}
969+
970+
pub(crate) fn set_column_gap(&self, value: Length) -> bool {
971+
if self.other_style().column_gap == value {
972+
return false;
973+
}
974+
self.clone_style(StyleBit::Other);
975+
self.other_style().column_gap = value;
976+
true
977+
}
948978
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use crate::*;
2+
3+
#[test]
4+
fn gap() {
5+
assert_xml!(
6+
r#"
7+
<div style="display: flex; width: 100px; gap: 10px;">
8+
<div style="height: 10px; flex: 1" expect_width="45"></div>
9+
<div style="height: 10px; flex: 1" expect_width="45" expect_left="55"></div>
10+
</div>
11+
"#
12+
)
13+
}
14+
15+
#[test]
16+
fn column_gap_in_flex_row_box() {
17+
assert_xml!(
18+
r#"
19+
<div style="display: flex; width: 100px; column-gap: 10px; flex-wrap: wrap;">
20+
<div style="width: 100px; height: 30px; flex-shrink: 0" expect_width="100"></div>
21+
<div style="width: 100px; height: 30px; flex-shrink: 0" expect_width="100" expect_top="40"></div>
22+
</div>
23+
"#
24+
)
25+
}
26+
27+
#[test]
28+
fn row_gap_in_flex_row_box() {
29+
assert_xml!(
30+
r#"
31+
<div style="display: flex; width: 100px; row-gap: 10px;">
32+
<div style="height: 10px; flex: 1" expect_width="45"></div>
33+
<div style="height: 10px; flex: 1" expect_width="45" expect_left="55"></div>
34+
</div>
35+
"#
36+
)
37+
}
38+
39+
#[test]
40+
fn column_gap_in_flex_column_box() {
41+
assert_xml!(
42+
r#"
43+
<div style="display: flex; flex-direction: column; width: 100px; height: 50px; column-gap: 10px; flex-wrap: wrap; align-content: flex-start">
44+
<div style="width: 30px; height: 30px; flex-shrink: 0" expect_height="30"></div>
45+
<div style="width: 30px; height: 30px; flex-shrink: 0" expect_height="30" expect_left="40"></div>
46+
</div>
47+
"#
48+
)
49+
}
50+
51+
#[test]
52+
fn row_gap_in_flex_column_box() {
53+
assert_xml!(
54+
r#"
55+
<div style="display: flex; flex-direction: column; width: 100px; height: 100px; row-gap: 10px;">
56+
<div style="width: 100px; height: 30px;" expect_width="100"></div>
57+
<div style="width: 100px; height: 30px;" expect_width="100" expect_top="40"></div>
58+
</div>
59+
"#
60+
)
61+
}

float-pigment-forest/tests/custom/css_flexbox/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ mod order;
99
mod align_content;
1010

1111
mod flex_item_margin;
12+
mod gap;

0 commit comments

Comments
 (0)