Ejemplo n.º 1
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            OxyPlot.HorizontalAlignment halign,
            OxyPlot.VerticalAlignment valign,
            OxySize?maxSize)
        {
            var tb = new TextBlock {
                Text = text, Foreground = new SolidColorBrush(fill.ToColor())
            };

            // tb.SetValue(TextOptions.TextHintingModeProperty, TextHintingMode.Animated);
            if (fontFamily != null)
            {
                tb.FontFamily = new FontFamily(fontFamily);
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            tb.FontWeight = GetFontWeight(fontWeight);

            tb.Measure(new Size(1000, 1000));
            var size = new Size(tb.ActualWidth, tb.ActualHeight);

            if (maxSize != null)
            {
                if (size.Width > maxSize.Value.Width)
                {
                    size.Width = maxSize.Value.Width;
                }

                if (size.Height > maxSize.Value.Height)
                {
                    size.Height = maxSize.Value.Height;
                }

                tb.Clip = new RectangleGeometry {
                    Rect = new Rect(0, 0, size.Width, size.Height)
                };
            }

            double dx = 0;

            if (halign == OxyPlot.HorizontalAlignment.Center)
            {
                dx = -size.Width / 2;
            }

            if (halign == OxyPlot.HorizontalAlignment.Right)
            {
                dx = -size.Width;
            }

            double dy = 0;

            if (valign == OxyPlot.VerticalAlignment.Middle)
            {
                dy = -size.Height / 2;
            }

            if (valign == OxyPlot.VerticalAlignment.Bottom)
            {
                dy = -size.Height;
            }

            var transform = new TransformGroup();

            transform.Children.Add(new TranslateTransform {
                X = (int)dx, Y = (int)dy
            });
            if (!rotate.Equals(0))
            {
                transform.Children.Add(new RotateTransform {
                    Angle = rotate
                });
            }

            transform.Children.Add(new TranslateTransform {
                X = (int)p.X, Y = (int)p.Y
            });
            tb.RenderTransform = transform;
            this.ApplyTooltip(tb);

            if (this.clip)
            {
                // add a clipping container that is not rotated
                var c = new Canvas();
                c.Children.Add(tb);
                this.Add(c);
            }
            else
            {
                this.Add(tb);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The draw text.
        /// </summary>
        /// <param name="p">The p.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotate.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            OxyPlot.HorizontalAlignment halign,
            OxyPlot.VerticalAlignment valign,
            OxySize?maxSize)
        {
            if (fill.IsInvisible() || string.IsNullOrEmpty(text))
            {
                return;
            }

            var tb = new TextBlock {
                Text = text, Foreground = fill.ToBrush()
            };

            // tb.SetValue(TextOptions.TextHintingModeProperty, TextHintingMode.Animated);
            if (fontFamily != null)
            {
                tb.FontFamily = new FontFamily(fontFamily);
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            tb.FontWeight = GetFontWeight(fontWeight);

            tb.Measure(new Size(1000, 1000));

            double dx = 0;

            if (halign == OxyPlot.HorizontalAlignment.Center)
            {
                dx = -tb.ActualWidth / 2;
            }

            if (halign == OxyPlot.HorizontalAlignment.Right)
            {
                dx = -tb.ActualWidth;
            }

            double dy = 0;

            if (valign == OxyPlot.VerticalAlignment.Middle)
            {
                dy = -tb.ActualHeight / 2;
            }

            if (valign == OxyPlot.VerticalAlignment.Bottom)
            {
                dy = -tb.ActualHeight;
            }

            var transform = new TransformGroup();

            transform.Children.Add(new TranslateTransform {
                X = (int)dx, Y = (int)dy
            });
            if (!rotate.Equals(0.0))
            {
                transform.Children.Add(new RotateTransform {
                    Angle = rotate
                });
            }

            transform.Children.Add(new TranslateTransform {
                X = (int)p.X, Y = (int)p.Y
            });
            tb.RenderTransform = transform;

            if (this.clip.HasValue)
            {
                // add a clipping container that is not rotated
                var c = new Canvas();
                c.Children.Add(tb);
                this.Add(c);
            }
            else
            {
                this.Add(tb);
            }
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily = null, double fontSize = 10, double fontWeight = 400, double rotation = 0, OxyPlot.HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Left, OxyPlot.VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Top, OxySize?maxSize = null)
        {
            if (text == null || !fill.IsVisible())
            {
                return;
            }

            var font           = this.GetFontOrThrow(fontFamily, fontSize, this.ToFontStyle(fontWeight));
            var actualFontSize = this.NominalFontSizeToPoints(fontSize);

            var outputX        = this.Convert(p.X);
            var outputY        = this.Convert(p.Y);
            var outputPosition = new PointF(outputX, outputY);

            var cos = (float)Math.Cos(rotation * Math.PI / 180.0);
            var sin = (float)Math.Sin(rotation * Math.PI / 180.0);

            // measure bounds of the whole text (we only need the height)
            var bounds       = this.MeasureTextLoose(text, fontFamily, fontSize, fontWeight);
            var boundsHeight = this.Convert(bounds.Height);
            var offsetHeight = new PointF(boundsHeight * -sin, boundsHeight * cos);

            // determine the font metrids for this font size at 96 DPI
            var actualDescent = this.Convert(actualFontSize * this.MilliPointsToNominalResolution(font.Descender));
            var offsetDescent = new PointF(actualDescent * -sin, actualDescent * cos);

            var actualLineHeight = this.Convert(actualFontSize * this.MilliPointsToNominalResolution(font.LineHeight));
            var offsetLineHeight = new PointF(actualLineHeight * -sin, actualLineHeight * cos);

            var actualLineGap = this.Convert(actualFontSize * this.MilliPointsToNominalResolution(font.LineGap));
            var offsetLineGap = new PointF(actualLineGap * -sin, actualLineGap * cos);

            // find top of the whole text
            var deltaY = verticalAlignment switch
            {
                OxyPlot.VerticalAlignment.Top => 1.0f,
                OxyPlot.VerticalAlignment.Middle => 0.5f,
                OxyPlot.VerticalAlignment.Bottom => 0.0f,
                _ => throw new ArgumentOutOfRangeException(nameof(verticalAlignment)),
            };

            // this is the top of the top line
            var topPosition = outputPosition + (offsetHeight * deltaY) - offsetHeight;

            // need this later
            var deltaX = horizontalAlignment switch
            {
                OxyPlot.HorizontalAlignment.Left => - 0.0f,
                OxyPlot.HorizontalAlignment.Center => - 0.5f,
                OxyPlot.HorizontalAlignment.Right => - 1.0f,
                _ => throw new ArgumentOutOfRangeException(nameof(horizontalAlignment)),
            };

            var lines = StringHelper.SplitLines(text);

            for (int li = 0; li < lines.Length; li++)
            {
                var line = lines[li];

                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                // measure bounds of just the line (we only need the width)
                var lineBounds      = this.MeasureTextLoose(line, fontFamily, fontSize, fontWeight);
                var lineBoundsWidth = this.Convert(lineBounds.Width);
                var offsetLineWidth = new PointF(lineBoundsWidth * cos, lineBoundsWidth * sin);

                // find the left baseline position
                var lineTop          = topPosition + (offsetLineGap * li) + (offsetLineHeight * li);
                var lineBaseLineLeft = lineTop + offsetLineWidth * deltaX + offsetLineHeight + offsetDescent;

                // this seems to produce consistent and correct results, but we have to rotate it manually, so render it at the origin for simplicity
                var glyphsAtOrigin = TextBuilder.GenerateGlyphs(line, new PointF(0f, 0f), new RendererOptions(font, this.Dpi, this.Dpi)
                {
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment   = VerticalAlignment.Bottom, // sit on the line (baseline)
                    ApplyKerning        = true,
                });

                // translate and rotate into possition
                var transform = Matrix3x2Extensions.CreateRotationDegrees((float)rotation);
                transform.Translation = lineBaseLineLeft;
                var glyphs = glyphsAtOrigin.Transform(transform);

                // draw the glyphs
                this.Target.Mutate(img =>
                {
                    img.Fill(ToRgba32(fill), glyphs);
                });
            }
        }
Ejemplo n.º 4
0
        public void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily = null, double fontSize = 10, double fontWeight = 500, double rotate = 0, OxyPlot.HorizontalAlignment halign = HorizontalAlignment.Left, VerticalAlignment valign = VerticalAlignment.Top, OxySize?maxSize = new OxySize?())
        {
            using (var paint = new Paint())
            {
                paint.AntiAlias = true;
                paint.TextSize  = (float)fontSize;
                paint.Color     = fill.ToColor();
                var bounds = new Rect();
                paint.GetTextBounds(text, 0, text.Length, bounds);

                float dx = 0;
                if (halign == HorizontalAlignment.Center)
                {
                    dx = -bounds.Width() / 2;
                }

                if (halign == HorizontalAlignment.Right)
                {
                    dx = -bounds.Width();
                }

                float dy = 0;
                if (valign == VerticalAlignment.Middle)
                {
                    dy = +bounds.Height() / 2;
                }

                if (valign == VerticalAlignment.Top)
                {
                    dy = bounds.Height();
                }

                canvas.Save();
                canvas.Translate(dx, dy);
                canvas.Rotate((float)rotate);
                canvas.Translate((float)p.X, (float)p.Y);
                canvas.DrawText(text, 0, 0, paint);
                canvas.Restore();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The text color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            var tb = this.CreateAndAdd <TextBlock>();

            tb.Text       = text;
            tb.Foreground = this.GetCachedBrush(fill);
            if (fontFamily != null)
            {
                tb.FontFamily = this.GetCachedFontFamily(fontFamily);
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            if (fontWeight > 0)
            {
                tb.FontWeight = GetFontWeight(fontWeight);
            }

#if !NET35
            TextOptions.SetTextFormattingMode(tb, this.TextFormattingMode);
#endif

            double dx = 0;
            double dy = 0;

            if (maxSize != null || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Top)
            {
                tb.Measure(new Size(1000, 1000));
                var size = tb.DesiredSize;
                if (maxSize != null)
                {
                    if (size.Width > maxSize.Value.Width + 1e-3)
                    {
                        size.Width = Math.Max(maxSize.Value.Width, 0);
                    }

                    if (size.Height > maxSize.Value.Height + 1e-3)
                    {
                        size.Height = Math.Max(maxSize.Value.Height, 0);
                    }

                    tb.Width  = size.Width;
                    tb.Height = size.Height;
                }

                if (halign == HorizontalAlignment.Center)
                {
                    dx = -size.Width / 2;
                }

                if (halign == HorizontalAlignment.Right)
                {
                    dx = -size.Width;
                }

                if (valign == VerticalAlignment.Middle)
                {
                    dy = -size.Height / 2;
                }

                if (valign == VerticalAlignment.Bottom)
                {
                    dy = -size.Height;
                }
            }

            var transform = new TransformGroup();
            transform.Children.Add(new TranslateTransform(dx, dy));
            if (Math.Abs(rotate) > double.Epsilon)
            {
                transform.Children.Add(new RotateTransform(rotate));
            }

            transform.Children.Add(new TranslateTransform(p.X, p.Y));
            tb.RenderTransform = transform;
            if (tb.Clip != null)
            {
                tb.Clip.Transform = tb.RenderTransform.Inverse as Transform;
            }

#if !NET35
            tb.SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Enabled);
#endif
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The text color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            var tb = CreateAndAdd <TextBlock>();

            tb.Text       = text;
            tb.Foreground = GetCachedBrush(fill);
            if (fontFamily != null)
            {
                tb.FontFamily = fontFamily;
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            if (fontWeight > 0)
            {
                tb.FontWeight = GetFontWeight(fontWeight);
            }

            double dx = 0;
            double dy = 0;

            if (maxSize != null || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Top)
            {
                tb.Measure(new Size(1000, 1000));
                var size = tb.DesiredSize;
                if (maxSize != null)
                {
                    if (size.Width > maxSize.Value.Width + 1e-3)
                    {
                        size = size.WithWidth(Math.Max(maxSize.Value.Width, 0));
                    }

                    if (size.Height > maxSize.Value.Height + 1e-3)
                    {
                        size = size.WithHeight(Math.Max(maxSize.Value.Height, 0));
                    }

                    tb.Width  = size.Width;
                    tb.Height = size.Height;
                }

                if (halign == HorizontalAlignment.Center)
                {
                    dx = -size.Width / 2;
                }

                if (halign == HorizontalAlignment.Right)
                {
                    dx = -size.Width;
                }

                if (valign == VerticalAlignment.Middle)
                {
                    dy = -size.Height / 2;
                }

                if (valign == VerticalAlignment.Bottom)
                {
                    dy = -size.Height;
                }
            }

            var transform = new TransformGroup();

            transform.Children.Add(new TranslateTransform(dx, dy));
            if (Math.Abs(rotate) > double.Epsilon)
            {
                transform.Children.Add(new RotateTransform(rotate));
            }

            transform.Children.Add(new TranslateTransform(p.X, p.Y));
            tb.RenderTransform = transform;
            if (tb.Clip != null)
            {
                tb.Clip.Transform = new MatrixTransform(tb.RenderTransform.Value.Invert());
            }
        }
Ejemplo n.º 7
0
        /// <inheritdoc/>
        public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily = null, double fontSize = 10, double fontWeight = 400, double rotation = 0, OxyPlot.HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Left, OxyPlot.VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Top, OxySize?maxSize = null)
        {
            var font = GetFontOrThrow(fontFamily, fontSize, FontStyle.Regular);

            float outputX = (float)p.X;
            float outputY = (float)p.Y;

            var bounds = MeasureText(text, fontFamily, fontSize, fontWeight);

            switch (horizontalAlignment)
            {
            case OxyPlot.HorizontalAlignment.Center:
                outputX = (float)(outputX - bounds.Width / 2.0);
                break;

            case OxyPlot.HorizontalAlignment.Right:
                outputX = (float)(outputX - bounds.Width);
                break;
            }

            switch (verticalAlignment)
            {
            case OxyPlot.VerticalAlignment.Bottom:
                outputY = (float)(outputY - bounds.Height);
                break;

            case OxyPlot.VerticalAlignment.Middle:
                outputY = (float)(outputY - bounds.Height / 2.0);
                break;
            }

            var outputPosition = new PointF(outputX, outputY);

            image.Mutate(img =>
            {
                img.DrawText(text, font, new Rgba32(fill.R, fill.G, fill.B, fill.A), outputPosition);
            });
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            OxyPlot.HorizontalAlignment halign,
            OxyPlot.VerticalAlignment valign,
            OxySize?maxSize)
        {
            if (string.IsNullOrWhiteSpace(fontFamily))
            {
                fontFamily = "Arial";
            }

            if (text == null)
            {
                text = string.Empty;
            }

            var format    = new TextFormat(this.dwtFactory, fontFamily, GetFontWeight(fontWeight), FontStyle.Normal, FontStretch.Normal, (float)fontSize);
            var maxWidth  = 1000f;
            var maxHeight = 1000f;

            if (maxSize != null)
            {
                maxHeight = (float)maxSize.Value.Height;
                maxWidth  = (float)maxSize.Value.Width;
            }

            var layout = new TextLayout(this.dwtFactory, text, format, maxWidth, maxHeight);

            var size = new Size2F(layout.Metrics.Width, layout.Metrics.Height);

            if (maxSize != null)
            {
                if (size.Width > maxSize.Value.Width)
                {
                    size.Width = (float)maxSize.Value.Width;
                }

                if (size.Height > maxSize.Value.Height)
                {
                    size.Height = (float)maxSize.Value.Height;
                }
            }

            float dx = 0;

            if (halign == OxyPlot.HorizontalAlignment.Center)
            {
                dx = -size.Width / 2;
            }

            if (halign == OxyPlot.HorizontalAlignment.Right)
            {
                dx = -size.Width;
            }

            float dy = 0;

            if (valign == OxyPlot.VerticalAlignment.Middle)
            {
                dy = -size.Height / 2;
            }

            if (valign == OxyPlot.VerticalAlignment.Bottom)
            {
                dy = -size.Height;
            }

            this.renderUnits.Add(new TextRenderUnit(layout, this.GetBrush(fill), Matrix3x2.Translation(dx, dy) * Matrix3x2.Rotation((float)rotate) * Matrix3x2.Translation(p.ToVector2())));
            format.Dispose();
        }
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize? maxSize)
        {
            var tb = new TextBlock { Text = text, Foreground = this.GetCachedBrush(fill) };
            if (fontFamily != null)
            {
                tb.FontFamily = new FontFamily(fontFamily);
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            if (fontWeight > 0)
            {
                tb.FontWeight = GetFontWeight(fontWeight);
            }

            double dx = 0;
            double dy = 0;

            if (maxSize != null || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Top)
            {
                tb.Measure(new Size(1000, 1000));
                var size = tb.DesiredSize;
                if (maxSize != null)
                {
                    if (size.Width > maxSize.Value.Width)
                    {
                        size.Width = Math.Max(maxSize.Value.Width, 0);
                    }

                    if (size.Height > maxSize.Value.Height)
                    {
                        size.Height = Math.Max(maxSize.Value.Height, 0);
                    }

                    tb.Width = size.Width;
                    tb.Height = size.Height;
                }

                if (halign == HorizontalAlignment.Center)
                {
                    dx = -size.Width / 2;
                }

                if (halign == HorizontalAlignment.Right)
                {
                    dx = -size.Width;
                }

                if (valign == VerticalAlignment.Middle)
                {
                    dy = -size.Height / 2;
                }

                if (valign == VerticalAlignment.Bottom)
                {
                    dy = -size.Height;
                }
            }

            var transform = new TransformGroup();
            transform.Children.Add(new TranslateTransform(dx, dy));
            if (Math.Abs(rotate) > double.Epsilon)
            {
                transform.Children.Add(new RotateTransform(rotate));
            }

            transform.Children.Add(new TranslateTransform(p.X, p.Y));
            tb.RenderTransform = transform;
            tb.SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Enabled);
            this.ApplyTooltip(tb);

            if (this.clip.HasValue)
            {
                // add a clipping container that is not rotated
                var c = new Canvas();
                c.Children.Add(tb);
                this.Add(c);
            }
            else
            {
                this.Add(tb);
            }
        }
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            var tb = new TextBlock {
                Text = text, Foreground = this.GetCachedBrush(fill)
            };

            if (fontFamily != null)
            {
                tb.FontFamily = new FontFamily(fontFamily);
            }

            if (fontSize > 0)
            {
                tb.FontSize = fontSize;
            }

            if (fontWeight > 0)
            {
                tb.FontWeight = GetFontWeight(fontWeight);
            }

            double dx = 0;
            double dy = 0;

            if (maxSize != null || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Top)
            {
                tb.Measure(new Size(1000, 1000));
                var size = tb.DesiredSize;
                if (maxSize != null)
                {
                    if (size.Width > maxSize.Value.Width)
                    {
                        size.Width = Math.Max(maxSize.Value.Width, 0);
                    }

                    if (size.Height > maxSize.Value.Height)
                    {
                        size.Height = Math.Max(maxSize.Value.Height, 0);
                    }

                    tb.Width  = size.Width;
                    tb.Height = size.Height;
                }

                if (halign == HorizontalAlignment.Center)
                {
                    dx = -size.Width / 2;
                }

                if (halign == HorizontalAlignment.Right)
                {
                    dx = -size.Width;
                }

                if (valign == VerticalAlignment.Middle)
                {
                    dy = -size.Height / 2;
                }

                if (valign == VerticalAlignment.Bottom)
                {
                    dy = -size.Height;
                }
            }

            var transform = new TransformGroup();

            transform.Children.Add(new TranslateTransform(dx, dy));
            if (Math.Abs(rotate) > double.Epsilon)
            {
                transform.Children.Add(new RotateTransform(rotate));
            }

            transform.Children.Add(new TranslateTransform(p.X, p.Y));
            tb.RenderTransform = transform;
            tb.SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Enabled);
            this.ApplyTooltip(tb);

            if (this.clip.HasValue)
            {
                // add a clipping container that is not rotated
                var c = new Canvas();
                c.Children.Add(tb);
                this.Add(c);
            }
            else
            {
                this.Add(tb);
            }
        }