<commit_before>﻿#if XNA
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endif

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using SadConsole.Controls;

namespace SadConsole.Renderers
{
    /// <summary>
    /// Draws a text surface to the screen.
    /// </summary>
    [DataContract]
    public class ControlsConsole : Console
    {
        /// <summary>
        /// Controls to render.
        /// </summary>
        public List<Controls.ControlBase> Controls { get; set; } = new List<SadConsole.Controls.ControlBase>();

        /// <summary>
        /// Renders a surface to the screen.
        /// </summary>
        /// <param name="surface">The surface to render.</param>
        /// <param name="force">When <see langword="true"/> draws the surface even if <see cref="CellSurface.IsDirty"/> is <see langword="false"/>.</param>
        public override void Render(SadConsole.Console surface, bool force = false)
        {
            RenderBegin(surface, force);
            RenderCells(surface, force);

            foreach (var control in Controls)
                RenderControlCells(control, surface.IsDirty || force);

            //RenderControls(surface, force);
            RenderTint(surface, force);
            RenderEnd(surface, force);
        }

        public void RenderControlCells(ControlBase control, bool draw = false)
        {
            if (!draw || !control.IsVisible) return;
            //if (control.Surface.Tint.A == 255) return;

            if (control.Surface.DefaultBackground.A != 0)
            {
                var (x, y) = (control.Position - control.Parent.ViewPort.Location).ConsoleLocationToPixel(control.Parent.Font);
                var (width, height) = new Point(control.Width, control.Height) * control.Parent.Font.Size;
                Global.SpriteBatch.Draw(control.Parent.Font.FontImage, new Rectangle(x, y, width, height), control.Parent.Font.GlyphRects[control.Parent.Font.SolidGlyphIndex], control.Surface.DefaultBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.2f);
            }

            for (var i = 0; i < control.Surface.Cells.Length; i++)
            {
                ref var cell = ref control.Surface.Cells[i];

                if (!cell.IsVisible) continue;

                var cellRenderPosition = i.ToPoint(control.Width) + control.Position;

                if (!control.Parent.ViewPort.Contains(cellRenderPosition)) continue;

                Rectangle renderRect = control.Parent.RenderRects[(cellRenderPosition - control.Parent.ViewPort.Location).ToIndex(control.Parent.Width)];

                if (cell.Background != Color.Transparent && cell.Background != control.Surface.DefaultBackground)
                    Global.SpriteBatch.Draw(control.Parent.Font.FontImage, renderRect, control.Parent.Font.GlyphRects[control.Parent.Font.SolidGlyphIndex], cell.Background, 0f, Vector2.Zero, SpriteEffects.None, 0.3f);

                if (cell.Foreground != Color.Transparent)
                    Global.SpriteBatch.Draw(control.Parent.Font.FontImage, renderRect, control.Parent.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f);

                foreach (var decorator in cell.Decorators)<commit_msg>Fix 3d button rendering. Fixes #208<commit_after>﻿#if XNA
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endif

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using SadConsole.Controls;

namespace SadConsole.Renderers
{
    /// <summary>
    /// Draws a text surface to the screen.
    /// </summary>
    [DataContract]
    public class ControlsConsole : Console
    {
        /// <summary>
        /// Controls to render.
        /// </summary>
        public List<Controls.ControlBase> Controls { get; set; } = new List<SadConsole.Controls.ControlBase>();

        /// <summary>
        /// Renders a surface to the screen.
        /// </summary>
        /// <param name="surface">The surface to render.</param>
        /// <param name="force">When <see langword="true"/> draws the surface even if <see cref="CellSurface.IsDirty"/> is <see langword="false"/>.</param>
        public override void Render(SadConsole.Console surface, bool force = false)
        {
            RenderBegin(surface, force);
            RenderCells(surface, force);

            foreach (var control in Controls)
                RenderControlCells(control, surface.IsDirty || force);

            //RenderControls(surface, force);
            RenderTint(surface, force);
            RenderEnd(surface, force);
        }

        public void RenderControlCells(ControlBase control, bool draw = false)
        {
            if (!draw || !control.IsVisible) return;
            //if (control.Surface.Tint.A == 255) return;

            if (control.Surface.DefaultBackground.A != 0)
            {
                var (x, y) = (control.Position - control.Parent.ViewPort.Location).ConsoleLocationToPixel(control.Parent.Font);
                var (width, height) = new Point(control.Surface.Width, control.Surface.Height) * control.Parent.Font.Size;
                Global.SpriteBatch.Draw(control.Parent.Font.FontImage, new Rectangle(x, y, width, height), control.Parent.Font.GlyphRects[control.Parent.Font.SolidGlyphIndex], control.Surface.DefaultBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.2f);
            }

            for (var i = 0; i < control.Surface.Cells.Length; i++)
            {
                ref var cell = ref control.Surface.Cells[i];

                if (!cell.IsVisible) continue;

                var cellRenderPosition = i.ToPoint(control.Surface.Width) + control.Position;

                if (!control.Parent.ViewPort.Contains(cellRenderPosition)) continue;

                Rectangle renderRect = control.Parent.RenderRects[(cellRenderPosition - control.Parent.ViewPort.Location).ToIndex(control.Parent.Width)];

                if (cell.Background != Color.Transparent && cell.Background != control.Surface.DefaultBackground)
                    Global.SpriteBatch.Draw(control.Parent.Font.FontImage, renderRect, control.Parent.Font.GlyphRects[control.Parent.Font.SolidGlyphIndex], cell.Background, 0f, Vector2.Zero, SpriteEffects.None, 0.3f);

                if (cell.Foreground != Color.Transparent)
                    Global.SpriteBatch.Draw(control.Parent.Font.FontImage, renderRect, control.Parent.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f);

                foreach (var decorator in cell.Decorators)
{'fraction_non_alphanumeric': 0.12086745526235972, 'fraction_numerical': 0.005762814680012132, 'mean_word_length': 2.507978723404255, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 33, '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': '7144469', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1748, 'n_words': 390}