<commit_before>﻿using System;
using System.Linq;

namespace OxyPlot
{
    // LegendPosition (LegendPlacement=Outside)
    //
    // +               +-----------------------------------+                 +
    //                 |              Title                |
    //                 |            Subtitle               |
    //                 +-----------------------------------+
    //                 |TopLeft       TopCenter    TopRight|
    //                 +-----------------------------------+
    //                 |              Top axis             |
    // +----------+----+-----------------------------------+-----+-----------+
    // |LeftTop   |    |                                   |     |RightTop   |
    // |          |    |                                   |     |           |
    // |          |Left|                                   |Right|           |
    // |LeftMiddle|axis|              PlotArea             |axis |RightMiddle|
    // |          |    |                                   |     |           |
    // |          |    |                                   |     |           |
    // |LeftBottom|    |                                   |     |RightBottom|
    // +----------+----+-----------------------------------+-----+-----------+
    //                 |             Bottom axis           |
    //                 +-----------------------------------+
    //                 |BottomLeft BottomCenter BottomRight|
    // +               +-----------------------------------+                 +

    /// <summary>
    /// Partial PlotModel class - this file contains methods related to the series legends.
    /// </summary>
    partial class PlotModel
    {
        private OxySize RenderLegends(IRenderContext rc, OxyRect rect, bool measureOnly = false)
        {
            // Render background and border around legend
            if (!measureOnly && rect.Width > 0 && rect.Height > 0)
                rc.DrawRectangleAsPolygon(rect, LegendBackground, LegendBorder, LegendBorderThickness);

            double availableWidth = rect.Width;
            double availableHeight = rect.Height;

            double x = LegendPadding;
            double top = LegendPadding;

            var size = new OxySize();
            if (!String.IsNullOrEmpty(LegendTitle))
            {
                OxySize titleSize;
                if (measureOnly)
                    titleSize = rc.MeasureMathText(LegendTitle, LegendTitleFont, LegendTitleFontSize, LegendTitleFontWeight);
                else
                    titleSize = rc.DrawMathText(new ScreenPoint(rect.Left + x, rect.Top + top),
                                LegendTitle, TextColor,
                                LegendTitleFont, LegendTitleFontSize, LegendTitleFontWeight, 0, HorizontalTextAlign.Left,
                                VerticalTextAlign.Top, true);
                top += titleSize.Height;
                size.Width = x + titleSize.Width + LegendPadding;
                size.Height = top + titleSize.Height;
            }

            double y = top;

            double lineHeight = 0;
            double rowWidth = 0;

            var items = LegendItemOrder == LegendItemOrder.Reverse ? Series.Reverse() : Series;

            foreach (var s in items)
            {
                if (String.IsNullOrEmpty(s.Title))
                    continue;
                var textSize = rc.MeasureMathText(s.Title, LegendFont, LegendFontSize, LegendFontWeight);
                double itemWidth = LegendSymbolLength + LegendSymbolMargin + textSize.Width;
                double itemHeight = textSize.Height;

                if (LegendOrientation == LegendOrientation.Horizontal)
                {
                    // Add spacing between items
                    if (x > LegendPadding) x += LegendItemSpacing;

                    if (x + itemWidth > availableWidth - LegendPadding)
                    {
                        // new line
                        x = LegendPadding;
                        y += lineHeight;
                        lineHeight = 0;
                    }

                    if (textSize.Height > lineHeight)
                        lineHeight = textSize.Height;

                    if (!measureOnly)
                    {
                        var r = new OxyRect(rect.Left + x, rect.Top + y, textSize.Width, textSize.Height);
                        RenderLegend(rc, s, r);
                    }
                    x += itemWidth;
                    if (x > size.Width)
                        size.Width = x;
                    if (y + textSize.Height > size.Height)
                        size.Height = y + textSize.Height;
                }
                else
                {
                    if (y + itemHeight > availableHeight - LegendPadding)
                    {
                        y = top;
                        x += rowWidth + LegendColumnSpacing;
                        rowWidth = 0;
                    }

                    if (!measureOnly)
                    {
                        var r = new OxyRect(rect.Left + x, rect.Top + y, rect.Width - x - LegendPadding, textSize.Height);
                        RenderLegend(rc, s, r);
                    }

                    y += itemHeight;
                    if (itemWidth > rowWidth)
                        rowWidth = itemWidth;

                    if (x + itemWidth > size.Width)
                        size.Width = x + itemWidth;

                    if (y > size.Height)
                        size.Height = y;



                }


            }
            if (size.Width > 0)
                size.Width += LegendPadding;
            if (size.Height > 0)
                size.Height += LegendPadding;

            return size;
        }

        private void RenderLegend(IRenderContext rc, ISeries s, OxyRect rect)
        {
            double x = rect.Left;
            switch (LegendItemAlignment)
            {
                case HorizontalTextAlign.Center:
                    x = (rect.Left + rect.Right) / 2;
                    if (LegendSymbolPlacement == LegendSymbolPlacement.Left)
                        x -= (LegendSymbolLength + LegendSymbolMargin) / 2;
                    else
                        x -= (LegendSymbolLength + LegendSymbolMargin) / 2;
                    break;
                case HorizontalTextAlign.Right:
                    x = rect.Right;
                    //   if (LegendSymbolPlacement == LegendSymbolPlacement.Right)
                    x -= LegendSymbolLength + LegendSymbolMargin;
                    break;
            }
            if (LegendSymbolPlacement == LegendSymbolPlacement.Left)
                x += LegendSymbolLength + LegendSymbolMargin;

            var textSize = rc.DrawMathText(new ScreenPoint(x, rect.Top), s.Title, TextColor,
                                               LegendFont, LegendFontSize, LegendFontWeight, 0,
                                               LegendItemAlignment, VerticalTextAlign.Top, true);
            double x0 = x;
            switch (LegendItemAlignment)
            {
                case HorizontalTextAlign.Center:
                    x0 = x - textSize.Width / 2;
                    break;
                case HorizontalTextAlign.Right:
                    x0 = x - textSize.Width;
                    break;
            }

            var symbolRect = new OxyRect(LegendSymbolPlacement == LegendSymbolPlacement.Right ? x0 + textSize.Width + LegendSymbolMargin : x0 - LegendSymbolMargin - LegendSymbolLength, rect.Top,
                LegendSymbolLength, textSize.Height);

            s.RenderLegend(rc, symbolRect);
        }

        /// <summary>
        /// Gets the rectangle of the legend box.
        /// </summary><commit_msg>PlotModel legends use DefaultFont if LegendFont is not set<commit_after>﻿using System;
using System.Linq;

namespace OxyPlot
{
    // LegendPosition (LegendPlacement=Outside)
    //
    // +               +-----------------------------------+                 +
    //                 |              Title                |
    //                 |            Subtitle               |
    //                 +-----------------------------------+
    //                 |TopLeft       TopCenter    TopRight|
    //                 +-----------------------------------+
    //                 |              Top axis             |
    // +----------+----+-----------------------------------+-----+-----------+
    // |LeftTop   |    |                                   |     |RightTop   |
    // |          |    |                                   |     |           |
    // |          |Left|                                   |Right|           |
    // |LeftMiddle|axis|              PlotArea             |axis |RightMiddle|
    // |          |    |                                   |     |           |
    // |          |    |                                   |     |           |
    // |LeftBottom|    |                                   |     |RightBottom|
    // +----------+----+-----------------------------------+-----+-----------+
    //                 |             Bottom axis           |
    //                 +-----------------------------------+
    //                 |BottomLeft BottomCenter BottomRight|
    // +               +-----------------------------------+                 +

    /// <summary>
    /// Partial PlotModel class - this file contains methods related to the series legends.
    /// </summary>
    partial class PlotModel
    {
        private OxySize RenderLegends(IRenderContext rc, OxyRect rect, bool measureOnly = false)
        {
            // Render background and border around legend
            if (!measureOnly && rect.Width > 0 && rect.Height > 0)
                rc.DrawRectangleAsPolygon(rect, LegendBackground, LegendBorder, LegendBorderThickness);

            double availableWidth = rect.Width;
            double availableHeight = rect.Height;

            double x = LegendPadding;
            double top = LegendPadding;

            var size = new OxySize();
            if (!String.IsNullOrEmpty(LegendTitle))
            {
                OxySize titleSize;
                if (measureOnly)
                    titleSize = rc.MeasureMathText(LegendTitle, LegendTitleFont ?? DefaultFont, LegendTitleFontSize, LegendTitleFontWeight);
                else
                    titleSize = rc.DrawMathText(new ScreenPoint(rect.Left + x, rect.Top + top),
                                LegendTitle, TextColor,
                                LegendTitleFont ?? DefaultFont, LegendTitleFontSize, LegendTitleFontWeight, 0, HorizontalTextAlign.Left,
                                VerticalTextAlign.Top, true);
                top += titleSize.Height;
                size.Width = x + titleSize.Width + LegendPadding;
                size.Height = top + titleSize.Height;
            }

            double y = top;

            double lineHeight = 0;
            double rowWidth = 0;

            var items = LegendItemOrder == LegendItemOrder.Reverse ? Series.Reverse() : Series;

            foreach (var s in items)
            {
                if (String.IsNullOrEmpty(s.Title))
                    continue;
                var textSize = rc.MeasureMathText(s.Title, LegendFont ?? DefaultFont, LegendFontSize, LegendFontWeight);
                double itemWidth = LegendSymbolLength + LegendSymbolMargin + textSize.Width;
                double itemHeight = textSize.Height;

                if (LegendOrientation == LegendOrientation.Horizontal)
                {
                    // Add spacing between items
                    if (x > LegendPadding) x += LegendItemSpacing;

                    if (x + itemWidth > availableWidth - LegendPadding)
                    {
                        // new line
                        x = LegendPadding;
                        y += lineHeight;
                        lineHeight = 0;
                    }

                    if (textSize.Height > lineHeight)
                        lineHeight = textSize.Height;

                    if (!measureOnly)
                    {
                        var r = new OxyRect(rect.Left + x, rect.Top + y, textSize.Width, textSize.Height);
                        RenderLegend(rc, s, r);
                    }
                    x += itemWidth;
                    if (x > size.Width)
                        size.Width = x;
                    if (y + textSize.Height > size.Height)
                        size.Height = y + textSize.Height;
                }
                else
                {
                    if (y + itemHeight > availableHeight - LegendPadding)
                    {
                        y = top;
                        x += rowWidth + LegendColumnSpacing;
                        rowWidth = 0;
                    }

                    if (!measureOnly)
                    {
                        var r = new OxyRect(rect.Left + x, rect.Top + y, rect.Width - x - LegendPadding, textSize.Height);
                        RenderLegend(rc, s, r);
                    }

                    y += itemHeight;
                    if (itemWidth > rowWidth)
                        rowWidth = itemWidth;

                    if (x + itemWidth > size.Width)
                        size.Width = x + itemWidth;

                    if (y > size.Height)
                        size.Height = y;



                }


            }
            if (size.Width > 0)
                size.Width += LegendPadding;
            if (size.Height > 0)
                size.Height += LegendPadding;

            return size;
        }

        private void RenderLegend(IRenderContext rc, ISeries s, OxyRect rect)
        {
            double x = rect.Left;
            switch (LegendItemAlignment)
            {
                case HorizontalTextAlign.Center:
                    x = (rect.Left + rect.Right) / 2;
                    if (LegendSymbolPlacement == LegendSymbolPlacement.Left)
                        x -= (LegendSymbolLength + LegendSymbolMargin) / 2;
                    else
                        x -= (LegendSymbolLength + LegendSymbolMargin) / 2;
                    break;
                case HorizontalTextAlign.Right:
                    x = rect.Right;
                    //   if (LegendSymbolPlacement == LegendSymbolPlacement.Right)
                    x -= LegendSymbolLength + LegendSymbolMargin;
                    break;
            }
            if (LegendSymbolPlacement == LegendSymbolPlacement.Left)
                x += LegendSymbolLength + LegendSymbolMargin;

            var textSize = rc.DrawMathText(new ScreenPoint(x, rect.Top), s.Title, TextColor,
                                               LegendFont ?? DefaultFont, LegendFontSize, LegendFontWeight, 0,
                                               LegendItemAlignment, VerticalTextAlign.Top, true);
            double x0 = x;
            switch (LegendItemAlignment)
            {
                case HorizontalTextAlign.Center:
                    x0 = x - textSize.Width / 2;
                    break;
                case HorizontalTextAlign.Right:
                    x0 = x - textSize.Width;
                    break;
            }

            var symbolRect = new OxyRect(LegendSymbolPlacement == LegendSymbolPlacement.Right ? x0 + textSize.Width + LegendSymbolMargin : x0 - LegendSymbolMargin - LegendSymbolLength, rect.Top,
                LegendSymbolLength, textSize.Height);

            s.RenderLegend(rc, symbolRect);
        }

        /// <summary>
        /// Gets the rectangle of the legend box.
        /// </summary>
{'fraction_non_alphanumeric': 0.11659991099243436, 'fraction_numerical': 0.002415919638883591, 'mean_word_length': 0.9124620060790274, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 44, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2225914', 'n_tokens_mistral': 3655, 'n_tokens_neox': 3368, 'n_words': 781}