SvgGraphicsText.vb
'' 
'' このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
'' 
Imports System
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Imaging
Imports GrapeCity.Documents.Svg
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' このサンプルは、GcSvgGraphics を使用して SVG 上にテキストを描画する方法を示します。
'' パスではなく、実際の SVG の <text> 要素としてテキストを描画する方法を示し、
'' これにより、テキストは検索、選択、コピーが可能な状態に保たれます。
'' 本デモでは、専用の DrawRoundRect / FillRoundRect メソッドを使用する方法と、
'' カスタムのグラフィックスパスを構築する方法の2通りで
'' 角丸四角形を描画します。
'' 図形の内部には DrawString を使用してラベルを追加し、
'' 最終結果は SVG ドキュメントとして保存されます。
'' RoundRectangle および SvgGraphicsRoundRectangle のサンプルも参照してください。
Public Class SvgGraphicsText
    Public ReadOnly Property DefaultMime As String
        Get
            Return Util.MimeTypes.SVG
        End Get
    End Property

    Public Function GenerateImageStream(
            ByVal targetMime As String,
            ByVal pixelSize As Size,
            ByVal dpi As Single,
            ByVal opaque As Boolean,
            Optional ByVal sampleParams As String() = Nothing) As Stream

        If targetMime <> Util.MimeTypes.SVG Then
            Throw New Exception("This sample only supports SVG output format.")
        End If

        Dim Inch = dpi
        Dim ms = New MemoryStream()
        Using g As New GcSvgGraphics(pixelSize.Width, pixelSize.Height)

            '' 重要:GcSvgGraphicsではこのプロパティはデフォルトでTrueに設定されています。
            '' 通常はその方がテキストの再現性が高くなりますが、その場合、テキストの検索・選択・コピーができなくなり、
            '' SVGのファイルサイズも大きくなります。
            '' このプロパティをFalseに設定すると、テキストはSVGの 'text' 要素を使用してレンダリングされるため、
            '' テキストの検索・選択・コピーが可能になります。
            '' この例と同一ですが、テキストをパスとして描画する SvgGraphicsRoundRectangle の例と比較してみてください。
            g.DrawTextAsPath = False

            If opaque Then
                g.FillRectangle(New RectangleF(0, 0, g.Width, g.Height), Color.White)
            End If

            Dim rc = Util.AddNote(
                "GcGraphics has dedicated methods to easily draw and fill rectangles with rounded corners. " +
                "This sample also shows how the same result may be achieved using graphics paths. " +
                "While they are not really needed for drawing round rectangles, graphics paths allow " +
                "to draw and fill arbitrary figures with complex geometries." & vbCrLf & vbCrLf &
                "Note that this version of the ""Round Rectangles"" sample draws on a GcSvgGraphics, " +
                "and produces a vector SVG image rather than a raster image (JPEG, PNG etc.).",
                g)

            '' 角丸長方形の半径です。
            Dim rx As Single = 36, ry As Single = 24

            '' 専用メソッドを使用して角丸長方形を描画および塗りつぶします。
            Dim rEasy = New RectangleF(rc.Left, rc.Bottom + Inch / 2, Inch * 2, Inch)
            g.FillRoundRect(rEasy, rx, ry, Color.PaleGreen)
            g.DrawRoundRect(rEasy, rx, ry, Color.Blue, 4)
            '' ラベルを追加します。
            Dim tf = New TextFormat() With {
                .Font = GCTEXT.Font.FromFile(System.IO.Path.Combine("Resources", "Fonts", "FreeSerif.ttf")),
                .FontSize = Inch / 6
            }
            g.DrawString("The easy way.", tf, rEasy, TextAlignment.Center, ParagraphAlignment.Center, False)

            '' グラフィックスパスを使用して同じ結果を実現します。
            Dim rHard = rEasy
            rHard.Offset(0, rEasy.Height + Inch / 2)
            Dim path = MakeRoundRect(g, rHard, rx, ry)
            g.FillPath(path, Color.PaleVioletRed)
            g.DrawPath(path, Color.Purple, 4)
            '' ラベルを追加します。
            g.DrawString("The hard way.", tf, rHard, TextAlignment.Center, ParagraphAlignment.Center, False)

            '' 画像ファイルを保存します。
            Dim svg = g.ToSvgDocument()
            svg.Save(ms)
            ms.Seek(0, SeekOrigin.Begin)
            Return ms
        End Using
    End Function

    '' このメソッドは、GcGraphics上で任意の形状を塗りつぶしたり描画したりするために使用できる
    '' グラフィックスパスの作成方法を示しています。
    Private Function MakeRoundRect(g As GcGraphics, rc As RectangleF, rx As Single, ry As Single) As IPath
        Dim path = g.CreatePath()
        Dim sz = New SizeF(rx, ry)
        '' 上部左側の水平部分から開始します。
        path.BeginFigure(New PointF(rc.Left + rx, rc.Top))
        path.AddLine(New PointF(rc.Right - rx, rc.Top))
        path.AddArc(New ArcSegment() With {.Point = New PointF(rc.Right, rc.Top + ry), .SweepDirection = SweepDirection.Clockwise, .Size = sz})
        path.AddLine(New PointF(rc.Right, rc.Bottom - ry))
        path.AddArc(New ArcSegment() With {.Point = New PointF(rc.Right - rx, rc.Bottom), .SweepDirection = SweepDirection.Clockwise, .Size = sz})
        path.AddLine(New PointF(rc.Left + rx, rc.Bottom))
        path.AddArc(New ArcSegment() With {.Point = New PointF(rc.Left, rc.Bottom - ry), .SweepDirection = SweepDirection.Clockwise, .Size = sz})
        path.AddLine(New PointF(rc.Left, rc.Top + ry))
        path.AddArc(New ArcSegment() With {.Point = New PointF(rc.Left + rx, rc.Top), .SweepDirection = SweepDirection.Clockwise, .Size = sz})
        path.EndFigure(FigureEnd.Closed)
        Return path
    End Function
End Class