<commit_before>use app_units::Au;
use batch::{BatchBuilder, TileParams};
use device::TextureId;
use euclid::{Rect, Point2D, Size2D};
use fnv::FnvHasher;
use frame::FrameId;
use internal_types::{AxisDirection, BasicRotationAngle, BorderRadiusRasterOp, BoxShadowRasterOp};
use internal_types::{GlyphKey, PackedVertexColorMode, RasterItem, RectColors, RectPolygon};
use internal_types::{RectSide, RectUv, DevicePixel};
use renderer::BLUR_INFLATION_FACTOR;
use resource_cache::ResourceCache;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::hash_state::DefaultState;
use std::f32;
use std::num::Zero;
//use tessellator::{self, BorderCornerTessellation};
use texture_cache::{TextureCacheItem};
use util;
use util::RectVaryings;
use webrender_traits::{ColorF, ImageFormat, BorderStyle, BoxShadowClipMode};
use webrender_traits::{BorderSide, FontKey, GlyphInstance, ImageKey};
use webrender_traits::{BorderDisplayItem, GradientStop, ImageRendering};
use webrender_traits::{WebGLContextId};

const BORDER_DASH_SIZE: f32 = 3.0;

enum ClipState {
    None,
    ClipIn,
    ClipOut(Option<Rect<f32>>)
}

impl<'a> BatchBuilder<'a> {

    // Colors are in the order: top left, top right, bottom right, bottom left.
    pub fn add_simple_rectangle(&mut self,
                                color_texture_id: TextureId,
                                pos_rect: &Rect<f32>,
                                uv_rect: &RectUv<f32>,
                                mask_texture_id: TextureId,
                                muv_rect: &RectUv<DevicePixel>,
                                colors: &[ColorF; 4],
                                tile_params: Option<TileParams>) {
        if pos_rect.size.width == 0.0 || pos_rect.size.height == 0.0 {
            return
        }

        self.add_rectangle(color_texture_id,
                           mask_texture_id,
                           pos_rect,
                           uv_rect,
                           muv_rect,
                           colors,
                           PackedVertexColorMode::Gradient,
                           tile_params);
    }

    #[inline]
    fn snap_value_to_device_pixel(&self, value: &mut f32) {
        *value = (*value * self.device_pixel_ratio).round() / self.device_pixel_ratio;
    }

    // Colors are in the order: top left, top right, bottom right, bottom left.
    pub fn add_complex_clipped_rectangle(&mut self,
                                         color_texture_id: TextureId,
                                         pos_rect: &Rect<f32>,
                                         uv_rect: &RectUv<f32>,
                                         colors: &[ColorF; 4],
                                         tile_params: Option<TileParams>,
                                         resource_cache: &ResourceCache,
                                         frame_id: FrameId) {
        if pos_rect.size.width == 0.0 || pos_rect.size.height == 0.0 {
            return
        }

        match self.complex_clip {
            Some(complex_clip) => {
                // Get clip rect in local space of the display rect
                let complex_clip_origin = complex_clip.rect.origin - pos_rect.origin;
                let mut local_pos_rect = Rect::new(Point2D::zero(), pos_rect.size);

                // TODO(gw): Perhaps this should be caught higher up, or perhaps we
                //           can even remove this requirement.
                self.snap_value_to_device_pixel(&mut local_pos_rect.size.width);
                self.snap_value_to_device_pixel(&mut local_pos_rect.size.height);

                // Generate all vertices for each line
                let mut x_points = [
                    complex_clip_origin.x + 0.0,
                    complex_clip_origin.x + complex_clip.radii.top_left.width,
                    complex_clip_origin.x + complex_clip.rect.size.width - complex_clip.radii.top_right.width,
                    complex_clip_origin.x + complex_clip.radii.bottom_left.width,
                    complex_clip_origin.x + complex_clip.rect.size.width - complex_clip.radii.bottom_right.width,
                    complex_clip_origin.x + complex_clip.rect.size.width,
                ];

                // Generate all vertices for each line
                let mut y_points = [
                    complex_clip_origin.y + 0.0,
                    complex_clip_origin.y + complex_clip.radii.top_left.height,
                    complex_clip_origin.y + complex_clip.radii.top_right.height,
                    complex_clip_origin.y + complex_clip.rect.size.height - complex_clip.radii.bottom_left.height,
                    complex_clip_origin.y + complex_clip.rect.size.height - complex_clip.radii.bottom_right.height,
                    complex_clip_origin.y + complex_clip.rect.size.height,
                ];

                for x_point in &mut x_points {
                    self.snap_value_to_device_pixel(x_point);
                }

                for y_point in &mut y_points {
                    self.snap_value_to_device_pixel(y_point);
                }

                let tl_clip = Rect::new(Point2D::new(x_points[0], y_points[0]),
                                        Size2D::new(x_points[1] - x_points[0], y_points[1] - y_points[0]));

                let tr_clip = Rect::new(Point2D::new(x_points[2], y_points[0]),
                                        Size2D::new(x_points[5] - x_points[2], y_points[2] - y_points[0]));

                let bl_clip = Rect::new(Point2D::new(x_points[0], y_points[3]),
                                        Size2D::new(x_points[3] - x_points[0], y_points[5] - y_points[3]));

                let br_clip = Rect::new(Point2D::new(x_points[4], y_points[4]),
                                        Size2D::new(x_points[5] - x_points[4], y_points[5] - y_points[4]));

                x_points.sort_by(|a, b| {
                    a.partial_cmp(b).unwrap()
                });
                y_points.sort_by(|a, b| {
                    a.partial_cmp(b).unwrap()
                });

                for xi in 0..x_points.len()-1 {
                    for yi in 0..y_points.len()-1 {
                        let x0 = x_points[xi+0];<commit_msg>Accuracy fix for sub-pixel clip rect radii.<commit_after>use app_units::Au;
use batch::{BatchBuilder, TileParams};
use device::TextureId;
use euclid::{Rect, Point2D, Size2D};
use fnv::FnvHasher;
use frame::FrameId;
use internal_types::{AxisDirection, BasicRotationAngle, BorderRadiusRasterOp, BoxShadowRasterOp};
use internal_types::{GlyphKey, PackedVertexColorMode, RasterItem, RectColors, RectPolygon};
use internal_types::{RectSide, RectUv, DevicePixel};
use renderer::BLUR_INFLATION_FACTOR;
use resource_cache::ResourceCache;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::hash_state::DefaultState;
use std::f32;
use std::num::Zero;
//use tessellator::{self, BorderCornerTessellation};
use texture_cache::{TextureCacheItem};
use util;
use util::RectVaryings;
use webrender_traits::{ColorF, ImageFormat, BorderStyle, BoxShadowClipMode};
use webrender_traits::{BorderSide, FontKey, GlyphInstance, ImageKey};
use webrender_traits::{BorderDisplayItem, GradientStop, ImageRendering};
use webrender_traits::{WebGLContextId};

const BORDER_DASH_SIZE: f32 = 3.0;

enum ClipState {
    None,
    ClipIn,
    ClipOut(Option<Rect<f32>>)
}

impl<'a> BatchBuilder<'a> {

    // Colors are in the order: top left, top right, bottom right, bottom left.
    pub fn add_simple_rectangle(&mut self,
                                color_texture_id: TextureId,
                                pos_rect: &Rect<f32>,
                                uv_rect: &RectUv<f32>,
                                mask_texture_id: TextureId,
                                muv_rect: &RectUv<DevicePixel>,
                                colors: &[ColorF; 4],
                                tile_params: Option<TileParams>) {
        if pos_rect.size.width == 0.0 || pos_rect.size.height == 0.0 {
            return
        }

        self.add_rectangle(color_texture_id,
                           mask_texture_id,
                           pos_rect,
                           uv_rect,
                           muv_rect,
                           colors,
                           PackedVertexColorMode::Gradient,
                           tile_params);
    }

    #[inline]
    fn snap_value_to_device_pixel(&self, value: &mut f32) {
        *value = (*value * self.device_pixel_ratio).round() / self.device_pixel_ratio;
    }

    // Colors are in the order: top left, top right, bottom right, bottom left.
    pub fn add_complex_clipped_rectangle(&mut self,
                                         color_texture_id: TextureId,
                                         pos_rect: &Rect<f32>,
                                         uv_rect: &RectUv<f32>,
                                         colors: &[ColorF; 4],
                                         tile_params: Option<TileParams>,
                                         resource_cache: &ResourceCache,
                                         frame_id: FrameId) {
        if pos_rect.size.width == 0.0 || pos_rect.size.height == 0.0 {
            return
        }

        match self.complex_clip {
            Some(complex_clip) => {
                // Get clip rect in local space of the display rect
                let complex_clip_origin = complex_clip.rect.origin - pos_rect.origin;
                let mut local_pos_rect = Rect::new(Point2D::zero(), pos_rect.size);

                // TODO(gw): Perhaps this should be caught higher up, or perhaps we
                //           can even remove this requirement.
                self.snap_value_to_device_pixel(&mut local_pos_rect.size.width);
                self.snap_value_to_device_pixel(&mut local_pos_rect.size.height);

                let mut tl_xr = complex_clip.radii.top_left.width;
                let mut tl_yr = complex_clip.radii.top_left.height;
                let mut tr_xr = complex_clip.radii.top_right.width;
                let mut tr_yr = complex_clip.radii.top_right.height;

                let mut bl_xr = complex_clip.radii.bottom_left.width;
                let mut bl_yr = complex_clip.radii.bottom_left.height;
                let mut br_xr = complex_clip.radii.bottom_right.width;
                let mut br_yr = complex_clip.radii.bottom_right.height;

                self.snap_value_to_device_pixel(&mut tl_xr);
                self.snap_value_to_device_pixel(&mut tl_yr);
                self.snap_value_to_device_pixel(&mut tr_xr);
                self.snap_value_to_device_pixel(&mut tr_yr);
                self.snap_value_to_device_pixel(&mut bl_xr);
                self.snap_value_to_device_pixel(&mut bl_yr);
                self.snap_value_to_device_pixel(&mut br_xr);
                self.snap_value_to_device_pixel(&mut br_yr);

                // Generate all vertices for each line
                let mut x_points = [
                    complex_clip_origin.x + 0.0,
                    complex_clip_origin.x + complex_clip.radii.top_left.width,
                    complex_clip_origin.x + complex_clip.rect.size.width - complex_clip.radii.top_right.width,
                    complex_clip_origin.x + complex_clip.radii.bottom_left.width,
                    complex_clip_origin.x + complex_clip.rect.size.width - complex_clip.radii.bottom_right.width,
                    complex_clip_origin.x + complex_clip.rect.size.width,
                ];

                // Generate all vertices for each line
                let mut y_points = [
                    complex_clip_origin.y + 0.0,
                    complex_clip_origin.y + complex_clip.radii.top_left.height,
                    complex_clip_origin.y + complex_clip.radii.top_right.height,
                    complex_clip_origin.y + complex_clip.rect.size.height - complex_clip.radii.bottom_left.height,
                    complex_clip_origin.y + complex_clip.rect.size.height - complex_clip.radii.bottom_right.height,
                    complex_clip_origin.y + complex_clip.rect.size.height,
                ];

                for x_point in &mut x_points {
                    self.snap_value_to_device_pixel(x_point);
                }

                for y_point in &mut y_points {
                    self.snap_value_to_device_pixel(y_point);
                }

                let tl_clip = Rect::new(Point2D::new(x_points[0], y_points[0]),
                                        Size2D::new(tl_xr, tl_yr));

                let tr_clip = Rect::new(Point2D::new(x_points[2], y_points[0]),
                                        Size2D::new(tr_xr, tr_yr));

                let bl_clip = Rect::new(Point2D::new(x_points[0], y_points[3]),
                                        Size2D::new(bl_xr, bl_yr));

                let br_clip = Rect::new(Point2D::new(x_points[4], y_points[4]),
                                        Size2D::new(br_xr, br_yr));

                x_points.sort_by(|a, b| {
                    a.partial_cmp(b).unwrap()
                });
                y_points.sort_by(|a, b| {
                    a.partial_cmp(b).unwrap()
                });

                for xi in 0..x_points.len()-1 {
                    for yi in 0..y_points.len()-1 {
                        let x0 = x_points[xi+0];
{'fraction_non_alphanumeric': 0.09685301740096261, 'fraction_numerical': 0.009626064420584968, 'mean_word_length': 1.6936577582768249, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4513205', 'n_tokens_mistral': 4002, 'n_tokens_neox': 3808, 'n_words': 693}