Unverified Commit 1e8177aa authored by Jeremy Soller's avatar Jeremy Soller Committed by GitHub

Merge pull request #47 from robbycerantola/mode

Implement window drawing mode property 
parents 498d7a46 31075bab
......@@ -15,7 +15,7 @@ keywords = [
[dependencies]
time = "*"
rayon = "1.0"
rayon = "0.8"
[features]
default = []
......
extern crate orbclient;
use orbclient::{Color, Window, Renderer, EventOption, GraphicsPath};
use orbclient::{Color, Window, Renderer, EventOption, GraphicsPath, Mode};
fn main() {
let (width, height) = orbclient::get_display_size().unwrap();
......@@ -70,6 +71,21 @@ fn main() {
println!("Testing colors: they are NOT the same!")
}
//Draw a transparent rectangle over window content
// default mode is Blend
window.rect(250, 200, 80, 80, Color::rgba(100,100,100,100));
//Draw an opaque rectangle replacing window content
window.mode().set(Mode::Overwrite); // set window drawing mode to Overwrite from now on
window.rect(300, 220, 80, 80, Color::rgb(100,100,100));
//Possibly draw a hole in the window replacing alpha channel ?? (Only in Orbital, not in SDL2)
window.rect(300, 100, 80, 80, Color::rgba(10,10,10,1));
//Draw a transparent rectangle over window content
window.mode().set(Mode::Blend); //set mode to Blend fron now on
window.rect(200, 230, 80, 80, Color::rgba(100,100,100,100));
window.sync();
'events: loop {
......
......@@ -35,6 +35,12 @@ pub enum WindowFlag {
Unclosable
}
#[derive(Clone, Copy, Debug)]
pub enum Mode {
Blend, //Composite
Overwrite //Replace
}
#[cfg(all(not(feature="no_std"), target_os = "redox"))]
#[path="sys/orbital.rs"]
mod sys;
......
extern crate rayon;
use core::cmp;
use std::cell::Cell;
use FONT;
use color::Color;
use graphicspath::GraphicsPath;
use graphicspath::PointType;
use Mode;
#[cfg(target_arch = "x86")]
#[inline(always)]
......@@ -47,8 +49,15 @@ pub trait Renderer {
/// Flip the buffer
fn sync(&mut self) -> bool;
/// Draw a pixel
/// Set/get drawing mode
fn mode(&self) -> &Cell<Mode>;
///Draw a pixel
fn pixel(&mut self, x: i32, y: i32, color: Color) {
let replace = match self.mode().get() {
Mode::Blend => false,
Mode::Overwrite => true,
};
let w = self.width();
let h = self.height();
let data = self.data_mut();
......@@ -57,11 +66,11 @@ pub trait Renderer {
let new = color.data;
let alpha = (new >> 24) & 0xFF;
if alpha > 0 {
//if alpha > 0 {
let old = unsafe{ &mut data[y as usize * w as usize + x as usize].data};
if alpha >= 255 {
if alpha >= 255 || replace {
*old = new;
} else {
} else if alpha >0 {
let n_r = (((new >> 16) & 0xFF) * alpha) >> 8;
let n_g = (((new >> 8) & 0xFF) * alpha) >> 8;
let n_b = ((new & 0xFF) * alpha) >> 8;
......@@ -74,7 +83,7 @@ pub trait Renderer {
*old = ((o_a << 24) | (o_r << 16) | (o_g << 8) | o_b) + ((alpha << 24) | (n_r << 16) | (n_g << 8) | n_b);
}
}
//}
}
}
......@@ -265,8 +274,11 @@ pub trait Renderer {
self.set(Color::rgb(0,0,0));
}
/// Draw rectangle
fn rect(&mut self, x: i32, y: i32, w: u32, h: u32, color: Color) {
let replace = match self.mode().get() {
Mode::Blend => false,
Mode::Overwrite => true,
};
let self_w = self.width();
let self_h = self.height();
......@@ -277,8 +289,8 @@ pub trait Renderer {
let len = cmp::max(start_x, cmp::min(self_w as i32, x + w as i32)) - start_x;
let alpha = (color.data >> 24) & 0xFF;
if alpha > 0 {
if alpha >= 255 {
//if alpha > 0 {
if alpha >= 255 || replace {
let data = self.data_mut();
for y in start_y..end_y {
unsafe {
......@@ -292,20 +304,25 @@ pub trait Renderer {
}
}
}
}
//}
}
/// Display an image
fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
//check if image is inside window
if (w + start_x as u32) > self.width() {
self.image_legacy(start_x, start_y, w, h, data);
} else {
self.image_fast(start_x, start_y, w, h, data);
match self.mode().get() {
Mode::Blend => if (w + start_x as u32) > self.width() {
self.image_legacy(start_x, start_y, w, h, data)
} else {
self.image_fast(start_x, start_y, w, h, data);
},
Mode::Overwrite => self.image_opaque(start_x, start_y, w, h, data),
//and so on with many more modes and implementations....
}
}
// TODO: Improve speed
#[inline(always)]
fn image_legacy(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
let mut i = 0;
for y in start_y..start_y + h as i32 {
......@@ -330,6 +347,7 @@ pub trait Renderer {
}
///Display an image using non transparent method
#[inline(always)]
fn image_opaque (&mut self, start_x: i32, start_y: i32, w: u32, h: u32, image_data: &[Color]) {
let w = w as usize;
let mut h = h as usize;
......@@ -360,6 +378,7 @@ pub trait Renderer {
}
// Speed improved, but image has to be all inside of window boundary
#[inline(always)]
fn image_fast (&mut self, start_x: i32, start_y: i32, w: u32, h: u32, image_data: &[Color]) {
let window_w = self.width() as usize;
let window_len = self.data().len();
......
......@@ -4,11 +4,13 @@ use std::{env, mem, slice, thread};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, RawFd};
use std::cell::Cell;
use color::Color;
use event::{Event, EVENT_RESIZE};
use renderer::Renderer;
use WindowFlag;
use Mode;
pub fn get_display_size() -> Result<(u32, u32), String> {
let display_path = try!(env::var("DISPLAY").or(Err("DISPLAY not set")));
......@@ -42,6 +44,8 @@ pub struct Window {
async: bool,
/// True if the window can be resized
resizable: bool,
/// Drawing mode
mode: Cell<Mode>,
/// The input scheme
file: File,
/// Window data
......@@ -73,6 +77,11 @@ impl Renderer for Window {
fn sync(&mut self) -> bool {
self.file.sync_data().is_ok()
}
/// Set/get mode
fn mode(&self) -> &Cell<Mode> {
&self.mode
}
}
impl Window {
......@@ -116,6 +125,7 @@ impl Window {
t: title.to_string(),
async: async,
resizable: resizable,
mode: Cell::new(Mode::Blend),
file: file,
data: unsafe { slice::from_raw_parts_mut(address as *mut Color, (w * h) as usize) },
})
......
......@@ -2,11 +2,13 @@ extern crate sdl2;
use std::{mem, ptr, slice};
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use std::cell::Cell;
use color::Color;
use event::*;
use renderer::Renderer;
use WindowFlag;
use Mode;
static SDL_USAGES: AtomicUsize = ATOMIC_USIZE_INIT;
/// SDL2 Context
......@@ -48,6 +50,8 @@ pub struct Window {
t: String,
/// True if the window should not wait for events
async: bool,
/// Drawing mode
mode: Cell<Mode>,
/// The inner renderer
inner: sdl2::render::WindowCanvas,
}
......@@ -84,6 +88,11 @@ impl Renderer for Window {
self.inner.present();
true
}
/// Set/get mode
fn mode(&self) -> &Cell<Mode> {
&self.mode
}
}
impl Window {
......@@ -133,6 +142,7 @@ impl Window {
h: h,
t: title.to_string(),
async: async,
mode: Cell::new(Mode::Blend),
inner: window.into_canvas().software().build().unwrap(),
}),
Err(_) => None
......
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