<commit_before>﻿namespace Microsoft.Xna.Framework.Graphics
{
    using SadConsole;
    using SadConsole.Consoles;
    using System;

    public static class TextureExtensions
    {
        public static void DrawImageToSurface(this Texture2D texture, TextSurface surface, Point position, bool useBackground, Func<Color, Color, Color> blendOperation = null)
        {
            Color[] pixels = new Color[texture.Width * texture.Height];
            texture.GetData<Color>(pixels);

            int startX = position.X;
            int widthCounter = 0;

            for (int i = 0; i < pixels.Length; i++)
            {
                if (widthCounter >= texture.Width)
                {
                    widthCounter = 0;
                    position.X = startX;
                    position.Y++;
                }

                if (surface.IsValidCell(position.X, position.Y))
                {
                    int destinationIndex = position.ToIndex(surface.Width);

                    if (useBackground)
                    {
                        if (blendOperation == null)
                            surface[destinationIndex].Background = pixels[i];
                        else
                            surface[destinationIndex].Background = blendOperation(surface[destinationIndex].Background, pixels[i]);
                    }
                    else
                    {
                        if (blendOperation == null)
                            surface[destinationIndex].Foreground = pixels[i];
                        else
                            surface[destinationIndex].Foreground = blendOperation(surface[destinationIndex].Foreground, pixels[i]);
                    }
                }

                position.X++;
                widthCounter++;
            }
        }

        public static void DrawImageToSurface(this Texture2D texture, TextSurface surface, Point position, Action<int, Cell, Color> cellProcessor)
        {
            Color[] pixels = new Color[texture.Width * texture.Height];
            texture.GetData<Color>(pixels);

            int startX = position.X;
            int widthCounter = 0;

            for (int i = 0; i < pixels.Length; i++)
            {
                if (widthCounter >= texture.Width)
                {
                    widthCounter = 0;
                    position.X = startX;
                    position.Y++;
                }

                if (surface.IsValidCell(position.X, position.Y))
                {
                    int destinationIndex = position.ToIndex(surface.Width);

                    cellProcessor(destinationIndex, surface[destinationIndex], pixels[i]);
                }

                position.X++;
                widthCounter++;
            }
        }
    }
}<commit_msg>Moved the 3d projection -> surface code to the core library as an extension on the Texture2D type.<commit_after>﻿namespace Microsoft.Xna.Framework.Graphics
{
    using SadConsole;
    using SadConsole.Consoles;
    using System;

    public static class TextureExtensions
    {
        public static TextSurface ToSurface(this Texture2D image, Font font, bool blockMode = false)
        {
            TextSurface surface = new TextSurface(image.Width / font.Size.X, image.Height / font.Size.Y, font);
            Color[] pixels = new Color[image.Width * image.Height];
            image.GetData<Color>(pixels);

            System.Threading.Tasks.Parallel.For(0, image.Height / surface.Font.Size.Y, (h) =>
            //for (int h = 0; h < image.Height / surface.Font.Size.Y; h++)
            {
                int startY = (h * surface.Font.Size.Y);
                //System.Threading.Tasks.Parallel.For(0, image.Width / surface.Font.Size.X, (w) =>
                for (int w = 0; w < image.Width / surface.Font.Size.X; w++)
                {
                    int startX = (w * surface.Font.Size.X);

                    float allR = 0;
                    float allG = 0;
                    float allB = 0;

                    for (int y = 0; y < surface.Font.Size.Y; y++)
                    {
                        for (int x = 0; x < surface.Font.Size.X; x++)
                        {
                            int cY = y + startY;
                            int cX = x + startX;

                            Color color = pixels[cY * image.Width + cX];

                            allR += color.R;
                            allG += color.G;
                            allB += color.B;
                        }
                    }

                    byte sr = (byte)(allR / (surface.Font.Size.X * surface.Font.Size.Y));
                    byte sg = (byte)(allG / (surface.Font.Size.X * surface.Font.Size.Y));
                    byte sb = (byte)(allB / (surface.Font.Size.X * surface.Font.Size.Y));

                    var newColor = new Color(sr, sg, sb);

                    float sbri = newColor.GetBrightness() * 255;

                    if (blockMode)
                    {
                        if (sbri > 204)
                            surface.SetCharacter(w, h, 219, newColor); //█
                        else if (sbri > 152)
                            surface.SetCharacter(w, h, 178, newColor); //▓
                        else if (sbri > 100)
                            surface.SetCharacter(w, h, 177, newColor); //▒
                        else if (sbri > 48)
                            surface.SetCharacter(w, h, 176, newColor); //░
                    }
                    else
                    {
                        if (sbri > 230)
                            surface.SetCharacter(w, h, (int)'#', newColor);
                        else if (sbri > 207)
                            surface.SetCharacter(w, h, (int)'&', newColor);
                        else if (sbri > 184)
                            surface.SetCharacter(w, h, (int)'$', newColor);
                        else if (sbri > 161)
                            surface.SetCharacter(w, h, (int)'X', newColor);
                        else if (sbri > 138)
                            surface.SetCharacter(w, h, (int)'x', newColor);
                        else if (sbri > 115)
                            surface.SetCharacter(w, h, (int)'=', newColor);
                        else if (sbri > 92)
                            surface.SetCharacter(w, h, (int)'+', newColor);
                        else if (sbri > 69)
                            surface.SetCharacter(w, h, (int)';', newColor);
                        else if (sbri > 46)
                            surface.SetCharacter(w, h, (int)':', newColor);
                        else if (sbri > 23)
                            surface.SetCharacter(w, h, (int)'.', newColor);
                    }
                }
            }
            );

            return surface;
        }

        public static void ToSurface(this Texture2D image, TextSurface surface, Color[] cachedColorArray, bool blockMode = false)
        {
            image.GetData<Color>(cachedColorArray);
            surface.Clear();
            System.Threading.Tasks.Parallel.For(0, image.Height / surface.Font.Size.Y, (h) =>
            //for (int h = 0; h < image.Height / surface.Font.Size.Y; h++)
            {
                int startY = (h * surface.Font.Size.Y);
                //System.Threading.Tasks.Parallel.For(0, image.Width / surface.Font.Size.X, (w) =>
                for (int w = 0; w < image.Width / surface.Font.Size.X; w++)
                {
                    int startX = (w * surface.Font.Size.X);

                    float allR = 0;
                    float allG = 0;
                    float allB = 0;

                    for (int y = 0; y < surface.Font.Size.Y; y++)
                    {
                        for (int x = 0; x < surface.Font.Size.X; x++)
                        {
                            int cY = y + startY;
                            int cX = x + startX;

                            Color color = cachedColorArray[cY * image.Width + cX];

                            allR += color.R;
                            allG += color.G;
                            allB += color.B;
                        }
                    }

                    byte sr = (byte)(allR / (surface.Font.Size.X * surface.Font.Size.Y));
                    byte sg = (byte)(allG / (surface.Font.Size.X * surface.Font.Size.Y));
                    byte sb = (byte)(allB / (surface.Font.Size.X * surface.Font.Size.Y));

                    var newColor = new Color(sr, sg, sb);

                    float sbri = newColor.GetBrightness() * 255;

                    if (blockMode)
                    {
                        if (sbri > 204)
                            surface.SetCharacter(w, h, 219, newColor); //█
                        else if (sbri > 152)
                            surface.SetCharacter(w, h, 178, newColor); //▓
                        else if (sbri > 100)
                            surface.SetCharacter(w, h, 177, newColor); //▒
                        else if (sbri > 48)
                            surface.SetCharacter(w, h, 176, newColor); //░
                    }
                    else
                    {
                        if (sbri > 230)
                            surface.SetCharacter(w, h, (int)'#', newColor);
                        else if (sbri > 207)
                            surface.SetCharacter(w, h, (int)'&', newColor);
                        else if (sbri > 184)
                            surface.SetCharacter(w, h, (int)'$', newColor);
                        else if (sbri > 161)
                            surface.SetCharacter(w, h, (int)'X', newColor);
                        else if (sbri > 138)
                            surface.SetCharacter(w, h, (int)'x', newColor);
                        else if (sbri > 115)
                            surface.SetCharacter(w, h, (int)'=', newColor);
                        else if (sbri > 92)
                            surface.SetCharacter(w, h, (int)'+', newColor);
                        else if (sbri > 69)
                            surface.SetCharacter(w, h, (int)';', newColor);
                        else if (sbri > 46)
                            surface.SetCharacter(w, h, (int)':', newColor);
                        else if (sbri > 23)
                            surface.SetCharacter(w, h, (int)'.', newColor);
                    }
                }
            }
            );
        }
    }
}
{'fraction_non_alphanumeric': 0.10741760850983, 'fraction_numerical': 0.012726754677557224, 'mean_word_length': 1.0234435049961568, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 44, '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': '7582083', 'n_tokens_mistral': 2845, 'n_tokens_neox': 2579, 'n_words': 639}