use super::*;
use ab_glyph::PxScale;
use ordered_float::OrderedFloat;
use std::{borrow::Cow, f32, hash::*};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SectionText<'a> {
pub text: &'a str,
pub scale: PxScale,
pub color: Color,
pub font_id: FontId,
}
impl Default for SectionText<'static> {
#[inline]
fn default() -> Self {
Self {
text: "",
scale: PxScale::from(16.0),
color: [0.0, 0.0, 0.0, 1.0],
font_id: <_>::default(),
}
}
}
impl<'a> SectionText<'a> {
#[inline]
pub fn to_text(&self, z: f32) -> crate::Text<'a> {
crate::Text::new(self.text)
.with_scale(self.scale)
.with_color(self.color)
.with_font_id(self.font_id)
.with_z(z)
}
}
impl<'a> From<&crate::Text<'a>> for SectionText<'a> {
#[inline]
fn from(t: &crate::Text<'a>) -> Self {
Self {
text: t.text,
scale: t.scale,
color: t.extra.color,
font_id: t.font_id,
}
}
}
impl<'a> From<crate::Text<'a>> for SectionText<'a> {
#[inline]
fn from(t: crate::Text<'a>) -> Self {
Self::from(&t)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct VariedSection<'a> {
pub screen_position: (f32, f32),
pub bounds: (f32, f32),
pub z: f32,
pub layout: Layout<BuiltInLineBreaker>,
pub text: Vec<SectionText<'a>>,
}
impl Default for VariedSection<'static> {
#[inline]
fn default() -> Self {
Self {
screen_position: (0.0, 0.0),
bounds: (f32::INFINITY, f32::INFINITY),
z: 0.0,
layout: Layout::default(),
text: vec![],
}
}
}
impl<'a> From<VariedSection<'a>> for Cow<'a, VariedSection<'a>> {
fn from(owned: VariedSection<'a>) -> Self {
Cow::Owned(owned)
}
}
impl<'a, 'b> From<&'b VariedSection<'a>> for Cow<'b, VariedSection<'a>> {
fn from(owned: &'b VariedSection<'a>) -> Self {
Cow::Borrowed(owned)
}
}
impl<'a> From<VariedSection<'a>> for Cow<'a, crate::Section<'a>> {
#[inline]
fn from(s: VariedSection<'a>) -> Self {
Cow::Owned(s.into())
}
}
impl<'a, 'b> From<&'b VariedSection<'a>> for Cow<'b, crate::Section<'a>> {
#[inline]
fn from(s: &'b VariedSection<'a>) -> Self {
Cow::Owned(s.into())
}
}
impl<'a> From<&crate::Section<'a>> for VariedSection<'a> {
#[inline]
fn from(s: &crate::Section<'a>) -> Self {
Self {
text: s.text.iter().map(SectionText::from).collect(),
bounds: s.bounds,
screen_position: s.screen_position,
layout: s.layout,
z: s.text.get(0).map(|t| t.extra.z).unwrap_or(0.0),
}
}
}
impl Hash for VariedSection<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
let VariedSection {
screen_position: (screen_x, screen_y),
bounds: (bound_w, bound_h),
z,
layout,
ref text,
} = *self;
let ord_floats: &[OrderedFloat<_>] = &[
screen_x.into(),
screen_y.into(),
bound_w.into(),
bound_h.into(),
z.into(),
];
layout.hash(state);
hash_section_text(state, text);
ord_floats.hash(state);
}
}
#[inline]
fn hash_section_text<H: Hasher>(state: &mut H, text: &[SectionText]) {
for t in text {
let SectionText {
text,
scale,
color,
font_id,
} = *t;
let ord_floats: &[OrderedFloat<_>] = &[
scale.x.into(),
scale.y.into(),
color[0].into(),
color[1].into(),
color[2].into(),
color[3].into(),
];
(text, font_id, ord_floats).hash(state);
}
}
impl<'text> VariedSection<'text> {
pub fn to_owned(&self) -> OwnedVariedSection {
OwnedVariedSection {
screen_position: self.screen_position,
bounds: self.bounds,
z: self.z,
layout: self.layout,
text: self.text.iter().map(OwnedSectionText::from).collect(),
}
}
}
impl From<&VariedSection<'_>> for SectionGeometry {
fn from(section: &VariedSection<'_>) -> Self {
Self {
bounds: section.bounds,
screen_position: section.screen_position,
}
}
}
impl<'a> From<&VariedSection<'a>> for crate::Section<'a> {
#[inline]
fn from(s: &VariedSection<'a>) -> Self {
crate::Section::default()
.with_layout(s.layout)
.with_bounds(s.bounds)
.with_screen_position(s.screen_position)
.with_text(s.text.iter().map(|t| t.to_text(s.z)).collect())
}
}
impl<'a> From<VariedSection<'a>> for crate::Section<'a> {
#[inline]
fn from(s: VariedSection<'a>) -> Self {
Self::from(&s)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Section<'a> {
pub text: &'a str,
pub screen_position: (f32, f32),
pub bounds: (f32, f32),
pub scale: PxScale,
pub color: [f32; 4],
pub z: f32,
pub layout: Layout<BuiltInLineBreaker>,
pub font_id: FontId,
}
impl Default for Section<'static> {
#[inline]
fn default() -> Self {
Self {
text: "",
screen_position: (0.0, 0.0),
bounds: (f32::INFINITY, f32::INFINITY),
scale: PxScale::from(16.0),
color: [0.0, 0.0, 0.0, 1.0],
z: 0.0,
layout: Layout::default(),
font_id: FontId::default(),
}
}
}
impl<'a> From<&Section<'a>> for VariedSection<'a> {
fn from(s: &Section<'a>) -> Self {
let Section {
text,
scale,
color,
screen_position,
bounds,
z,
layout,
font_id,
} = *s;
VariedSection {
text: vec![SectionText {
text,
scale,
color,
font_id,
}],
screen_position,
bounds,
z,
layout,
}
}
}
impl<'a> From<Section<'a>> for VariedSection<'a> {
fn from(s: Section<'a>) -> Self {
VariedSection::from(&s)
}
}
impl<'a> From<Section<'a>> for Cow<'a, VariedSection<'a>> {
fn from(section: Section<'a>) -> Self {
Cow::Owned(VariedSection::from(section))
}
}
impl<'a> From<&Section<'a>> for Cow<'a, VariedSection<'a>> {
fn from(section: &Section<'a>) -> Self {
Cow::Owned(VariedSection::from(section))
}
}
impl<'a> From<&Section<'a>> for crate::Section<'a> {
fn from(s: &Section<'a>) -> Self {
let Section {
text,
scale,
color,
screen_position,
bounds,
z,
layout,
font_id,
} = *s;
crate::Section::default()
.add_text(
Text::new(text)
.with_scale(scale)
.with_color(color)
.with_z(z)
.with_font_id(font_id),
)
.with_screen_position(screen_position)
.with_bounds(bounds)
.with_layout(layout)
}
}
impl<'a> From<Section<'a>> for crate::Section<'a> {
fn from(s: Section<'a>) -> Self {
crate::Section::from(&s)
}
}
impl<'a> From<Section<'a>> for Cow<'a, crate::Section<'a>> {
fn from(section: Section<'a>) -> Self {
Cow::Owned(crate::Section::from(section))
}
}
impl<'a> From<&Section<'a>> for Cow<'a, crate::Section<'a>> {
fn from(section: &Section<'a>) -> Self {
Cow::Owned(crate::Section::from(section))
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct OwnedVariedSection {
pub screen_position: (f32, f32),
pub bounds: (f32, f32),
pub z: f32,
pub layout: Layout<BuiltInLineBreaker>,
pub text: Vec<OwnedSectionText>,
}
impl Default for OwnedVariedSection {
fn default() -> Self {
Self {
screen_position: (0.0, 0.0),
bounds: (f32::INFINITY, f32::INFINITY),
z: 0.0,
layout: Layout::default(),
text: vec![],
}
}
}
impl OwnedVariedSection {
#[inline]
pub fn to_borrowed(&self) -> VariedSection<'_> {
VariedSection {
screen_position: self.screen_position,
bounds: self.bounds,
z: self.z,
layout: self.layout,
text: self.text.iter().map(|t| t.into()).collect(),
}
}
}
impl<'a> From<&'a OwnedVariedSection> for VariedSection<'a> {
fn from(owned: &'a OwnedVariedSection) -> Self {
owned.to_borrowed()
}
}
impl<'a> From<&'a OwnedVariedSection> for Cow<'a, VariedSection<'a>> {
fn from(owned: &'a OwnedVariedSection) -> Self {
Cow::Owned(owned.to_borrowed())
}
}
impl<'a> From<&'a OwnedVariedSection> for crate::Section<'a> {
#[inline]
fn from(owned: &'a OwnedVariedSection) -> Self {
owned.to_borrowed().into()
}
}
impl<'a> From<&'a OwnedVariedSection> for Cow<'a, crate::Section<'a>> {
#[inline]
fn from(owned: &'a OwnedVariedSection) -> Self {
Cow::Owned(owned.to_borrowed().into())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct OwnedSectionText {
pub text: String,
pub scale: PxScale,
pub color: [f32; 4],
pub font_id: FontId,
}
impl Default for OwnedSectionText {
fn default() -> Self {
Self {
text: String::new(),
scale: PxScale::from(16.0),
color: [0.0, 0.0, 0.0, 1.0],
font_id: FontId::default(),
}
}
}
impl<'a> From<&'a OwnedSectionText> for SectionText<'a> {
fn from(owned: &'a OwnedSectionText) -> Self {
Self {
text: owned.text.as_str(),
scale: owned.scale,
color: owned.color,
font_id: owned.font_id,
}
}
}
impl From<&SectionText<'_>> for OwnedSectionText {
fn from(st: &SectionText<'_>) -> Self {
Self {
text: st.text.into(),
scale: st.scale,
color: st.color,
font_id: st.font_id,
}
}
}