<commit_before>﻿// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Runtime.InteropServices;
using Perspex.Cairo.Media.Imaging;
using Perspex.Media;

namespace Perspex.Cairo.Media
{
    using Perspex.Media.Imaging;
    using Cairo = global::Cairo;

    /// <summary>
    /// Draws using Direct2D1.
    /// </summary>
    public class DrawingContext : IDrawingContextImpl, IDisposable
    {
        /// <summary>
        /// The cairo context.
        /// </summary>
        private readonly Cairo.Context _context;

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        /// <param name="surface">The target surface.</param>
        public DrawingContext(Cairo.Surface surface)
        {
            _context = new Cairo.Context(surface);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        /// <param name="surface">The GDK drawable.</param>
        public DrawingContext(Gdk.Drawable drawable)
        {
            _context = Gdk.CairoHelper.Create(drawable);
        }


        private Matrix _transform = Matrix.Identity;
        /// <summary>
        /// Gets the current transform of the drawing context.
        /// </summary>
        public Matrix Transform
        {
            get { return _transform; }
            set
            {
                _transform = value;
                _context.Matrix = value.ToCairo();
                
            }
        }

        /// <summary>
        /// Ends a draw operation.
        /// </summary>
        public void Dispose()
        {
            _context.Dispose();
        }

        /// <summary>
        /// Draws a bitmap image.
        /// </summary>
        /// <param name="source">The bitmap image.</param>
        /// <param name="opacity">The opacity to draw with.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect)
        {
            var impl = bitmap.PlatformImpl as BitmapImpl;
            var size = new Size(impl.PixelWidth, impl.PixelHeight);
            var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height);

            _context.Save();
            _context.Scale(scale.X, scale.Y);
            destRect /= scale;

			if (opacityOverride < 1.0f) {
				_context.PushGroup ();
				Gdk.CairoHelper.SetSourcePixbuf (
					_context, 
					impl.Surface, 
					-sourceRect.X + destRect.X, 
					-sourceRect.Y + destRect.Y);

				_context.Rectangle (destRect.ToCairo ());
				_context.Fill ();
				_context.PopGroupToSource ();
				_context.PaintWithAlpha (opacityOverride);
			} else {
				_context.PushGroup ();
				Gdk.CairoHelper.SetSourcePixbuf (
					_context, 
					impl.Surface, 
					-sourceRect.X + destRect.X, 
					-sourceRect.Y + destRect.Y);

				_context.Rectangle (destRect.ToCairo ());
				_context.Fill ();
				_context.PopGroupToSource ();
				_context.PaintWithAlpha (opacityOverride);			
			}
            _context.Restore();
        }

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="p1">The first point of the line.</param>
        /// <param name="p1">The second point of the line.</param>
        public void DrawLine(Pen pen, Point p1, Point p2)
        {
            var size = new Rect(p1, p2).Size;
            
			using (var p = SetPen(pen, size)) 
			{
				_context.MoveTo(p1.ToCairo());
				_context.LineTo(p2.ToCairo());
				_context.Stroke();
			}
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(Brush brush, Pen pen, Geometry geometry)
        {
            var impl = geometry.PlatformImpl as StreamGeometryImpl;

            var oldMatrix = Transform;
            Transform *= impl.Transform;

            

            if (brush != null)
            {
                _context.AppendPath(impl.Path);
                using (var b = SetBrush(brush, geometry.Bounds.Size))
                {
                    if (pen != null)
                        _context.FillPreserve();
                    else
                        _context.Fill();
                }
            }
            if (pen != null)
            {
                _context.AppendPath(impl.Path);
                using (var p = SetPen(pen, geometry.Bounds.Size))
                {
                    _context.Stroke();
                }
            }
            Transform = oldMatrix;
        }

        /// <summary>
        /// Draws the outline of a rectangle.
        /// </summary>
        /// <param name="pen">The pen.</param>
        /// <param name="rect">The rectangle bounds.</param>
        public void DrawRectangle(Pen pen, Rect rect, float cornerRadius)
        {
			using (var p = SetPen(pen, rect.Size)) 
			{<commit_msg>Fixed cairo unit tests, however that change doesn't have any sense<commit_after>﻿// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Runtime.InteropServices;
using Perspex.Cairo.Media.Imaging;
using Perspex.Media;

namespace Perspex.Cairo.Media
{
    using Perspex.Media.Imaging;
    using Cairo = global::Cairo;

    /// <summary>
    /// Draws using Direct2D1.
    /// </summary>
    public class DrawingContext : IDrawingContextImpl, IDisposable
    {
        /// <summary>
        /// The cairo context.
        /// </summary>
        private readonly Cairo.Context _context;

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        /// <param name="surface">The target surface.</param>
        public DrawingContext(Cairo.Surface surface)
        {
            _context = new Cairo.Context(surface);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        /// <param name="surface">The GDK drawable.</param>
        public DrawingContext(Gdk.Drawable drawable)
        {
            _context = Gdk.CairoHelper.Create(drawable);
        }


        private Matrix _transform = Matrix.Identity;
        /// <summary>
        /// Gets the current transform of the drawing context.
        /// </summary>
        public Matrix Transform
        {
            get { return _transform; }
            set
            {
                _transform = value;
                _context.Matrix = value.ToCairo();
                
            }
        }

        /// <summary>
        /// Ends a draw operation.
        /// </summary>
        public void Dispose()
        {
            _context.Dispose();
        }

        /// <summary>
        /// Draws a bitmap image.
        /// </summary>
        /// <param name="source">The bitmap image.</param>
        /// <param name="opacity">The opacity to draw with.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect)
        {
            var impl = bitmap.PlatformImpl as BitmapImpl;
            var size = new Size(impl.PixelWidth, impl.PixelHeight);
            var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height);

            _context.Save();
            _context.Scale(scale.X, scale.Y);
            destRect /= scale;

			if (opacityOverride < 1.0f) {
				_context.PushGroup ();
				Gdk.CairoHelper.SetSourcePixbuf (
					_context, 
					impl.Surface, 
					-sourceRect.X + destRect.X, 
					-sourceRect.Y + destRect.Y);

				_context.Rectangle (destRect.ToCairo ());
				_context.Fill ();
				_context.PopGroupToSource ();
				_context.PaintWithAlpha (opacityOverride);
			} else {
				_context.PushGroup ();
				Gdk.CairoHelper.SetSourcePixbuf (
					_context, 
					impl.Surface, 
					-sourceRect.X + destRect.X, 
					-sourceRect.Y + destRect.Y);

				_context.Rectangle (destRect.ToCairo ());
				_context.Fill ();
				_context.PopGroupToSource ();
				_context.PaintWithAlpha (opacityOverride);			
			}
            _context.Restore();
        }

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="p1">The first point of the line.</param>
        /// <param name="p1">The second point of the line.</param>
        public void DrawLine(Pen pen, Point p1, Point p2)
        {
            var size = new Rect(p1, p2).Size;
            
			using (var p = SetPen(pen, size)) 
			{
				_context.MoveTo(p1.ToCairo());
				_context.LineTo(p2.ToCairo());
				_context.Stroke();
			}
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(Brush brush, Pen pen, Geometry geometry)
        {
            var impl = geometry.PlatformImpl as StreamGeometryImpl;

            var oldMatrix = Transform;
            Transform *= impl.Transform;

            
            if (brush != null)
            {
                _context.AppendPath(impl.Path);
                using (var b = SetBrush(brush, geometry.Bounds.Size))
                {
                    if (pen != null)
                        _context.FillPreserve();
                    else
                        _context.Fill();
                }
            }
            Transform = oldMatrix;

            if (pen != null)
            {
                _context.AppendPath(impl.Path);
                using (var p = SetPen(pen, geometry.Bounds.Size))
                {
                    _context.Stroke();
                }
            }
        }

        /// <summary>
        /// Draws the outline of a rectangle.
        /// </summary>
        /// <param name="pen">The pen.</param>
        /// <param name="rect">The rectangle bounds.</param>
        public void DrawRectangle(Pen pen, Rect rect, float cornerRadius)
        {
			using (var p = SetPen(pen, rect.Size)) 
			{
{'fraction_non_alphanumeric': 0.12397216951296648, 'fraction_numerical': 0.002168609379235565, 'mean_word_length': 1.634610806950726, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5386736', 'n_tokens_mistral': 3285, 'n_tokens_neox': 2983, 'n_words': 754}