<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use azure::azure::AzFloat;
use azure::azure_hl::{DrawTarget, SurfaceFormat, BackendType, StrokeOptions, DrawOptions, Pattern};
use azure::azure_hl::{ColorPattern, PathBuilder, JoinStyle, CapStyle, DrawSurfaceOptions, Filter};
use azure::azure_hl::{GradientStop, LinearGradientPattern, RadialGradientPattern, ExtendMode};
use geom::matrix2d::Matrix2D;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::color;
use util::task::spawn_named;
use util::vec::byte_swap;

use cssparser::RGBA;
use std::borrow::ToOwned;
use std::sync::mpsc::{channel, Sender};

#[derive(Clone)]
pub enum CanvasMsg {
    FillRect(Rect<f32>),
    ClearRect(Rect<f32>),
    StrokeRect(Rect<f32>),
    BeginPath,
    ClosePath,
    Fill,
    DrawImage(Vec<u8>, Rect<i32>, Rect<i32>, bool),
    DrawImageSelf(Size2D<i32>, Rect<i32>, Rect<i32>, bool),
    MoveTo(Point2D<f32>),
    LineTo(Point2D<f32>),
    QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
    BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>),
    Arc(Point2D<f32>, f32, f32, f32, bool),
    SetFillStyle(FillOrStrokeStyle),
    SetStrokeStyle(FillOrStrokeStyle),
    SetTransform(Matrix2D<f32>),
    Recreate(Size2D<i32>),
    SendPixelContents(Sender<Vec<u8>>),
    GetImageData(Rect<i32>, Size2D<i32>, Sender<Vec<u8>>),
    PutImageData(Vec<u8>, Rect<i32>, Option<Rect<i32>>),
    Close,
}

impl<'a> CanvasPaintTask<'a> {
    /// It reads image data from the canvas
    /// canvas_size: The size of the canvas we're reading from
    /// read_rect: The area of the canvas we want to read from
    fn read_pixels(&self, read_rect: Rect<i32>, canvas_size: Size2D<i32>) -> Vec<u8>{
        let canvas_rect = Rect(Point2D(0i32, 0i32), canvas_size);
        let src_read_rect = canvas_rect.intersection(&read_rect).unwrap_or(Rect::zero());

        let mut image_data = Vec::new();
        if src_read_rect.is_empty() || canvas_size.width <= 0 && canvas_size.height <= 0 {
          return image_data;
        }

        let data_surface = self.drawtarget.snapshot().get_data_surface();
        let mut src_data = Vec::new();
        data_surface.with_data(|element| { src_data = element.to_vec(); });
        let stride = data_surface.stride();

        //start offset of the copyable rectangle
        let mut src = (src_read_rect.origin.y * stride + src_read_rect.origin.x * 4) as usize;
        //copy the data to the destination vector
        for _ in range(0, src_read_rect.size.height) {
           let row = &src_data[src .. src + (4 * src_read_rect.size.width) as usize];
           image_data.push_all(row);
           src += stride as usize;
        }

        image_data
    }

    /// It writes image data to the canvas
    /// source_rect: the area of the image data to be written
    /// dest_rect: The area of the canvas where the imagedata will be copied
    /// smoothing_enabled: if smoothing is applied to the copied pixels
    fn write_pixels(&self, imagedata: &Vec<u8>,
                           image_size: Size2D<i32>,
                           source_rect: Rect<i32>,
                           dest_rect: Rect<i32>,
                           smoothing_enabled: bool) {
        // From spec https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
        // When scaling up, if the imageSmoothingEnabled attribute is set to true, the user agent should attempt
        // to apply a smoothing algorithm to the image data when it is scaled.
        // Otherwise, the image must be rendered using nearest-neighbor interpolation.
        let filter = if smoothing_enabled {
           Filter::Linear
        } else {
           Filter::Point
        };

        let source_surface = self.drawtarget.create_source_surface_from_data(imagedata.as_slice(),
           image_size, image_size.width * 4, SurfaceFormat::B8G8R8A8);

        let draw_surface_options = DrawSurfaceOptions::new(filter, true);
        let draw_options = DrawOptions::new(1.0f64 as AzFloat, 0);

        self.drawtarget.draw_surface(source_surface,
                                    dest_rect.to_azfloat(),
                                    source_rect.to_azfloat(),
                                    draw_surface_options, draw_options);
    }

    /// dirty_rect: original dirty_rect provided by the putImageData call
    /// image_data_rect: the area of the image to be copied<commit_msg>Fix indentation in canvas_paint_task.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use azure::azure::AzFloat;
use azure::azure_hl::{DrawTarget, SurfaceFormat, BackendType, StrokeOptions, DrawOptions, Pattern};
use azure::azure_hl::{ColorPattern, PathBuilder, JoinStyle, CapStyle, DrawSurfaceOptions, Filter};
use azure::azure_hl::{GradientStop, LinearGradientPattern, RadialGradientPattern, ExtendMode};
use geom::matrix2d::Matrix2D;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::color;
use util::task::spawn_named;
use util::vec::byte_swap;

use cssparser::RGBA;
use std::borrow::ToOwned;
use std::sync::mpsc::{channel, Sender};

#[derive(Clone)]
pub enum CanvasMsg {
    FillRect(Rect<f32>),
    ClearRect(Rect<f32>),
    StrokeRect(Rect<f32>),
    BeginPath,
    ClosePath,
    Fill,
    DrawImage(Vec<u8>, Rect<i32>, Rect<i32>, bool),
    DrawImageSelf(Size2D<i32>, Rect<i32>, Rect<i32>, bool),
    MoveTo(Point2D<f32>),
    LineTo(Point2D<f32>),
    QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
    BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>),
    Arc(Point2D<f32>, f32, f32, f32, bool),
    SetFillStyle(FillOrStrokeStyle),
    SetStrokeStyle(FillOrStrokeStyle),
    SetTransform(Matrix2D<f32>),
    Recreate(Size2D<i32>),
    SendPixelContents(Sender<Vec<u8>>),
    GetImageData(Rect<i32>, Size2D<i32>, Sender<Vec<u8>>),
    PutImageData(Vec<u8>, Rect<i32>, Option<Rect<i32>>),
    Close,
}

impl<'a> CanvasPaintTask<'a> {
    /// It reads image data from the canvas
    /// canvas_size: The size of the canvas we're reading from
    /// read_rect: The area of the canvas we want to read from
    fn read_pixels(&self, read_rect: Rect<i32>, canvas_size: Size2D<i32>) -> Vec<u8>{
        let canvas_rect = Rect(Point2D(0i32, 0i32), canvas_size);
        let src_read_rect = canvas_rect.intersection(&read_rect).unwrap_or(Rect::zero());

        let mut image_data = Vec::new();
        if src_read_rect.is_empty() || canvas_size.width <= 0 && canvas_size.height <= 0 {
          return image_data;
        }

        let data_surface = self.drawtarget.snapshot().get_data_surface();
        let mut src_data = Vec::new();
        data_surface.with_data(|element| { src_data = element.to_vec(); });
        let stride = data_surface.stride();

        //start offset of the copyable rectangle
        let mut src = (src_read_rect.origin.y * stride + src_read_rect.origin.x * 4) as usize;
        //copy the data to the destination vector
        for _ in range(0, src_read_rect.size.height) {
            let row = &src_data[src .. src + (4 * src_read_rect.size.width) as usize];
            image_data.push_all(row);
            src += stride as usize;
        }

        image_data
    }

    /// It writes image data to the canvas
    /// source_rect: the area of the image data to be written
    /// dest_rect: The area of the canvas where the imagedata will be copied
    /// smoothing_enabled: if smoothing is applied to the copied pixels
    fn write_pixels(&self, imagedata: &Vec<u8>,
                    image_size: Size2D<i32>,
                    source_rect: Rect<i32>,
                    dest_rect: Rect<i32>,
                    smoothing_enabled: bool) {
        // From spec https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
        // When scaling up, if the imageSmoothingEnabled attribute is set to true, the user agent should attempt
        // to apply a smoothing algorithm to the image data when it is scaled.
        // Otherwise, the image must be rendered using nearest-neighbor interpolation.
        let filter = if smoothing_enabled {
            Filter::Linear
        } else {
            Filter::Point
        };

        let source_surface = self.drawtarget.create_source_surface_from_data(imagedata.as_slice(),
            image_size, image_size.width * 4, SurfaceFormat::B8G8R8A8);

        let draw_surface_options = DrawSurfaceOptions::new(filter, true);
        let draw_options = DrawOptions::new(1.0f64 as AzFloat, 0);

        self.drawtarget.draw_surface(source_surface,
                                     dest_rect.to_azfloat(),
                                     source_rect.to_azfloat(),
                                     draw_surface_options, draw_options);
    }

    /// dirty_rect: original dirty_rect provided by the putImageData call
    /// image_data_rect: the area of the image to be copied
{'fraction_non_alphanumeric': 0.116056888502877, 'fraction_numerical': 0.02410161763109326, 'mean_word_length': 2.953648068669528, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 81, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1995122', 'n_tokens_mistral': 3024, 'n_tokens_neox': 2893, 'n_words': 732}