/// <summary> /// Calculates the dimensions of the Legend. This includes the maximum width /// and height of a single entry, as well as the total width and height of /// the Legend. public void CalculateDimensions(Paint paint, ViewPortHandler viewPortHandler) { var maxEntrySize = GetMaximumEntrySize(paint); float defaultFormSize = FormSize.DpToPixel(); float stackSpace = StackSpace.DpToPixel(); float formToTextSpace = FormToTextSpace.DpToPixel(); float xEntrySpace = XEntrySpace.DpToPixel(); float yEntrySpace = YEntrySpace.DpToPixel(); var wordWrapEnabled = WordWrapEnabled; var entries = Entries; int entryCount = entries.Count; TextWidthMax = maxEntrySize.Width; TextHeightMax = maxEntrySize.Height; switch (Orientation) { case Orientation.Vertical: { float maxWidth = 0f, maxHeight = 0f, width = 0f; float labelLineHeight = paint.LineHeight(); bool wasStacked = false; for (int i = 0; i < entryCount; i++) { LegendEntry e = entries[i]; var drawingForm = e.Form != Form.None; float formSize = float.IsNaN(e.FormSize) ? defaultFormSize : e.FormSize.DpToPixel(); var label = e.Label; if (!wasStacked) { width = 0.0f; } if (drawingForm) { if (wasStacked) { width += stackSpace; } width += formSize; } // grouped forms have null labels if (label != null) { var size = paint.MeasureWidth(label); // make a step to the left if (drawingForm && !wasStacked) { width += formToTextSpace; } else if (wasStacked) { maxWidth = Math.Max(maxWidth, width); maxHeight += labelLineHeight + yEntrySpace; width = 0.0f; wasStacked = false; } width += size; maxHeight += labelLineHeight + yEntrySpace; } else { wasStacked = true; width += formSize; if (i < entryCount - 1) { width += stackSpace; } } maxWidth = Math.Max(maxWidth, width); } NeededWidth = maxWidth; NeededHeight = maxHeight; break; } case Orientation.Horizontal: { float labelLineHeight = paint.LineHeight(); float labelLineSpacing = paint.LineSpacing() + yEntrySpace; float contentWidth = viewPortHandler.ContentWidth * MaxSizePercent; // Start calculating layout float maxLineWidth = 0.0f; float currentLineWidth = 0.0f; float requiredWidth = 0.0f; int stackedStartIndex = -1; CalculatedLabelBreakPoints.Clear(); CalculatedLabelSizes.Clear(); CalculatedLineSizes.Clear(); for (int i = 0; i < entryCount; i++) { LegendEntry e = entries[i]; var drawingForm = e.Form != Form.None; float formSize = float.IsNaN(e.FormSize) ? defaultFormSize : e.FormSize.DpToPixel(); var label = e.Label; CalculatedLabelBreakPoints.Add(false); if (stackedStartIndex == -1) { // we are not stacking, so required width is for this label // only requiredWidth = 0.0f; } else { // add the spacing appropriate for stacked labels/forms requiredWidth += stackSpace; } // grouped forms have null labels if (label != null) { CalculatedLabelSizes.Add(paint.Measure(label)); requiredWidth += drawingForm ? formToTextSpace + formSize : 0.0f; requiredWidth += CalculatedLabelSizes[i].Width; } else { CalculatedLabelSizes.Add(new ChartSize(0, 0)); requiredWidth += drawingForm ? formSize : 0.0f; if (stackedStartIndex == -1) { // mark this index as we might want to break here later stackedStartIndex = i; } } if (label != null || i == entryCount - 1) { float requiredSpacing = currentLineWidth == 0.0f ? 0.0f : xEntrySpace; if (!wordWrapEnabled // No word wrapping, it must fit. // The line is empty, it must fit || currentLineWidth == 0.0f // It simply fits || (contentWidth - currentLineWidth >= requiredSpacing + requiredWidth)) { // Expand current line currentLineWidth += requiredSpacing + requiredWidth; } else { // It doesn't fit, we need to wrap a line // Add current line size to array CalculatedLineSizes.Add(new ChartSize(currentLineWidth, labelLineHeight)); maxLineWidth = Math.Max(maxLineWidth, currentLineWidth); // Start a new line CalculatedLabelBreakPoints.Insert( stackedStartIndex > -1 ? stackedStartIndex : i, true); currentLineWidth = requiredWidth; } if (i == entryCount - 1) { // Add last line size to array CalculatedLineSizes.Add(new ChartSize(currentLineWidth, labelLineHeight)); maxLineWidth = Math.Max(maxLineWidth, currentLineWidth); } } stackedStartIndex = label != null ? -1 : stackedStartIndex; } NeededWidth = maxLineWidth; NeededHeight = labelLineHeight * (float)(CalculatedLineSizes.Count) + labelLineSpacing * (float)(CalculatedLineSizes.Count == 0 ? 0 : (CalculatedLineSizes.Count - 1)); break; } } NeededHeight += YOffset; NeededWidth += XOffset; }