Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Florian Blasius
OrbRender
Commits
639389e8
Commit
639389e8
authored
Dec 28, 2018
by
Florian Blasius
🤘
Browse files
Initial cairo backend. Add runner struct.
parent
6fe4d8fb
Pipeline
#2334
passed with stage
in 3 minutes
Changes
8
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Cargo.lock
View file @
639389e8
This diff is collapsed.
Click to expand it.
Cargo.toml
View file @
639389e8
...
...
@@ -8,10 +8,11 @@ edition = "2018"
stdweb
=
"0.4.12"
[target.'cfg(not(target_arch
=
"wasm32"
))
'.dependencies]
winit
=
"0.18"
glutin
=
"0.19"
gleam
=
"0.6.8"
glium
=
"0.22.0"
euclid
=
"0.19"
webrender
=
{
git
=
"https://github.com/servo/webrender.git"
}
#winit = "0.18"
#glutin = "0.19"
#gleam = "0.6.8"
#glium = "0.22.0"
#euclid = "0.19"
#webrender = { git = "https://github.com/servo/webrender.git" }
rust-cairo
=
{
git
=
"https://gitlab.redox-os.org/redox-os/rust-cairo.git"
}
orbclient
=
{
git
=
"https://gitlab.redox-os.org/redox-os/orbclient.git"
}
\ No newline at end of file
examples/Cargo.lock
View file @
639389e8
This diff is collapsed.
Click to expand it.
examples/drawing/src/main.rs
View file @
639389e8
use
orbrender
;
use
orbrender
::
backend
::
Runner
;
use
orbrender
::
prelude
::
*
;
use
stdweb
;
use
time
::
PreciseTime
;
use
std
::
sync
::
atomic
::{
self
,
AtomicBool
};
use
std
::
sync
::
Arc
;
fn
main
()
{
let
mut
window
=
WindowBuilder
::
new
()
.with_title
(
"OrbRender - drawing example"
)
...
...
@@ -50,41 +55,64 @@ fn main() {
.with_text
(
"OrbRender"
)
.with_position
(
Point
::
new
(
10.0
,
80.0
))
.with_foreground
(
Color
::
rgb
(
100
,
100
,
100
))
.with_font
(
FontConfig
::
default
()
.with_family
(
"Roboto"
)
.with_size
(
22.0
))
.with_font
(
FontConfig
::
default
()
.with_family
(
"Roboto"
)
.with_size
(
22.0
))
,
);
window
.push_image
(
window
.push_image
(
Image
::
default
()
.with_position
(
Point
::
new
(
10.0
,
100.0
))
.with_source
(
"res/orbtk-space.png"
)
.with_source
(
"res/orbtk-space.png"
)
,
);
// let mut draw = false;
let
mut
running
=
true
;
let
mut
update
=
true
;
let
update
=
Arc
::
new
(
AtomicBool
::
new
(
true
));
loop
{
if
!
running
{
break
;
}
// let start = PreciseTime::now();
if
update
{
let
mut
runner
=
Runner
::
new
(
Box
::
new
(
move
||
{
if
update
.load
(
atomic
::
Ordering
::
Acquire
)
{
window
.render
();
update
=
false
;
update
.store
(
false
,
atomic
::
Ordering
::
Release
)
;
}
for
event
in
window
.events
()
{
match
event
{
Event
::
System
(
system_event
)
=>
match
system_event
{
SystemEvent
::
Quit
=>
{
running
=
false
;
//
running = false;
}
_
=>
{}
},
_
=>
{}
}
}
// let end = PreciseTime::now();
// println!("{} seconds for whatever you did.", start.to(end));
}
}));
runner
.run
();
// let mut draw = false;
// let mut running = true;
// let mut update = true;
//
// loop {
// if !running {
// break;
// }
// // let start = PreciseTime::now();
// if update {
// window.render();
// update = false;
// }
//
// for event in window.events() {
// match event {
// Event::System(system_event) => match system_event {
// SystemEvent::Quit => {
// running = false;
// }
// _ => {}
// },
// _ => {}
// }
// }
// // let end = PreciseTime::now();
// // println!("{} seconds for whatever you did.", start.to(end));
// }
}
src/backend/cairo/mod.rs
0 → 100644
View file @
639389e8
use
orbclient
;
use
orbclient
::
Renderer
;
use
rust_cairo
::
*
;
use
std
::
ffi
::
CString
;
use
std
::
os
::
raw
::
c_char
;
use
crate
::{
events
::{
Event
,
SystemEvent
},
render_objects
::{
Image
,
Rectangle
,
RenderStorage
,
Text
},
structs
::
Color
,
traits
::
Window
,
window
::
WindowBuilder
,
};
pub
struct
Runner
{
run
:
Box
<
FnMut
()
>
,
}
impl
Runner
{
pub
fn
new
(
run
:
Box
<
FnMut
()
>
)
->
Self
{
Runner
{
run
}
}
pub
fn
run
(
mut
self
)
{
loop
{
(
self
.run
)();
}
}
}
unsafe
fn
rounded_rect
(
x
:
f64
,
y
:
f64
,
w
:
f64
,
h
:
f64
,
r
:
f64
,
context
:
*
mut
cairo_t
,
color
:
&
Color
,
)
{
let
m_pi
=
3.14159265
;
let
degrees
=
m_pi
/
180.0
;
//draw object
cairo_new_sub_path
(
context
);
cairo_arc
(
context
,
(
x
+
w
-
r
)
as
f64
,
(
y
+
r
)
as
f64
,
(
r
)
as
f64
,
-
90.0
*
degrees
,
0.0
*
degrees
,
);
cairo_arc
(
context
,
(
x
+
w
-
r
)
as
f64
,
(
y
+
h
-
r
)
as
f64
,
(
r
)
as
f64
,
0.0
*
degrees
,
90.0
*
degrees
,
);
cairo_arc
(
context
,
(
x
+
r
)
as
f64
,
(
y
+
h
-
r
)
as
f64
,
(
r
)
as
f64
,
90.0
*
degrees
,
180.0
*
degrees
,
);
cairo_arc
(
context
,
(
x
+
r
)
as
f64
,
(
y
+
r
)
as
f64
,
(
r
)
as
f64
,
180.0
*
degrees
,
270.0
*
degrees
,
);
cairo_close_path
(
context
);
cairo_set_source_rgba
(
context
,
color
.r_f
()
as
f64
,
color
.g_f
()
as
f64
,
color
.b_f
()
as
f64
,
color
.a_f
()
as
f64
,
);
cairo_fill
(
context
);
}
pub
fn
build_window
(
window_builder
:
WindowBuilder
)
->
Box
<
Window
>
{
Box
::
new
(
CairoWindow
::
from
(
window_builder
))
}
pub
fn
initialize
()
{}
/// Backend for Cairo library.
pub
struct
CairoWindow
{
inner_window
:
orbclient
::
Window
,
render_storage
:
RenderStorage
,
background
:
Color
,
cairo_context
:
*
mut
_cairo
,
}
impl
Window
for
CairoWindow
{
fn
render
(
&
mut
self
)
{
// window background
self
.inner_window
.set
(
orbclient
::
Color
::
rgba
(
self
.background
.r
(),
self
.background
.g
(),
self
.background
.b
(),
self
.background
.a
(),
));
for
render_object
in
self
.render_storage
.into_iter
()
{
unsafe
{
// Render rectangles
if
let
Some
(
rectangle
)
=
render_object
.downcast_ref
::
<
Rectangle
>
()
{
let
size
=
rectangle
.size
;
let
position
=
rectangle
.position
;
let
border_thickness
=
rectangle
.border_thickness
;
// Render border
if
border_thickness
.left
>
0.0
||
border_thickness
.top
>
0.0
||
border_thickness
.right
>
0.0
||
border_thickness
.bottom
>
0.0
{
// todo: use border_thickness
if
let
Some
(
border_color
)
=
rectangle
.border_color
{
if
rectangle
.radius
>
0.0
{
rounded_rect
(
position
.x
as
f64
,
position
.y
as
f64
,
size
.width
as
f64
,
size
.height
as
f64
,
rectangle
.radius
as
f64
,
self
.cairo_context
,
&
border_color
,
);
}
else
{
cairo_rectangle
(
self
.cairo_context
,
position
.x
as
f64
,
position
.y
as
f64
,
size
.width
as
f64
,
size
.height
as
f64
);
cairo_set_source_rgba
(
self
.cairo_context
,
border_color
.r_f
()
as
f64
,
border_color
.g_f
()
as
f64
,
border_color
.b_f
()
as
f64
,
border_color
.a_f
()
as
f64
,
);
cairo_fill
(
self
.cairo_context
);
}
}
}
if
let
Some
(
background
)
=
rectangle
.background
{
if
rectangle
.radius
>
0.0
{
rounded_rect
(
(
position
.x
+
border_thickness
.left
)
as
f64
,
(
position
.y
+
border_thickness
.top
)
as
f64
,
(
size
.width
-
border_thickness
.left
-
border_thickness
.right
)
as
f64
,
(
size
.height
-
border_thickness
.top
-
border_thickness
.bottom
)
as
f64
,
rectangle
.radius
as
f64
,
self
.cairo_context
,
&
background
,
);
}
else
{
cairo_rectangle
(
self
.cairo_context
,
(
position
.x
+
border_thickness
.left
)
as
f64
,
(
position
.y
+
border_thickness
.top
)
as
f64
,
(
size
.width
-
border_thickness
.left
-
border_thickness
.right
)
as
f64
,
(
size
.height
-
border_thickness
.top
-
border_thickness
.bottom
)
as
f64
);
cairo_set_source_rgba
(
self
.cairo_context
,
background
.r_f
()
as
f64
,
background
.g_f
()
as
f64
,
background
.b_f
()
as
f64
,
background
.a_f
()
as
f64
,
);
cairo_fill
(
self
.cairo_context
);
}
}
}
if
let
Some
(
tx
)
=
render_object
.downcast_ref
::
<
Text
>
()
{
let
position
=
tx
.position
;
cairo_set_source_rgba
(
self
.cairo_context
,
tx
.foreground
.r_f
()
as
f64
,
tx
.foreground
.g_f
()
as
f64
,
tx
.foreground
.b_f
()
as
f64
,
tx
.foreground
.a_f
()
as
f64
);
let
font
=
CString
::
new
(
tx
.font.family
.clone
())
.expect
(
"CString::new failed"
);
let
text
=
CString
::
new
(
tx
.text
.clone
())
.expect
(
"CString::new failed"
);
cairo_select_font_face
(
self
.cairo_context
,
font
.as_ptr
(),
CAIRO_FONT_SLANT_NORMAL
,
CAIRO_FONT_WEIGHT_NORMAL
);
// if self.text_bold {
// cairo_select_font_face(cr, font.as_ptr(), CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
// }
cairo_set_font_size
(
self
.cairo_context
,
tx
.font.size
as
f64
);
let
mut
text_extens
=
cairo_text_extents_t
{
x_bearing
:
0.0
,
y_bearing
:
0.0
,
width
:
0.0
,
height
:
0.0
,
x_advance
:
0.0
,
y_advance
:
0.0
,
};
cairo_text_extents
(
self
.cairo_context
,
text
.as_ptr
(),
&
mut
text_extens
as
*
mut
cairo_text_extents_t
);
cairo_move_to
(
self
.cairo_context
,
position
.x
as
f64
,
position
.y
as
f64
);
cairo_show_text
(
self
.cairo_context
,
text
.as_ptr
());
}
if
let
Some
(
img
)
=
render_object
.downcast_ref
::
<
Image
>
()
{
// cairo_new_sub_path(self.cairo_context);
// let image = Image::from_path(img.source);
// let c_image = cairo_image_surface_create_for_data()
// cairo_set_source_surface(self.cairo_context, )
}
}
}
self
.inner_window
.sync
();
}
fn
background
(
&
mut
self
,
background
:
Color
)
{
self
.background
=
background
;
}
fn
push_rectangle_with_z
(
&
mut
self
,
rectangle
:
Rectangle
,
z
:
usize
)
->
usize
{
self
.render_storage
.push_with_z
(
rectangle
,
z
)
}
fn
push_text_with_z
(
&
mut
self
,
text
:
Text
,
z
:
usize
)
->
usize
{
self
.render_storage
.push_with_z
(
text
,
z
)
}
fn
push_image_with_z
(
&
mut
self
,
image
:
Image
,
z
:
usize
)
->
usize
{
self
.render_storage
.push_with_z
(
image
,
z
)
}
fn
remove_render_objet
(
&
mut
self
,
index
:
usize
)
{
self
.render_storage
.remove
(
index
);
}
fn
clear
(
&
mut
self
)
{
self
.render_storage
.clear
();
}
fn
events
(
&
mut
self
)
->
Vec
<
Event
>
{
let
mut
events
=
vec!
[];
for
event
in
self
.inner_window
.events
()
{
match
event
.to_option
()
{
orbclient
::
EventOption
::
Quit
(
_
)
=>
{
events
.push
(
Event
::
System
(
SystemEvent
::
Quit
));
}
_
=>
{}
}
}
events
}
}
impl
From
<
WindowBuilder
>
for
CairoWindow
{
fn
from
(
builder
:
WindowBuilder
)
->
CairoWindow
{
let
mut
flags
=
vec!
[];
if
builder
.transparent
{
flags
.push
(
orbclient
::
WindowFlag
::
Transparent
);
}
if
!
builder
.decorations
{
flags
.push
(
orbclient
::
WindowFlag
::
Borderless
);
}
let
mut
inner_window
=
orbclient
::
Window
::
new_flags
(
0
,
0
,
builder
.size.width
as
u32
,
builder
.size.height
as
u32
,
&
builder
.title
[
..
],
&
flags
,
)
.unwrap
();
let
mut
cr
;
unsafe
{
let
surface
=
cairo_image_surface_create_for_data
(
inner_window
.data_mut
()
.as_mut_ptr
()
as
*
mut
u8
,
CAIRO_FORMAT_ARGB32
,
builder
.size.width
as
i32
,
builder
.size.height
as
i32
,
cairo_format_stride_for_width
(
CAIRO_FORMAT_ARGB32
,
builder
.size.width
as
i32
),
);
cr
=
cairo_create
(
surface
);
//WHY I DO THIS?????
//The Answer -> https://mobtowers.com/2013/04/15/html5-canvas-crisp-lines-every-time/
// cairo_translate(cr, 0.5, 0.5);
}
CairoWindow
{
inner_window
,
render_storage
:
RenderStorage
::
default
(),
background
:
builder
.background
,
cairo_context
:
cr
,
}
}
}
src/backend/mod.rs
View file @
639389e8
#[cfg(target_arch
=
"wasm32"
)]
pub
use
self
::
stdweb
::{
build_window
,
initialize
};
pub
use
self
::
stdweb
::{
build_window
,
initialize
,
Runner
};
#[cfg(target_arch
=
"wasm32"
)]
mod
stdweb
;
#[cfg(not(target_arch
=
"wasm32"
))]
pub
use
self
::
orbclient
::{
build_window
,
initialize
};
pub
use
self
::
cairo
::{
build_window
,
initialize
,
Runner
};
#[cfg(not(target_arch
=
"wasm32"
))]
mod
orbclient
;
\ No newline at end of file
mod
cairo
;
////
//#[cfg(not(target_arch = "wasm32"))]
//pub use self::orbclient::{build_window, initialize};
//
//#[cfg(not(target_arch = "wasm32"))]
//mod orbclient;
////#[cfg(feature="webren")]
//pub use self::webrender::{build_window, initialize};
//
////#[cfg(feature="webren")]
//mod webrender;
\ No newline at end of file
src/backend/stdweb/mod.rs
View file @
639389e8
...
...
@@ -5,6 +5,23 @@ use stdweb::{
web
::{
document
,
html_element
::{
CanvasElement
,
ImageElement
},
window
,
CanvasRenderingContext2d
,
FillRule
},
};
pub
struct
Runner
{
run
:
Box
<
FnMut
()
>
,
}
impl
Runner
{
pub
fn
new
(
run
:
Box
<
FnMut
()
>
)
->
Self
{
Runner
{
run
}
}
pub
fn
run
(
mut
self
)
{
(
self
.run
)();
window
()
.request_animation_frame
(|
_
|
self
.run
());
}
}
// Shamelessly stolen from webplatform's TodoMVC example.
macro_rules!
enclose
{
(
(
$
(
$x:ident
),
*
)
$y:expr
)
=>
{
...
...
@@ -186,7 +203,7 @@ impl Window for StdWebWindow {
}
fn
events
(
&
mut
self
)
->
Vec
<
Event
>
{
stdweb
::
event_loop
();
vec!
[
Event
::
System
(
SystemEvent
::
Quit
)]
}
}
...
...
@@ -206,6 +223,8 @@ impl From<WindowBuilder> for StdWebWindow {
canvas
.set_width
(
builder
.size.width
as
u32
);
canvas
.set_height
(
builder
.size.height
as
u32
);
stdweb
::
event_loop
();
StdWebWindow
{
canvas
,
context
,
...
...
src/backend/webrender/mod.rs
View file @
639389e8
...
...
@@ -15,12 +15,14 @@ use winit;
use
crate
::{
enums
::
WindowMode
,
events
::{
Event
as
OrbEvent
,
SystemEvent
},
render_objects
::{
Rectangle
,
RenderStorage
},
render_objects
::{
Rectangle
,
Text
,
RenderStorage
,
Image
},
structs
::
Color
,
traits
::
Window
,
window
::
WindowBuilder
,
};
pub
fn
initialize
()
{}
pub
fn
build_window
(
window_builder
:
WindowBuilder
)
->
Box
<
Window
>
{
Box
::
new
(
WebRenderWindow
::
from
(
window_builder
))
}
...
...
@@ -251,8 +253,12 @@ impl Window for WebRenderWindow {
self
.render_storage
.push_with_z
(
rectangle
,
z
)
}
fn
push_rectangle
(
&
mut
self
,
rectangle
:
Rectangle
)
->
usize
{
self
.render_storage
.push_with_z
(
rectangle
,
0
)
fn
push_text_with_z
(
&
mut
self
,
text
:
Text
,
z
:
usize
)
->
usize
{
self
.render_storage
.push_with_z
(
text
,
z
)
}
fn
push_image_with_z
(
&
mut
self
,
image
:
Image
,
z
:
usize
)
->
usize
{
self
.render_storage
.push_with_z
(
image
,
z
)
}
fn
remove_render_objet
(
&
mut
self
,
index
:
usize
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment