'**************************************************************
' IDAutomation DotCode Font Encoder 2020
' © Copyright, 2020 IDAutomation.com, Inc. All rights reserved.
' Portions of this program utilize IDAutomation USA Patent 7,637,436
'
'' To provide the quickest implementation, consider
'' licensing this product instead of using the demo.
'' The licensed version is provided with a 30 day
'' money back satisfaction guarantee.
'' To order, please visit:
'' https://www.idautomation.com/
'' 
''*****************************************************************
'' Limitations of the Demo Version:
'' The demo version of this product includes a fully
'' functional 2D font and is designed only for the
'' purpose of testing the font in various applications
'' and point sizes. To generate dynamic symbols,
'' a font encoder is required to format the data being
'' encoded into the 2D symbol.
'' Only static data can be provided for the encoders
'' in the demo version, because providing a working
'' encoder would reveal the complete source code,
'' which is only available in the licensed version.
'' 
''*****************************************************************
''
'' Please refer to the User Manual and Included Examples
'' https://www.idautomation.com/barcode-components/dotnet-standard/
''
''*****************************************************************


Imports System.Text

''' <summary>
''' FontEncoder DotCode barcode class.
''' </summary>
Public Class DotCode


    Dim aMatrix(,) As Integer
    Dim NCOL As Integer
    Dim NROW As Integer
    Dim iQZ As Integer

    ''   Optional Parameter Defaults may be changed below
    ''   DataToEncode                 text to encode
    ''   ReturnType                   0 (font circles), 1 (font squares), 2 (Courier), 3 (Courier), 4 (Courier)
    ''   ProcessTilde = 1             If = 1 the Tilde will be processed | http://www.idautomation.com/barcode-faq/2d/dotcode/#Control_Characters
    ''   Mask = 0                     Default 0 (best mask, fast process), 1 (best mask, slow process), 2 (Mask 0), 3 (Mask 1), 4 (Mask 2), 5 (Mask 3)
    ''                                When = 1 the mask will be processed and symbols will take more time to generate
    ''   NewLineCharacter = vbCrLf

    ''' <summary>
    ''' Function, which creates a dotcode barcode, depending on the various input options chosen. 
    ''' </summary>
    ''' <param name="DataToEncode">The data that Is encoded in the barcode.</param>
    ''' <param name="ApplyTilde">Enables processing of tilde And parentheses characters for purposes of encoding ASCII functions And GS1 application identifiers.</param>
    ''' <param name="EncodingMode">Various modes used to Data represented in the symbol may be encoded by one of these types.</param>
    ''' <param name="Ratio">Represents the Columns (Width) to Rows (Height) Aspect Ratio.</param>
    ''' <param name="Columns">Represents the columns sizes of the symbol.</param>
    ''' <param name="Rows">Represents the rows sizes of the symbol.</param>
    ''' <param name="Mask">Represents the various pattern for mask of the symbol.</param>
    ''' <param name="QuietZone">Define the size of a blank zone around the code.</param>
    ''' <param name="ModuleSize">Define the size of each module.</param>
    ''' <returns>An array representation of barcode's image.</returns>
    Public Function EncodeDotCode(DataToEncode As String,
                                  Optional ApplyTilde As Boolean = True,
                                  Optional EncodingMode As EncodingModes = EncodingModes.Auto,
                                  Optional Ratio As Integer = 21,
                                  Optional Columns As Integer = 0,
                                  Optional Rows As Integer = 0,
                                  Optional Mask As Integer = 0,
                                  Optional QuietZone As Integer = 1,
                                  Optional ModuleSize As Integer = 1)

        Call _encode(DataToEncode, ApplyTilde, EncodingMode, Ratio, Columns, Rows, Mask, QuietZone)

        Dim Result As Byte()
        Dim k As Integer
        Dim intPad As Integer = 0
        Dim pixels As Integer
        Dim bit As Integer
        Dim bWidth As Integer
        Dim x As Integer
        Dim y As Integer
        Dim ncols As Integer
        Dim nrows As Integer

        ModuleSize = ModuleSize * 2 + 1


        ncols = (NCOL + 2 * iQZ) * ModuleSize
        nrows = (NROW + 2 * iQZ) * ModuleSize

        bWidth = (Math.Floor((ncols) / 8) + (If((ncols) Mod 8 > 0, 1, 0)))
        Dim intTemp As Integer = bWidth Mod 4
        If (intTemp <> 0) Then
            intPad = 4 - intTemp
        End If

        ReDim Result(64 + nrows * (bWidth + intPad) - 1)


        Result(0) = &H42
        Result(1) = &H4D
        For k = 0 To 7
            Result(2 + k) = 0
        Next
        Result(10) = &H3E
        For k = 0 To 2
            Result(11 + k) = 0
        Next
        Result(14) = &H28
        For k = 0 To 2
            Result(15 + k) = 0
        Next

        '' width
        Result(18) = CByte(Math.Floor((ncols) Mod 256))
        Result(19) = CByte(Math.Floor((ncols) / 256))
        Result(20) = 0
        Result(21) = 0

        '' height
        Result(22) = CByte(Math.Floor((nrows) Mod 256))
        Result(23) = CByte(Math.Floor((nrows) / 256))
        Result(24) = 0
        Result(25) = 0

        Result(26) = 1
        Result(27) = 0
        Result(28) = 1
        Result(29) = 0
        For k = 0 To 7
            Result(30 + k) = 0
        Next
        Result(38) = &H25
        Result(39) = &HE
        Result(40) = 0
        Result(41) = 0

        Result(42) = &H25
        Result(43) = &HE
        Result(44) = 0
        Result(45) = 0

        For k = 0 To 7
            Result(46 + k) = 0
        Next

        For k = 0 To 2
            Result(54 + k) = &HFF
        Next
        For k = 0 To 4
            Result(57 + k) = 0
        Next

        Dim pos As Integer = 62
        Dim bFlag As Boolean
        Dim cx As Integer
        Dim cy As Integer

        For y = nrows - 1 To 0 Step -1

            pixels = 0
            bit = 8

            For x = 0 To ncols - 1

                bFlag = (aMatrix(Int(y / ModuleSize), Int(x / ModuleSize)) <> 0)
                If bFlag Then
                    cx = Int(x / ModuleSize) * ModuleSize + Int((ModuleSize / 2))
                    cy = Int(y / ModuleSize) * ModuleSize + Int((ModuleSize / 2))

                    If ModuleSize = 3 Then
                        bFlag = (cx = x) Or (cy = y)
                    Else
                        bFlag = bFlag And ((y - cy) ^ 2 + (x - cx) ^ 2 <= (ModuleSize / 2) ^ 2)
                    End If

                End If
                If bFlag Then
                    bit = bit - 1
                    pixels = pixels + Math.Floor(Math.Pow(2, bit))
                    If (bit = 0) Then
                        Result(pos) = CByte(pixels)
                        pos += 1
                        bit = 8
                        pixels = 0
                    End If

                Else
                    bit = bit - 1
                    If (bit = 0) Then
                        Result(pos) = CByte(pixels)
                        pos += 1
                        bit = 8
                        pixels = 0
                    End If

                End If
            Next
            If (bit <> 8) Then
                Result(pos) = CByte(pixels)
                pos += 1
            End If
            pos = pos + intPad
        Next

        Return Result


    End Function


    ''' <summary>
    ''' Function, which creates a dotcode barcode, depending on the various input options chosen. 
    ''' </summary>
    ''' <param name="DataToEncode">The data that Is encoded in the barcode.</param>
    ''' <param name="ApplyTilde">Enables processing of tilde And parentheses characters for purposes of encoding ASCII functions And GS1 application identifiers.</param>
    ''' <param name="EncodingMode">Various modes used to Data represented in the symbol may be encoded by one of these types.</param>
    ''' <param name="Ratio">Represents the Columns (Width) to Rows (Height) Aspect Ratio.</param>
    ''' <param name="Columns">Represents the columns sizes of the symbol.</param>
    ''' <param name="Rows">Represents the rows sizes of the symbol.</param>
    ''' <param name="Mask">Represents the various pattern for mask of the symbol.</param>
    ''' <param name="VectorType">Define the type of vector image for output.</param>
    ''' <param name="NewLine">String indicating EOL character. Defaults to the operating system EOL character if left NULL.</param>
    ''' <param name="QuietZone">Define the size of a blank zone around the code.</param>
    ''' <param name="ModuleSize">Define the size of each module.</param>
    ''' <returns>A string representation of vector dotcode's image.</returns>

    Public Function EncodeDotCode(DataToEncode As String,
                                  Optional ApplyTilde As Boolean = True,
                                  Optional EncodingMode As EncodingModes = EncodingModes.Auto,
                                  Optional Ratio As Integer = 21,
                                  Optional Columns As Integer = 0,
                                  Optional Rows As Integer = 0,
                                  Optional Mask As Integer = 0,
                                  Optional VectorType As VectorTypes = VectorTypes.VecEPS,
                                  Optional NewLine As String = "",
                                  Optional QuietZone As Integer = 1,
                                  Optional ModuleSize As Integer = 1)

        Call _encode(DataToEncode, ApplyTilde, EncodingMode, Ratio, Columns, Rows, Mask, QuietZone)

        '' allows user to set an end-of-line (EOL) string
        If (NewLine = "") Then
            NewLine = Environment.NewLine '' Default
        End If

        Dim strOut As StringBuilder = New StringBuilder("")
        Dim tempW As String
        Dim tempH As String
        Dim x As Integer
        Dim y As Integer
        Dim ncols As Integer
        Dim nrows As Integer

        ncols = NCOL + 2 * iQZ
        nrows = NROW + 2 * iQZ

        ModuleSize = ModuleSize * 4
        tempW = (ncols * ModuleSize).ToString()
        tempH = (nrows * ModuleSize).ToString()

        If (VectorType = VectorTypes.VecSVG) Then

            strOut.Append("<?xml version='1.0' standalone='no'?>" + NewLine)
            strOut.Append("<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>" + NewLine)
            strOut.Append("<svg width='" + tempW + "' height='" + tempH + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" + NewLine)
            strOut.Append("  <g id='dotcode'>" + NewLine)
            strOut.Append("    <g id='background' fill='#ffffff' stroke='#ffffff'>" + NewLine)
            strOut.Append("      <rect x='0' y='0' width='" + tempW + "' height='" + tempH + "' />" + NewLine)
            strOut.Append("    </g>" + NewLine)
            strOut.Append("    <g id='pattern' fill='#000000' stroke='#000000'>" + NewLine)

            For y = 0 To nrows - 1
                For x = 0 To ncols - 1
                    If (aMatrix(y, x) <> 0) Then
                        strOut.Append("    <g id='R" + y.ToString() + "C" + x.ToString() + "' >" + NewLine)
                        strOut.Append(Replace("      <circle cx='" + ((x + 0.5) * ModuleSize).ToString() + "' cy='" + ((y + 0.5) * ModuleSize).ToString() + "' r='" + (0.98 * ModuleSize / 2).ToString() + "' />", ",", ".") + NewLine)
                        strOut.Append("    </g>" + NewLine)
                    End If
                Next
            Next
            strOut.Append("    </g>" + NewLine)
            strOut.Append("  </g>" + NewLine)
            strOut.Append("</svg>" + NewLine)

        ElseIf (VectorType = VectorTypes.VecEPS) Then
            strOut.Append("%!PS-Adobe-3.0 EPSF-3.0" + NewLine)
            strOut.Append("%%Creator: IDAutomation.com" + NewLine)
            strOut.Append("%%Title: dotcode" + NewLine)
            strOut.Append("%%CreationDate: " + DateTime.Now.ToString("ddd mmm d hh:mm:ss yyyy") + NewLine)
            strOut.Append("%%BoundingBox: 0 0 " + tempW + " " + tempH + NewLine)
            strOut.Append("%%DocumentData: Clean7Bit" + NewLine)
            strOut.Append("%%EndComments" + NewLine)
            strOut.Append("%%BeginProlog" + NewLine)
            strOut.Append("/bd { bind def } bind def" + NewLine)
            strOut.Append("/incompound false def" + NewLine)
            strOut.Append("/m { moveto } bd" + NewLine)
            strOut.Append("/l { lineto } bd" + NewLine)
            strOut.Append("/*U { /incompound false def f} bd" + NewLine)
            strOut.Append("/k { setcmykcolor } bd" + NewLine)

            strOut.Append("/c { curveto } bd" + NewLine)
            strOut.Append("/F { incompound not {fill} if } bd" + NewLine)
            strOut.Append("/f { closepath F } bd" + NewLine)
            strOut.Append("/S { stroke } bd" + NewLine)
            strOut.Append("/*u { /incompound true def } bd" + NewLine)
            strOut.Append("/K { k } bd" + NewLine)

            strOut.Append("%%EndProlog" + NewLine)
            strOut.Append("%%BeginSetup" + NewLine)
            strOut.Append("%%EndSetup" + NewLine)
            strOut.Append("0.000 0.000 0.000 0.000 k" + NewLine)
            strOut.Append("0 0 m" + NewLine)
            strOut.Append("0 0 l" + NewLine)
            strOut.Append(tempW + " 0 l" + NewLine)
            strOut.Append(tempW + " " + tempH + " l" + NewLine)
            strOut.Append("0 " + tempH + " l" + NewLine)
            strOut.Append("f" + NewLine)
            strOut.Append("*U" + NewLine)

            Dim sngLx As Single
            Dim sngLy As Single

            sngLx = 4 / 3 * (Math.Sqrt(2) - 1) * (ModuleSize / 2)
            sngLy = 4 / 3 * (Math.Sqrt(2) - 1) * (ModuleSize / 2)

            Dim n As Integer = Rows * ModuleSize
            strOut.Append("0.000 0.000 0.000 1.000 k" + NewLine)
            For y = 0 To nrows - 1
                For x = 0 To ncols - 1
                    If (aMatrix(y, x) <> 0) Then
                        strOut.Append(Replace(((x + 1) * ModuleSize).ToString() + " " + ((nrows - y - 0.5) * ModuleSize).ToString() + " m" + NewLine, ",", "."))

                        strOut.Append(Replace(((x + 1) * ModuleSize).ToString() + " " + (nrows * ModuleSize - ((y + 0.5) * ModuleSize - sngLy)).ToString() + " " +
                                                ((x + 0.5) * ModuleSize + sngLx).ToString() + " " + ((nrows - y) * ModuleSize).ToString() + " " +
                                                ((x + 0.5) * ModuleSize).ToString() + " " + ((nrows - y) * ModuleSize).ToString() + " c" + NewLine, ",", "."))

                        strOut.Append(Replace(((x + 0.5) * ModuleSize - sngLx).ToString() + " " + ((nrows - y) * ModuleSize).ToString() + " " +
                                                (x * ModuleSize).ToString() + " " + (nrows * ModuleSize - ((y + 0.5) * ModuleSize - sngLy)).ToString() + " " +
                                                (x * ModuleSize).ToString() + " " + ((nrows - y - 0.5) * ModuleSize).ToString() + " c" + NewLine, ",", "."))

                        strOut.Append(Replace((x * ModuleSize).ToString() + " " + (nrows * ModuleSize - ((y + 0.5) * ModuleSize + sngLy)).ToString() + " " +
                                                ((x + 0.5) * ModuleSize - sngLx).ToString() + " " + ((nrows - y - 1) * ModuleSize).ToString() + " " +
                                                ((x + 0.5) * ModuleSize).ToString() + " " + ((nrows - y - 1) * ModuleSize).ToString() + " c" + NewLine, ",", "."))

                        strOut.Append(Replace(((x + 0.5) * ModuleSize + sngLx).ToString() + " " + ((nrows - y - 1) * ModuleSize).ToString() + " " +
                                                ((x + 1) * ModuleSize).ToString() + " " + (nrows * ModuleSize - ((y + 0.5) * ModuleSize + sngLy)).ToString() + " " +
                                                ((x + 1) * ModuleSize).ToString() + " " + ((nrows - y - 0.5) * ModuleSize).ToString() + " c" + NewLine, ",", "."))
                        strOut.Append("f" + NewLine)
                    End If
                Next
            Next

            strOut.Append("*U" + NewLine)
            strOut.Append("%%Trailer" + NewLine)
            strOut.Append("%%EOF" + NewLine)

        ElseIf (VectorType = VectorTypes.VecHTML) Then
            strOut.Append("<meta http-equiv='X-UA-Compatible' content='IE=10' />")
            strOut.Append("<div style='font-size:0;background-color:#ffffff;position:relative;width:" + tempW + "px;height:" + tempH + "px;'>" + NewLine)

            For y = 0 To nrows - 1
                For x = 0 To ncols - 1
                    If (aMatrix(y, x) <> 0) Then
                        strOut.Append("<div style='-webkit-border-radius:50%; -moz-border-radius:50%; border-radius:50%; background:#000000;width:" + ModuleSize.ToString() + "px;height:" + ModuleSize.ToString() + "px;position:absolute;left:" + (x * ModuleSize).ToString() + "px;top:" + (y * ModuleSize).ToString() + "px;'>&nbsp</div>" + NewLine)
                    End If
                Next
            Next

            strOut.Append("</div>" + NewLine)
        End If

        Return strOut.ToString()
    End Function


    ''' <summary>
    ''' Function, which creates a dotcode barcode, depending on the various input options chosen. 
    ''' </summary>
    ''' <param name="DataToEncode">The data that Is encoded in the barcode.</param>
    ''' <param name="ReturnType">Represents the type of output text 0 (font circles), 1 (font squares), 2 (Courier), 3 (Courier), 4 (Courier)</param>
    ''' <param name="ApplyTilde">Enables processing of tilde And parentheses characters for purposes of encoding ASCII functions And GS1 application identifiers.</param>
    ''' <param name="EncodingMode">Various modes used to Data represented in the symbol may be encoded by one of these types.</param>
    ''' <param name="Ratio">Represents the Columns (Width) to Rows (Height) Aspect Ratio.</param>
    ''' <param name="Columns">Represents the columns sizes of the symbol.</param>
    ''' <param name="Rows">Represents the rows sizes of the symbol.</param>
    ''' <param name="NewLine">String indicating EOL character. Defaults to the operating system EOL character if left NULL.</param>
    ''' <param name="Mask">Represents the various pattern for mask of the symbol.</param>
    ''' <param name="QuietZone">Define the size of a blank zone around the code.</param>
    ''' <returns>Encoded text for use with the 2D barcode font.</returns>
    Public Function EncodeDotCode(DataToEncode As String,
                                  Optional ReturnType As Integer = 0,
                                  Optional ApplyTilde As Boolean = True,
                                  Optional EncodingMode As EncodingModes = EncodingModes.Auto,
                                  Optional Ratio As Integer = 21,
                                  Optional Columns As Integer = 0,
                                  Optional Rows As Integer = 0,
                                  Optional NewLine As String = "",
                                  Optional Mask As Integer = 0,
                                  Optional QuietZone As Integer = 1) As String

        'DataToEncode must have a value; otherwise null is returned

        EncodeDotCode = ""
        Try

            If (DataToEncode.Length > 0) And ((EncodingMode >= -1) Or (EncodingMode <= 3)) Then

                Call _encode(DataToEncode, ApplyTilde, EncodingMode, Ratio, Columns, Rows, Mask, QuietZone)

                '' allows user to set an end-of-line (EOL) string
                If (NewLine = "") Then
                    NewLine = Environment.NewLine '' Default
                End If

                EncodeDotCode = Matrix2Font(ReturnType, NewLine)
            End If

        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try

    End Function


    Private Sub _encode(DataToEncode As String,
                  Optional ProcessTilde As Integer = 1,
                  Optional EncodingMode As EncodingModes = EncodingModes.Auto,
                  Optional Ratio As Integer = 21,
                  Optional Columns As Integer = 0,
                  Optional Rows As Integer = 0,
                  Optional Mask As Integer = 0,
                  Optional QuietZone As Integer = 1)

        iQZ = 1

        NROW = 18
        NCOL = 35
        aMatrix = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                        {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                        {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0},
                        {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0},
                        {0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
                        {0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0},
                        {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0},
                        {0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
                        {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                        {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
                        {0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0},
                        {0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0},
                        {0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
                        {0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                        {0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0},
                        {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
                        {0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
                        {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0},
                        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        }

    End Sub

    Private Function Matrix2Font(ReturnType As Integer, NewLineCharacter As String) As String
        Dim x As Integer
        Dim y As Integer
        Dim result As String
        Dim FontSet(4) As String

        FontSet(0) = "abcdefghijklmnop"
        FontSet(1) = "ABCDEFGHIJKLMNOP"
        FontSet(2) = " " & ChrW(9679)
        FontSet(3) = " " & ChrW(&H2666) 'ChrW(9670)
        FontSet(4) = ChrW(8729) & ChrW(9679)

        result = ""

        If (ReturnType >= 0) And (ReturnType <= 1) Then
            For y = 0 To NROW + 2 * iQZ - 1 Step 4
                For x = 0 To NCOL + 2 * iQZ - 1
                    If aMatrix(y, x) = 0 Then
                        If aMatrix(y + 1, x) = 0 Then
                            If aMatrix(y + 2, x) = 0 Then
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 16, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 15, 1)
                                End If
                            Else
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 14, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 13, 1)
                                End If
                            End If
                        Else
                            If aMatrix(y + 2, x) = 0 Then
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 12, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 11, 1)
                                End If
                            Else
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 10, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 9, 1)
                                End If
                            End If
                        End If
                    Else

                        If aMatrix(y + 1, x) = 0 Then
                            If aMatrix(y + 2, x) = 0 Then
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 8, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 7, 1)
                                End If
                            Else
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 6, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 5, 1)
                                End If
                            End If
                        Else
                            If aMatrix(y + 2, x) = 0 Then
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 4, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 3, 1)
                                End If
                            Else
                                If aMatrix(y + 3, x) = 0 Then
                                    result = result & Mid(FontSet(ReturnType), 2, 1)
                                Else
                                    result = result & Mid(FontSet(ReturnType), 1, 1)
                                End If
                            End If
                        End If

                    End If
                Next
                result = result & NewLineCharacter
            Next

        ElseIf (ReturnType > 1) And (ReturnType <= 4) Then

            For y = 0 To NROW + 2 * iQZ - 1
                For x = 0 To NCOL + 2 * iQZ - 1
                    If aMatrix(y, x) = 0 Then
                        result = result & Mid(FontSet(ReturnType), 1, 1)
                    Else
                        result = result & Mid(FontSet(ReturnType), 2, 1)
                    End If

                    '' remove extraspace on QuietZone
                    If (x >= iQZ) And (x < NCOL + iQZ - 1) Then result = result & Mid(FontSet(ReturnType), 1, 1)

                Next
                result = result & NewLineCharacter
            Next

        End If

        Matrix2Font = result

    End Function


End Class


''' <summary>
''' Various modes used to Data represented in the symbol may be encoded by one of these types.
''' </summary>
Public Enum EncodingModes
    '''  <summary>
    '''  In this mode data Is encoded with SetCodeC
    '''  </summary>
    Auto

    '''  <summary>
    '''  In this mode data Is encoded with SetCodeA
    '''  </summary>
    CodeSetA

    '''  <summary>
    '''  In this mode data Is encoded with SetCodeB
    '''  </summary>
    CodeSetB


    '''  <summary>
    '''  In this mode data Is encoded with SetCodeC
    '''  </summary>
    CodeSetC

    '''  <summary>
    '''  In this mode data Is encoded with Binary
    '''  </summary>
    Binary
End Enum


''' <summary>
''' Various types of vector image output.
''' </summary>
Public Enum VectorTypes

    ''' <summary>
    ''' Returns a string with the SVG representation. 
    ''' </summary>
    VecSVG

    ''' <summary>
    ''' Return a string with the EPS representation.
    ''' </summary>
    VecEPS

    ''' <summary>
    ''' Return a string with the HTML representation.
    ''' </summary>
    VecHTML

End Enum