the beginnings of the text_svg
This commit is contained in:
parent
46cdf53c6e
commit
ed80ccaa55
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -1156,6 +1156,12 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colors-transform"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9226dbc05df4fb986f48d730b001532580883c4c06c5d1c213f4b34c1c157178"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "com"
|
name = "com"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -4165,6 +4171,7 @@ name = "lumina"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"colors-transform",
|
||||||
"cosmic-time",
|
"cosmic-time",
|
||||||
"crisp",
|
"crisp",
|
||||||
"dirs",
|
"dirs",
|
||||||
|
|
|
@ -28,6 +28,7 @@ gstreamer = "0.23.3"
|
||||||
gstreamer-app = "0.23.3"
|
gstreamer-app = "0.23.3"
|
||||||
cosmic-time = "0.2.0"
|
cosmic-time = "0.2.0"
|
||||||
url = "2"
|
url = "2"
|
||||||
|
colors-transform = "0.2.11"
|
||||||
# rfd = { version = "0.12.1", features = ["xdg-portal"], default-features = false }
|
# rfd = { version = "0.12.1", features = ["xdg-portal"], default-features = false }
|
||||||
|
|
||||||
[dependencies.iced_video_player]
|
[dependencies.iced_video_player]
|
||||||
|
|
|
@ -305,15 +305,19 @@ impl SongEditor {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, slide)| {
|
.map(|(index, slide)| {
|
||||||
let svg = Handle::from_memory(r#"<svg viewBox="0 0 240 100" xmlns="http://www.w3.org/2000/svg">
|
let svg = Handle::from_memory(r#"<svg viewBox="0 0 1280 720" xmlns="http://www.w3.org/2000/svg">
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="shadow2">
|
<filter id="shadow">
|
||||||
<feDropShadow dx="0" dy="0" stdDeviation="0" flood-color="cyan" />
|
<feDropShadow dx="10" dy="10" stdDeviation="5" flood-color='#000' />
|
||||||
</filter>
|
</filter>
|
||||||
</defs>
|
</defs>
|
||||||
<text x="0" y="50" font-weight="bold" font-family="Quicksand" font-size="40" fill="white" stroke="black" stroke-width="2" style="filter:url(#shadow2);">
|
<text x="0" y="300" font-weight="bold" font-family="Quicksand" font-size="80" fill="white" stroke="black" stroke-width="2" style="filter:url(#shadow);">
|
||||||
Hello World
|
Hello World
|
||||||
</text></svg>"#.as_bytes());
|
</text>
|
||||||
|
<text x="0" y="350" font-weight="bold" font-family="Quicksand" font-size="40" fill="white" stroke="black" stroke-width="2" style="filter:url(#shadow);">
|
||||||
|
Hello World
|
||||||
|
</text>
|
||||||
|
</svg>"#.as_bytes());
|
||||||
stack!(
|
stack!(
|
||||||
container(
|
container(
|
||||||
slide_view(
|
slide_view(
|
||||||
|
|
|
@ -1,38 +1,125 @@
|
||||||
use cosmic::iced::Font as IcedFont;
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
use colors_transform::Rgb;
|
||||||
|
use cosmic::{
|
||||||
|
iced::font::{Style, Weight},
|
||||||
|
prelude::*,
|
||||||
|
widget::{svg::Handle, Svg},
|
||||||
|
};
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct TextSvg {
|
pub struct TextSvg {
|
||||||
text: String,
|
text: String,
|
||||||
font: Font,
|
font: Font,
|
||||||
shadow: Shadow,
|
shadow: Option<Shadow>,
|
||||||
stroke: Stroke,
|
stroke: Option<Stroke>,
|
||||||
fill: Color,
|
fill: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub struct Font(IcedFont);
|
pub struct Font {
|
||||||
|
name: String,
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
weight: Weight,
|
||||||
pub struct Color {
|
style: Style,
|
||||||
red: u8,
|
size: u8,
|
||||||
green: u8,
|
|
||||||
blue: u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
impl From<&str> for Font {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
name: value.to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Font {
|
||||||
|
fn get_name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_weight(&self) -> Weight {
|
||||||
|
self.weight.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_style(&self) -> Style {
|
||||||
|
self.style.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn weight(mut self, weight: impl Into<Weight>) -> Self {
|
||||||
|
self.weight = weight.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn style(mut self, style: impl Into<Style>) -> Self {
|
||||||
|
self.style = style.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(mut self, name: impl Into<String>) -> Self {
|
||||||
|
self.name = name.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Color(Rgb);
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub fn from_hex_str(color: impl AsRef<str>) -> Color {
|
||||||
|
match Rgb::from_hex_str(color.as_ref()) {
|
||||||
|
Ok(rgb) => Color(rgb),
|
||||||
|
Err(e) => {
|
||||||
|
error!("error in making color from hex_str: {:?}", e);
|
||||||
|
Color::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Color {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
Self::from_hex_str(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Color {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(
|
||||||
|
Rgb::from_hex_str("#000")
|
||||||
|
.expect("This is not a hex color"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Color {
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0.to_css_hex_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct Shadow {
|
pub struct Shadow {
|
||||||
offset_x: i16,
|
pub offset_x: i16,
|
||||||
offset_y: i16,
|
pub offset_y: i16,
|
||||||
spread: u16,
|
pub spread: u16,
|
||||||
color: Color,
|
pub color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct Stroke {
|
pub struct Stroke {
|
||||||
size: u16,
|
size: u16,
|
||||||
color: Color,
|
color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Message {
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
impl TextSvg {
|
impl TextSvg {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -46,12 +133,12 @@ impl TextSvg {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
|
pub fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
|
||||||
self.shadow = shadow.into();
|
self.shadow = Some(shadow.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stroke(mut self, stroke: impl Into<Stroke>) -> Self {
|
pub fn stroke(mut self, stroke: impl Into<Stroke>) -> Self {
|
||||||
self.stroke = stroke.into();
|
self.stroke = Some(stroke.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,4 +146,58 @@ impl TextSvg {
|
||||||
self.font = font.into();
|
self.font = font.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn view(&self) -> Element<Message> {
|
||||||
|
let shadow = if let Some(shadow) = &self.shadow {
|
||||||
|
format!("<filter id=\"shadow\"><feDropShadow dx=\"{}\" dy=\"{}\" stdDeviation=\"{}\" flood-color=\"{}\"/></filter>",
|
||||||
|
shadow.offset_x,
|
||||||
|
shadow.offset_y,
|
||||||
|
shadow.spread,
|
||||||
|
shadow.color)
|
||||||
|
} else {
|
||||||
|
"".into()
|
||||||
|
};
|
||||||
|
let stroke = if let Some(stroke) = &self.stroke {
|
||||||
|
format!(
|
||||||
|
"stroke=\"{}\" stroke-width=\"{}\"",
|
||||||
|
stroke.color, stroke.size
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"".into()
|
||||||
|
};
|
||||||
|
// text y coords are based on bottom left corner so we need to take height into consideration
|
||||||
|
let base = format!("<svg viewBox=\"0 0 240 100\" xmlns=\"http://www.w3.org/2000/svg\"><defs>{}</defs>
|
||||||
|
<text x=\"0\" y=\"50\" font-weight=\"bold\" font-family=\"{}\" font-size=\"{}\" fill=\"{}\" {} style=\"filter:url(#shadow);\">
|
||||||
|
{}
|
||||||
|
</text></svg>", shadow, self.font.name, self.font.size, self.fill, stroke, self.text);
|
||||||
|
Svg::new(Handle::from_memory(
|
||||||
|
Box::leak(base.into_boxed_str()).as_bytes(),
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shadow(
|
||||||
|
offset_x: i16,
|
||||||
|
offset_y: i16,
|
||||||
|
spread: u16,
|
||||||
|
color: impl Into<Color>,
|
||||||
|
) -> Shadow {
|
||||||
|
Shadow {
|
||||||
|
offset_x,
|
||||||
|
offset_y,
|
||||||
|
spread,
|
||||||
|
color: color.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stroke(size: u16, color: impl Into<Color>) -> Stroke {
|
||||||
|
Stroke {
|
||||||
|
size,
|
||||||
|
color: color.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color(color: impl AsRef<str>) -> Color {
|
||||||
|
Color::from_hex_str(color)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue