mirror of
https://github.com/servo/servo.git
synced 2025-06-21 23:59:00 +01:00
auto merge of #1288 : ryanhc/servo/transparent_png, r=larsbergstrom
Modified to use libpng to read .png files. We use stb_image to read all other image files. This requires updated submodule: https://github.com/mozilla-servo/rust-png/pull/13 This patch is for: https://github.com/mozilla/servo/issues/1279
This commit is contained in:
commit
052a543f14
6 changed files with 58 additions and 36 deletions
|
@ -15,6 +15,7 @@ extern mod extra;
|
||||||
extern mod geom = "rust-geom";
|
extern mod geom = "rust-geom";
|
||||||
extern mod layers = "rust-layers";
|
extern mod layers = "rust-layers";
|
||||||
extern mod stb_image;
|
extern mod stb_image;
|
||||||
|
extern mod png;
|
||||||
extern mod servo_net (name = "net");
|
extern mod servo_net (name = "net");
|
||||||
extern mod servo_util (name = "util");
|
extern mod servo_util (name = "util");
|
||||||
extern mod style;
|
extern mod style;
|
||||||
|
|
|
@ -17,6 +17,7 @@ use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use geom::side_offsets::SideOffsets2D;
|
use geom::side_offsets::SideOffsets2D;
|
||||||
use servo_net::image::base::Image;
|
use servo_net::image::base::Image;
|
||||||
|
use png::{RGBA8, K8, KA8};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::libc::types::common::c99::uint16_t;
|
use std::libc::types::common::c99::uint16_t;
|
||||||
|
@ -54,7 +55,7 @@ impl<'self> RenderContext<'self> {
|
||||||
self.draw_target.make_current();
|
self.draw_target.make_current();
|
||||||
let mut dash: [AzFloat, ..2] = [0 as AzFloat, 0 as AzFloat];
|
let mut dash: [AzFloat, ..2] = [0 as AzFloat, 0 as AzFloat];
|
||||||
let mut stroke_opts = StrokeOptions(0 as AzFloat, 10 as AzFloat);
|
let mut stroke_opts = StrokeOptions(0 as AzFloat, 10 as AzFloat);
|
||||||
|
|
||||||
// draw top border
|
// draw top border
|
||||||
RenderContext::apply_border_style(style.top, border.top, dash, &mut stroke_opts);
|
RenderContext::apply_border_style(style.top, border.top, dash, &mut stroke_opts);
|
||||||
let y = rect.origin.y + border.top * 0.5;
|
let y = rect.origin.y + border.top * 0.5;
|
||||||
|
@ -103,11 +104,17 @@ impl<'self> RenderContext<'self> {
|
||||||
pub fn draw_image(&self, bounds: Rect<Au>, image: Arc<~Image>) {
|
pub fn draw_image(&self, bounds: Rect<Au>, image: Arc<~Image>) {
|
||||||
let image = image.get();
|
let image = image.get();
|
||||||
let size = Size2D(image.width as i32, image.height as i32);
|
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();
|
self.draw_target.make_current();
|
||||||
let draw_target_ref = &self.draw_target;
|
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);
|
stride as i32, B8G8R8A8);
|
||||||
let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
||||||
Size2D(image.width as AzFloat, image.height 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.
|
//FIXME(sammykim): This doesn't work with dash_pattern and cap_style well. I referred firefox code.
|
||||||
border_style::dotted => {
|
border_style::dotted => {
|
||||||
stroke_opts.line_width = border_width;
|
stroke_opts.line_width = border_width;
|
||||||
|
|
||||||
if border_width > 2.0 {
|
if border_width > 2.0 {
|
||||||
dash[0] = 0 as AzFloat;
|
dash[0] = 0 as AzFloat;
|
||||||
dash[1] = border_width * 2.0;
|
dash[1] = border_width * 2.0;
|
||||||
|
@ -165,9 +172,9 @@ impl<'self> RenderContext<'self> {
|
||||||
border_style::solid => {
|
border_style::solid => {
|
||||||
stroke_opts.set_cap_style(AZ_CAP_BUTT as u8);
|
stroke_opts.set_cap_style(AZ_CAP_BUTT as u8);
|
||||||
stroke_opts.set_join_style(AZ_JOIN_BEVEL 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;
|
stroke_opts.mDashLength = 0 as size_t;
|
||||||
}
|
}
|
||||||
//FIXME(sammykim): Five more styles should be implemented.
|
//FIXME(sammykim): Five more styles should be implemented.
|
||||||
//double, groove, ridge, inset, outset
|
//double, groove, ridge, inset, outset
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,7 @@ pub fn run_compositor(compositor: &CompositorTask) {
|
||||||
let img = png::Image {
|
let img = png::Image {
|
||||||
width: width as u32,
|
width: width as u32,
|
||||||
height: height as u32,
|
height: height as u32,
|
||||||
color_type: png::RGB8,
|
color_type: png::RGBA8,
|
||||||
pixels: pixels,
|
pixels: pixels,
|
||||||
};
|
};
|
||||||
let res = png::store_png(&img, &path);
|
let res = png::store_png(&img, &path);
|
||||||
|
|
|
@ -4,14 +4,19 @@
|
||||||
|
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use stb_image = stb_image::image;
|
use stb_image = stb_image::image;
|
||||||
|
use png;
|
||||||
|
|
||||||
// FIXME: Images must not be copied every frame. Instead we should atomically
|
// FIXME: Images must not be copied every frame. Instead we should atomically
|
||||||
// reference count them.
|
// reference count them.
|
||||||
|
pub type Image = png::Image;
|
||||||
|
|
||||||
pub type Image = stb_image::Image<u8>;
|
pub fn Image(width: u32, height: u32, color_type: png::ColorType, data: ~[u8]) -> Image {
|
||||||
|
png::Image {
|
||||||
pub fn Image(width: uint, height: uint, depth: uint, data: ~[u8]) -> Image {
|
width: width,
|
||||||
stb_image::new_image(width, height, depth, data)
|
height: height,
|
||||||
|
color_type: color_type,
|
||||||
|
pixels: data,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TEST_IMAGE: &'static [u8] = include_bin!("test.jpeg");
|
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<Image> {
|
pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||||
// Can't remember why we do this. Maybe it's what cairo wants
|
if png::is_png(buffer) {
|
||||||
static FORCE_DEPTH: uint = 4;
|
match png::load_png_from_memory(buffer) {
|
||||||
|
Ok(png_image) => Some(png_image),
|
||||||
match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
Err(_err) => None,
|
||||||
stb_image::ImageU8(image) => {
|
}
|
||||||
assert!(image.depth == 4);
|
} else {
|
||||||
// Do color space conversion :(
|
// For non-png images, we use stb_image
|
||||||
let data = do vec::from_fn(image.width * image.height * 4) |i| {
|
// Can't remember why we do this. Maybe it's what cairo wants
|
||||||
let color = i % 4;
|
static FORCE_DEPTH: uint = 4;
|
||||||
let pixel = i / 4;
|
|
||||||
match color {
|
match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||||
0 => image.data[pixel * 4 + 2],
|
stb_image::ImageU8(image) => {
|
||||||
1 => image.data[pixel * 4 + 1],
|
assert!(image.depth == 4);
|
||||||
2 => image.data[pixel * 4 + 0],
|
// Do color space conversion :(
|
||||||
3 => 0xffu8,
|
let data = do vec::from_fn(image.width * image.height * 4) |i| {
|
||||||
_ => fail!()
|
let color = i % 4;
|
||||||
}
|
let pixel = i / 4;
|
||||||
};
|
match color {
|
||||||
|
0 => image.data[pixel * 4 + 2],
|
||||||
assert!(image.data.len() == data.len());
|
1 => image.data[pixel * 4 + 1],
|
||||||
|
2 => image.data[pixel * 4 + 0],
|
||||||
Some(Image(image.width, image.height, image.depth, data))
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ extern mod http;
|
||||||
extern mod servo_util (name = "util");
|
extern mod servo_util (name = "util");
|
||||||
extern mod stb_image;
|
extern mod stb_image;
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
extern mod png;
|
||||||
|
|
||||||
/// Image handling.
|
/// Image handling.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit bd3b394e35dee36989e3c80abd9bcc1f99affa27
|
Subproject commit 519c291139813bf6cda192a45745013d543c99fe
|
Loading…
Add table
Add a link
Reference in a new issue