SurrogatesPort.vb
''
'' This code is part of GrapeCity Documents for PDF samples.
'' Copyright (c) GrapeCity, Inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text

'' This sample renders a variety of interesting Unicode characters
'' including surrogate pairs, similar to the Surrogates sample.
'' Unlike that sample though, it does not rely on any system-provided
'' fallbacks. Instead, in this sample we purposefully restrict fallback
'' font lookup to the program's own font collection, and provide
'' our own set of fallback fonts.
'' This makes the code platform and system independent, so it produces
'' exactly the same result on Windows, Linux or Mac.
Public Class SurrogatesPort
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.NewPage()
        Dim g = page.Graphics

        '' As in the Surrogates sample, we specify a standard font
        '' (which lacks many of the glyphs we will be rendering),
        '' and will rely on font fallback support provided by FontCollection:
        Dim font = StandardFonts.Helvetica

        '' Set up text formats for captions, "interesting chars" and spacing:
        Dim tf = New TextFormat() With {.Font = font, .FontSize = 12}
        Dim tf1 = New TextFormat(tf) With {.FontSize = 14}
        Dim tfs = New TextFormat(tf) With {.FontSize = 6}

        '' Create a font collection to use:
        Dim fc = New FontCollection()
        '' Add our own fallback fonts to use (note that order is imortant here,
        '' first come first found):
        fc.AppendFallbackFonts(
            Font.FromFile(Path.Combine("Resources", "Fonts", "arialuni.ttf")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "l_10646.ttf")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "seguiemj.ttf")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "seguisym.ttf")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "simsun.ttc")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
            Font.FromFile(Path.Combine("Resources", "Fonts", "YuGothR.ttc"))
        )

        '' Restricting default font lookup is done in the TextLayout, so unlike the
        '' {Surrogates} sample, here we cannot use DrawString, but must use
        '' TextLayout and DrawTextLayout directly.
        '' Notes: 
        ''  - Specify the font collection to use;
        ''  - Restrict default fonts/fallbacks lookup to the specified collection only.
        Dim tl = New TextLayout(72) With {
            .FontCollection = fc,
            .RestrictedFontLookup = True,
            .FontFallbackScope = FontFallbackScope.FontCollectionOnly,
            .MaxWidth = page.Size.Width,
            .MaxHeight = page.Size.Height,
            .MarginLeft = 72,
            .MarginRight = 72,
            .MarginTop = 36,
            .MarginBottom = 36,
            .TextAlignment = TextAlignment.Center
        }

        tl.Append("Some Interesting Unicode Characters (system-independent)",
                  New TextFormat(tf) With {.Underline = True, .FontSize = tf.FontSize + 2})
        tl.PerformLayout(True)
        g.DrawTextLayout(tl, PointF.Empty)

        tl.MarginTop = tl.ContentRectangle.Bottom + 20
        tl.Clear()
        tl.TextAlignment = TextAlignment.Leading

        '' Draw the strings:
        tl.Append("Surrogate Pairs:" + vbCrLf, tf)
        tl.Append($"{ChrW(&HD867)}{ChrW(&HDEDB)} {ChrW(&HD840)}{ChrW(&HDC0B)} {ChrW(&HD834)}{ChrW(&HDD1E)} {ChrW(&HD834)}{ChrW(&HDD61)} {ChrW(&HD83D)}{ChrW(&HDC04)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Currency Symbols:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H24)} {ChrW(&H20A0)} {ChrW(&H20A1)} {ChrW(&H20A2)} {ChrW(&H20A3)} {ChrW(&H20A4)} {ChrW(&H20AC)} {ChrW(&H20B9)} {ChrW(&H20BD)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Mathematical Operators:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H221A)} {ChrW(&H222B)} {ChrW(&H2211)} {ChrW(&H2210)} {ChrW(&H2264)} {ChrW(&H2265)} {ChrW(&H2202)} {ChrW(&H2208)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("CJK Ideographs Extension A:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H3400)} {ChrW(&H3401)} {ChrW(&H3402)} {ChrW(&H3403)} {ChrW(&H3404)} {ChrW(&H3405)} {ChrW(&H3406)} {ChrW(&H3407)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Letterlike Symbols:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H2110)} {ChrW(&H2111)} {ChrW(&H2112)} {ChrW(&H2113)} {ChrW(&H2114)} {ChrW(&H2115)} {ChrW(&H211B)} {ChrW(&H211C)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Private Use Area:" + vbCrLf, tf)
        tl.Append($"{ChrW(&HE000)} {ChrW(&HE001)} {ChrW(&HE010)} {ChrW(&HE011)} {ChrW(&HE012)} {ChrW(&HE013)} {ChrW(&HE014)} {ChrW(&HE015)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Arrows:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H2190)} {ChrW(&H2191)} {ChrW(&H2192)} {ChrW(&H2193)} {ChrW(&H21B0)} {ChrW(&H21E6)} {ChrW(&H21CB)} {ChrW(&H21A9)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Dingbats:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H2714)} {ChrW(&H2717)} {ChrW(&H275B)} {ChrW(&H275C)} {ChrW(&H2706)} {ChrW(&H2707)} {ChrW(&H2708)} {ChrW(&H2709)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Braille Patterns:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H2830)} {ChrW(&H2831)} {ChrW(&H2832)} {ChrW(&H2833)} {ChrW(&H2834)} {ChrW(&H2835)} {ChrW(&H2836)} {ChrW(&H2837)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Geometric Shapes:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H25D0)} {ChrW(&H25D1)} {ChrW(&H25D2)} {ChrW(&H25D3)} {ChrW(&H25A4)} {ChrW(&H25F0)} {ChrW(&H25BC)} {ChrW(&H25CE)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Latin Extended A:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H100)} {ChrW(&H101)} {ChrW(&H102)} {ChrW(&H103)} {ChrW(&H104)} {ChrW(&H105)} {ChrW(&H106)} {ChrW(&H107)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.Append("Miscellaneous Symbols:" + vbCrLf, tf)
        tl.Append($"{ChrW(&H2600)} {ChrW(&H2601)} {ChrW(&H2602)} {ChrW(&H2603)} {ChrW(&H2604)} {ChrW(&H2605)} {ChrW(&H2606)} " +
                  $"{ChrW(&H2607)} {ChrW(&H2608)} {ChrW(&H2609)} {ChrW(&H2614)} {ChrW(&H2615)} {ChrW(&H26F0)}{vbCrLf}", tf1)
        tl.Append(vbCrLf, tfs)

        tl.PerformLayout(True)
        g.DrawTextLayout(tl, PointF.Empty)
        ''
        '' Done:
        doc.Save(stream)
        Return doc.Pages.Count
    End Function
End Class