1use super::*;
4use crate::abi;
5use crate::resolve;
6use core::ffi::c_void;
7use crate::mangle::{self, swift_type};
8
9mangle::modifier_types! {
12 pub(crate) ASPECT_T = ty("_AspectRatioLayout");
14 pub(crate) FIXED_SIZE_T = ty("_FixedSizeLayout");
16 pub(crate) Z_INDEX_T = ty("_TraitWritingModifier").of(vec![ty("ZIndexTraitKey")]);
18 pub(crate) DISABLED_T = ty("_EnvironmentKeyTransformModifier").of(vec![Type::Verbatim("Sb".into())]);
20 pub(crate) HIDDEN_T = ty("_HiddenModifier");
22 pub(crate) BLEND_T = ty("_BlendModeEffect");
24 pub(crate) OVERLAY_ANY_T = ty("_OverlayModifier").of(vec![ty("AnyView")]);
26 pub(crate) BACKGROUND_ANY_T = ty("_BackgroundModifier").of(vec![ty("AnyView")]);
28 pub(crate) MASK_ANY_T = ty("_MaskAlignmentEffect").of(vec![ty("AnyView")]);
30 pub(crate) CLIP_CIRCLE_T = ty("_ClipEffect").of(vec![ty("Circle")]);
33 pub(crate) CLIP_CAPSULE_T = ty("_ClipEffect").of(vec![ty("Capsule")]);
35 pub(crate) CLIP_ELLIPSE_T = ty("_ClipEffect").of(vec![ty("Ellipse")]);
37 pub(crate) CLIP_RRECT_T = ty("_ClipEffect").of(vec![ty("RoundedRectangle")]);
39}
40
41
42
43
44
45
46
47
48#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
55pub enum ContentMode {
56 #[default]
58 Fit,
59 Fill,
61}
62
63#[derive(Clone, Copy, Debug, Default, PartialEq)]
70#[repr(C)]
71pub struct EdgeInsets {
72 pub top: f64,
74 pub leading: f64,
76 pub bottom: f64,
78 pub trailing: f64,
80}
81
82impl EdgeInsets {
83 pub fn all(amount: f64) -> Self {
85 Self { top: amount, leading: amount, bottom: amount, trailing: amount }
86 }
87
88 pub fn from_swift(top: f64, leading: f64, bottom: f64, trailing: f64) -> Self {
95 unsafe {
96 let (a, b, c, d): (f64, f64, f64, f64);
97 core::arch::asm!("blr {f}", f = in(reg) resolve::edge_insets_init(),
98 inlateout("d0") top => a,
99 inlateout("d1") leading => b,
100 inlateout("d2") bottom => c,
101 inlateout("d3") trailing => d,
102 lateout("x0") _, lateout("x1") _, lateout("x2") _, lateout("x3") _,
103 lateout("x4") _, lateout("x5") _, lateout("x6") _, lateout("x7") _,
104 lateout("x8") _, lateout("x9") _, lateout("x10") _, lateout("x11") _,
105 lateout("x12") _, lateout("x13") _, lateout("x14") _, lateout("x15") _,
106 lateout("x16") _, lateout("x17") _, lateout("lr") _,
107 lateout("x20") _, lateout("x21") _, clobber_abi("C"),
108 );
109 Self { top: a, leading: b, bottom: c, trailing: d }
110 }
111 }
112}
113
114pub fn padding_insets(view: &ViewHandle, insets: EdgeInsets) -> ViewHandle {
119 unsafe {
120 let (meta, wt, size) = super::opaque_result_type(
121 resolve::padding_insets_oret(),
122 &[view.meta, view.wt],
123 );
124 let mut result = vec![0u8; size];
125 let this = view.value_ptr();
126 core::arch::asm!("blr {f}", f = in(reg) resolve::padding_insets_fn(),
127 in("d0") insets.top,
128 in("d1") insets.leading,
129 in("d2") insets.bottom,
130 in("d3") insets.trailing,
131 in("x0") view.meta,
132 in("x1") view.wt,
133 in("x8") result.as_mut_ptr(),
134 in("x20") this,
135 lateout("x2") _, lateout("x3") _, lateout("x4") _, lateout("x5") _,
136 lateout("x6") _, lateout("x7") _,
137 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
138 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
139 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
140 );
141 super::wrap_owned(result, meta, wt)
142 }
143}
144
145pub fn aspect_ratio_content_mode(
151 view: &ViewHandle,
152 ratio: Option<f64>,
153 mode: ContentMode,
154) -> ViewHandle {
155 match ratio {
156 Some(r) => aspect_ratio(view, r, mode == ContentMode::Fill),
157 None => aspect_ratio_mode(view, mode == ContentMode::Fill),
158 }
159}
160
161pub fn aspect_ratio(view: &ViewHandle, ratio: f64, fill: bool) -> ViewHandle {
163 unsafe {
164 let (_, _, size) = ASPECT_T.applied_to(view.meta);
165 let r = abi::call_modifier(resolve::aspect_ratio_fn(), view.value_ptr(), view.meta, view.wt,
167 &[ratio.to_bits(), 0, u64::from(fill)],
168 [0.0; 4],
169 size,
170 );
171 wrap_modified(r, &ASPECT_T, view)
172 }
173}
174
175pub fn aspect_ratio_mode(view: &ViewHandle, fill: bool) -> ViewHandle {
181 unsafe {
182 let (_, _, size) = ASPECT_T.applied_to(view.meta);
183 let r = abi::call_modifier(resolve::aspect_ratio_fn(), view.value_ptr(), view.meta, view.wt,
184 &[0, 1, u64::from(fill)],
185 [0.0; 4],
186 size,
187 );
188 wrap_modified(r, &ASPECT_T, view)
189 }
190}
191
192pub fn fixed_size(view: &ViewHandle, horizontal: bool, vertical: bool) -> ViewHandle {
194 unsafe {
195 let (_, _, size) = FIXED_SIZE_T.applied_to(view.meta);
196 let r = abi::call_modifier(resolve::fixed_size_fn(), view.value_ptr(), view.meta, view.wt,
197 &[u64::from(horizontal), u64::from(vertical)],
198 [0.0; 4],
199 size,
200 );
201 wrap_modified(r, &FIXED_SIZE_T, view)
202 }
203}
204
205pub fn z_index(view: &ViewHandle, value: f64) -> ViewHandle {
207 unsafe {
208 let (_, _, size) = Z_INDEX_T.applied_to(view.meta);
209 let r = abi::call_modifier(resolve::z_index_fn(), view.value_ptr(), view.meta, view.wt, &[], [value, 0.0, 0.0, 0.0], size);
210 wrap_modified(r, &Z_INDEX_T, view)
211 }
212}
213
214pub fn disabled(view: &ViewHandle, value: bool) -> ViewHandle {
216 unsafe {
217 let (_, _, size) = DISABLED_T.applied_to(view.meta);
218 let r =
219 abi::call_modifier(resolve::disabled_fn(), view.value_ptr(), view.meta, view.wt, &[u64::from(value)], [0.0; 4], size);
220 wrap_modified(r, &DISABLED_T, view)
221 }
222}
223
224pub fn hidden(view: &ViewHandle) -> ViewHandle {
226 unsafe {
227 let (_, _, size) = HIDDEN_T.applied_to(view.meta);
228 let r = abi::call_modifier(resolve::hidden_fn(), view.value_ptr(), view.meta, view.wt, &[], [0.0; 4], size);
229 wrap_modified(r, &HIDDEN_T, view)
230 }
231}
232
233pub fn blend_mode(view: &ViewHandle, mode: u8) -> ViewHandle {
237 unsafe {
238 let (_, _, size) = BLEND_T.applied_to(view.meta);
239 let mut buf = [mode];
240 let r = abi::call_modifier(resolve::blend_mode_fn(), view.value_ptr(), view.meta, view.wt,
241 &[buf.as_mut_ptr() as u64],
242 [0.0; 4],
243 size,
244 );
245 wrap_modified(r, &BLEND_T, view)
246 }
247}
248
249
250
251
252
253
254pub(crate) unsafe fn clip_shape_impl(
259 view: &ViewHandle,
260 shape_bytes: &[u8],
261 shape_mangled: &[u8],
262 modifier: &ModifierType,
263) -> ViewHandle {
264 unsafe {
265 let shape_meta = abi::resolve_type_by_mangled_name(shape_mangled);
266 assert!(!shape_meta.is_null(), "shape metadata");
267 let shape_wt = abi::get_view_wt_for_proto(shape_meta, resolve::shape_proto());
268 assert!(!shape_wt.is_null(), "shape: Shape");
269
270 let mut shape_buf = vec![0u8; abi::type_bytes(shape_meta)];
271 shape_buf[..shape_bytes.len()].copy_from_slice(shape_bytes);
272
273 let (_, _, size) = modifier.applied_to(view.meta);
274 let mut result = vec![0u8; size];
275 let this = view.value_ptr();
276 core::arch::asm!("blr {f}", f = in(reg) resolve::clip_shape_fn(),
281 in("x0") shape_buf.as_mut_ptr(),
282 in("x1") 0x0100u64, in("x2") view.meta,
284 in("x3") shape_meta,
285 in("x4") view.wt,
286 in("x5") shape_wt,
287 in("x8") result.as_mut_ptr(),
288 in("x20") this,
289 lateout("x6") _, lateout("x7") _,
290 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
291 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
292 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
293 );
294 wrap_modified(result, modifier, view)
295 }
296}
297
298pub fn clip_circle(view: &ViewHandle) -> ViewHandle {
300 unsafe { clip_shape_impl(view, &[], swift_type!(SwiftUI.Circle).as_bytes(), &CLIP_CIRCLE_T) }
301}
302
303pub fn clip_ellipse(view: &ViewHandle) -> ViewHandle {
305 unsafe { clip_shape_impl(view, &[], swift_type!(SwiftUI.Ellipse).as_bytes(), &CLIP_ELLIPSE_T) }
306}
307
308pub fn clip_capsule(view: &ViewHandle) -> ViewHandle {
310 clip_capsule_styled(view, true)
311}
312
313pub fn clip_capsule_styled(view: &ViewHandle, continuous: bool) -> ViewHandle {
321 unsafe {
322 clip_shape_impl(
323 view,
324 &[u8::from(continuous)],
325 swift_type!(SwiftUI.Capsule).as_bytes(),
326 &CLIP_CAPSULE_T,
327 )
328 }
329}
330
331pub fn clip_rounded_rect(view: &ViewHandle, radius: f64) -> ViewHandle {
333 clip_rounded_rect_styled(view, radius, true)
334}
335
336pub fn clip_rounded_rect_styled(view: &ViewHandle, radius: f64, continuous: bool) -> ViewHandle {
342 let mut buf = [0u8; 17];
343 buf[..8].copy_from_slice(&radius.to_le_bytes());
344 buf[8..16].copy_from_slice(&radius.to_le_bytes());
345 buf[16] = u8::from(continuous);
346 unsafe { clip_shape_impl(view, &buf, swift_type!(SwiftUI.RoundedRectangle).as_bytes(), &CLIP_RRECT_T) }
347}
348
349pub(crate) unsafe fn overlay_or_mask(
351 view: &ViewHandle,
352 content: &ViewHandle,
353 func: *const c_void,
354 modifier: &ModifierType,
355 alignment: super::Alignment,
356) -> ViewHandle {
357 unsafe {
358 let (_, _, size) = modifier.applied_to_content(view.meta, content.meta, content.wt);
359 let mut result = vec![0u8; size];
360 let this = view.value_ptr();
361
362 let kid_handles = Child::new(content, Content::Concrete);
363 let handles = kid_handles.element();
364 let payload = TuplePayload { children: handles.as_ptr(), count: 1 };
365 let mut ctx = abi::ClosureCtx::new(emit_tuple, &payload as *const TuplePayload as *mut c_void);
366
367 let [ah, av] = alignment.words();
368 core::arch::asm!("blr {f}", f = in(reg) func,
372 in("x0") ah, in("x1") av,
373 in("x2") abi::swift_closure_thunk as *const c_void,
374 in("x3") &mut ctx as *mut abi::ClosureCtx,
375 in("x4") view.meta, in("x5") content.meta, in("x6") view.wt, in("x7") content.wt, in("x8") result.as_mut_ptr(),
380 in("x20") this,
381 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
382 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
383 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
384 );
385 let (meta, wt, _) = modifier.applied_to_content(view.meta, content.meta, content.wt);
386 wrap_owned(result, meta, wt)
387 }
388}
389
390pub fn overlay_aligned(
392 view: &ViewHandle,
393 content: &ViewHandle,
394 alignment: super::Alignment,
395) -> ViewHandle {
396 unsafe { overlay_or_mask(view, content, resolve::overlay_fn(), &OVERLAY_ANY_T, alignment) }
397}
398
399pub fn overlay(view: &ViewHandle, content: &ViewHandle) -> ViewHandle {
401 overlay_aligned(view, content, super::Alignment::Center)
402}
403
404pub fn background_content(
412 view: &ViewHandle,
413 content: &ViewHandle,
414 alignment: super::Alignment,
415) -> ViewHandle {
416 unsafe {
417 overlay_or_mask(
418 view,
419 content,
420 resolve::background_content_fn(),
421 &BACKGROUND_ANY_T,
422 alignment,
423 )
424 }
425}
426
427pub fn mask_aligned(
429 view: &ViewHandle,
430 content: &ViewHandle,
431 alignment: super::Alignment,
432) -> ViewHandle {
433 unsafe { overlay_or_mask(view, content, resolve::mask_fn(), &MASK_ANY_T, alignment) }
434}
435
436pub fn mask(view: &ViewHandle, content: &ViewHandle) -> ViewHandle {
438 mask_aligned(view, content, super::Alignment::Center)
439}
440
441pub unsafe fn background_style_in_shape(
451 view: &ViewHandle,
452 style: &[u8],
453 style_meta: *const c_void,
454 style_wt: *const c_void,
455 shape: &super::Shape,
456) -> ViewHandle {
457 unsafe {
458 style_in_shape(
459 resolve::background_style_in_fn(),
460 resolve::background_style_in_oret(),
461 view,
462 style,
463 style_meta,
464 style_wt,
465 shape,
466 )
467 }
468}
469
470pub unsafe fn background_style_in_insettable(
483 view: &ViewHandle,
484 style: &[u8],
485 style_meta: *const c_void,
486 style_wt: *const c_void,
487 shape: &super::Shape,
488) -> ViewHandle {
489 unsafe {
490 let (bytes, meta, _) = shape.parts();
491 let insettable = abi::get_view_wt_for_proto(meta, resolve::insettable_shape_proto());
492 assert!(!insettable.is_null(), "{} !: InsettableShape", crate::diag::type_name(meta));
493 style_in_shape_with(
494 resolve::background_style_in_insettable_fn(),
495 resolve::background_style_in_insettable_oret(),
496 view,
497 style,
498 style_meta,
499 style_wt,
500 &bytes,
501 meta,
502 insettable,
503 )
504 }
505}
506
507pub unsafe fn overlay_style_in_shape(
519 view: &ViewHandle,
520 style: &[u8],
521 style_meta: *const c_void,
522 style_wt: *const c_void,
523 shape: &super::Shape,
524) -> ViewHandle {
525 unsafe {
526 style_in_shape(
527 resolve::overlay_in_fn(),
528 resolve::overlay_in_oret(),
529 view,
530 style,
531 style_meta,
532 style_wt,
533 shape,
534 )
535 }
536}
537
538#[allow(clippy::too_many_arguments)]
540unsafe fn style_in_shape(
541 func: *const c_void,
542 oret: *const c_void,
543 view: &ViewHandle,
544 style: &[u8],
545 style_meta: *const c_void,
546 style_wt: *const c_void,
547 shape: &super::Shape,
548) -> ViewHandle {
549 let (b, m, w) = shape.parts();
550 unsafe { style_in_shape_with(func, oret, view, style, style_meta, style_wt, &b, m, w) }
551}
552
553#[allow(clippy::too_many_arguments)]
556unsafe fn style_in_shape_with(
557 func: *const c_void,
558 oret: *const c_void,
559 view: &ViewHandle,
560 style: &[u8],
561 style_meta: *const c_void,
562 style_wt: *const c_void,
563 shape_bytes: &[u8],
564 shape_meta: *const c_void,
565 shape_wt: *const c_void,
566) -> ViewHandle {
567 unsafe {
568 let shape_bytes = shape_bytes.to_vec();
569 let subst = [
570 view.meta,
571 style_meta,
572 shape_meta,
573 view.wt,
574 style_wt,
575 shape_wt,
576 ];
577 let (meta, wt, size) = super::opaque_result_type(oret, &subst);
578
579 let mut result = vec![0u8; size];
580 let this = view.value_ptr();
581 let mut style_arg = style.to_vec();
582 let mut shape_arg = shape_bytes;
583 shape_arg.push(0);
584 core::arch::asm!(
585 "sub sp, sp, #16",
586 "str {a}, [sp]",
587 "blr {f}",
588 "add sp, sp, #16",
589 f = in(reg) func,
590 a = in(reg) subst[5],
591 in("x0") style_arg.as_mut_ptr(),
592 in("x1") shape_arg.as_mut_ptr(),
593 in("x2") FILL_STYLE_DEFAULT_WORD,
594 in("x3") subst[0],
595 in("x4") subst[1],
596 in("x5") subst[2],
597 in("x6") subst[3],
598 in("x7") subst[4],
599 in("x8") result.as_mut_ptr(),
600 in("x20") this,
601 lateout("x9") _, lateout("x10") _, lateout("x11") _,
602 lateout("x12") _, lateout("x13") _, lateout("x14") _, lateout("x15") _,
603 lateout("x16") _, lateout("x17") _, lateout("lr") _, lateout("x21") _,
604 clobber_abi("C"),
605 );
606 wrap_owned(result, meta, wt)
607 }
608}
609
610const FILL_STYLE_DEFAULT_WORD: u64 = 0x0100;
612
613pub fn padding_default(view: &ViewHandle) -> ViewHandle {
619 unsafe {
620 let (meta, wt, size) = super::opaque_result_type(
621 resolve::padding_edges_oret(),
622 &[view.meta, view.wt],
623 );
624 let mut result = vec![0u8; size];
625 let this = view.value_ptr();
626 core::arch::asm!("blr {f}", f = in(reg) resolve::padding_edges_fn(),
629 in("x0") 0x0fu64,
630 in("x1") 0u64, in("x2") 1u64,
631 in("x3") view.meta,
632 in("x4") view.wt,
633 in("x8") result.as_mut_ptr(),
634 in("x20") this,
635 lateout("x5") _, lateout("x6") _, lateout("x7") _, lateout("x9") _,
636 lateout("x10") _, lateout("x11") _, lateout("x12") _, lateout("x13") _,
637 lateout("x14") _, lateout("x15") _, lateout("x16") _, lateout("x17") _,
638 lateout("lr") _, lateout("x21") _, clobber_abi("C"),
639 );
640 wrap_owned(result, meta, wt)
641 }
642}
643
644pub fn padding_set(view: &ViewHandle, edges: super::EdgeSet, length: Option<f64>) -> ViewHandle {
654 unsafe {
655 let meta = abi::metadata0(resolve::edge_set_ma());
656 let (bits, _) = super::static_getter(edges.resolved(), meta);
657 padding_edges(view, bits, length)
658 }
659}
660
661pub fn padding_edges(view: &ViewHandle, edges: u64, length: Option<f64>) -> ViewHandle {
662 unsafe {
663 let (meta, wt, size) = super::opaque_result_type(
664 resolve::padding_edges_oret(),
665 &[view.meta, view.wt],
666 );
667 let mut result = vec![0u8; size];
668 let this = view.value_ptr();
669 let (bits, tag) = match length {
670 Some(v) => (v.to_bits(), 0u64),
671 None => (0u64, 1u64),
672 };
673 core::arch::asm!("blr {f}", f = in(reg) resolve::padding_edges_fn(),
674 in("x0") edges,
675 in("x1") bits, in("x2") tag,
676 in("x3") view.meta,
677 in("x4") view.wt,
678 in("x8") result.as_mut_ptr(),
679 in("x20") this,
680 lateout("x5") _, lateout("x6") _, lateout("x7") _, lateout("x9") _,
681 lateout("x10") _, lateout("x11") _, lateout("x12") _, lateout("x13") _,
682 lateout("x14") _, lateout("x15") _, lateout("x16") _, lateout("x17") _,
683 lateout("lr") _, lateout("x21") _, clobber_abi("C"),
684 );
685 wrap_owned(result, meta, wt)
686 }
687}
688
689pub fn background_in_circle(view: &ViewHandle) -> ViewHandle {
694 unsafe {
695 let shape = super::Shape::circle();
696 let (mut bytes, shape_meta, _) = shape.parts();
697 bytes.push(0);
698 let shape_wt = resolve::circle_wt();
699 let subst = [view.meta, shape_meta, view.wt, shape_wt];
700 let (meta, wt, size) =
701 super::opaque_result_type(resolve::background_in_oret(), &subst);
702 let mut result = vec![0u8; size];
703 let this = view.value_ptr();
704 core::arch::asm!("blr {f}", f = in(reg) resolve::background_in_fn(),
705 in("x0") bytes.as_mut_ptr(),
706 in("x1") 0x0100u64, in("x2") subst[0], in("x3") subst[1], in("x4") subst[2], in("x5") subst[3],
708 in("x8") result.as_mut_ptr(),
709 in("x20") this,
710 lateout("x6") _, lateout("x7") _, lateout("x9") _, lateout("x10") _,
711 lateout("x11") _, lateout("x12") _, lateout("x13") _, lateout("x14") _,
712 lateout("x15") _, lateout("x16") _, lateout("x17") _, lateout("lr") _,
713 lateout("x21") _, clobber_abi("C"),
714 );
715 wrap_owned(result, meta, wt)
716 }
717}
718
719pub fn background_style_color(view: &ViewHandle, r: f64, g: f64, b: f64, a: f64) -> ViewHandle {
729 background_style_value(view, unsafe { super::color_value(r, g, b, a) })
730}
731
732pub fn background_style_value(view: &ViewHandle, color: u64) -> ViewHandle {
734 unsafe {
737 background_style_of(
738 view,
739 &color.to_le_bytes(),
740 resolve::color_meta(),
741 resolve::color_shapestyle_wt(),
742 )
743 }
744}
745
746pub fn background_style_hierarchical(view: &ViewHandle, level: super::Hierarchical) -> ViewHandle {
748 let (style, meta, wt) = super::hierarchical_style(level);
751 unsafe { background_style_of(view, &style, meta, wt) }
752}
753
754pub unsafe fn background_style_of(
760 view: &ViewHandle,
761 style: &[u8],
762 style_meta: *const c_void,
763 style_wt: *const c_void,
764) -> ViewHandle {
765 unsafe {
766 let subst = [view.meta, style_meta, view.wt, style_wt];
767 let (meta, wt, size) =
768 super::opaque_result_type(resolve::background_style_oret(), &subst);
769 let mut result = vec![0u8; size];
770 let this = view.value_ptr();
771 let mut arg = style.to_vec();
772 core::arch::asm!("blr {f}", f = in(reg) resolve::background_style_fn(),
773 in("x0") arg.as_mut_ptr(),
774 in("x1") subst[0], in("x2") subst[1], in("x3") subst[2], in("x4") subst[3],
775 in("x8") result.as_mut_ptr(),
776 in("x20") this,
777 lateout("x5") _, lateout("x6") _, lateout("x7") _, lateout("x9") _,
778 lateout("x10") _, lateout("x11") _, lateout("x12") _, lateout("x13") _,
779 lateout("x14") _, lateout("x15") _, lateout("x16") _, lateout("x17") _,
780 lateout("lr") _, lateout("x21") _, clobber_abi("C"),
781 );
782 wrap_owned(result, meta, wt)
783 }
784}
785
786pub fn mask_plain(view: &ViewHandle, content: &ViewHandle) -> ViewHandle {
798 unsafe {
799 let desc = resolve::mask_effect_desc();
800 if desc.is_null() {
801 return mask(view, content);
802 }
803 let effect = abi::generic_metadata_from_descriptor(desc, &[content.meta, content.wt]);
804 if effect.is_null() {
805 return mask(view, content);
806 }
807 if abi::struct_field_offsets(effect).as_deref() != Some(&[0][..]) {
811 return mask(view, content);
812 }
813 if abi::type_bytes(effect) != abi::type_bytes(content.meta) {
814 return mask(view, content);
815 }
816 if !crate::diag::type_name(effect).starts_with("SwiftUI._MaskEffect<") {
817 return mask(view, content);
818 }
819 let bytes =
820 core::slice::from_raw_parts(content.value_ptr() as *const u8, abi::type_bytes(effect));
821 super::apply_modifier(view, effect, bytes)
822 }
823}