mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Implement TakeElementScreenshot WebDriver command
This commit is contained in:
parent
a084997afe
commit
d3696baf27
12 changed files with 134 additions and 28 deletions
|
@ -14,7 +14,7 @@ use crate::CompositionPipeline;
|
|||
use crate::SendableFrameTree;
|
||||
use crossbeam_channel::Sender;
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::{Point2D, Scale, Vector2D};
|
||||
use euclid::{Point2D, Rect, Scale, Vector2D};
|
||||
use gfx_traits::Epoch;
|
||||
#[cfg(feature = "gl")]
|
||||
use image::{DynamicImage, ImageFormat};
|
||||
|
@ -442,8 +442,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.touch_handler.on_event_processed(result);
|
||||
},
|
||||
|
||||
(Msg::CreatePng(reply), ShutdownState::NotShuttingDown) => {
|
||||
let res = self.composite_specific_target(CompositeTarget::WindowAndPng);
|
||||
(Msg::CreatePng(rect, reply), ShutdownState::NotShuttingDown) => {
|
||||
let res = self.composite_specific_target(CompositeTarget::WindowAndPng, rect);
|
||||
if let Err(ref e) = res {
|
||||
info!("Error retrieving PNG: {:?}", e);
|
||||
}
|
||||
|
@ -1229,7 +1229,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
|
||||
pub fn composite(&mut self) {
|
||||
let target = self.composite_target;
|
||||
match self.composite_specific_target(target) {
|
||||
match self.composite_specific_target(target, None) {
|
||||
Ok(_) => {
|
||||
if self.output_file.is_some() || self.exit_after_load {
|
||||
println!("Shutting down the Constellation after generating an output file or exit flag specified");
|
||||
|
@ -1256,6 +1256,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
fn composite_specific_target(
|
||||
&mut self,
|
||||
target: CompositeTarget,
|
||||
rect: Option<Rect<f32, CSSPixel>>,
|
||||
) -> Result<Option<Image>, UnableToComposite> {
|
||||
let size = self.embedder_coordinates.framebuffer.to_u32();
|
||||
|
||||
|
@ -1347,6 +1348,22 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
}
|
||||
}
|
||||
|
||||
let (x, y, width, height) = match rect {
|
||||
Some(rect) => {
|
||||
let rect = self.device_pixels_per_page_px().transform_rect(&rect);
|
||||
|
||||
let x = rect.origin.x as i32;
|
||||
// We need to convert to the bottom-left origin coordinate
|
||||
// system used by OpenGL
|
||||
let y = (size.height as f32 - rect.origin.y - rect.size.height) as i32;
|
||||
let w = rect.size.width as u32;
|
||||
let h = rect.size.height as u32;
|
||||
|
||||
(x, y, w, h)
|
||||
},
|
||||
None => (0, 0, size.width, size.height),
|
||||
};
|
||||
|
||||
let rv = match target {
|
||||
CompositeTarget::Window => None,
|
||||
#[cfg(feature = "gl")]
|
||||
|
@ -1354,8 +1371,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
let img = gl::draw_img(
|
||||
&*self.window.gl(),
|
||||
rt_info,
|
||||
FramebufferUintLength::new(size.width),
|
||||
FramebufferUintLength::new(size.height),
|
||||
x,
|
||||
y,
|
||||
FramebufferUintLength::new(width),
|
||||
FramebufferUintLength::new(height),
|
||||
);
|
||||
Some(Image {
|
||||
width: img.width(),
|
||||
|
@ -1378,8 +1397,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
let img = gl::draw_img(
|
||||
gl,
|
||||
rt_info,
|
||||
FramebufferUintLength::new(size.width),
|
||||
FramebufferUintLength::new(size.height),
|
||||
x,
|
||||
y,
|
||||
FramebufferUintLength::new(width),
|
||||
FramebufferUintLength::new(height),
|
||||
);
|
||||
let dynamic_image = DynamicImage::ImageRgb8(img);
|
||||
if let Err(e) = dynamic_image.write_to(&mut file, ImageFormat::PNG)
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::compositor::CompositingReason;
|
|||
use crate::SendableFrameTree;
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use embedder_traits::EventLoopWaker;
|
||||
use euclid::Rect;
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
|
||||
|
@ -17,6 +18,7 @@ use profile_traits::time;
|
|||
use script_traits::{AnimationState, ConstellationMsg, EventResult, MouseButton, MouseEventType};
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api;
|
||||
use webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
||||
use webvr_traits::WebVRMainThreadHeartbeat;
|
||||
|
@ -80,7 +82,7 @@ pub enum Msg {
|
|||
/// Script has handled a touch event, and either prevented or allowed default actions.
|
||||
TouchEventProcessed(EventResult),
|
||||
/// Composite to a PNG file and return the Image over a passed channel.
|
||||
CreatePng(IpcSender<Option<Image>>),
|
||||
CreatePng(Option<Rect<f32, CSSPixel>>, IpcSender<Option<Image>>),
|
||||
/// Alerts the compositor that the viewport has been constrained in some manner
|
||||
ViewportConstrained(PipelineId, ViewportConstraints),
|
||||
/// A reply to the compositor asking if the output image is stable.
|
||||
|
|
|
@ -82,6 +82,8 @@ pub fn initialize_png(
|
|||
pub fn draw_img(
|
||||
gl: &dyn gl::Gl,
|
||||
render_target_info: RenderTargetInfo,
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: FramebufferUintLength,
|
||||
height: FramebufferUintLength,
|
||||
) -> RgbImage {
|
||||
|
@ -96,8 +98,8 @@ pub fn draw_img(
|
|||
gl.bind_vertex_array(0);
|
||||
|
||||
let mut pixels = gl.read_pixels(
|
||||
0,
|
||||
0,
|
||||
x,
|
||||
y,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei,
|
||||
gl::RGB,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue