From d82114007f4703bfc71c5445a33406f342fa905a Mon Sep 17 00:00:00 2001 From: Ryan Choi Date: Mon, 18 Nov 2013 16:50:00 +0900 Subject: [PATCH 1/2] add support for transparant png --- src/components/gfx/gfx.rc | 1 + src/components/gfx/render_context.rs | 19 ++++--- src/components/main/compositing/run.rs | 2 +- src/components/net/image/base.rs | 69 +++++++++++++++----------- src/components/net/net.rc | 1 + 5 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/components/gfx/gfx.rc b/src/components/gfx/gfx.rc index e803ccd2192..47c5bbc8f90 100644 --- a/src/components/gfx/gfx.rc +++ b/src/components/gfx/gfx.rc @@ -15,6 +15,7 @@ extern mod extra; extern mod geom; extern mod layers; extern mod stb_image; +extern mod png; extern mod servo_net (name = "net"); extern mod servo_util (name = "util"); extern mod style; diff --git a/src/components/gfx/render_context.rs b/src/components/gfx/render_context.rs index bb88a81c8fe..8fe801cd3f4 100644 --- a/src/components/gfx/render_context.rs +++ b/src/components/gfx/render_context.rs @@ -17,6 +17,7 @@ use geom::rect::Rect; use geom::size::Size2D; use geom::side_offsets::SideOffsets2D; use servo_net::image::base::Image; +use png::{RGBA8, K8, KA8}; use servo_util::geometry::Au; use std::vec; use std::libc::types::common::c99::uint16_t; @@ -54,7 +55,7 @@ impl<'self> RenderContext<'self> { self.draw_target.make_current(); let mut dash: [AzFloat, ..2] = [0 as AzFloat, 0 as AzFloat]; let mut stroke_opts = StrokeOptions(0 as AzFloat, 10 as AzFloat); - + // draw top border RenderContext::apply_border_style(style.top, border.top, dash, &mut stroke_opts); let y = rect.origin.y + border.top * 0.5; @@ -103,11 +104,17 @@ impl<'self> RenderContext<'self> { pub fn draw_image(&self, bounds: Rect, image: Arc<~Image>) { let image = image.get(); let size = Size2D(image.width as i32, image.height as i32); - let stride = image.width * 4; + let pixel_width = match image.color_type { + RGBA8 => 4, + K8 => 1, + KA8 => 2, + _ => fail!(~"color type not supported"), + }; + let stride = image.width * pixel_width; self.draw_target.make_current(); let draw_target_ref = &self.draw_target; - let azure_surface = draw_target_ref.create_source_surface_from_data(image.data, size, + let azure_surface = draw_target_ref.create_source_surface_from_data(image.pixels, 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)); @@ -140,7 +147,7 @@ impl<'self> RenderContext<'self> { //FIXME(sammykim): This doesn't work with dash_pattern and cap_style well. I referred firefox code. border_style::dotted => { stroke_opts.line_width = border_width; - + if border_width > 2.0 { dash[0] = 0 as AzFloat; dash[1] = border_width * 2.0; @@ -165,9 +172,9 @@ impl<'self> RenderContext<'self> { border_style::solid => { stroke_opts.set_cap_style(AZ_CAP_BUTT as u8); stroke_opts.set_join_style(AZ_JOIN_BEVEL as u8); - stroke_opts.line_width = border_width; + stroke_opts.line_width = border_width; stroke_opts.mDashLength = 0 as size_t; - } + } //FIXME(sammykim): Five more styles should be implemented. //double, groove, ridge, inset, outset } diff --git a/src/components/main/compositing/run.rs b/src/components/main/compositing/run.rs index b14bc78aac4..6d8ec7bca72 100644 --- a/src/components/main/compositing/run.rs +++ b/src/components/main/compositing/run.rs @@ -359,7 +359,7 @@ pub fn run_compositor(compositor: &CompositorTask) { let img = png::Image { width: width as u32, height: height as u32, - color_type: png::RGB8, + color_type: png::RGBA8, pixels: pixels, }; let res = png::store_png(&img, &path); diff --git a/src/components/net/image/base.rs b/src/components/net/image/base.rs index 7b2bbe2f22b..f715f534640 100644 --- a/src/components/net/image/base.rs +++ b/src/components/net/image/base.rs @@ -4,14 +4,19 @@ use std::vec; use stb_image = stb_image::image; +use png; // FIXME: Images must not be copied every frame. Instead we should atomically // reference count them. +pub type Image = png::Image; -pub type Image = stb_image::Image; - -pub fn Image(width: uint, height: uint, depth: uint, data: ~[u8]) -> Image { - stb_image::new_image(width, height, depth, data) +pub fn Image(width: u32, height: u32, color_type: png::ColorType, data: ~[u8]) -> Image { + png::Image { + width: width, + height: height, + color_type: color_type, + pixels: data, + } } static TEST_IMAGE: &'static [u8] = include_bin!("test.jpeg"); @@ -21,30 +26,38 @@ pub fn test_image_bin() -> ~[u8] { } pub fn load_from_memory(buffer: &[u8]) -> Option { - // Can't remember why we do this. Maybe it's what cairo wants - static FORCE_DEPTH: uint = 4; - - match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) { - stb_image::ImageU8(image) => { - assert!(image.depth == 4); - // Do color space conversion :( - let data = do vec::from_fn(image.width * image.height * 4) |i| { - let color = i % 4; - let pixel = i / 4; - match color { - 0 => image.data[pixel * 4 + 2], - 1 => image.data[pixel * 4 + 1], - 2 => image.data[pixel * 4 + 0], - 3 => 0xffu8, - _ => fail!() - } - }; - - assert!(image.data.len() == data.len()); - - Some(Image(image.width, image.height, image.depth, data)) + if png::is_png(buffer) { + match png::load_png_from_memory(buffer) { + Ok(png_image) => Some(png_image), + Err(_err) => None, + } + } else { + // For non-png images, we use stb_image + // Can't remember why we do this. Maybe it's what cairo wants + static FORCE_DEPTH: uint = 4; + + match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) { + stb_image::ImageU8(image) => { + assert!(image.depth == 4); + // Do color space conversion :( + let data = do vec::from_fn(image.width * image.height * 4) |i| { + let color = i % 4; + let pixel = i / 4; + match color { + 0 => image.data[pixel * 4 + 2], + 1 => image.data[pixel * 4 + 1], + 2 => image.data[pixel * 4 + 0], + 3 => 0xffu8, + _ => fail!() + } + }; + + assert!(image.data.len() == data.len()); + + Some(Image(image.width as u32, image.height as u32, png::RGBA8, data)) + } + stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"), + stb_image::Error => None } - stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"), - stb_image::Error => None } } diff --git a/src/components/net/net.rc b/src/components/net/net.rc index b8df8855e31..da445e1e964 100644 --- a/src/components/net/net.rc +++ b/src/components/net/net.rc @@ -15,6 +15,7 @@ extern mod http; extern mod servo_util (name = "util"); extern mod stb_image; extern mod extra; +extern mod png; /// Image handling. /// From 589530c289384513e0c9b200d53395c2ea4ccfbe Mon Sep 17 00:00:00 2001 From: Ryan Choi Date: Wed, 20 Nov 2013 11:36:39 +0900 Subject: [PATCH 2/2] submodule updated --- src/support/png/rust-png | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/support/png/rust-png b/src/support/png/rust-png index bd3b394e35d..519c2911398 160000 --- a/src/support/png/rust-png +++ b/src/support/png/rust-png @@ -1 +1 @@ -Subproject commit bd3b394e35dee36989e3c80abd9bcc1f99affa27 +Subproject commit 519c291139813bf6cda192a45745013d543c99fe