mirror of
https://github.com/servo/servo.git
synced 2025-08-10 16:05:43 +01:00
Extract RenderContext from render_task
This commit is contained in:
parent
6bfa2254a0
commit
0c8886f6f6
8 changed files with 254 additions and 244 deletions
|
@ -1,5 +1,16 @@
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use gfx::render_task::LayerBuffer;
|
use azure::cairo_hl::ImageSurface;
|
||||||
|
use azure::azure_hl::{DrawTarget};
|
||||||
|
use geom::size::Size2D;
|
||||||
|
|
||||||
|
struct LayerBuffer {
|
||||||
|
// TODO: We should not be coupled to Cairo this tightly. Instead we should pull the buffer out
|
||||||
|
// of the draw target with the Azure API.
|
||||||
|
cairo_surface: ImageSurface,
|
||||||
|
|
||||||
|
draw_target: DrawTarget,
|
||||||
|
size: Size2D<uint>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The interface used to by the renderer to aquire draw targets for
|
The interface used to by the renderer to aquire draw targets for
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use azure::azure_hl::DrawTarget;
|
use azure::azure_hl::DrawTarget;
|
||||||
use gfx::render_task::{draw_solid_color, draw_image, draw_text, draw_border};
|
|
||||||
use gfx::geometry::*;
|
use gfx::geometry::*;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use image::base::Image;
|
use image::base::Image;
|
||||||
use render_task::RenderContext;
|
use render_context::RenderContext;
|
||||||
use servo_text::text_run;
|
use servo_text::text_run;
|
||||||
|
|
||||||
use std::arc::ARC;
|
use std::arc::ARC;
|
||||||
|
@ -32,7 +31,7 @@ pub enum DisplayItemData {
|
||||||
|
|
||||||
fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) {
|
fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
match self.data {
|
match self.data {
|
||||||
SolidColorData(r,g,b) => draw_solid_color(ctx, &self.bounds, r, g, b),
|
SolidColorData(r,g,b) => ctx.draw_solid_color(&self.bounds, r, g, b),
|
||||||
_ => fail
|
_ => fail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ fn draw_Text(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
match self.data {
|
match self.data {
|
||||||
TextData(run, offset, len) => {
|
TextData(run, offset, len) => {
|
||||||
let new_run = text_run::deserialize(ctx.font_cache, run);
|
let new_run = text_run::deserialize(ctx.font_cache, run);
|
||||||
draw_text(ctx, self.bounds, new_run, offset, len)
|
ctx.draw_text(self.bounds, new_run, offset, len)
|
||||||
},
|
},
|
||||||
_ => fail
|
_ => fail
|
||||||
}
|
}
|
||||||
|
@ -49,14 +48,14 @@ fn draw_Text(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
|
|
||||||
fn draw_Image(self: &DisplayItem, ctx: &RenderContext) {
|
fn draw_Image(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
match self.data {
|
match self.data {
|
||||||
ImageData(ref img) => draw_image(ctx, self.bounds, clone_arc(img)),
|
ImageData(ref img) => ctx.draw_image(self.bounds, clone_arc(img)),
|
||||||
_ => fail
|
_ => fail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_Border(self: &DisplayItem, ctx: &RenderContext) {
|
fn draw_Border(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
match self.data {
|
match self.data {
|
||||||
BorderData(width, r, g, b) => draw_border(ctx, &self.bounds, width, r, g, b),
|
BorderData(width, r, g, b) => ctx.draw_border(&self.bounds, width, r, g, b),
|
||||||
_ => fail
|
_ => fail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use dvec::DVec;
|
||||||
use display_list::DisplayList;
|
use display_list::DisplayList;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use core::io::BytesWriter;
|
use core::io::BytesWriter;
|
||||||
use gfx::render_task::LayerBuffer;
|
use gfx::compositor::LayerBuffer;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use gfx::render_layers::RenderLayer;
|
use gfx::render_layers::RenderLayer;
|
||||||
|
|
||||||
|
|
231
src/servo/gfx/render_context.rs
Normal file
231
src/servo/gfx/render_context.rs
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
use mod au = geometry;
|
||||||
|
|
||||||
|
use compositor::LayerBuffer;
|
||||||
|
use text::font::Font;
|
||||||
|
use text::text_run::TextRun;
|
||||||
|
use text::font_cache::FontCache;
|
||||||
|
use image::base::Image;
|
||||||
|
use au = au::au;
|
||||||
|
|
||||||
|
use core::libc::types::common::c99::uint16_t;
|
||||||
|
use core::ptr::to_unsafe_ptr;
|
||||||
|
use core::dvec::DVec;
|
||||||
|
use std::arc::ARC;
|
||||||
|
use geom::size::Size2D;
|
||||||
|
use geom::point::Point2D;
|
||||||
|
use geom::rect::Rect;
|
||||||
|
use azure::bindgen::AzDrawTargetFillGlyphs;
|
||||||
|
use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t};
|
||||||
|
use azure::cairo_hl::ImageSurface;
|
||||||
|
use azure::{AzDrawOptions, AzFloat, AzGlyph, AzGlyphBuffer};
|
||||||
|
use azure::azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions, DrawSurfaceOptions, StrokeOptions};
|
||||||
|
use azure::azure_hl::{DrawTarget, Linear};
|
||||||
|
|
||||||
|
struct RenderContext {
|
||||||
|
canvas: &LayerBuffer,
|
||||||
|
font_cache: @FontCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderContext {
|
||||||
|
pub fn draw_solid_color(&self, bounds: &Rect<au>, r: u8, g: u8, b: u8) {
|
||||||
|
let color = Color(r.to_float() as AzFloat,
|
||||||
|
g.to_float() as AzFloat,
|
||||||
|
b.to_float() as AzFloat,
|
||||||
|
1f as AzFloat);
|
||||||
|
|
||||||
|
self.canvas.draw_target.fill_rect(&bounds.to_azure_rect(), &ColorPattern(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_border(&self, bounds: &Rect<au>, width: au, r: u8, g: u8, b: u8) {
|
||||||
|
let rect = bounds.to_azure_rect();
|
||||||
|
let color = Color(r.to_float() as AzFloat,
|
||||||
|
g.to_float() as AzFloat,
|
||||||
|
b.to_float() as AzFloat,
|
||||||
|
1f as AzFloat);
|
||||||
|
let pattern = ColorPattern(color);
|
||||||
|
let stroke_fields = 2; // CAP_SQUARE
|
||||||
|
let stroke_opts = StrokeOptions(au::to_px(width) as AzFloat, 10 as AzFloat, stroke_fields);
|
||||||
|
let draw_opts = DrawOptions(1 as AzFloat, 0 as uint16_t);
|
||||||
|
|
||||||
|
self.canvas.draw_target.stroke_rect(&rect, &pattern, &stroke_opts, &draw_opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_image(&self, bounds: Rect<au>, image: ARC<~Image>) {
|
||||||
|
let image = std::arc::get(&image);
|
||||||
|
let size = Size2D(image.width as i32, image.height as i32);
|
||||||
|
let stride = image.width * 4;
|
||||||
|
|
||||||
|
let draw_target_ref = &self.canvas.draw_target;
|
||||||
|
let azure_surface = draw_target_ref.create_source_surface_from_data(image.data, size,
|
||||||
|
stride as i32, B8G8R8A8);
|
||||||
|
let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
||||||
|
Size2D(image.width as AzFloat, image.height as AzFloat));
|
||||||
|
let dest_rect = bounds.to_azure_rect();
|
||||||
|
let draw_surface_options = DrawSurfaceOptions(Linear, true);
|
||||||
|
let draw_options = DrawOptions(1.0f as AzFloat, 0);
|
||||||
|
draw_target_ref.draw_surface(azure_surface, dest_rect, source_rect, draw_surface_options,
|
||||||
|
draw_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_text(&self, bounds: Rect<au>, run: &TextRun, offset: uint, length: uint) {
|
||||||
|
use ptr::{null};
|
||||||
|
use vec::raw::to_ptr;
|
||||||
|
use libc::types::common::c99::{uint16_t, uint32_t};
|
||||||
|
use geom::point::Point2D;
|
||||||
|
use text::font_cache::FontCache;
|
||||||
|
use text::font::Font;
|
||||||
|
use azure::{AzNativeFont, AzFloat, AZ_NATIVE_FONT_CAIRO_FONT_FACE};
|
||||||
|
use azure::bindgen::{AzCreateScaledFontWithCairo,
|
||||||
|
AzReleaseScaledFont,
|
||||||
|
AzCreateColorPattern,
|
||||||
|
AzReleaseColorPattern};
|
||||||
|
use azure::cairo::bindgen::cairo_scaled_font_destroy;
|
||||||
|
|
||||||
|
let font = run.font;
|
||||||
|
|
||||||
|
let nfont: AzNativeFont = {
|
||||||
|
mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
|
||||||
|
mFont: null()
|
||||||
|
};
|
||||||
|
|
||||||
|
let cfont = get_cairo_font(font);
|
||||||
|
let azfont = AzCreateScaledFontWithCairo(to_unsafe_ptr(&nfont), 1f as AzFloat, cfont);
|
||||||
|
assert azfont.is_not_null();
|
||||||
|
cairo_scaled_font_destroy(cfont);
|
||||||
|
|
||||||
|
let color = {
|
||||||
|
r: 0f as AzFloat,
|
||||||
|
g: 0f as AzFloat,
|
||||||
|
b: 0f as AzFloat,
|
||||||
|
a: 1f as AzFloat
|
||||||
|
};
|
||||||
|
let pattern = AzCreateColorPattern(to_unsafe_ptr(&color));
|
||||||
|
assert pattern.is_not_null();
|
||||||
|
|
||||||
|
let options: AzDrawOptions = {
|
||||||
|
mAlpha: 1f as AzFloat,
|
||||||
|
fields: 0 as uint16_t
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut origin = Point2D(bounds.origin.x, bounds.origin.y.add(&bounds.size.height));
|
||||||
|
let azglyphs = DVec();
|
||||||
|
azglyphs.reserve(length);
|
||||||
|
|
||||||
|
do run.glyphs.iter_glyphs_for_range(offset, length) |_i, glyph| {
|
||||||
|
let glyph_advance = glyph.advance();
|
||||||
|
let glyph_offset = glyph.offset().get_default(au::zero_point());
|
||||||
|
|
||||||
|
let azglyph: AzGlyph = {
|
||||||
|
mIndex: glyph.index() as uint32_t,
|
||||||
|
mPosition: {
|
||||||
|
x: au::to_px(origin.x + glyph_offset.x) as AzFloat,
|
||||||
|
y: au::to_px(origin.y + glyph_offset.y) as AzFloat
|
||||||
|
}
|
||||||
|
};
|
||||||
|
origin = Point2D(origin.x + glyph_advance, origin.y);
|
||||||
|
azglyphs.push(move azglyph)
|
||||||
|
};
|
||||||
|
|
||||||
|
let azglyph_buf_len = azglyphs.len();
|
||||||
|
let azglyph_buf = dvec::unwrap(move azglyphs);
|
||||||
|
let glyphbuf: AzGlyphBuffer = unsafe {{
|
||||||
|
mGlyphs: to_ptr(azglyph_buf),
|
||||||
|
mNumGlyphs: azglyph_buf_len as uint32_t
|
||||||
|
}};
|
||||||
|
|
||||||
|
// TODO: this call needs to move into azure_hl.rs
|
||||||
|
AzDrawTargetFillGlyphs(self.canvas.draw_target.azure_draw_target, azfont,
|
||||||
|
to_unsafe_ptr(&glyphbuf), pattern, to_unsafe_ptr(&options), null());
|
||||||
|
|
||||||
|
AzReleaseColorPattern(pattern);
|
||||||
|
AzReleaseScaledFont(azfont);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&self) {
|
||||||
|
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
|
||||||
|
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
||||||
|
Size2D(self.canvas.size.width as AzFloat, self.canvas.size.height as AzFloat));
|
||||||
|
self.canvas.draw_target.fill_rect(&rect, &pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait to_float {
|
||||||
|
fn to_float() -> float;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl u8 : to_float {
|
||||||
|
fn to_float() -> float {
|
||||||
|
(self as float) / 255f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ToAzureRect {
|
||||||
|
fn to_azure_rect() -> Rect<AzFloat>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rect<au> : ToAzureRect {
|
||||||
|
fn to_azure_rect() -> Rect<AzFloat> {
|
||||||
|
Rect(Point2D(au::to_px(self.origin.x) as AzFloat, au::to_px(self.origin.y) as AzFloat),
|
||||||
|
Size2D(au::to_px(self.size.width) as AzFloat, au::to_px(self.size.height) as AzFloat))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
|
||||||
|
|
||||||
|
use libc::c_int;
|
||||||
|
use azure::cairo_ft::bindgen::{cairo_ft_font_face_create_for_ft_face};
|
||||||
|
|
||||||
|
let ftface = font.native_font.face;
|
||||||
|
let cface = cairo_ft_font_face_create_for_ft_face(ftface, 0 as c_int);
|
||||||
|
// FIXME: error handling
|
||||||
|
return cface;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
|
||||||
|
use azure::cairo_quartz::bindgen::cairo_quartz_font_face_create_for_cgfont;
|
||||||
|
|
||||||
|
let cgfont = font.native_font.cgfont;
|
||||||
|
let face = cairo_quartz_font_face_create_for_cgfont(cgfont);
|
||||||
|
// FIXME: error handling
|
||||||
|
return face;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
|
||||||
|
|
||||||
|
use libc::c_double;
|
||||||
|
use azure::cairo;
|
||||||
|
use cairo::cairo_matrix_t;
|
||||||
|
use cairo::bindgen::{cairo_matrix_init_identity,
|
||||||
|
cairo_matrix_scale,
|
||||||
|
cairo_font_options_create,
|
||||||
|
cairo_scaled_font_create,
|
||||||
|
cairo_font_options_destroy,
|
||||||
|
cairo_font_face_destroy};
|
||||||
|
|
||||||
|
// FIXME: error handling
|
||||||
|
|
||||||
|
let face = get_cairo_face(font);
|
||||||
|
|
||||||
|
let idmatrix: cairo_matrix_t = {
|
||||||
|
xx: 0 as c_double,
|
||||||
|
yx: 0 as c_double,
|
||||||
|
xy: 0 as c_double,
|
||||||
|
yy: 0 as c_double,
|
||||||
|
x0: 0 as c_double,
|
||||||
|
y0: 0 as c_double
|
||||||
|
};
|
||||||
|
cairo_matrix_init_identity(to_unsafe_ptr(&idmatrix));
|
||||||
|
|
||||||
|
let fontmatrix = idmatrix;
|
||||||
|
cairo_matrix_scale(to_unsafe_ptr(&fontmatrix), 20f as c_double, 20f as c_double);
|
||||||
|
let options = cairo_font_options_create();
|
||||||
|
let cfont = cairo_scaled_font_create(face, to_unsafe_ptr(&fontmatrix),
|
||||||
|
to_unsafe_ptr(&idmatrix), options);
|
||||||
|
cairo_font_options_destroy(options);
|
||||||
|
cairo_font_face_destroy(face);
|
||||||
|
|
||||||
|
return cfont;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use gfx::display_list::DisplayList;
|
use gfx::display_list::DisplayList;
|
||||||
use gfx::render_task::LayerBuffer;
|
use gfx::compositor::LayerBuffer;
|
||||||
|
|
||||||
use azure::azure_hl::DrawTarget;
|
use azure::azure_hl::DrawTarget;
|
||||||
use azure::cairo::CAIRO_FORMAT_RGB24;
|
use azure::cairo::CAIRO_FORMAT_RGB24;
|
||||||
|
|
|
@ -1,33 +1,17 @@
|
||||||
use mod azure::azure_hl;
|
|
||||||
|
|
||||||
use au = gfx::geometry;
|
use au = gfx::geometry;
|
||||||
use au::au;
|
use au::au;
|
||||||
use azure::bindgen::AzDrawTargetFillGlyphs;
|
|
||||||
use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t};
|
|
||||||
use azure::cairo_hl::ImageSurface;
|
|
||||||
use azure::{AzDrawOptions, AzFloat, AzGlyph, AzGlyphBuffer};
|
|
||||||
use azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions, DrawSurfaceOptions, StrokeOptions};
|
|
||||||
use azure_hl::{DrawTarget, Linear};
|
|
||||||
use comm::*;
|
use comm::*;
|
||||||
use compositor::Compositor;
|
use compositor::Compositor;
|
||||||
use core::dvec::DVec;
|
|
||||||
use dl = display_list;
|
use dl = display_list;
|
||||||
use geom::point::Point2D;
|
|
||||||
use geom::rect::Rect;
|
|
||||||
use geom::size::Size2D;
|
|
||||||
use mod gfx::render_layers;
|
use mod gfx::render_layers;
|
||||||
use gfx::render_layers::RenderLayer;
|
use gfx::render_layers::RenderLayer;
|
||||||
use image::base::Image;
|
|
||||||
use libc::size_t;
|
use libc::size_t;
|
||||||
use libc::types::common::c99::uint16_t;
|
use libc::types::common::c99::uint16_t;
|
||||||
use pipes::{Port, Chan};
|
use pipes::{Port, Chan};
|
||||||
use platform::osmain;
|
use platform::osmain;
|
||||||
use ptr::to_unsafe_ptr;
|
|
||||||
use std::arc::ARC;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use text::text_run::TextRun;
|
|
||||||
use text::font::Font;
|
|
||||||
use text::font_cache::FontCache;
|
use text::font_cache::FontCache;
|
||||||
|
use render_context::RenderContext;
|
||||||
|
|
||||||
pub type Renderer = comm::Chan<Msg>;
|
pub type Renderer = comm::Chan<Msg>;
|
||||||
|
|
||||||
|
@ -36,20 +20,6 @@ pub enum Msg {
|
||||||
ExitMsg(pipes::Chan<()>)
|
ExitMsg(pipes::Chan<()>)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LayerBuffer {
|
|
||||||
// TODO: We should not be coupled to Cairo this tightly. Instead we should pull the buffer out
|
|
||||||
// of the draw target with the Azure API.
|
|
||||||
cairo_surface: ImageSurface,
|
|
||||||
|
|
||||||
draw_target: DrawTarget,
|
|
||||||
size: Size2D<uint>
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderContext {
|
|
||||||
canvas: &LayerBuffer,
|
|
||||||
font_cache: @FontCache,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type RenderTask = comm::Chan<Msg>;
|
pub type RenderTask = comm::Chan<Msg>;
|
||||||
|
|
||||||
pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
|
pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
|
||||||
|
@ -95,7 +65,7 @@ pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
|
||||||
font_cache: font_cache
|
font_cache: font_cache
|
||||||
};
|
};
|
||||||
|
|
||||||
clear(&ctx);
|
ctx.clear();
|
||||||
render_layer.display_list.draw(&ctx);
|
render_layer.display_list.draw(&ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,204 +81,3 @@ pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait to_float {
|
|
||||||
fn to_float() -> float;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl u8 : to_float {
|
|
||||||
fn to_float() -> float {
|
|
||||||
(self as float) / 255f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ToAzureRect {
|
|
||||||
fn to_azure_rect() -> Rect<AzFloat>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rect<au> : ToAzureRect {
|
|
||||||
fn to_azure_rect() -> Rect<AzFloat> {
|
|
||||||
Rect(Point2D(au::to_px(self.origin.x) as AzFloat, au::to_px(self.origin.y) as AzFloat),
|
|
||||||
Size2D(au::to_px(self.size.width) as AzFloat, au::to_px(self.size.height) as AzFloat))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_solid_color(ctx: &RenderContext, bounds: &Rect<au>, r: u8, g: u8, b: u8) {
|
|
||||||
let color = Color(r.to_float() as AzFloat,
|
|
||||||
g.to_float() as AzFloat,
|
|
||||||
b.to_float() as AzFloat,
|
|
||||||
1f as AzFloat);
|
|
||||||
|
|
||||||
ctx.canvas.draw_target.fill_rect(&bounds.to_azure_rect(), &ColorPattern(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_border(ctx: &RenderContext, bounds: &Rect<au>, width: au, r: u8, g: u8, b: u8) {
|
|
||||||
let rect = bounds.to_azure_rect();
|
|
||||||
let color = Color(r.to_float() as AzFloat,
|
|
||||||
g.to_float() as AzFloat,
|
|
||||||
b.to_float() as AzFloat,
|
|
||||||
1f as AzFloat);
|
|
||||||
let pattern = ColorPattern(color);
|
|
||||||
let stroke_fields = 2; // CAP_SQUARE
|
|
||||||
let stroke_opts = StrokeOptions(au::to_px(width) as AzFloat, 10 as AzFloat, stroke_fields);
|
|
||||||
let draw_opts = DrawOptions(1 as AzFloat, 0 as uint16_t);
|
|
||||||
|
|
||||||
ctx.canvas.draw_target.stroke_rect(&rect, &pattern, &stroke_opts, &draw_opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_image(ctx: &RenderContext, bounds: Rect<au>, image: ARC<~Image>) {
|
|
||||||
let image = std::arc::get(&image);
|
|
||||||
let size = Size2D(image.width as i32, image.height as i32);
|
|
||||||
let stride = image.width * 4;
|
|
||||||
|
|
||||||
let draw_target_ref = &ctx.canvas.draw_target;
|
|
||||||
let azure_surface = draw_target_ref.create_source_surface_from_data(image.data, size,
|
|
||||||
stride as i32, B8G8R8A8);
|
|
||||||
let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
|
||||||
Size2D(image.width as AzFloat, image.height as AzFloat));
|
|
||||||
let dest_rect = bounds.to_azure_rect();
|
|
||||||
let draw_surface_options = DrawSurfaceOptions(Linear, true);
|
|
||||||
let draw_options = DrawOptions(1.0f as AzFloat, 0);
|
|
||||||
draw_target_ref.draw_surface(azure_surface, dest_rect, source_rect, draw_surface_options,
|
|
||||||
draw_options);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_text(ctx: &RenderContext, bounds: Rect<au>, run: &TextRun, offset: uint, length: uint) {
|
|
||||||
use ptr::{null};
|
|
||||||
use vec::raw::to_ptr;
|
|
||||||
use libc::types::common::c99::{uint16_t, uint32_t};
|
|
||||||
use geom::point::Point2D;
|
|
||||||
use text::font_cache::FontCache;
|
|
||||||
use text::font::Font;
|
|
||||||
use azure::{AzNativeFont, AzFloat, AZ_NATIVE_FONT_CAIRO_FONT_FACE};
|
|
||||||
use azure::bindgen::{AzCreateScaledFontWithCairo,
|
|
||||||
AzReleaseScaledFont,
|
|
||||||
AzCreateColorPattern,
|
|
||||||
AzReleaseColorPattern};
|
|
||||||
use azure::cairo::bindgen::cairo_scaled_font_destroy;
|
|
||||||
|
|
||||||
let font = run.font;
|
|
||||||
|
|
||||||
let nfont: AzNativeFont = {
|
|
||||||
mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
|
|
||||||
mFont: null()
|
|
||||||
};
|
|
||||||
|
|
||||||
let cfont = get_cairo_font(font);
|
|
||||||
let azfont = AzCreateScaledFontWithCairo(to_unsafe_ptr(&nfont), 1f as AzFloat, cfont);
|
|
||||||
assert azfont.is_not_null();
|
|
||||||
cairo_scaled_font_destroy(cfont);
|
|
||||||
|
|
||||||
let color = {
|
|
||||||
r: 0f as AzFloat,
|
|
||||||
g: 0f as AzFloat,
|
|
||||||
b: 0f as AzFloat,
|
|
||||||
a: 1f as AzFloat
|
|
||||||
};
|
|
||||||
let pattern = AzCreateColorPattern(to_unsafe_ptr(&color));
|
|
||||||
assert pattern.is_not_null();
|
|
||||||
|
|
||||||
let options: AzDrawOptions = {
|
|
||||||
mAlpha: 1f as AzFloat,
|
|
||||||
fields: 0 as uint16_t
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut origin = Point2D(bounds.origin.x, bounds.origin.y.add(&bounds.size.height));
|
|
||||||
let azglyphs = DVec();
|
|
||||||
azglyphs.reserve(length);
|
|
||||||
|
|
||||||
do run.glyphs.iter_glyphs_for_range(offset, length) |_i, glyph| {
|
|
||||||
let glyph_advance = glyph.advance();
|
|
||||||
let glyph_offset = glyph.offset().get_default(au::zero_point());
|
|
||||||
|
|
||||||
let azglyph: AzGlyph = {
|
|
||||||
mIndex: glyph.index() as uint32_t,
|
|
||||||
mPosition: {
|
|
||||||
x: au::to_px(origin.x + glyph_offset.x) as AzFloat,
|
|
||||||
y: au::to_px(origin.y + glyph_offset.y) as AzFloat
|
|
||||||
}
|
|
||||||
};
|
|
||||||
origin = Point2D(origin.x + glyph_advance, origin.y);
|
|
||||||
azglyphs.push(move azglyph)
|
|
||||||
};
|
|
||||||
|
|
||||||
let azglyph_buf_len = azglyphs.len();
|
|
||||||
let azglyph_buf = dvec::unwrap(move azglyphs);
|
|
||||||
let glyphbuf: AzGlyphBuffer = unsafe {{
|
|
||||||
mGlyphs: to_ptr(azglyph_buf),
|
|
||||||
mNumGlyphs: azglyph_buf_len as uint32_t
|
|
||||||
}};
|
|
||||||
|
|
||||||
// TODO: this call needs to move into azure_hl.rs
|
|
||||||
AzDrawTargetFillGlyphs(ctx.canvas.draw_target.azure_draw_target, azfont,
|
|
||||||
to_unsafe_ptr(&glyphbuf), pattern, to_unsafe_ptr(&options), null());
|
|
||||||
|
|
||||||
AzReleaseColorPattern(pattern);
|
|
||||||
AzReleaseScaledFont(azfont);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
|
|
||||||
|
|
||||||
use libc::c_int;
|
|
||||||
use azure::cairo_ft::bindgen::{cairo_ft_font_face_create_for_ft_face};
|
|
||||||
|
|
||||||
let ftface = font.native_font.face;
|
|
||||||
let cface = cairo_ft_font_face_create_for_ft_face(ftface, 0 as c_int);
|
|
||||||
// FIXME: error handling
|
|
||||||
return cface;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
|
|
||||||
use azure::cairo_quartz::bindgen::cairo_quartz_font_face_create_for_cgfont;
|
|
||||||
|
|
||||||
let cgfont = font.native_font.cgfont;
|
|
||||||
let face = cairo_quartz_font_face_create_for_cgfont(cgfont);
|
|
||||||
// FIXME: error handling
|
|
||||||
return face;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
|
|
||||||
|
|
||||||
use libc::c_double;
|
|
||||||
use azure::cairo;
|
|
||||||
use cairo::cairo_matrix_t;
|
|
||||||
use cairo::bindgen::{cairo_matrix_init_identity,
|
|
||||||
cairo_matrix_scale,
|
|
||||||
cairo_font_options_create,
|
|
||||||
cairo_scaled_font_create,
|
|
||||||
cairo_font_options_destroy,
|
|
||||||
cairo_font_face_destroy};
|
|
||||||
|
|
||||||
// FIXME: error handling
|
|
||||||
|
|
||||||
let face = get_cairo_face(font);
|
|
||||||
|
|
||||||
let idmatrix: cairo_matrix_t = {
|
|
||||||
xx: 0 as c_double,
|
|
||||||
yx: 0 as c_double,
|
|
||||||
xy: 0 as c_double,
|
|
||||||
yy: 0 as c_double,
|
|
||||||
x0: 0 as c_double,
|
|
||||||
y0: 0 as c_double
|
|
||||||
};
|
|
||||||
cairo_matrix_init_identity(to_unsafe_ptr(&idmatrix));
|
|
||||||
|
|
||||||
let fontmatrix = idmatrix;
|
|
||||||
cairo_matrix_scale(to_unsafe_ptr(&fontmatrix), 20f as c_double, 20f as c_double);
|
|
||||||
let options = cairo_font_options_create();
|
|
||||||
let cfont = cairo_scaled_font_create(face, to_unsafe_ptr(&fontmatrix),
|
|
||||||
to_unsafe_ptr(&idmatrix), options);
|
|
||||||
cairo_font_options_destroy(options);
|
|
||||||
cairo_font_face_destroy(face);
|
|
||||||
|
|
||||||
return cfont;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear(ctx: &RenderContext) {
|
|
||||||
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
|
|
||||||
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
|
||||||
Size2D(ctx.canvas.size.width as AzFloat, ctx.canvas.size.height as AzFloat));
|
|
||||||
ctx.canvas.draw_target.fill_rect(&rect, &pattern);
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,8 +4,7 @@ use azure::cairo;
|
||||||
use azure::cairo_hl::ImageSurface;
|
use azure::cairo_hl::ImageSurface;
|
||||||
use dvec::DVec;
|
use dvec::DVec;
|
||||||
use azure::cairo::cairo_surface_t;
|
use azure::cairo::cairo_surface_t;
|
||||||
use gfx::compositor::Compositor;
|
use gfx::compositor::{LayerBuffer, Compositor};
|
||||||
use gfx::render_task::LayerBuffer;
|
|
||||||
use dom::event::{Event, ResizeEvent};
|
use dom::event::{Event, ResizeEvent};
|
||||||
use layers::ImageLayer;
|
use layers::ImageLayer;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
|
|
|
@ -78,6 +78,7 @@ pub mod gfx {
|
||||||
pub mod png_compositor;
|
pub mod png_compositor;
|
||||||
pub mod display_list;
|
pub mod display_list;
|
||||||
pub mod render_layers;
|
pub mod render_layers;
|
||||||
|
priv mod render_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod image {
|
pub mod image {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue