DrawSlantedText.vb
''
'' This code is part of Document Solutions for PDF .NET demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

Public Class DrawSlantedText
    Public Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.Pages.Add()
        Dim g = page.Graphics
        ' Set up some values to manage layout:
        Dim gap = g.Resolution
        Dim w = page.Size.Width / 3
        Dim h = w

        ' Various text alignments with SlantedTextAlignment.BelowRotatedInside:
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Distributed)
        ' Various text alignments with SlantedTextAlignment.BelowRotatedOutside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Distributed)
        ' Various text alignments with SlantedTextAlignment.AboveRotatedInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Distributed)
        ' Various text alignments with SlantedTextAlignment.AboveRotatedOutside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Distributed)
        ' Various text alignments with SlantedTextAlignment.CenterInsideOutside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterInsideOutside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterInsideOutside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterInsideOutside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterInsideOutside, TextAlignment.Distributed)
        ' Various text alignments with SlantedTextAlignment.CenterOutsideInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-70, False, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Distributed)
        ' Examples with positive rotation angle using SlantedTextAlignment.BelowRotatedInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=70, False, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Distributed)
        ' Examples with positive rotation angle using SlantedTextAlignment.AboveRotatedInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=70, False, SlantedTextAlignment.AboveRotatedInside, TextAlignment.Distributed)

        ' Below are examples of vertically stacked text.

        ' Vertically stacked text rotated to a negative angle using SlantedTextAlignment.BelowRotatedInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedInside, TextAlignment.Distributed)
        ' Vertically stacked text rotated to a negative angle using SlantedTextAlignment.BelowRotatedOutside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=-20, True, SlantedTextAlignment.BelowRotatedOutside, TextAlignment.Distributed)
        ' Vertically stacked text rotated to a positive angle using SlantedTextAlignment.AboveRotatedOutside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=20, True, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=20, True, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=20, True, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=20, True, SlantedTextAlignment.AboveRotatedOutside, TextAlignment.Distributed)
        ' Vertically stacked text rotated to a positive angle using SlantedTextAlignment.CenterOutsideInside:
        page = doc.Pages.Add()
        g = page.Graphics
        Draw(g, New RectangleF(gap, gap, w, h), angle:=20, True, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Leading)
        Draw(g, New RectangleF(gap + w + gap, gap, w, h), angle:=20, True, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Trailing)
        Draw(g, New RectangleF(gap, gap + h + gap, w, h), angle:=20, True, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Center)
        Draw(g, New RectangleF(gap + w + gap, gap + h + gap, w, h), angle:=20, True, SlantedTextAlignment.CenterOutsideInside, TextAlignment.Distributed)

        doc.Save(stream)
        Return doc.Pages.Count
    End Function

    Shared Sub Draw(ByVal g As GcGraphics, ByVal rect As RectangleF, ByVal angle As Integer, ByVal verticalStacking As Boolean,
            ByVal slantedAlign As SlantedTextAlignment, ByVal textAlign As TextAlignment)
        ' Draw a legend stating the current DrawRotatedText arguments' values:
        Dim tlLegend = g.CreateTextLayout()
        tlLegend.DefaultFormat.FontName = "Calibri"
        tlLegend.DefaultFormat.FontSize = 9
        tlLegend.AppendLine($"Rotation angle: {angle}°")
        tlLegend.AppendLine($"Text alignment: {textAlign}")
        tlLegend.AppendLine($"Slanted text alignment: {slantedAlign}")
        tlLegend.AppendLine($"Is vertical stacking: {verticalStacking}")
        g.DrawTextLayout(tlLegend, rect.Location)

        ' The target rectangle for the DrawRotatedText call:
        Dim d = tlLegend.ContentHeight + g.Resolution
        rect.Y += d
        rect.Height -= d
        rect.Width -= d / 2
        Dim x = rect.X
        Dim y = rect.Y
        Dim w = rect.Width
        Dim h = rect.Height

        ' Draw the target rectangle:
        g.DrawRectangle(rect, New GCDRAW.Pen(Color.PaleGreen, 3))

        If Not verticalStacking Then
            Dim dx = CSng(h / Math.Tan(Math.PI * angle / -180.0))
            Select Case slantedAlign
                Case SlantedTextAlignment.BelowRotatedInside,
                     SlantedTextAlignment.AboveRotatedOutside,
                     SlantedTextAlignment.CenterInsideOutside
                    g.DrawPolygon(New PointF() {
                        New PointF(x + dx, y), New PointF(x + dx + w, y),
                        New PointF(x + w, y + h), New PointF(x, y + h)},
                        New GCDRAW.Pen(Color.Red, 1))
                Case SlantedTextAlignment.BelowRotatedOutside,
                     SlantedTextAlignment.AboveRotatedInside,
                     SlantedTextAlignment.CenterOutsideInside
                    g.DrawPolygon(New PointF() {
                        New PointF(x, y), New PointF(x + w, y),
                        New PointF(x - dx + w, y + h), New PointF(x - dx, y + h)},
                        New GCDRAW.Pen(Color.Red, 1))
            End Select
        Else
            Dim dy = CSng(w * Math.Tan(Math.PI * angle / 180.0))
            Select Case slantedAlign
                Case SlantedTextAlignment.BelowRotatedInside,
                     SlantedTextAlignment.AboveRotatedOutside,
                     SlantedTextAlignment.CenterInsideOutside
                    If angle >= 0 Then
                        g.DrawPolygon(New PointF() {
                            New PointF(x, y), New PointF(x + w, y + dy), New PointF(x + w, y + dy + h), New PointF(x, y + h)},
                            New GCDRAW.Pen(Color.Red, 1))
                    Else
                        g.DrawPolygon(New PointF() {
                            New PointF(x, y - dy), New PointF(x + w, y), New PointF(x + w, y + h), New PointF(x, y - dy + h)},
                            New GCDRAW.Pen(Color.Red, 1))
                    End If
                Case SlantedTextAlignment.BelowRotatedOutside,
                     SlantedTextAlignment.AboveRotatedInside,
                     SlantedTextAlignment.CenterOutsideInside
                    If angle >= 0 Then
                        g.DrawPolygon(New PointF() {
                            New PointF(x, y - dy), New PointF(x + w, y), New PointF(x + w, y + h), New PointF(x, y - dy + h)},
                            New GCDRAW.Pen(Color.Red, 1))
                    Else
                        g.DrawPolygon(New PointF() {
                            New PointF(x, y), New PointF(x + w, y + dy), New PointF(x + w, y + dy + h), New PointF(x, y + h)},
                            New GCDRAW.Pen(Color.Red, 1))
                    End If
            End Select
        End If
        ' Draw slanted text:
        Dim tl = g.CreateTextLayout()
        tl.DefaultFormat.FontName = "Calibri"
        tl.DefaultFormat.FontSize = 12
        tl.TextAlignment = textAlign
        tl.Append("The quick brown fox jumps over the lazy dog. ")
        tl.Append("The quick brown fox jumps over the lazy dog.")
        g.DrawSlantedText(tl, angle, verticalStacking, rect, slantedAlign)
    End Sub
End Class