use crate::{
get_context,
types::{Color, Rect},
};
use glam::{vec2, Vec2};
use quad_gl::{DrawMode, Vertex};
pub fn draw_text(text: &str, x: f32, y: f32, font_size: f32, color: Color) {
let context = &mut get_context().draw_context;
let atlas = context.ui.font_atlas.clone();
let mut total_width = 0.;
for character in text.chars() {
if let Some(font_data) = atlas.character_infos.get(&character) {
let font_data = font_data.scale(font_size);
total_width += font_data.left_padding;
let left_coord = total_width;
let top_coord = font_size as f32 - font_data.height_over_line;
total_width += font_data.size.0 + font_data.right_padding;
let dest = Rect::new(
left_coord + x,
top_coord + y,
font_data.size.0,
font_data.size.1,
);
let source = Rect::new(
font_data.tex_coords.0 * context.font_texture.width(),
font_data.tex_coords.1 * context.font_texture.height(),
font_data.tex_size.0 * context.font_texture.width(),
font_data.tex_size.1 * context.font_texture.height(),
);
crate::texture::draw_texture_ex(
context.font_texture,
dest.x,
dest.y,
color,
crate::texture::DrawTextureParams {
dest_size: Some(vec2(dest.w, dest.h)),
source: Some(source),
..Default::default()
},
);
}
}
}
pub fn measure_text(text: &str, font_size: f32) -> (f32, f32) {
let context = &mut get_context().draw_context;
let atlas = context.ui.font_atlas.clone();
let mut width = 0.;
let mut height: f32 = 0.;
for character in text.chars() {
if let Some(font_data) = atlas.character_infos.get(&character) {
let font_data = font_data.scale(font_size);
width += font_data.left_padding + font_data.size.0 + font_data.right_padding;
height = height.max(font_data.size.1);
}
}
return (width, height);
}
pub fn draw_triangle(v1: Vec2, v2: Vec2, v3: Vec2, color: Color) {
let context = &mut get_context().draw_context;
let mut vertices = Vec::<Vertex>::new();
vertices.push(Vertex::new(v1.x(), v1.y(), 0., 0., 0., color));
vertices.push(Vertex::new(v2.x(), v2.y(), 0., 0., 0., color));
vertices.push(Vertex::new(v3.x(), v3.y(), 0., 0., 0., color));
let indices: [u16; 3] = [0, 1, 2];
context.gl.texture(None);
context.gl.draw_mode(DrawMode::Triangles);
context.gl.geometry(&vertices, &indices);
}
pub fn draw_triangle_lines(v1: Vec2, v2: Vec2, v3: Vec2, thickness: f32, color: Color) {
draw_line(v1.x(), v1.y(), v2.x(), v2.y(), thickness, color);
draw_line(v2.x(), v2.y(), v3.x(), v3.y(), thickness, color);
draw_line(v3.x(), v3.y(), v1.x(), v1.y(), thickness, color);
}
pub fn draw_rectangle(x: f32, y: f32, w: f32, h: f32, color: Color) {
let context = &mut get_context().draw_context;
context.draw_rectangle(x, y, w, h, color);
}
pub fn draw_rectangle_lines(x: f32, y: f32, w: f32, h: f32, thickness: f32, color: Color) {
let t = thickness / 2.;
draw_rectangle(x, y, w, t, color);
draw_rectangle(x + w - t, y + t, t, h - t, color);
draw_rectangle(x, y + h - t, w, t, color);
draw_rectangle(x, y + t, t, h - t, color);
}
pub fn draw_hexagon(
x: f32,
y: f32,
size: f32,
border: f32,
vertical: bool,
border_color: Color,
fill_color: Color,
) {
let rotation = if vertical {
90.
} else {
0.
};
draw_poly(x, y, 6, size, rotation, fill_color);
if border > 0. {
draw_poly_lines(x, y, 6, size, rotation, border, border_color);
}
}
pub fn draw_poly(x: f32, y: f32, sides: u8, radius: f32, rotation: f32, color: Color) {
let context = &mut get_context().draw_context;
let mut vertices = Vec::<Vertex>::new();
let mut indices = Vec::<u16>::new();
let rot = rotation.to_radians();
vertices.push(Vertex::new(x, y, 0., 0., 0., color));
for i in 0..sides + 1 {
let rx = (i as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).cos();
let ry = (i as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).sin();
let vertex = Vertex::new(x + radius * rx, y + radius * ry, 0., rx, ry, color);
vertices.push(vertex);
if i != sides {
indices.extend_from_slice(&[0, i as u16 + 1, i as u16 + 2]);
}
}
context.gl.texture(None);
context.gl.draw_mode(DrawMode::Triangles);
context.gl.geometry(&vertices, &indices);
}
pub fn draw_poly_lines(
x: f32,
y: f32,
sides: u8,
radius: f32,
rotation: f32,
thickness: f32,
color: Color,
) {
let rot = rotation.to_radians();
for i in 0..sides {
let rx = (i as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).cos();
let ry = (i as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).sin();
let p0 = vec2(x + radius * rx, y + radius * ry);
let rx = ((i + 1) as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).cos();
let ry = ((i + 1) as f32 / sides as f32 * std::f32::consts::PI * 2. + rot).sin();
let p1 = vec2(x + radius * rx, y + radius * ry);
draw_line(p0.x(), p0.y(), p1.x(), p1.y(), thickness, color);
}
}
pub fn draw_circle(x: f32, y: f32, r: f32, color: Color) {
draw_poly(x, y, 200, r, 0., color);
}
pub fn draw_circle_lines(x: f32, y: f32, r: f32, thickness: f32, color: Color) {
draw_poly_lines(x, y, 200, r, 0., thickness, color);
}
pub fn draw_line(x1: f32, y1: f32, x2: f32, y2: f32, thickness: f32, color: Color) {
let context = &mut get_context().draw_context;
context.draw_line(x1, y1, x2, y2, thickness, color);
}