<commit_before>﻿using System;
using System.IO;
using System.Threading;
using Mapsui.Styles;
using Mapsui.Tests.Common.Maps;
using NUnit.Framework;
using SkiaSharp;

#if SKIA
using Mapsui.Rendering.Skia;
#endif

namespace Mapsui.Rendering.Xaml.Tests
{
    [TestFixture, Apartment(ApartmentState.STA)]
    class MapRendererTests
    {
        [Test]
        public void RenderPointsWithVectorStyle()
        {
            // arrange
            var map = VectorStyleSample.CreateMap();
            const string fileName = "vector_symbol.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPointWithBitmapSymbols()
        {
            // arrange
            var map = BitmapSymbolSample.CreateMap();
            const string fileName = "points_with_symbolstyle.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderRotatedBitmapSymbolWithOffset()
        {
            // arrange
            var map = BitmapSymbolWithRotationAndOffsetSample.CreateMap();
            const string fileName = "bitmap_symbol.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPointsWithDifferentSymbolTypes()
        {
            // arrange
            var map = SymbolTypesSample.CreateMap();
            const string fileName = "vector_symbol_symboltype.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderSymbolWithWorldUnits()
        {
            // arrange
            var map = PointInWorldUnits.CreateMap();
            const string fileName = "vector_symbol_unittype.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPolygon()
        {
            // arrange
            var map = PolygonSample.CreateMap();
            const string fileName = "polygon.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap));
        }

        [Test]
        public void RenderLine()
        {
            // arrange
            var map = LineSample.CreateMap();
            const string fileName = "line.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap));
        }

        [Test]
        public void RenderTiles()
        {
            // arrange
            var map = TilesSample.CreateMap();
            const string fileName = "tilelayer.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside;
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 2, 0.99));
        }

        [Test]
        public void RenderLabels()
        {
            // arrange
            var map = LabelSample.CreateMap();
            const string fileName = "labels.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside;
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.97));
        }

        private static bool CompareColors(SKColor color1, SKColor color2, int allowedColorDistance)
        {
            if (color1.Alpha == 0 && color2.Alpha == 0) return true; // If both are transparent all colors are ignored
            if (Math.Abs(color1.Alpha - color2.Alpha) > allowedColorDistance) return false;
            if (Math.Abs(color1.Red - color2.Red) > allowedColorDistance) return false;
            if (Math.Abs(color1.Green- color2.Green) > allowedColorDistance) return false;
            if (Math.Abs(color1.Blue - color2.Blue) > allowedColorDistance) return false;
            return true;
        }

        private bool CompareBitmaps(Stream bitmapStream1, Stream bitmapStream2, int allowedColorDistance = 0, double proportionCorrect = 1)
        {
            // The bitmaps in WPF can slightly differ from test to test. No idea why. So introduced proportion correct.

            bitmapStream1.Position = 0;
            bitmapStream2.Position = 0;

            long trueCount = 0;
            long falseCount = 0;

            var bitmap1 = SKBitmap.FromImage(SKImage.FromEncodedData(SKData.Create(bitmapStream1)));
            var bitmap2 = SKBitmap.FromImage(SKImage.FromEncodedData(SKData.Create(bitmapStream1)));

            for (var x = 0; x < bitmap1.Width; x++)
            {
                for (var y = 0; y < bitmap1.Height; y++)
                {
                    var color1 = bitmap1.GetPixel(x, y);
                    var color2 = bitmap2.GetPixel(x, y);
                    if (color1 == color2)
                        trueCount++;
                    else
                    {
                        if (CompareColors(color1, color2, allowedColorDistance))
                            trueCount++;
                        else<commit_msg>Fixed bug introduced in previous commit<commit_after>﻿using System;
using System.IO;
using System.Threading;
using Mapsui.Styles;
using Mapsui.Tests.Common.Maps;
using NUnit.Framework;
using SkiaSharp;

#if SKIA
using Mapsui.Rendering.Skia;
#endif

namespace Mapsui.Rendering.Xaml.Tests
{
    [TestFixture, Apartment(ApartmentState.STA)]
    class MapRendererTests
    {
        [Test]
        public void RenderPointsWithVectorStyle()
        {
            // arrange
            var map = VectorStyleSample.CreateMap();
            const string fileName = "vector_symbol.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPointWithBitmapSymbols()
        {
            // arrange
            var map = BitmapSymbolSample.CreateMap();
            const string fileName = "points_with_symbolstyle.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderRotatedBitmapSymbolWithOffset()
        {
            // arrange
            var map = BitmapSymbolWithRotationAndOffsetSample.CreateMap();
            const string fileName = "bitmap_symbol.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPointsWithDifferentSymbolTypes()
        {
            // arrange
            var map = SymbolTypesSample.CreateMap();
            const string fileName = "vector_symbol_symboltype.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderSymbolWithWorldUnits()
        {
            // arrange
            var map = PointInWorldUnits.CreateMap();
            const string fileName = "vector_symbol_unittype.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.99));
        }

        [Test]
        public void RenderPolygon()
        {
            // arrange
            var map = PolygonSample.CreateMap();
            const string fileName = "polygon.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap));
        }

        [Test]
        public void RenderLine()
        {
            // arrange
            var map = LineSample.CreateMap();
            const string fileName = "line.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap));
        }

        [Test]
        public void RenderTiles()
        {
            // arrange
            var map = TilesSample.CreateMap();
            const string fileName = "tilelayer.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside;
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 2, 0.99));
        }

        [Test]
        public void RenderLabels()
        {
            // arrange
            var map = LabelSample.CreateMap();
            const string fileName = "labels.png";

            // act
            var bitmap = new MapRenderer().RenderToBitmapStream(map.Viewport, map.Layers, map.BackColor);

            // aside;
            File.WriteToGeneratedFolder(fileName, bitmap);

            // assert
            Assert.IsTrue(CompareBitmaps(File.ReadFromOriginalFolder(fileName), bitmap, 1, 0.97));
        }

        private static bool CompareColors(SKColor color1, SKColor color2, int allowedColorDistance)
        {
            if (color1.Alpha == 0 && color2.Alpha == 0) return true; // If both are transparent all colors are ignored
            if (Math.Abs(color1.Alpha - color2.Alpha) > allowedColorDistance) return false;
            if (Math.Abs(color1.Red - color2.Red) > allowedColorDistance) return false;
            if (Math.Abs(color1.Green- color2.Green) > allowedColorDistance) return false;
            if (Math.Abs(color1.Blue - color2.Blue) > allowedColorDistance) return false;
            return true;
        }

        private bool CompareBitmaps(Stream bitmapStream1, Stream bitmapStream2, int allowedColorDistance = 0, double proportionCorrect = 1)
        {
            // The bitmaps in WPF can slightly differ from test to test. No idea why. So introduced proportion correct.

            long trueCount = 0;
            long falseCount = 0;

            bitmapStream1.Position = 0;
            bitmapStream2.Position = 0;

            var bitmap1 = SKBitmap.FromImage(SKImage.FromEncodedData(SKData.Create(bitmapStream1)));
            var bitmap2 = SKBitmap.FromImage(SKImage.FromEncodedData(SKData.Create(bitmapStream2)));

            for (var x = 0; x < bitmap1.Width; x++)
            {
                for (var y = 0; y < bitmap1.Height; y++)
                {
                    var color1 = bitmap1.GetPixel(x, y);
                    var color2 = bitmap2.GetPixel(x, y);
                    if (color1 == color2)
                        trueCount++;
                    else
                    {
                        if (CompareColors(color1, color2, allowedColorDistance))
                            trueCount++;
                        else
{'fraction_non_alphanumeric': 0.0955641135358722, 'fraction_numerical': 0.009699044358864642, 'mean_word_length': 1.8181270096463023, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, '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': '7244701', 'n_tokens_mistral': 3686, 'n_tokens_neox': 3573, 'n_words': 790}