diff --git a/src/rust-azure b/src/rust-azure index c787b5eb2b3..7c683d825eb 160000 --- a/src/rust-azure +++ b/src/rust-azure @@ -1 +1 @@ -Subproject commit c787b5eb2b3cc9ec5be5024098bdc1a368791fb7 +Subproject commit 7c683d825ebe58f4c378dd6c5b69da8cbbd50deb diff --git a/src/servo/gfx/renderer.rs b/src/servo/gfx/renderer.rs index 690f5bafeb0..d58eff1c7f7 100644 --- a/src/servo/gfx/renderer.rs +++ b/src/servo/gfx/renderer.rs @@ -8,6 +8,11 @@ import azure::bindgen::*; import libc::size_t; import text::text_run::TextRun; import dom::event::{Event, ResizeEvent}; +import geom::size::Size2D; +import geom::rect::Rect; +import geom::point::Point2D; +import azure_hl::AsAzureRect; +import ptr::addr_of; type Renderer = chan; @@ -116,46 +121,44 @@ fn draw_solid_color(draw_target: AzDrawTargetRef, item: dl::display_item, AzReleaseColorPattern(red_pattern); } -fn draw_image(draw_target: AzDrawTargetRef, item: dl::display_item, - -image: ~image) { - // FIXME: This is hideously inefficient. +fn draw_image(draw_target: AzDrawTargetRef, item: dl::display_item, -image: ~image) unsafe { + let size = Size2D(image.width as i32, image.height as i32); + let stride = image.width * 4; - let bounds = copy (*item).bounds; - - if (image.depth < 3u) { - #debug("TODO: can't draw images with depth less than 3 yet"); - ret; - } - - let stride = image.width * image.depth; - for uint::range(0u, image.height) |y| { - for uint::range(0u, image.width) |x| { - let color = { - r: image.data[y * stride + x * image.depth].to_float() - as AzFloat, - g: image.data[y * stride + x * image.depth + 1u].to_float() - as AzFloat, - b: image.data[y * stride + x * image.depth + 2u].to_float() - as AzFloat, - a: 1f as AzFloat - }; - let pattern = AzCreateColorPattern(ptr::addr_of(color)); - - let pixel_rect = { - x: (au_to_px(bounds.origin.x) + (x as int)) as AzFloat, - y: (au_to_px(bounds.origin.y) + (y as int)) as AzFloat, - width: 1f as AzFloat, - height: 1f as AzFloat - }; - AzDrawTargetFillRect( - draw_target, - ptr::addr_of(pixel_rect), - unsafe { unsafe::reinterpret_cast(pattern) } - ); - - AzReleaseColorPattern(pattern); + // Do color space conversion :( + let data = do vec::from_fn(image.width * image.height * 4) |i| { + let color = i % 4; + let pixel = i / 4; + alt color { + 0 { image.data[pixel * 3 + 2] } + 1 { image.data[pixel * 3 + 1] } + 2 { image.data[pixel * 3 + 0] } + 3 { 0xffu8 } + _ { fail } } - } + }; + + let azure_surface = + AzDrawTargetCreateSourceSurfaceFromData(draw_target, + addr_of(data[0]), + unsafe::reinterpret_cast(addr_of(size)), + stride as i32, + 0u32); + let source_rect = Rect(Point2D(0.0f as AzFloat, 0.0f as AzFloat), + Size2D(image.width as AzFloat, image.height as AzFloat)); + let dest_rect = Rect(Point2D(au_to_px(item.bounds.origin.x) as AzFloat, + au_to_px(item.bounds.origin.y) as AzFloat), + Size2D(au_to_px(item.bounds.size.width) as AzFloat, + au_to_px(item.bounds.size.height) as AzFloat)); + let draw_surface_options = azure_hl::DrawSurfaceOptions(azure_hl::Linear, true); + let draw_options = azure_hl::DrawOptions(1.0f as AzFloat, 0); + AzDrawTargetDrawSurface(draw_target, + azure_surface, + addr_of(dest_rect.as_azure_rect()), + addr_of(source_rect.as_azure_rect()), + addr_of(draw_surface_options.as_azure_draw_surface_options()), + addr_of(draw_options.as_azure_draw_options())); + AzReleaseSourceSurface(azure_surface); } fn draw_text(draw_target: AzDrawTargetRef, item: dl::display_item, text_run: TextRun) { diff --git a/src/test/test-many-images.html b/src/test/test-many-images.html new file mode 100644 index 00000000000..bc8b83e9a19 --- /dev/null +++ b/src/test/test-many-images.html @@ -0,0 +1,94 @@ + + + +test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +