image + text align
This commit is contained in:
parent
d6b3f9791c
commit
919241aeac
144
src/main.rs
144
src/main.rs
@ -5,6 +5,7 @@ use std::ops::Deref;
|
|||||||
use std::os::linux::raw::stat;
|
use std::os::linux::raw::stat;
|
||||||
use send_wrapper::SendWrapper;
|
use send_wrapper::SendWrapper;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
use std::cmp;
|
||||||
|
|
||||||
use fontdue::{Font, FontSettings};
|
use fontdue::{Font, FontSettings};
|
||||||
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
||||||
@ -33,7 +34,7 @@ use core::slice::IterMut;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ClipboardContent {
|
enum ClipboardContent {
|
||||||
Image(Vec<u8>),
|
Image(ImageData<'static>),
|
||||||
Text(String),
|
Text(String),
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -41,7 +42,7 @@ enum ClipboardContent {
|
|||||||
fn get_clipboard(clipboard: &mut Clipboard) -> ClipboardContent {
|
fn get_clipboard(clipboard: &mut Clipboard) -> ClipboardContent {
|
||||||
match clipboard.get_image() {
|
match clipboard.get_image() {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
ClipboardContent::Image(i.bytes.to_vec())
|
ClipboardContent::Image(i.to_owned_img())
|
||||||
}, Err(e) => {
|
}, Err(e) => {
|
||||||
match clipboard.get_text() {
|
match clipboard.get_text() {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
@ -88,15 +89,15 @@ fn render_text(text: String, font_size: f32, font: &Font, color: Color) -> Pixma
|
|||||||
for gl in layout.glyphs() {
|
for gl in layout.glyphs() {
|
||||||
let ch = gl.parent;
|
let ch = gl.parent;
|
||||||
|
|
||||||
let height = gl.y as u32 + gl.height as u32;
|
let height = gl.y as i32 + gl.height as i32;
|
||||||
|
|
||||||
let rendered = render_char(ch, font_size, font, color);
|
let rendered = render_char(ch, font_size, font, color);
|
||||||
text_width = gl.x as u32 + gl.width as u32;
|
text_width = gl.x as i32 + gl.width as i32;
|
||||||
if height > max_height { max_height = height; }
|
if height > max_height { max_height = height; }
|
||||||
chars.push((rendered, gl.x, gl.y));
|
chars.push((rendered, gl.x, gl.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pixmap = match Pixmap::new(text_width, max_height) {
|
let mut pixmap = match Pixmap::new(text_width as u32, max_height as u32) {
|
||||||
Some(i) => {i},
|
Some(i) => {i},
|
||||||
None => { return Pixmap::new(1, 1).unwrap(); },
|
None => { return Pixmap::new(1, 1).unwrap(); },
|
||||||
};
|
};
|
||||||
@ -118,30 +119,37 @@ fn render_text(text: String, font_size: f32, font: &Font, color: Color) -> Pixma
|
|||||||
pixmap
|
pixmap
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_text_with_ln(text: String, size: f32, font: &Font, char_padding: usize, line_padding: usize, color: Color) -> Pixmap {
|
fn render_text_with_ln(text: String, size: f32, font: &Font, line_height: i32, color: Color) -> Pixmap {
|
||||||
let mut width = 0;
|
let mut width = 0;
|
||||||
let mut line_height = 0;
|
|
||||||
let mut lines: Vec<Pixmap> = Vec::new();
|
let mut lines: Vec<Pixmap> = Vec::new();
|
||||||
for ele in text.split("\n") {
|
for ele in text.split("\n") {
|
||||||
let rendered = render_text(ele.to_string(), size, font, color);
|
let rendered = render_text(ele.to_string(), size, font, color);
|
||||||
if rendered.width() > width { width = rendered.width(); }
|
if rendered.width() > width { width = rendered.width(); }
|
||||||
if rendered.height() > line_height { line_height = rendered.height(); }
|
|
||||||
lines.push(rendered);
|
lines.push(rendered);
|
||||||
}
|
}
|
||||||
let height = (line_height + line_padding as u32) * lines.len() as u32;
|
let height = (line_height * lines.len() as i32) as i32;
|
||||||
|
|
||||||
let mut pixmap = Pixmap::new(width, height).unwrap();
|
let mut pixmap = Pixmap::new(width, height as u32).unwrap();
|
||||||
let paint = PixmapPaint::default();
|
let paint = PixmapPaint::default();
|
||||||
|
|
||||||
let mut y: u32 = 0;
|
let mut y: i32 = 0;
|
||||||
for ele in lines {
|
for ele in lines {
|
||||||
pixmap.draw_pixmap(0, (y + (line_height - ele.height())) as i32, ele.as_ref(), &paint, Transform::identity(), None);
|
pixmap.draw_pixmap(0, (y + (line_height - ele.height() as i32)) as i32, ele.as_ref(), &paint, Transform::identity(), None);
|
||||||
y += line_height + line_padding as u32;
|
y += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixmap
|
pixmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_image(image: ImageData<'static>) -> Pixmap {
|
||||||
|
let mut pixmap = Pixmap::new(image.width as u32, image.height as u32).unwrap();
|
||||||
|
let data: &mut [u8] = pixmap.data_mut();
|
||||||
|
for i in 0..image.bytes.len() {
|
||||||
|
data[i] = image.bytes[i];
|
||||||
|
}
|
||||||
|
pixmap
|
||||||
|
}
|
||||||
|
|
||||||
pub trait RemoveElem<T: PartialEq> {
|
pub trait RemoveElem<T: PartialEq> {
|
||||||
fn remove_elem<F>(&mut self, predicate: F) -> Option<T>
|
fn remove_elem<F>(&mut self, predicate: F) -> Option<T>
|
||||||
where F: Fn(&T) -> bool;
|
where F: Fn(&T) -> bool;
|
||||||
@ -220,6 +228,27 @@ fn get_window<'a>(windows: IterMut<'a, Note>, id: WindowId) -> Option<&'a mut No
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_debug_rect<'a>(pixmap: &'a mut Pixmap, x: i32, y: i32, w: i32, h: i32) {
|
||||||
|
let path = PathBuilder::from_rect(
|
||||||
|
Rect::from_xywh(
|
||||||
|
x as f32,
|
||||||
|
y as f32,
|
||||||
|
w as f32,
|
||||||
|
h as f32
|
||||||
|
).unwrap());
|
||||||
|
|
||||||
|
let mut paint = Paint::default();
|
||||||
|
paint.set_color_rgba8(220, 0, 0, 255);
|
||||||
|
|
||||||
|
pixmap.fill_path(
|
||||||
|
&path,
|
||||||
|
&paint,
|
||||||
|
FillRule::EvenOdd,
|
||||||
|
Transform::identity(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn run_event_loop(event_loop: EventLoop<MyUserEvent>, windows: RefCell<Vec<Note>>) {
|
fn run_event_loop(event_loop: EventLoop<MyUserEvent>, windows: RefCell<Vec<Note>>) {
|
||||||
let font: Font = Font::from_bytes(include_bytes!("../resources/Roboto.ttf") as &[u8], FontSettings::default()).unwrap();
|
let font: Font = Font::from_bytes(include_bytes!("../resources/Roboto.ttf") as &[u8], FontSettings::default()).unwrap();
|
||||||
|
|
||||||
@ -314,6 +343,77 @@ fn run_event_loop(event_loop: EventLoop<MyUserEvent>, windows: RefCell<Vec<Note>
|
|||||||
let mut pixmap = Pixmap::new(width, height).unwrap();
|
let mut pixmap = Pixmap::new(width, height).unwrap();
|
||||||
pixmap.fill(Color::from_rgba8(250, 250, 120, 250));
|
pixmap.fill(Color::from_rgba8(250, 250, 120, 250));
|
||||||
|
|
||||||
|
let mut pixmap_paint = PixmapPaint::default();
|
||||||
|
|
||||||
|
match &win.clipboard {
|
||||||
|
ClipboardContent::Text(t) => {
|
||||||
|
let win_size: (f32,f32) = (width as f32, height as f32);
|
||||||
|
let text_table_size: (f32,f32) = {
|
||||||
|
let pix = render_text_with_ln(
|
||||||
|
t.to_string(),
|
||||||
|
10.0,
|
||||||
|
&font,
|
||||||
|
12,
|
||||||
|
Color::from_rgba8(255, 0, 0, 255)
|
||||||
|
);
|
||||||
|
(
|
||||||
|
pix.width() as f32 / 10.0,
|
||||||
|
pix.height() as f32 / 10.0
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// dbg!(&text_table_size);
|
||||||
|
|
||||||
|
let text_size = cmp::min(
|
||||||
|
(win_size.1 / text_table_size.1) as i32,
|
||||||
|
(win_size.0 / text_table_size.0) as i32
|
||||||
|
) as f32;
|
||||||
|
|
||||||
|
let mut text_pixmap = render_text_with_ln(
|
||||||
|
t.to_string(),
|
||||||
|
text_size,
|
||||||
|
&font,
|
||||||
|
(text_size * 1.2) as i32,
|
||||||
|
Color::from_rgba8(255, 0, 0, 255)
|
||||||
|
);
|
||||||
|
|
||||||
|
let text_pos = (
|
||||||
|
width as i32 / 2 - text_pixmap.width() as i32 / 2,
|
||||||
|
height as i32 / 2 - text_pixmap.height() as i32 / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
// draw_debug_rect(
|
||||||
|
// &mut pixmap,
|
||||||
|
// text_pos.0 as i32,
|
||||||
|
// text_pos.1 as i32,
|
||||||
|
// text_pixmap.width() as i32,
|
||||||
|
// text_pixmap.height() as i32
|
||||||
|
// );
|
||||||
|
|
||||||
|
pixmap.draw_pixmap(text_pos.0, text_pos.1, text_pixmap.as_ref(), &pixmap_paint, Transform::identity(), None);
|
||||||
|
},
|
||||||
|
ClipboardContent::Image(im) => {
|
||||||
|
let mut image_pixmap = render_image(im.clone());
|
||||||
|
|
||||||
|
let win_size: (f32,f32) = (width as f32, height as f32);
|
||||||
|
let image_size: (f32,f32) = (image_pixmap.width() as f32, image_pixmap.height() as f32);
|
||||||
|
let image_scale = (win_size.0 / image_size.0, win_size.1 / image_size.1);
|
||||||
|
|
||||||
|
let image_pos: (i32, i32) = (0,0);
|
||||||
|
|
||||||
|
pixmap.draw_pixmap(
|
||||||
|
image_pos.0,
|
||||||
|
image_pos.1,
|
||||||
|
image_pixmap.as_ref(),
|
||||||
|
&pixmap_paint,
|
||||||
|
Transform::from_scale(
|
||||||
|
image_scale.0,
|
||||||
|
image_scale.1),
|
||||||
|
None);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
|
||||||
let path = PathBuilder::from_rect(Rect::from_xywh(width as f32 - 30.0, 0.0, 30.0, 30.0).unwrap());
|
let path = PathBuilder::from_rect(Rect::from_xywh(width as f32 - 30.0, 0.0, 30.0, 30.0).unwrap());
|
||||||
|
|
||||||
let mut paint = Paint::default();
|
let mut paint = Paint::default();
|
||||||
@ -365,19 +465,6 @@ fn run_event_loop(event_loop: EventLoop<MyUserEvent>, windows: RefCell<Vec<Note>
|
|||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut paint = PixmapPaint::default();
|
|
||||||
|
|
||||||
match &win.clipboard {
|
|
||||||
ClipboardContent::Text(t) => {
|
|
||||||
pixmap.draw_pixmap(20, 20,
|
|
||||||
render_text_with_ln(t.to_string(),
|
|
||||||
50.0, &font, 5, 20, Color::from_rgba8(255, 0, 0, 255)).as_ref(),
|
|
||||||
&paint, Transform::identity(), None);
|
|
||||||
},
|
|
||||||
ClipboardContent::Image(i) => {},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut buffer = win.surface.buffer_mut().unwrap();
|
let mut buffer = win.surface.buffer_mut().unwrap();
|
||||||
for index in 0..(width * height) as usize {
|
for index in 0..(width * height) as usize {
|
||||||
buffer[index] = pixmap.data()[index * 4 + 2] as u32
|
buffer[index] = pixmap.data()[index * 4 + 2] as u32
|
||||||
@ -412,7 +499,10 @@ fn popup_clipboard(content: ClipboardContent) -> MyUserEvent {
|
|||||||
ClipboardContent::Text(_) => "Text",
|
ClipboardContent::Text(_) => "Text",
|
||||||
_ => "???"
|
_ => "???"
|
||||||
}))
|
}))
|
||||||
.with_inner_size(LogicalSize::new(800.0, 600.0))
|
.with_inner_size(match &content {
|
||||||
|
ClipboardContent::Image(i) => LogicalSize::new(i.width as f32, i.height as f32),
|
||||||
|
_ => LogicalSize::new(250.0, 300.0)
|
||||||
|
})
|
||||||
.with_resizable(true)
|
.with_resizable(true)
|
||||||
.with_visible(true)
|
.with_visible(true)
|
||||||
.with_min_inner_size(LogicalSize::new(50.0, 50.0)),
|
.with_min_inner_size(LogicalSize::new(50.0, 50.0)),
|
||||||
|
Loading…
Reference in New Issue
Block a user