Commit ab5c3b16 authored by Michael Hölzl's avatar Michael Hölzl Committed by Jeremy Soller

the first version of path support with bezier curves (#22)

* [bugfix] draw line (had problems with vertical or more complex lines)

* [feature] the first version of path support with bezier curves.
parent f0232e26
extern crate orbclient;
use orbclient::{Color, Window, Renderer, EventOption};
use orbclient::{Color, Window, Renderer, EventOption, GraphicsPath};
fn main() {
let (width, height) = orbclient::get_display_size().unwrap();
......@@ -30,6 +30,29 @@ fn main() {
// vertical and horizontal line test
window.line(100, 0, 100, 200, Color::rgb(0, 0, 255));
window.line(0, 100, 200, 100, Color::rgb(255, 255, 0));
// path and bezier curve example draw a cloud
let mut cloud_path = GraphicsPath::new();
cloud_path.move_to(170, 80);
cloud_path.bezier_curve_to(130, 100, 130, 150, 230, 150);
cloud_path.bezier_curve_to(250, 180, 320, 180, 340, 150);
cloud_path.bezier_curve_to(420, 150, 420, 120, 390, 100);
cloud_path.bezier_curve_to(430, 40, 370, 30, 340, 50);
cloud_path.bezier_curve_to(320, 5, 250, 20, 250, 50);
cloud_path.bezier_curve_to(200, 5, 150, 20, 170, 80);
window.draw_path_stroke(cloud_path, Color::rgb(0, 0, 255));
// path and quadratic curve example draw a balloon
let mut balloon_path = GraphicsPath::new();
balloon_path.move_to(75,25);
balloon_path.quadratic_curve_to(25,25,25,62);
balloon_path.quadratic_curve_to(25,100,50,100);
balloon_path.quadratic_curve_to(50,120,30,125);
balloon_path.quadratic_curve_to(60,120,65,100);
balloon_path.quadratic_curve_to(125,100,125,62);
balloon_path.quadratic_curve_to(125,25,75,25);
window.draw_path_stroke(balloon_path, Color::rgb(0, 0, 255));
window.sync();
'events: loop {
......
/// point type (is the point a new position or a connection point)
pub enum PointType {
Move,
Connect,
None,
}
/// graphic path with similar functions like html canvas
pub struct GraphicsPath {
x: i32,
y: i32,
pub points: Vec<(i32, i32, PointType)>,
}
impl GraphicsPath {
pub fn new() -> GraphicsPath {
GraphicsPath {
x : 0,
y : 0,
points: vec![],
}
}
/// move to position
pub fn move_to(&mut self, x: i32, y: i32){
self.points.push((x,y,PointType::Move));
self.x = x;
self.y = y;
}
/// create a line between the last and new point
pub fn line_to(&mut self, x: i32, y: i32) {
self.points.push((x,y,PointType::Connect));
self.x = x;
self.y = y;
}
/// quadratic bezier curve
pub fn quadratic_curve_to(&mut self, argx1: i32, argy1: i32, argx2: i32, argy2: i32){
let mut t:f32 = 0.0;
let mut u:f32;
let mut tt:f32;
let mut uu:f32;
let mut x:f32;
let mut y:f32;
while t < 1.0 {
u = 1.0 - t;
uu = u * u;
tt = t * t;
x = (self.x as f32) * uu;
y = (self.y as f32) * uu;
x += 2.0 * u * t * (argx1 as f32);
y += 2.0 * u * t * (argy1 as f32);
x += tt * (argx2 as f32);
y += tt * (argy2 as f32);
t = t+0.01;
self.points.push((x as i32, y as i32, PointType::Connect));
}
self.x = argx2;
self.y = argy2;
}
/// cubic bezier curve
pub fn bezier_curve_to(&mut self, argx1: i32, argy1: i32, argx2: i32, argy2: i32, argx3: i32, argy3: i32){
let mut t:f32 = 0.0;
let mut u:f32;
let mut tt:f32;
let mut uu:f32;
let mut uuu:f32;
let mut ttt:f32;
let mut x:f32;
let mut y:f32;
while t < 1.0 {
u = 1.0 - t;
tt = t * t;
uu = u * u;
uuu = uu * u;
ttt = tt * t;
x = (self.x as f32) * uuu;
y = (self.y as f32) * uuu;
x += 3.0 * uu * t * (argx1 as f32);
y += 3.0 * uu * t * (argy1 as f32);
x += 3.0 * u * tt * (argx2 as f32);
y += 3.0 * u * tt * (argy2 as f32);
x += ttt * (argx3 as f32);
y += ttt * (argy3 as f32);
t = t+0.01;
self.points.push((x as i32, y as i32, PointType::Connect));
}
self.x = argx3;
self.y = argy3;
}
}
\ No newline at end of file
......@@ -13,10 +13,12 @@ pub use color::Color;
pub use event::*;
pub use imp::*;
pub use renderer::Renderer;
pub use graphicspath::GraphicsPath;
pub mod color;
pub mod event;
pub mod renderer;
pub mod graphicspath;
#[cfg(target_os = "redox")]
#[path="orbital/mod.rs"]
......
......@@ -2,6 +2,8 @@ use std::cmp;
use FONT;
use color::Color;
use graphicspath::GraphicsPath;
use graphicspath::PointType;
#[cfg(target_arch = "x86")]
#[inline(always)]
......@@ -184,6 +186,21 @@ pub trait Renderer {
}
}
/// Draw a path (GraphicsPath)
fn draw_path_stroke(&mut self, graphicspath: GraphicsPath, color: Color) {
let mut x: i32 = 0;
let mut y: i32 = 0;
for point in graphicspath.points {
match point.2 {
PointType::Connect => {self.line(x,y, point.0, point.1, color)},
_ => {},
}
x = point.0;
y = point.1;
}
}
/// Draw a character, using the loaded font
fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
let mut offset = (c as usize) * 16;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment