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

'' This demo illustrates the results of using the GcGraphics.DrawRotatedText() method
'' with different combinations of arguments.
'' The DrawRotatedText() method draws text rotated within a specified rectangle
'' similar to how rotated text is drawn in MS Excel cells without borders.
'' See also the DrawSlantedText_0 demo.
Public Class DrawRotatedText
    Private Shared s_names As String() = New String() {
        "Rotate Counter-clockwise",
        "Rotate Clockwise",
        "Vertical Stacking",
        "Varying RotatedTextAlignment",
        "Vertical Stacking Align",
        "Horizontal Stacking Align"
    }

    Public Function GenerateImage(
        ByVal pixelSize As Size,
        ByVal dpi As Single,
        ByVal opaque As Boolean,
        Optional ByVal sampleParams As String() = Nothing) As GcBitmap

        If sampleParams Is Nothing Then
            sampleParams = GetSampleParamsList()(0)
        End If

        Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi)
        Using g = bmp.CreateGraphics(Color.White)
            '' Set up some values to manage layout:
            Dim margin = g.Resolution
            Dim gap = g.Resolution
            Dim w = pixelSize.Width * 0.3F
            Dim h = w

            Dim q0 = New RectangleF(margin, margin, w, h)
            Dim q1 = New RectangleF(pixelSize.Width - margin - w, margin, w, h)
            Dim q2 = New RectangleF(margin, margin + h + gap, w, h)
            Dim q3 = New RectangleF(pixelSize.Width - margin - w, margin + h + gap, w, h)

            If sampleParams(0) = s_names(0) Then
                '' Draw text at different negative angles:
                Draw(g, q0, -90, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
                Draw(g, q1, -60, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
                Draw(g, q2, -45, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
                Draw(g, q3, -30, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
            ElseIf sampleParams(0) = s_names(1) Then
                '' Draw text at different positive angles:
                Draw(g, q0, -90, False, RotatedTextAlignment.TopRight, TextAlignment.Leading)
                Draw(g, q1, -60, False, RotatedTextAlignment.TopRight, TextAlignment.Leading)
                Draw(g, q2, -45, False, RotatedTextAlignment.TopRight, TextAlignment.Leading)
                Draw(g, q3, -30, False, RotatedTextAlignment.TopRight, TextAlignment.Leading)
            ElseIf sampleParams(0) = s_names(2) Then
                '' Draw text using different vertical stacking:
                Draw(g, q0, -30, True, RotatedTextAlignment.TopRight, TextAlignment.Trailing)
                Draw(g, q1, -30, False, RotatedTextAlignment.TopRight, TextAlignment.Trailing)
                Draw(g, q2, -30, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
                Draw(g, q3, -30, True, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
            ElseIf sampleParams(0) = s_names(3) Then
                '' RotatedTextAlignment affects the location of text (red) within the target rectangle (green):
                Draw(g, q0, -30, True, RotatedTextAlignment.TopRight, TextAlignment.Trailing)
                Draw(g, q1, 60, False, RotatedTextAlignment.BottomRight, TextAlignment.Trailing)
                Draw(g, q2, 30, True, RotatedTextAlignment.TopLeft, TextAlignment.Leading)
                Draw(g, q3, -60, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
            ElseIf sampleParams(0) = s_names(4) Then
                '' Draw vertically stacked text using different TextAlignment values:
                Draw(g, q0, 30, True, RotatedTextAlignment.TopLeft, TextAlignment.Leading)
                Draw(g, q1, 30, True, RotatedTextAlignment.TopLeft, TextAlignment.Trailing)
                Draw(g, q2, 30, True, RotatedTextAlignment.TopLeft, TextAlignment.Center)
                Draw(g, q3, 30, True, RotatedTextAlignment.TopLeft, TextAlignment.Distributed)
            ElseIf sampleParams(0) = s_names(5) Then
                '' Draw horizontally stacked text using different TextAlignment values:
                Draw(g, q0, -70, False, RotatedTextAlignment.BottomLeft, TextAlignment.Leading)
                Draw(g, q1, -70, False, RotatedTextAlignment.BottomLeft, TextAlignment.Trailing)
                Draw(g, q2, -70, False, RotatedTextAlignment.BottomLeft, TextAlignment.Center)
                Draw(g, q3, -70, False, RotatedTextAlignment.BottomLeft, TextAlignment.Distributed)
            End If
        End Using
        Return bmp
    End Function

    Private Shared Sub Draw(g As GcGraphics, rect As RectangleF, angle As Integer, verticalStacking As Boolean,
        rotatedAlign As RotatedTextAlignment, 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($"Rotated text alignment: {rotatedAlign}")
        tlLegend.AppendLine($"Is vertical stacking: {verticalStacking}")
        g.DrawTextLayout(tlLegend, rect.Location)

        '' The target rectangle for the DrawRotatedText call:
        Dim d = tlLegend.ContentHeight + 12
        rect.Y += d
        rect.Height -= d

        Dim tl = g.CreateTextLayout()
        tl.DefaultFormat.FontName = "Calibri"
        tl.DefaultFormat.FontSize = 12
        tl.Append("The quick brown fox jumps over the lazy dog. ")
        tl.Append("The quick brown fox jumps over the lazy dog.")
        tl.TextAlignment = textAlign
        '' Draw rotated text:
        g.DrawRotatedText(tl, angle, verticalStacking, rect, rotatedAlign)

        '' Outline the target rectangle in green:
        g.DrawRectangle(rect, New GCDRAW.Pen(Color.PaleGreen, 3))
        '' Outline the actual text rectangle in red:
        Dim tlCopy = tl.Clone(True)
        Dim tlRect = g.MeasureRotatedText(tlCopy, angle, verticalStacking, rect, rotatedAlign)
        g.DrawRectangle(tlRect, New GCDRAW.Pen(Color.Red, 1))
    End Sub

    '' Strings are name, description, info. Rest are arbitrary strings:
    Public Shared Function GetSampleParamsList() As List(Of String())
        Return New List(Of String()) From {
            New String() {s_names(0), "Draw rotated text at different negative angles", Nothing},
            New String() {s_names(1), "Draw rotated text at different positive angles", Nothing},
            New String() {s_names(2), "Draw rotated text using different vertical stacking", Nothing},
            New String() {s_names(3), "Draw text using different rotated text alignments", Nothing},
            New String() {s_names(4), "Draw vertically stacked text using different TextAlignment values", Nothing},
            New String() {s_names(5), "Draw horizontally stacked text using different TextAlignment values", Nothing}
        }
    End Function
End Class