Rename fill_rectangle to fill_quad in Renderer

This commit is contained in:
Héctor Ramón Jiménez 2021-11-04 19:22:29 +07:00
parent 343f9b7e2e
commit 023aded277
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
19 changed files with 320 additions and 245 deletions

View file

@ -12,8 +12,7 @@ mod circle {
use iced_native::layout::{self, Layout}; use iced_native::layout::{self, Layout};
use iced_native::renderer; use iced_native::renderer;
use iced_native::{ use iced_native::{
Background, Color, Element, Hasher, Length, Point, Rectangle, Size, Color, Element, Hasher, Length, Point, Rectangle, Size, Widget,
Widget,
}; };
pub struct Circle { pub struct Circle {
@ -60,13 +59,15 @@ mod circle {
_cursor_position: Point, _cursor_position: Point,
_viewport: &Rectangle, _viewport: &Rectangle,
) { ) {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: layout.bounds(), renderer::Quad {
background: Background::Color(Color::BLACK), bounds: layout.bounds(),
border_radius: self.radius, border_radius: self.radius,
border_width: 0.0, border_width: 0.0,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
}); },
Color::BLACK,
);
} }
} }

View file

@ -3,7 +3,7 @@ use crate::{Primitive, Vector};
use iced_native::layout; use iced_native::layout;
use iced_native::renderer; use iced_native::renderer;
use iced_native::text::{self, Text}; use iced_native::text::{self, Text};
use iced_native::{Element, Font, Point, Rectangle, Size}; use iced_native::{Background, Element, Font, Point, Rectangle, Size};
pub use iced_native::renderer::Style; pub use iced_native::renderer::Style;
@ -88,10 +88,14 @@ where
}); });
} }
fn fill_rectangle(&mut self, quad: renderer::Quad) { fn fill_quad(
&mut self,
quad: renderer::Quad,
background: impl Into<Background>,
) {
self.primitives.push(Primitive::Quad { self.primitives.push(Primitive::Quad {
bounds: quad.bounds, bounds: quad.bounds,
background: quad.background, background: background.into(),
border_radius: quad.border_radius, border_radius: quad.border_radius,
border_width: quad.border_width, border_width: quad.border_width,
border_color: quad.border_color, border_color: quad.border_color,

View file

@ -4,8 +4,7 @@ use crate::mouse;
use crate::overlay; use crate::overlay;
use crate::renderer; use crate::renderer;
use crate::{ use crate::{
Background, Clipboard, Color, Hasher, Layout, Length, Point, Rectangle, Clipboard, Color, Hasher, Layout, Length, Point, Rectangle, Widget,
Widget,
}; };
/// A generic [`Widget`]. /// A generic [`Widget`].
@ -254,6 +253,7 @@ where
.draw(renderer, style, layout, cursor_position, viewport) .draw(renderer, style, layout, cursor_position, viewport)
} }
/// Returns the current [`mouse::Interaction`] of the [`Element`].
pub fn mouse_interaction( pub fn mouse_interaction(
&self, &self,
layout: Layout<'_>, layout: Layout<'_>,
@ -452,13 +452,15 @@ where
color: Color, color: Color,
layout: Layout<'_>, layout: Layout<'_>,
) { ) {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: layout.bounds(), renderer::Quad {
border_color: color, bounds: layout.bounds(),
border_width: 1.0, border_color: color,
border_radius: 0.0, border_width: 1.0,
background: Background::Color(Color::TRANSPARENT), border_radius: 0.0,
}); },
Color::TRANSPARENT,
);
for child in layout.children() { for child in layout.children() {
explain_layout(renderer, color, child); explain_layout(renderer, color, child);

View file

@ -253,13 +253,15 @@ where
) { ) {
let bounds = layout.bounds(); let bounds = layout.bounds();
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: self.style.background, bounds,
border_color: self.style.border_color, border_color: self.style.border_color,
border_width: self.style.border_width, border_width: self.style.border_width,
border_radius: 0.0, border_radius: 0.0,
}); },
self.style.background,
);
self.container self.container
.draw(renderer, style, layout, cursor_position, &bounds); .draw(renderer, style, layout, cursor_position, &bounds);
@ -432,13 +434,15 @@ where
}; };
if is_selected { if is_selected {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: self.style.selected_background, bounds,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
border_width: 0.0, border_width: 0.0,
border_radius: 0.0, border_radius: 0.0,
}); },
self.style.selected_background,
);
} }
renderer.fill_text(Text { renderer.fill_text(Text {

View file

@ -42,23 +42,28 @@ pub trait Renderer: Sized {
element.layout(self, limits) element.layout(self, limits)
} }
/// Draws the primitives recorded in the given closure in a new layer.
///
/// The layer will clip its contents to the provided `bounds`.
fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)); fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self));
/// Applies a `translation` to the primitives recorded in the given closure.
fn with_translation( fn with_translation(
&mut self, &mut self,
translation: Vector, translation: Vector,
f: impl FnOnce(&mut Self), f: impl FnOnce(&mut Self),
); );
/// Clears all of the recorded primitives in the [`Renderer`].
fn clear(&mut self); fn clear(&mut self);
fn fill_rectangle(&mut self, quad: Quad); /// Fills a [`Quad`] with the provided [`Background`].
fn fill_quad(&mut self, quad: Quad, background: impl Into<Background>);
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Quad { pub struct Quad {
pub bounds: Rectangle, pub bounds: Rectangle,
pub background: Background,
pub border_radius: f32, pub border_radius: f32,
pub border_width: f32, pub border_width: f32,
pub border_color: Color, pub border_color: Color,

View file

@ -1,6 +1,6 @@
use crate::renderer::{self, Renderer}; use crate::renderer::{self, Renderer};
use crate::text::{self, Text}; use crate::text::{self, Text};
use crate::{Font, Point, Rectangle, Size, Vector}; use crate::{Background, Font, Point, Rectangle, Size, Vector};
/// A renderer that does nothing. /// A renderer that does nothing.
/// ///
@ -27,7 +27,12 @@ impl Renderer for Null {
fn clear(&mut self) {} fn clear(&mut self) {}
fn fill_rectangle(&mut self, _quad: renderer::Quad) {} fn fill_quad(
&mut self,
_quad: renderer::Quad,
_background: impl Into<Background>,
) {
}
} }
impl text::Renderer for Null { impl text::Renderer for Null {

View file

@ -293,28 +293,32 @@ where
if styling.background.is_some() || styling.border_width > 0.0 { if styling.background.is_some() || styling.border_width > 0.0 {
if styling.shadow_offset != Vector::default() { if styling.shadow_offset != Vector::default() {
// TODO: Implement proper shadow support // TODO: Implement proper shadow support
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { renderer::Quad {
x: bounds.x + styling.shadow_offset.x, bounds: Rectangle {
y: bounds.y + styling.shadow_offset.y, x: bounds.x + styling.shadow_offset.x,
..bounds y: bounds.y + styling.shadow_offset.y,
..bounds
},
border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color([0.0, 0.0, 0.0, 0.5].into()), Background::Color([0.0, 0.0, 0.0, 0.5].into()),
border_radius: styling.border_radius, );
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
} }
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: styling bounds,
border_radius: styling.border_radius,
border_width: styling.border_width,
border_color: styling.border_color,
},
styling
.background .background
.unwrap_or(Background::Color(Color::TRANSPARENT)), .unwrap_or(Background::Color(Color::TRANSPARENT)),
border_radius: styling.border_radius, );
border_width: styling.border_width,
border_color: styling.border_color,
});
} }
self.content.draw( self.content.draw(

View file

@ -226,13 +226,15 @@ where
self.style_sheet.active(self.is_checked) self.style_sheet.active(self.is_checked)
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: style.background, bounds,
border_radius: style.border_radius, border_radius: style.border_radius,
border_width: style.border_width, border_width: style.border_width,
border_color: style.border_color, border_color: style.border_color,
}); },
style.background,
);
if self.is_checked { if self.is_checked {
renderer.fill_text(text::Text { renderer.fill_text(text::Text {

View file

@ -238,6 +238,7 @@ where
} }
} }
/// Draws the background of a [`Container`] given its [`Style`] and its `bounds`.
pub fn draw_background<Renderer>( pub fn draw_background<Renderer>(
renderer: &mut Renderer, renderer: &mut Renderer,
style: &Style, style: &Style,
@ -246,15 +247,17 @@ pub fn draw_background<Renderer>(
Renderer: crate::Renderer, Renderer: crate::Renderer,
{ {
if style.background.is_some() || style.border_width > 0.0 { if style.background.is_some() || style.border_width > 0.0 {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: style bounds,
border_radius: style.border_radius,
border_width: style.border_width,
border_color: style.border_color,
},
style
.background .background
.unwrap_or(Background::Color(Color::TRANSPARENT)), .unwrap_or(Background::Color(Color::TRANSPARENT)),
border_radius: style.border_radius, );
border_width: style.border_width,
border_color: style.border_color,
});
} }
} }

View file

@ -609,31 +609,34 @@ where
}; };
if let Some(highlight) = highlight { if let Some(highlight) = highlight {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: match axis { renderer::Quad {
Axis::Horizontal => Rectangle { bounds: match axis {
x: split_region.x, Axis::Horizontal => Rectangle {
y: (split_region.y x: split_region.x,
+ (split_region.height - highlight.width) y: (split_region.y
/ 2.0) + (split_region.height - highlight.width)
.round(), / 2.0)
width: split_region.width, .round(),
height: highlight.width, width: split_region.width,
}, height: highlight.width,
Axis::Vertical => Rectangle { },
x: (split_region.x Axis::Vertical => Rectangle {
+ (split_region.width - highlight.width) / 2.0) x: (split_region.x
.round(), + (split_region.width - highlight.width)
y: split_region.y, / 2.0)
width: highlight.width, .round(),
height: split_region.height, y: split_region.y,
width: highlight.width,
height: split_region.height,
},
}, },
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: highlight.color.into(), highlight.color,
border_radius: 0.0, );
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
} }
} }
} }

View file

@ -360,13 +360,15 @@ where
self.style_sheet.active() self.style_sheet.active()
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: style.background, bounds,
border_color: style.border_color, border_color: style.border_color,
border_width: style.border_width, border_width: style.border_width,
border_radius: style.border_radius, border_radius: style.border_radius,
}); },
style.background,
);
renderer.fill_text(Text { renderer.fill_text(Text {
content: &Renderer::ARROW_DOWN_ICON.to_string(), content: &Renderer::ARROW_DOWN_ICON.to_string(),

View file

@ -116,25 +116,29 @@ where
let style = self.style_sheet.style(); let style = self.style_sheet.style();
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { ..bounds }, renderer::Quad {
background: style.background, bounds: Rectangle { ..bounds },
border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
if active_progress_width > 0.0 {
renderer.fill_rectangle(renderer::Quad {
bounds: Rectangle {
width: active_progress_width,
..bounds
},
background: style.bar,
border_radius: style.border_radius, border_radius: style.border_radius,
border_width: 0.0, border_width: 0.0,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
}); },
style.background,
);
if active_progress_width > 0.0 {
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
width: active_progress_width,
..bounds
},
border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
style.bar,
);
} }
} }

View file

@ -10,8 +10,8 @@ use crate::text;
use crate::touch; use crate::touch;
use crate::widget::{self, Row, Text}; use crate::widget::{self, Row, Text};
use crate::{ use crate::{
Alignment, Background, Clipboard, Color, Element, Hasher, Layout, Length, Alignment, Clipboard, Color, Element, Hasher, Layout, Length, Point,
Point, Rectangle, Widget, Rectangle, Widget,
}; };
pub use iced_style::radio::{Style, StyleSheet}; pub use iced_style::radio::{Style, StyleSheet};
@ -243,27 +243,31 @@ where
self.style_sheet.active() self.style_sheet.active()
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: style.background, bounds,
border_radius: size / 2.0, border_radius: size / 2.0,
border_width: style.border_width, border_width: style.border_width,
border_color: style.border_color, border_color: style.border_color,
}); },
style.background,
);
if self.is_selected { if self.is_selected {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { renderer::Quad {
x: bounds.x + dot_size / 2.0, bounds: Rectangle {
y: bounds.y + dot_size / 2.0, x: bounds.x + dot_size / 2.0,
width: bounds.width - dot_size, y: bounds.y + dot_size / 2.0,
height: bounds.height - dot_size, width: bounds.width - dot_size,
height: bounds.height - dot_size,
},
border_radius: dot_size / 2.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color(style.dot_color), style.dot_color,
border_radius: dot_size / 2.0, );
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
} }
} }

View file

@ -2,8 +2,7 @@
use crate::layout; use crate::layout;
use crate::renderer; use crate::renderer;
use crate::{ use crate::{
Background, Color, Element, Hasher, Layout, Length, Point, Rectangle, Size, Color, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,
Widget,
}; };
use std::hash::Hash; use std::hash::Hash;
@ -113,13 +112,15 @@ where
} }
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: Background::Color(style.color), bounds,
border_radius: style.radius, border_radius: style.radius,
border_width: 0.0, border_width: 0.0,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
}); },
style.color,
);
} }
fn hash_layout(&self, state: &mut Hasher) { fn hash_layout(&self, state: &mut Hasher) {

View file

@ -526,28 +526,32 @@ where
}, },
|renderer| { |renderer| {
if is_scrollbar_visible { if is_scrollbar_visible {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: scrollbar.bounds, renderer::Quad {
background: style.background.unwrap_or( bounds: scrollbar.bounds,
Background::Color(Color::TRANSPARENT), border_radius: style.border_radius,
), border_width: style.border_width,
border_radius: style.border_radius, border_color: style.border_color,
border_width: style.border_width, },
border_color: style.border_color, style.background.unwrap_or(Background::Color(
}); Color::TRANSPARENT,
)),
);
} }
if is_mouse_over if is_mouse_over
|| self.state.is_scroller_grabbed() || self.state.is_scroller_grabbed()
|| is_scrollbar_visible || is_scrollbar_visible
{ {
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: scrollbar.scroller.bounds, renderer::Quad {
background: Background::Color(style.scroller.color), bounds: scrollbar.scroller.bounds,
border_radius: style.scroller.border_radius, border_radius: style.scroller.border_radius,
border_width: style.scroller.border_width, border_width: style.scroller.border_width,
border_color: style.scroller.border_color, border_color: style.scroller.border_color,
}); },
style.scroller.color,
);
} }
}, },
); );

View file

@ -58,6 +58,7 @@ where
T: Copy + From<u8> + std::cmp::PartialOrd, T: Copy + From<u8> + std::cmp::PartialOrd,
Message: Clone, Message: Clone,
{ {
/// The default height of a [`Slider`].
pub const DEFAULT_HEIGHT: u16 = 22; pub const DEFAULT_HEIGHT: u16 = 22;
/// Creates a new [`Slider`]. /// Creates a new [`Slider`].
@ -272,31 +273,35 @@ where
let rail_y = bounds.y + (bounds.height / 2.0).round(); let rail_y = bounds.y + (bounds.height / 2.0).round();
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { renderer::Quad {
x: bounds.x, bounds: Rectangle {
y: rail_y, x: bounds.x,
width: bounds.width, y: rail_y,
height: 2.0, width: bounds.width,
height: 2.0,
},
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color(style.rail_colors.0), style.rail_colors.0,
border_radius: 0.0, );
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { renderer::Quad {
x: bounds.x, bounds: Rectangle {
y: rail_y + 2.0, x: bounds.x,
width: bounds.width, y: rail_y + 2.0,
height: 2.0, width: bounds.width,
height: 2.0,
},
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color(style.rail_colors.1), Background::Color(style.rail_colors.1),
border_radius: 0.0, );
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
let (handle_width, handle_height, handle_border_radius) = match style let (handle_width, handle_height, handle_border_radius) = match style
.handle .handle
@ -325,18 +330,20 @@ where
/ (range_end - range_start) / (range_end - range_start)
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: Rectangle { renderer::Quad {
x: bounds.x + handle_offset.round(), bounds: Rectangle {
y: rail_y - handle_height / 2.0, x: bounds.x + handle_offset.round(),
width: handle_width, y: rail_y - handle_height / 2.0,
height: handle_height, width: handle_width,
height: handle_height,
},
border_radius: handle_border_radius,
border_width: style.handle.border_width,
border_color: style.handle.border_color,
}, },
background: Background::Color(style.handle.color), style.handle.color,
border_radius: handle_border_radius, );
border_width: style.handle.border_width,
border_color: style.handle.border_color,
});
} }
fn mouse_interaction( fn mouse_interaction(

View file

@ -163,6 +163,16 @@ where
} }
} }
/// Draws text using the same logic as the [`Text`] widget.
///
/// Specifically:
///
/// * If no `size` is provided, the default text size of the `Renderer` will be
/// used.
/// * If no `color` is provided, the [`renderer::Style::text_color`] will be
/// used.
/// * The alignment attributes do not affect the position of the bounds of the
/// [`Layout`].
pub fn draw<Renderer>( pub fn draw<Renderer>(
renderer: &mut Renderer, renderer: &mut Renderer,
style: &renderer::Style, style: &renderer::Style,

View file

@ -20,8 +20,8 @@ use crate::renderer;
use crate::text::{self, Text}; use crate::text::{self, Text};
use crate::touch; use crate::touch;
use crate::{ use crate::{
Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding, Clipboard, Color, Element, Hasher, Layout, Length, Padding, Point,
Point, Rectangle, Size, Vector, Widget, Rectangle, Size, Vector, Widget,
}; };
use std::u32; use std::u32;
@ -196,13 +196,15 @@ where
self.style_sheet.active() self.style_sheet.active()
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds, renderer::Quad {
background: style.background, bounds,
border_radius: style.border_radius, border_radius: style.border_radius,
border_width: style.border_width, border_width: style.border_width,
border_color: style.border_color, border_color: style.border_color,
}); },
style.background,
);
let text = value.to_string(); let text = value.to_string();
let size = self.size.unwrap_or(renderer.default_size()); let size = self.size.unwrap_or(renderer.default_size());
@ -221,20 +223,20 @@ where
); );
( (
Some(renderer::Quad { Some((
bounds: Rectangle { renderer::Quad {
x: text_bounds.x + text_value_width, bounds: Rectangle {
y: text_bounds.y, x: text_bounds.x + text_value_width,
width: 1.0, y: text_bounds.y,
height: text_bounds.height, width: 1.0,
height: text_bounds.height,
},
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color( self.style_sheet.value_color(),
self.style_sheet.value_color(), )),
),
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}),
offset, offset,
) )
} }
@ -265,20 +267,20 @@ where
let width = right_position - left_position; let width = right_position - left_position;
( (
Some(renderer::Quad { Some((
bounds: Rectangle { renderer::Quad {
x: text_bounds.x + left_position, bounds: Rectangle {
y: text_bounds.y, x: text_bounds.x + left_position,
width, y: text_bounds.y,
height: text_bounds.height, width,
height: text_bounds.height,
},
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}, },
background: Background::Color( self.style_sheet.selection_color(),
self.style_sheet.selection_color(), )),
),
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
}),
if end == right { if end == right {
right_offset right_offset
} else { } else {
@ -302,8 +304,8 @@ where
); );
let render = |renderer: &mut Renderer| { let render = |renderer: &mut Renderer| {
if let Some(cursor) = cursor { if let Some((cursor, color)) = cursor {
renderer.fill_rectangle(cursor); renderer.fill_quad(cursor, color);
} }
renderer.fill_text(Text { renderer.fill_text(Text {

View file

@ -258,13 +258,17 @@ where
height: bounds.height - (2.0 * space), height: bounds.height - (2.0 * space),
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: toggler_background_bounds, renderer::Quad {
background: style.background.into(), bounds: toggler_background_bounds,
border_radius, border_radius,
border_width: 1.0, border_width: 1.0,
border_color: style.background_border.unwrap_or(style.background), border_color: style
}); .background_border
.unwrap_or(style.background),
},
style.background,
);
let toggler_foreground_bounds = Rectangle { let toggler_foreground_bounds = Rectangle {
x: bounds.x x: bounds.x
@ -278,13 +282,17 @@ where
height: bounds.height - (4.0 * space), height: bounds.height - (4.0 * space),
}; };
renderer.fill_rectangle(renderer::Quad { renderer.fill_quad(
bounds: toggler_foreground_bounds, renderer::Quad {
background: style.foreground.into(), bounds: toggler_foreground_bounds,
border_radius, border_radius,
border_width: 1.0, border_width: 1.0,
border_color: style.foreground_border.unwrap_or(style.foreground), border_color: style
}); .foreground_border
.unwrap_or(style.foreground),
},
style.foreground,
);
} }
fn hash_layout(&self, state: &mut Hasher) { fn hash_layout(&self, state: &mut Hasher) {