Пример #1
0
        public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            PointF point1 = _controlPoints[0];
            PointF point2;

            if (_controlPoints.Count < 2)
            {
                point2 = mousePosition.Value;
            }
            else
            {
                point2 = _controlPoints[1];
            }

            // Clipping opitmization.
            RectangleF rectangle = new RectangleF(
                Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));

            if (rectangle.IntersectsWith(clippingRectangle) == false)
            {
                return;
            }

            // Draw base line.
            g.DrawLine(_dashedLinePen, point1, point2);

            float baseLevel = point1.Y;
            float height    = point2.Y - point1.Y;

            // Draw fibbonacci levels.
            float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 };
            for (int i = 0; i < levels.Length; i++)
            {
                float actualLevel = baseLevel + height * levels[i] / 100f;
                g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel);
                g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel);
            }



            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
Пример #2
0
 /// <summary>
 /// Helper.
 /// </summary>
 protected PointF DrawCustomMessage(GraphicsWrapper g, Font font, Brush brush, string message, PointF drawingLocation)
 {
     if (font != null && brush != null)
     {
         SizeF size = g.MeasureString(message, font);
         g.DrawString(message, font, brush, drawingLocation);
         drawingLocation.Y += size.Height;
     }
     return(drawingLocation);
 }
Пример #3
0
        public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false || _controlPoints.Count < 1)
            {
                return;
            }

            if (clippingRectangle.Contains(_controlPoints[0]) == false)
            {// Clipping opitmization.
                return;
            }

            SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont);

            if (size.Height < 0)
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height);
            }
            else
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height);
            }

            g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]);

            if (Selected || IsBuilding)
            {
                g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y));
            }

            // Rounding rectangle.
            //g.DrawRectangle(Pens.White, _rectangle);

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
        public override PointF DrawCustomMessages(ChartPane managingPane, GraphicsWrapper g, PointF drawingLocation)
        {
            if (Visible == false)
            {
                return drawingLocation;
            }

            // Draw any standard messages first (if any).
            drawingLocation = base.DrawCustomMessages(managingPane, g, drawingLocation);

            Font font = managingPane.TitleFont;
            if (CustomMessagesFont != null)
            {
                font = CustomMessagesFont;
            }

            foreach (FFNewsCustom.NewsEvent eventItem in Indicator.VisibleNewsEvents)
            {
                TimeSpan span = (eventItem.DateTime - DateTime.UtcNow);
                int hours = (int)Math.Abs(Math.Floor(span.TotalHours));

                string message;
                if (span.TotalSeconds < 0)
                {
                    message = hours.ToString() + " hrs " + Math.Abs(span.Minutes).ToString() + " mins since " + eventItem.Country + ": " + eventItem.Title;
                }
                else
                {
                    message = hours.ToString() + " hrs " + span.Minutes.ToString() + " mins until " + eventItem.Country + ": " + eventItem.Title;
                }
                drawingLocation = DrawCustomMessage(g, font, Indicator.TitleBrush, message, drawingLocation);

                float drawingLocationOriginalX = drawingLocation.X;
                SizeF size = new SizeF();
                if (font != null && Indicator.ImpactBrush != null)
                {
                    // Draw impact part.
                    string impactString = "Impact: " + eventItem.Impact.ToString();
                    size = g.MeasureString(impactString, font);
                    g.DrawString(impactString, font, Indicator.ImpactBrush, drawingLocation);
                    drawingLocation.X += size.Width;
                }

                // Draw previous part.
                if (string.IsNullOrEmpty(eventItem.Previous) == false)
                {
                    if (font != null && Indicator.PreviousBrush != null)
                    {
                        string previousString = "Previous: " + eventItem.Previous;
                        size = g.MeasureString(previousString, font);
                        g.DrawString(previousString, font, Indicator.PreviousBrush, drawingLocation);
                        drawingLocation.X += size.Width;
                    }
                }

                if (string.IsNullOrEmpty(eventItem.Forecast) == false)
                {
                    if (font != null && Indicator.ForecastBrush != null)
                    {
                        string forecastString = "Forecast: " + eventItem.Forecast;
                        size = g.MeasureString(forecastString, font);
                        g.DrawString(forecastString, font, Indicator.ForecastBrush, drawingLocation);
                        drawingLocation.X += size.Width;
                    }
                }

                drawingLocation.X = drawingLocationOriginalX;
                drawingLocation.Y += size.Height;
            }

            return drawingLocation;
        }
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false)
            {
                return;
            }

            if (_controlPoints.Count < 1)
            {
                return;
            }

            PointF point1 = _controlPoints[0];
            PointF point2;
            if (_controlPoints.Count < 2)
            {
                point2 = mousePosition.Value;
            }
            else
            {
                point2 = _controlPoints[1];
            }

            // Clipping opitmization.
            RectangleF rectangle = new RectangleF(
                Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
                Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y));

            if (rectangle.IntersectsWith(clippingRectangle) == false)
            {
                return;
            }

            // Draw base line.
            g.DrawLine(_dashedLinePen, point1, point2);

            float baseLevel = point1.Y;
            float height = point2.Y - point1.Y;

            // Draw fibbonacci levels.
            float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 };
            for (int i = 0; i < levels.Length; i++)
            {
                float actualLevel = baseLevel + height * levels[i] / 100f;
                g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel);
                g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel);
            }

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }
        /// <summary>
        /// Override this routine, to add the price labels at the space outside of the current drawing pane.
        /// </summary>
        /// <param name="managingPane"></param>
        /// <param name="g"></param>
        public override void DrawInitialActualSpaceOverlays(ChartPane managingPane, GraphicsWrapper g)
        {
            base.DrawInitialActualSpaceOverlays(managingPane, g);

            if (_dataProvider == null || _dataProvider.OperationalState != OperationalStateEnum.Operational)
            {
                return;
            }

            decimal? ask = _dataProvider.Quotes.Ask;
            decimal? bid = _dataProvider.Quotes.Bid;

            if (ask.HasValue == false
                || bid.HasValue == false)
            {
                return;
            }

            // Measure based on a default format of 6 symbols.
            SizeF size = g.MeasureString("00.0000", managingPane.LabelsFont);

            Brush fillBrush = managingPane.LabelsFill;
            if (fillBrush == null)
            {
                fillBrush = managingPane.ActualDrawingSpaceAreaFill;
            }

            if (_showCurrentAskLine)
            {
                PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Ask), true);
                position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight;
                position.Y -= size.Height;

                if (fillBrush != null)
                {
                    g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height));
                }

                if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null)
                {
                    g.DrawString(ask.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position);
                    g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width/* - 2*/, size.Height));
                }

            }

            if (_showCurrentBidLine)
            {
                PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Bid), true);
                position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight;

                if (fillBrush != null)
                {
                    g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height));
                }

                if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null)
                {
                    g.DrawString(bid.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position);
                    g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width/* - 2*/, size.Height));
                }
            }
        }
        /// <summary>
        /// Override this routine, to add the price labels at the space outside of the current drawing pane.
        /// </summary>
        /// <param name="managingPane"></param>
        /// <param name="g"></param>
        public override void DrawInitialActualSpaceOverlays(ChartPane managingPane, GraphicsWrapper g)
        {
            base.DrawInitialActualSpaceOverlays(managingPane, g);

            if (_dataProvider == null || _dataProvider.OperationalState != OperationalStateEnum.Operational)
            {
                return;
            }

            decimal?ask = _dataProvider.Quotes.Ask;
            decimal?bid = _dataProvider.Quotes.Bid;

            if (ask.HasValue == false ||
                bid.HasValue == false)
            {
                return;
            }

            // Measure based on a default format of 6 symbols.
            SizeF size = g.MeasureString("00.0000", managingPane.LabelsFont);

            Brush fillBrush = managingPane.LabelsFill;

            if (fillBrush == null)
            {
                fillBrush = managingPane.ActualDrawingSpaceAreaFill;
            }

            if (_showCurrentAskLine)
            {
                PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Ask), true);
                position.X  = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight;
                position.Y -= size.Height;

                if (fillBrush != null)
                {
                    g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height));
                }

                if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null)
                {
                    g.DrawString(ask.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position);
                    g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width /* - 2*/, size.Height));
                }
            }

            if (_showCurrentBidLine)
            {
                PointF position = managingPane.GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, (float)_dataProvider.Quotes.Bid), true);
                position.X = managingPane.Width - managingPane.ActualDrawingSpaceAreaMarginRight;

                if (fillBrush != null)
                {
                    g.FillRectangle(fillBrush, new RectangleF(position.X, position.Y, size.Width, size.Height));
                }

                if (managingPane.LabelsFont != null && managingPane.LabelsFontBrush != null)
                {
                    g.DrawString(bid.Value.ToString(_dataProvider.SessionInfo.ValueFormat), managingPane.LabelsFont, managingPane.LabelsFontBrush, position);
                    g.DrawRectangle(managingPane.ActualDrawingSpaceAreaBorderPen, new RectangleF(position.X, position.Y, size.Width /* - 2*/, size.Height));
                }
            }
        }
Пример #8
0
 /// <summary>
 /// Helper.
 /// </summary>
 protected PointF DrawCustomMessage(GraphicsWrapper g, Font font, Brush brush, string message, PointF drawingLocation)
 {
     if (font != null && brush != null)
     {
         SizeF size = g.MeasureString(message, font);
         g.DrawString(message, font, brush, drawingLocation);
         drawingLocation.Y += size.Height;
     }
     return drawingLocation;
 }
Пример #9
0
        protected virtual void DrawPostActualSpaceOverlays(GraphicsWrapper g)
        {
            if (_titleFont != null && _titleFontBrush != null)
            {
                // Title
                SizeF titleSize = g.MeasureString(_chartName, _titleFont);
                Rectangle titleRectangle = new Rectangle(_actualDrawingSpaceArea.Left, _actualDrawingSpaceArea.Top, (int)titleSize.Width, (int)titleSize.Height);
                g.DrawString(_chartName, _titleFont, _titleFontBrush, titleRectangle.Location);

                PointF drawingLocation = new PointF(_actualDrawingSpaceArea.Left, titleRectangle.Height + _actualDrawingSpaceArea.Top);
                // After the title, render any messages the chart series might have.
                foreach (ChartSeries series in _series)
                {
                    drawingLocation = series.DrawCustomMessages(this, g, drawingLocation);
                }
            }

            if (_actualDrawingSpaceAreaBorderPen != null)
            {
                // Border
                g.DrawRectangle(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceArea.X - 1, _actualDrawingSpaceArea.Y - 1, _actualDrawingSpaceArea.Width + 1, _actualDrawingSpaceArea.Height + 1);
            }
        }
Пример #10
0
        /// <summary>
        /// Initial part of drawing, called by Draw().
        /// Method takes care of setting up the basic drawing parameters of the chart, required for the drawing
        /// to be done; also draws the system overlays.
        /// </summary>
        protected virtual void DrawInitialActualSpaceOverlays(GraphicsWrapper g, TimeBasedChartSeries timeBasedSeries)
        {
            // Since this is dependant on current graphics scaling, also recalculate it here now.
            UpdateYAxisSpacings();

            CalculateActualDrawingSpaceAreaMarginTopAndBottom();

            if (XAxisLabels)
            {// X Axis Labels

                float totalItemWidth = _seriesItemWidth + _seriesItemMargin;
                float actualXSpacing = _xAxisLabelSpacing * totalItemWidth;

                // Consider X axis label scaling.
                int xScaling = Math.Abs((int)(1 / _graphicsWrapper.DrawingSpaceTransformClone.Elements[0]));
                if (xScaling > 1)
                {
                    actualXSpacing = actualXSpacing * xScaling;
                }

                // Set starting to the closes compatible positionactualXSpacing
                // TODO : this can be optimized further by narrowing the range of xStart to end
                float xStart = (int)(_drawingSpaceDisplayLimit.X / actualXSpacing);
                xStart = xStart * actualXSpacing;

                SizeF xAxisLabelTypicalSize = g.MeasureString("00/00/000 00:00", _axisLabelsFont);

                for (float i = xStart; i < _drawingSpaceDisplayLimit.X + _drawingSpaceDisplayLimit.Width; i += actualXSpacing)
                {
                    PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(i, 0), true);

                    if (point.X > (_actualDrawingSpaceArea.X - 2)
                        && point.X < (_actualDrawingSpaceArea.X + _actualDrawingSpaceArea.Width + 2 - xAxisLabelTypicalSize.Width))
                    {
                        int index = (int)(i / totalItemWidth);
                        string message = string.Empty;
                        if (timeBasedSeries != null)
                        {// If there is a leading dateAssignedSeries show labels based on its timing.
                            if (index < timeBasedSeries.ItemsCount)
                            {
                                message = GeneralHelper.GetShortDateTime(timeBasedSeries.GetTimeAtIndex(index));
                            }
                        }
                        else
                        {
                            message = index.ToString(_xAxisLabelsFormat);
                        }

                        if (_axisLabelsFont != null && _xAxisLabelsFontBrush != null)
                        {
                            g.DrawString(message, _axisLabelsFont, _xAxisLabelsFontBrush, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height);
                        }

                        // Draw the small line indicating where the string applies for.
                        g.DrawLine(_actualDrawingSpaceAreaBorderPen, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height + 5);
                    }
                }
            } // X Axis Labels.

            _actualDrawingSpaceAreaMarginLeft = _additionalDrawingSpaceAreaMarginLeft + 5;
            _actualDrawingSpaceAreaMarginRight = _additionalDrawingSpaceAreaMarginRight + 5;

            if (YAxisLabels)
            {// Y Axis Labels.

                int yAxisLabelsWidth = 0;

                // Set starting to the closes compatible positionactualYSpacing
                int maxDecimalPlaces = _autoYAxisLabelSpacing.ToString().Length - 1;

                float yStart = (int)(_drawingSpaceDisplayLimit.Y / _autoYAxisLabelSpacing);
                yStart = yStart * _autoYAxisLabelSpacing;

                // Round off to a fixed number of post decimal point digits, will only work for values under 1
                yStart = (float)Math.Round(yStart, maxDecimalPlaces);

                // This must auto adjust to format the number properly and always fit in 6 spaces.
                // Specify positive, negative and zero formats.
                //_yAxisLabelsFormat = " #0.###;-#0.###; Zero";

                int separatorPosition = _yAxisLabelsFormat.IndexOf(";", 0) - 1;

                // The default is 6 positions total for the y axis labels.
                yAxisLabelsWidth = ((int)g.MeasureString(_yAxisLabelsFormat.Substring(0, separatorPosition), _axisLabelsFont).Width);

                // Calculate the current margin and confirm with any controling subscriber.
                int labelSpacingMargin = yAxisLabelsWidth;

                if (_yAxisLabelsPosition == YAxisLabelPosition.Left ||
                    _yAxisLabelsPosition == YAxisLabelPosition.Both)
                {
                    _actualDrawingSpaceAreaMarginLeft += labelSpacingMargin;
                }

                if (_yAxisLabelsPosition == YAxisLabelPosition.Right ||
                    _yAxisLabelsPosition == YAxisLabelPosition.Both)
                {
                    _actualDrawingSpaceAreaMarginRight += labelSpacingMargin;
                }

                if (_yAxisLabelsPosition != YAxisLabelPosition.None)
                {
                    // A maximum of 10000 steps allowed for this drawing, otherwise some bug is probably present.
                    if ((_drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height - yStart) / _autoYAxisLabelSpacing < 10000)
                    {
                        // Pass 2 - actually draw the labels and label lines at the established and confirmed location.
                        for (float i = yStart; i < _drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height; i += _autoYAxisLabelSpacing)
                        {
                            float iRound = (float)Math.Round(i, maxDecimalPlaces);
                            PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, iRound), true);

                            if (point.Y <= _actualDrawingSpaceArea.Y - 5 ||
                                point.Y >= _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height)
                            {
                                continue;
                            }

                            // Draw labels on the left.
                            if (_yAxisLabelsPosition == YAxisLabelPosition.Left || _yAxisLabelsPosition == YAxisLabelPosition.Both)
                            {
                                if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null)
                                {
                                    g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, _actualDrawingSpaceAreaMarginLeft - yAxisLabelsWidth - 3, point.Y);
                                }

                                // Draw the small line indicating where the string applies for.
                                g.DrawLine(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceAreaMarginLeft - 5, point.Y, _actualDrawingSpaceAreaMarginLeft, point.Y);
                            }

                            // Draw labels on the right.
                            if (_yAxisLabelsPosition == YAxisLabelPosition.Right || _yAxisLabelsPosition == YAxisLabelPosition.Both)
                            {
                                if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null)
                                {
                                    g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush,
                                        this.Width - yAxisLabelsWidth - 3, point.Y);
                                }

                                if (point.Y >= _actualDrawingSpaceArea.Y)
                                {
                                    // Draw the small line indicating where the string applies for.
                                    g.DrawLine(_actualDrawingSpaceAreaBorderPen,
                                        this.Width - yAxisLabelsWidth - 6, point.Y,
                                        this.Width - yAxisLabelsWidth - 3, point.Y);
                                }
                            }
                        }
                    }
                    else
                    {
                        SystemMonitor.OperationError("Too many steps in drawing planned.");
                    }
                }
            }

            foreach (ChartSeries series in _series)
            {
                series.DrawInitialActualSpaceOverlays(this, g);
            }

            UpdateActualDrawingSpaceArea();

            // Actual space, drawing area, grid.
            _actualSpaceGrid.Draw(g, _actualDrawingSpaceArea, _actualDrawingSpaceArea, 1);

            if (ShowSeriesLabels)
            {
                DrawGraphicSeriesLabels(g, _actualDrawingSpaceArea.Left);
            }

            // Show
            if (_customObjectsManager.IsBuildingObject)
            {
                g.DrawImageUnscaledAndClipped(_customObjectDrawingImage, new Rectangle(4, (int)LabelsTopMargin, _customObjectDrawingImage.Width, _customObjectDrawingImage.Height));
            }
        }
Пример #11
0
        protected virtual void DrawGraphicSeriesLabels(GraphicsWrapper g, int initialMarginLeft)
        {
            _currentLabelsRectangles = new Rectangle[_series.Count];

            for (int i = 0; i < _series.Count; i++)
            {
                if (i == 0)
                {
                    _currentLabelsRectangles[0].X = initialMarginLeft;
                }
                else
                {
                    _currentLabelsRectangles[i].X = _currentLabelsRectangles[i - 1].Right + (int)_labelsMargin;
                }

                _currentLabelsRectangles[i].Y = (int)_labelsTopMargin;

                SizeF seriesSize = g.MeasureString(_series[i].Name, _labelsFont);
                _currentLabelsRectangles[i].Size = new Size((int)seriesSize.Width, (int)seriesSize.Height);

                int iconWidth = 18;

                // Add space for series icon
                _currentLabelsRectangles[i].Width += iconWidth;

                if (_labelsFill != null)
                {
                    g.FillRectangle(_labelsFill, _currentLabelsRectangles[i]);
                }

                if (_labelsFont != null)
                {
                    g.DrawString(_series[i].Name, _labelsFont, _labelsFontBrush, _currentLabelsRectangles[i].X + iconWidth, _currentLabelsRectangles[i].Y);
                }

                _series[i].DrawSeriesIcon(g, new Rectangle(_currentLabelsRectangles[i].X + 2, _currentLabelsRectangles[i].Y + 2, 14, _currentLabelsRectangles[i].Height - 4));
            }
        }
Пример #12
0
        public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace)
        {
            if (Visible == false || _controlPoints.Count < 1)
            {
                return;
            }

            if (clippingRectangle.Contains(_controlPoints[0]) == false)
            {// Clipping opitmization.
                return;
            }

            SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont);
            if (size.Height < 0)
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height);
            }
            else
            {
                _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height);
            }

            g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]);

            if (Selected || IsBuilding)
            {
                g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y));
            }

            // Rounding rectangle.
            //g.DrawRectangle(Pens.White, _rectangle);

            if (Selected)
            {
                DrawControlPoints(g);
            }
        }