Compare commits

..

No commits in common. "bb08064b9a70ee065f9909e54e8c240140cc5c92" and "fc70bb395592030c572682ca33a555686985c595" have entirely different histories.

2 changed files with 54 additions and 88 deletions

View File

@ -9,7 +9,7 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use cairo::{Context, Rectangle}; use cairo::Context;
use cyberpunk::{AsymLine, AsymLineCutout, GlowPen, Pen, Text}; use cyberpunk::{AsymLine, AsymLineCutout, GlowPen, Pen, Text};
use glib::{GString, Object}; use glib::{GString, Object};
use gtk::{ use gtk::{
@ -73,6 +73,13 @@ impl Index<usize> for Script {
} }
} }
struct Region {
left: f64,
top: f64,
width: f64,
height: f64,
}
struct Fade { struct Fade {
text: String, text: String,
position: Position, position: Position,
@ -84,7 +91,7 @@ struct Fade {
trait Animation { trait Animation {
fn position(&self) -> Position; fn position(&self) -> Position;
fn tick(&self, now: Instant, context: &Context, width: f64); fn tick(&self, now: Instant, context: &Context, region: Region);
} }
impl Animation for Fade { impl Animation for Fade {
@ -92,15 +99,15 @@ impl Animation for Fade {
self.position.clone() self.position.clone()
} }
fn tick(&self, now: Instant, context: &Context, width: f64) { fn tick(&self, now: Instant, context: &Context, region: Region) {
let total_frames = self.duration.as_secs() * FPS; let total_frames = self.duration.as_secs() * FPS;
let alpha_rate: f64 = 1. / total_frames as f64; let alpha_rate: f64 = 1. / total_frames as f64;
let frames = (now - self.start_time).as_secs_f64() * FPS as f64; let frames = (now - self.start_time).as_secs_f64() * FPS as f64;
let alpha = alpha_rate * frames as f64; let alpha = alpha_rate * frames as f64;
let text_display = Text::new(self.text.clone(), context, 32., width); let text_display = Text::new(self.text.clone(), context, 32.);
let _ = context.move_to(0., text_display.extents().height()); let _ = context.move_to(region.left, region.top + text_display.extents().height());
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha); let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
text_display.draw(); text_display.draw();
} }
@ -120,20 +127,20 @@ impl Animation for CrossFade {
self.position.clone() self.position.clone()
} }
fn tick(&self, now: Instant, context: &Context, width: f64) { fn tick(&self, now: Instant, context: &Context, region: Region) {
let total_frames = self.duration.as_secs() * FPS; let total_frames = self.duration.as_secs() * FPS;
let alpha_rate: f64 = 1. / total_frames as f64; let alpha_rate: f64 = 1. / total_frames as f64;
let frames = (now - self.start_time).as_secs_f64() * FPS as f64; let frames = (now - self.start_time).as_secs_f64() * FPS as f64;
let alpha = alpha_rate * frames as f64; let alpha = alpha_rate * frames as f64;
let text_display = Text::new(self.old_text.clone(), context, 32., width); let text_display = Text::new(self.old_text.clone(), context, 32.);
let _ = context.move_to(0., text_display.extents().height()); let _ = context.move_to(region.left, region.top + text_display.extents().height());
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, 1. - alpha); let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, 1. - alpha);
text_display.draw(); text_display.draw();
let text_display = Text::new(self.new_text.clone(), context, 32., width); let text_display = Text::new(self.new_text.clone(), context, 32.);
let _ = context.move_to(0., text_display.extents().height()); let _ = context.move_to(region.left, region.top + text_display.extents().height());
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha); let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
text_display.draw(); text_display.draw();
} }
@ -263,31 +270,24 @@ impl CyberScreen {
let _ = context.paint(); let _ = context.paint();
let pen = GlowPen::new(width, height, 2., 8., (0.7, 0., 1.)); let pen = GlowPen::new(width, height, 2., 8., (0.7, 0., 1.));
AsymLineCutout { /*
for i in 0..6 {
pen.move_to(0., height as f64 * i as f64 / 5.);
pen.line_to(width as f64, height as f64 * i as f64 / 5.);
}
pen.stroke();
*/
let line = AsymLineCutout {
orientation: gtk::Orientation::Horizontal, orientation: gtk::Orientation::Horizontal,
start_x: 25., start_x: 25.,
start_y: height as f64 / 7., start_y: height as f64 / 7.,
start_length: width as f64 / 3., start_length: width as f64 / 3.,
cutout_length: width as f64 / 3. - 100., cutout_length: width as f64 / 3. - 25.,
height: 50., height: 25.,
end_length: width as f64 / 3. - 50., end_length: width as f64 / 3. - 50.,
invert: false, invert: false,
} }.draw(&pen);
.draw(&pen);
pen.stroke(); pen.stroke();
AsymLine {
orientation: gtk::Orientation::Horizontal,
start_x: width as f64 / 4.,
start_y: height as f64 * 6. / 7.,
start_length: width as f64 * 2. / 3. - 25.,
height: 50.,
end_length: 0.,
invert: false,
}
.draw(&pen);
pen.stroke();
let tracery = pen.finish(); let tracery = pen.finish();
let _ = context.set_source(tracery); let _ = context.set_source(tracery);
let _ = context.paint(); let _ = context.paint();
@ -300,36 +300,33 @@ impl CyberScreen {
if let Some(animation) = animations.get(&Position::Top) { if let Some(animation) = animations.get(&Position::Top) {
let y = height as f64 * 1. / 5.; let y = height as f64 * 1. / 5.;
let surface = context.target().create_for_rectangle(Rectangle::new( let region = Region {
20., left: 20.,
y, top: y,
max_width, height: region_height,
region_height, width: max_width,
)).unwrap(); };
let ctx = Context::new(&surface).unwrap(); animation.tick(now, context, region);
animation.tick(now, &ctx, max_width);
} }
if let Some(animation) = animations.get(&Position::Middle) { if let Some(animation) = animations.get(&Position::Middle) {
let y = height as f64 * 2. / 5.; let y = height as f64 * 2. / 5.;
let surface = context.target().create_for_rectangle(Rectangle::new( let region = Region {
20., left: 20.,
y, top: y,
max_width, height: region_height,
region_height, width: max_width,
)).unwrap(); };
let ctx = Context::new(&surface).unwrap(); animation.tick(now, context, region);
animation.tick(now, &ctx, max_width);
} }
if let Some(animation) = animations.get(&Position::Bottom) { if let Some(animation) = animations.get(&Position::Bottom) {
let y = height as f64 * 3. / 5.; let y = height as f64 * 3. / 5.;
let surface = context.target().create_for_rectangle(Rectangle::new( let region = Region {
20., left: 20.,
y, top: y,
max_width, height: region_height,
region_height, width: max_width,
)).unwrap(); };
let ctx = Context::new(&surface).unwrap(); animation.tick(now, context, region);
animation.tick(now, &ctx, max_width);
} }
} }
}); });

View File

@ -251,53 +251,22 @@ impl Pen for GlowPen {
} }
pub struct Text<'a> { pub struct Text<'a> {
content: Vec<String>, content: String,
context: &'a Context, context: &'a Context,
} }
impl<'a> Text<'a> { impl<'a> Text<'a> {
pub fn new(content: String, context: &'a Context, size: f64, width: f64) -> Self { pub fn new(content: String, context: &'a Context, size: f64) -> Self {
context.select_font_face("Alegreya Sans SC", FontSlant::Normal, FontWeight::Bold); context.select_font_face("Alegreya Sans SC", FontSlant::Normal, FontWeight::Bold);
context.set_font_size(size); context.set_font_size(size);
Self { content, context }
let lines = word_wrap(content, context, width);
Self { content: lines, context }
} }
pub fn extents(&self) -> TextExtents { pub fn extents(&self) -> TextExtents {
self.context.text_extents(&self.content[0]).unwrap() self.context.text_extents(&self.content).unwrap()
} }
pub fn draw(&self) { pub fn draw(&self) {
let mut baseline = 0.; let _ = self.context.show_text(&self.content);
for line in self.content.iter() {
baseline += self.context.text_extents(line).unwrap().height() + 10.;
self.context.move_to(0., baseline);
let _ = self.context.show_text(&line);
} }
} }
}
fn word_wrap(content: String, context: &Context, max_width: f64) -> Vec<String> {
let mut lines = vec![];
let words: Vec<&str> = content.split_whitespace().collect();
let mut start: usize = 0;
let mut line = String::new();
for idx in 0..words.len() + 1 {
line = words[start..idx].join(" ");
let extents = context.text_extents(&line).unwrap();
if extents.width() > max_width {
let line = words[start..idx-1].join(" ");
println!("line: {}", line);
start = idx-1;
lines.push(line.clone());
}
}
if line.len() > 0 {
println!("line: {}", line);
lines.push(line);
}
lines
}