sized widgets!
This commit is contained in:
@@ -2,7 +2,7 @@ use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, SwashCache};
|
||||
use image::{Rgba, RgbaImage};
|
||||
|
||||
use crate::{
|
||||
layout::{TextureHandle, Textures, UiColor},
|
||||
layout::{TextureHandle, Textures, UiColor, Vec2},
|
||||
util::HashMap,
|
||||
};
|
||||
|
||||
@@ -20,12 +20,15 @@ impl Default for TextData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct TextAttrs {
|
||||
pub color: UiColor,
|
||||
pub size: f32,
|
||||
pub line_height: f32,
|
||||
}
|
||||
|
||||
pub type TextBuffer = Buffer;
|
||||
|
||||
impl Default for TextAttrs {
|
||||
fn default() -> Self {
|
||||
let size = 14.0;
|
||||
@@ -38,35 +41,57 @@ impl Default for TextAttrs {
|
||||
}
|
||||
|
||||
impl TextData {
|
||||
/// returns (handle, offset from top left)
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
buffer: &mut TextBuffer,
|
||||
content: &str,
|
||||
attrs: &TextAttrs,
|
||||
textures: &mut Textures,
|
||||
) -> TextureHandle {
|
||||
let metrics = Metrics::new(attrs.size, attrs.line_height);
|
||||
let mut buffer = Buffer::new(&mut self.font_system, metrics);
|
||||
let mut buffer = buffer.borrow_with(&mut self.font_system);
|
||||
buffer.set_text(content, &Attrs::new(), Shaping::Advanced);
|
||||
|
||||
// dawg what is this api ???
|
||||
) -> (TextureHandle, TextOffset) {
|
||||
buffer.set_metrics(
|
||||
&mut self.font_system,
|
||||
Metrics::new(attrs.size, attrs.line_height),
|
||||
);
|
||||
buffer.set_text(
|
||||
&mut self.font_system,
|
||||
content,
|
||||
&Attrs::new(),
|
||||
Shaping::Advanced,
|
||||
);
|
||||
let mut pixels = HashMap::new();
|
||||
let mut min_x = 0;
|
||||
let mut min_y = 0;
|
||||
let mut max_x = 0;
|
||||
let mut max_y = 0;
|
||||
let c = attrs.color;
|
||||
buffer.draw(
|
||||
&mut self.swash_cache,
|
||||
cosmic_text::Color::rgba(c.r, c.g, c.b, c.a),
|
||||
|x, y, _, _, color| {
|
||||
min_x = min_x.min(x);
|
||||
min_y = min_y.min(y);
|
||||
max_x = max_x.max(x);
|
||||
max_y = max_y.max(y);
|
||||
pixels.insert((x, y), Rgba(color.as_rgba()));
|
||||
},
|
||||
);
|
||||
let mut max_width = 0.0f32;
|
||||
for run in buffer.layout_runs() {
|
||||
for glyph in run.glyphs.iter() {
|
||||
let physical_glyph = glyph.physical((0., 0.), 1.0);
|
||||
|
||||
let glyph_color = match glyph.color_opt {
|
||||
Some(some) => some,
|
||||
None => cosmic_text::Color::rgba(c.r, c.g, c.b, c.a),
|
||||
};
|
||||
|
||||
self.swash_cache.with_pixels(
|
||||
&mut self.font_system,
|
||||
physical_glyph.cache_key,
|
||||
glyph_color,
|
||||
|x, y, color| {
|
||||
let x = physical_glyph.x + x;
|
||||
let y = run.line_y as i32 + physical_glyph.y + y;
|
||||
min_x = min_x.min(x);
|
||||
min_y = min_y.min(y);
|
||||
max_x = max_x.max(x);
|
||||
max_y = max_y.max(y);
|
||||
pixels.insert((x, y), Rgba(color.as_rgba()));
|
||||
},
|
||||
);
|
||||
}
|
||||
max_width = max_width.max(run.line_w);
|
||||
}
|
||||
let width = (max_x - min_x + 1) as u32;
|
||||
let height = (max_y - min_y + 1) as u32;
|
||||
let mut image = RgbaImage::new(width, height);
|
||||
@@ -75,6 +100,25 @@ impl TextData {
|
||||
let y = (y - min_y) as u32;
|
||||
image.put_pixel(x, y, color);
|
||||
}
|
||||
textures.add(image)
|
||||
let offset = TextOffset {
|
||||
top_left: Vec2::new(min_x as f32, min_y as f32),
|
||||
bot_right: Vec2::new(
|
||||
max_width - max_x as f32,
|
||||
attrs.line_height * buffer.lines.len() as f32 - max_y as f32,
|
||||
),
|
||||
};
|
||||
(textures.add(image), offset)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct TextOffset {
|
||||
pub top_left: Vec2,
|
||||
pub bot_right: Vec2,
|
||||
}
|
||||
|
||||
impl TextOffset {
|
||||
pub fn size(&self, handle: &TextureHandle) -> Vec2 {
|
||||
handle.size() - self.top_left + self.bot_right
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user