text_svg is working
This commit is contained in:
parent
ed5e434adb
commit
010f9a41d8
|
@ -1,3 +1,3 @@
|
||||||
max_width = 70
|
max_width = 70
|
||||||
style_edition = "2018"
|
# style_edition = "2018"
|
||||||
# version = "Two"
|
# version = "Two"
|
|
@ -32,6 +32,8 @@ use crate::{
|
||||||
BackgroundKind,
|
BackgroundKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::text_svg::{self, shadow, Font as SvgFont, TextSvg};
|
||||||
|
|
||||||
const REFERENCE_WIDTH: f32 = 1920.0;
|
const REFERENCE_WIDTH: f32 = 1920.0;
|
||||||
const REFERENCE_HEIGHT: f32 = 1080.0;
|
const REFERENCE_HEIGHT: f32 = 1080.0;
|
||||||
|
|
||||||
|
@ -542,23 +544,15 @@ pub(crate) fn slide_view<'a>(
|
||||||
responsive(move |size| {
|
responsive(move |size| {
|
||||||
let width = size.height * 16.0 / 9.0;
|
let width = size.height * 16.0 / 9.0;
|
||||||
let font_size = scale_font(slide.font_size() as f32, width);
|
let font_size = scale_font(slide.font_size() as f32, width);
|
||||||
|
let font = SvgFont::from(font).size(font_size.floor() as u8);
|
||||||
let slide_text = slide.text();
|
let slide_text = slide.text();
|
||||||
let lines = slide_text.lines();
|
let text = text_svg::TextSvg::new()
|
||||||
let text: Vec<Element<Message>> = lines
|
.fill("#fff")
|
||||||
.map(|t| {
|
.shadow(shadow(10, 10, 5, "#000000"))
|
||||||
rich_text([span(format!("{}\n", t.to_string()))
|
|
||||||
.background(
|
|
||||||
Background::Color(Color::BLACK)
|
|
||||||
.scale_alpha(0.4),
|
|
||||||
)
|
|
||||||
.padding(3)])
|
|
||||||
.size(font_size)
|
|
||||||
.font(font)
|
.font(font)
|
||||||
.center()
|
.text(slide_text)
|
||||||
.into()
|
.view()
|
||||||
})
|
.map(|m| Message::None);
|
||||||
.collect();
|
|
||||||
let text = Column::with_children(text).spacing(6);
|
|
||||||
let text_container = Container::new(text)
|
let text_container = Container::new(text)
|
||||||
.center(Length::Fill)
|
.center(Length::Fill)
|
||||||
.align_x(Horizontal::Left);
|
.align_x(Horizontal::Left);
|
||||||
|
|
|
@ -2,11 +2,14 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use colors_transform::Rgb;
|
use colors_transform::Rgb;
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::font::{Style, Weight},
|
iced::{
|
||||||
|
font::{Style, Weight},
|
||||||
|
Length,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widget::{responsive, svg::Handle, Svg},
|
widget::{container, responsive, svg::Handle, Svg},
|
||||||
};
|
};
|
||||||
use tracing::error;
|
use tracing::{debug, error};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct TextSvg {
|
pub struct TextSvg {
|
||||||
|
@ -25,6 +28,21 @@ pub struct Font {
|
||||||
size: u8,
|
size: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<cosmic::font::Font> for Font {
|
||||||
|
fn from(value: cosmic::font::Font) -> Self {
|
||||||
|
Self {
|
||||||
|
name: match value.family {
|
||||||
|
cosmic::iced::font::Family::Name(name) => {
|
||||||
|
name.to_string()
|
||||||
|
}
|
||||||
|
_ => "Quicksand Bold".into(),
|
||||||
|
},
|
||||||
|
size: 20,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&str> for Font {
|
impl From<&str> for Font {
|
||||||
fn from(value: &str) -> Self {
|
fn from(value: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -35,32 +53,37 @@ impl From<&str> for Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Font {
|
impl Font {
|
||||||
fn get_name(&self) -> String {
|
pub fn get_name(&self) -> String {
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_weight(&self) -> Weight {
|
pub fn get_weight(&self) -> Weight {
|
||||||
self.weight.clone()
|
self.weight.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_style(&self) -> Style {
|
pub fn get_style(&self) -> Style {
|
||||||
self.style.clone()
|
self.style.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weight(mut self, weight: impl Into<Weight>) -> Self {
|
pub fn weight(mut self, weight: impl Into<Weight>) -> Self {
|
||||||
self.weight = weight.into();
|
self.weight = weight.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style(mut self, style: impl Into<Style>) -> Self {
|
pub fn style(mut self, style: impl Into<Style>) -> Self {
|
||||||
self.style = style.into();
|
self.style = style.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(mut self, name: impl Into<String>) -> Self {
|
pub fn name(mut self, name: impl Into<String>) -> Self {
|
||||||
self.name = name.into();
|
self.name = name.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(mut self, size: u8) -> Self {
|
||||||
|
self.size = size;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -147,7 +170,12 @@ impl TextSvg {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn text(mut self, text: impl AsRef<str>) -> Self {
|
||||||
|
self.text = text.as_ref().to_string();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view<'a>(self) -> Element<'a, Message> {
|
||||||
let shadow = if let Some(shadow) = &self.shadow {
|
let shadow = if let Some(shadow) = &self.shadow {
|
||||||
format!("<filter id=\"shadow\"><feDropShadow dx=\"{}\" dy=\"{}\" stdDeviation=\"{}\" flood-color=\"{}\"/></filter>",
|
format!("<filter id=\"shadow\"><feDropShadow dx=\"{}\" dy=\"{}\" stdDeviation=\"{}\" flood-color=\"{}\"/></filter>",
|
||||||
shadow.offset_x,
|
shadow.offset_x,
|
||||||
|
@ -165,22 +193,39 @@ impl TextSvg {
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
"".into()
|
||||||
};
|
};
|
||||||
|
container(
|
||||||
responsive(move |s| {
|
responsive(move |s| {
|
||||||
let total_lines = self.text.lines().count();
|
let total_lines = self.text.lines().count();
|
||||||
let half_lines = (total_lines / 2) as f32;
|
let half_lines = (total_lines / 2) as f32;
|
||||||
let middle_position = s.height / 2.0;
|
let middle_position = s.height / 2.0;
|
||||||
let line_spacing = 10.0;
|
let line_spacing = 10.0;
|
||||||
let starting_y_position = middle_position - (half_lines * (self.font.size as f32 + line_spacing));
|
let text_and_line_spacing = self.font.size as f32 + line_spacing;
|
||||||
let text_pieces: Vec<String> = self.text.lines().map(|t| format!("<tspan>{}</tspan>", t)).collect();
|
let starting_y_position = middle_position - (half_lines * text_and_line_spacing);
|
||||||
let base = format!("<svg viewBox=\"0 0 {} {}\" xmlns=\"http://www.w3.org/2000/svg\"><defs>{}</defs>
|
|
||||||
<text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-weight=\"bold\" font-family=\"{}\" font-size=\"{}\" fill=\"{}\" {} style=\"filter:url(#shadow);\">
|
let text_pieces: Vec<String> = self.text.lines()
|
||||||
{}
|
.enumerate()
|
||||||
</text></svg>", s.width, s.height, shadow, self.font.name, self.font.size, self.fill, stroke, self.text);
|
.map(|(index, text)| {
|
||||||
|
format!("<tspan x=\"50%\" y=\"{}\">{}</tspan>", starting_y_position + (index as f32 * text_and_line_spacing), text)
|
||||||
|
}).collect();
|
||||||
|
let text: String = text_pieces.join("\n");
|
||||||
|
|
||||||
|
let final_svg = format!("<svg viewBox=\"0 0 {} {}\" xmlns=\"http://www.w3.org/2000/svg\"><defs>{}</defs><text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-weight=\"bold\" font-family=\"{}\" font-size=\"{}\" fill=\"{}\" {} style=\"filter:url(#shadow);\">{}</text></svg>",
|
||||||
|
s.width,
|
||||||
|
s.height,
|
||||||
|
shadow,
|
||||||
|
self.font.name,
|
||||||
|
self.font.size,
|
||||||
|
self.fill, stroke, text);
|
||||||
|
|
||||||
|
// debug!(final_svg);
|
||||||
|
|
||||||
Svg::new(Handle::from_memory(
|
Svg::new(Handle::from_memory(
|
||||||
Box::leak(base.into_boxed_str()).as_bytes(),
|
Box::leak(final_svg.into_boxed_str()).as_bytes(),
|
||||||
)).into()
|
))
|
||||||
})
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
.into()
|
.into()
|
||||||
|
})).width(Length::Fill).height(Length::Fill).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_spans(&self) -> Vec<String> {
|
fn text_spans(&self) -> Vec<String> {
|
||||||
|
|
Loading…
Reference in a new issue