Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
TLT Reader - TLTFormat.vb

TLTFormat.vb

Caricato da: Totem
Scarica il programma completo

  1. Imports System.IO
  2. Imports System.IO.Compression
  3. Imports System.Text.UTF8Encoding
  4. Namespace TLTFormat
  5.     'Questa classe rappresenta un chunk di testo e tutte le
  6.     'informazioni di formattazione ad esso connesse
  7.     Public Class TextChunk
  8.         'Enumeratore per l'allineamento. Ne esiste già uno,
  9.         'ma non ha il campo Giustificato
  10.         Public Enum Alignment
  11.             Left
  12.             Right
  13.             Center
  14.             Justify
  15.         End Enum
  16.  
  17.         'Grassetto
  18.         Private _IsBold As Boolean = False
  19.         'Corsivo
  20.         Private _IsItalic As Boolean = False
  21.         'Sottolineato
  22.         Private _IsUnderlined As Boolean = False
  23.         'Colore
  24.         Private _Color As Color = Drawing.Color.Black
  25.         'Nome del font
  26.         Private _FontName As String = "Times New Roman"
  27.         'Dimensione
  28.         Private _Size As Byte = 12
  29.         'Testo del chunk
  30.         Private _Text As String
  31.         'Allineamento
  32.         Private _Align As Alignment = Alignment.Left
  33.  
  34.         Public Property IsBold() As Boolean
  35.             Get
  36.                 Return _IsBold
  37.             End Get
  38.             Set(ByVal Value As Boolean)
  39.                 _IsBold = Value
  40.             End Set
  41.         End Property
  42.  
  43.         Public Property IsItalic() As Boolean
  44.             Get
  45.                 Return _IsItalic
  46.             End Get
  47.             Set(ByVal Value As Boolean)
  48.                 _IsItalic = Value
  49.             End Set
  50.         End Property
  51.  
  52.         Public Property IsUnderlined() As Boolean
  53.             Get
  54.                 Return _IsUnderlined
  55.             End Get
  56.             Set(ByVal Value As Boolean)
  57.                 _IsUnderlined = Value
  58.             End Set
  59.         End Property
  60.  
  61.         Public Property Color() As Color
  62.             Get
  63.                 Return _Color
  64.             End Get
  65.             Set(ByVal Value As Color)
  66.                 _Color = Value
  67.             End Set
  68.         End Property
  69.  
  70.         Public Property FontName() As String
  71.             Get
  72.                 Return _FontName
  73.             End Get
  74.             Set(ByVal Value As String)
  75.                 _FontName = Value
  76.             End Set
  77.         End Property
  78.  
  79.         Public Property Size() As Byte
  80.             Get
  81.                 Return _Size
  82.             End Get
  83.             Set(ByVal Value As Byte)
  84.                 _Size = Value
  85.             End Set
  86.         End Property
  87.  
  88.         Public Property Text() As String
  89.             Get
  90.                 Return _Text
  91.             End Get
  92.             Set(ByVal Value As String)
  93.                 _Text = Value
  94.             End Set
  95.         End Property
  96.  
  97.         Public Property Align() As Alignment
  98.             Get
  99.                 Return _Align
  100.             End Get
  101.             Set(ByVal value As Alignment)
  102.                 _Align = value
  103.             End Set
  104.         End Property
  105.  
  106.         'Questa proprietà è speciale.
  107.         'Permette di ottenere in un solo colpo tutte le
  108.         'caratteristiche di formattazione del chunk
  109.         'restituendo una classe font completa
  110.         Public ReadOnly Property Font() As Font
  111.             Get
  112.                 Dim Style As FontStyle
  113.  
  114.                 'Costruiamo lo stile del font a poco a poco,
  115.                 'poiché questo è un enumeratore su bit
  116.                 If Me.IsBold Then
  117.                     Style = Style Or FontStyle.Bold
  118.                 End If
  119.                 If Me.IsItalic Then
  120.                     Style = Style Or FontStyle.Italic
  121.                 End If
  122.                 If Me.IsUnderlined Then
  123.                     Style = Style Or FontStyle.Underline
  124.                 End If
  125.  
  126.                 Return New Font(Me.FontName, Me.Size, Style)
  127.             End Get
  128.         End Property
  129.     End Class
  130.  
  131.     'Questa classe ha il compito di scrivere su un file
  132.     'il testo formattato secondo le specifiche TLT
  133.     Public Class Writer
  134.         'Questa collezione conterrà una lista di
  135.         'tutti i piccoli pezzettini di testo che si devono
  136.         'scrivere
  137.         Private _Chunks As New List(Of TextChunk)
  138.  
  139.         Public ReadOnly Property Chunks() As List(Of TextChunk)
  140.             Get
  141.                 Return _Chunks
  142.             End Get
  143.         End Property
  144.  
  145.         'Questa funzione serve a comprimere il testo
  146.         Private Function Compress(ByVal Str As String) As Byte()
  147.             'Usiamo dei MemoryStream per due motivi:
  148.             '- Il testo proviene dall'applicazione, non da un file, ed è
  149.             '  sottoforma di stringa.
  150.             '- Non possiamo non usare uno stream, perchè la classe
  151.             '  di compressione lo richiede espressamente
  152.             'Lo stream che legge i dati dalla stringa
  153.             Dim Input As MemoryStream
  154.             'Lo stream di scrittura associato al file compresso
  155.             Dim Output As MemoryStream
  156.             'Lo stream compresso che scrive i dati codificati per mezzo
  157.             'dell'output stream
  158.             Dim Zipped As DeflateStream
  159.             'Risultato della compressione
  160.             Dim Result(), Buffer() As Byte
  161.  
  162.             'Inizializza lo stream di input
  163.             Input = New MemoryStream(UTF8.GetBytes(Str))
  164.             'Inizializza lo stream di output
  165.             Output = New MemoryStream()
  166.             'Inizializza lo zipper
  167.             Zipped = New DeflateStream(Output, CompressionMode.Compress)
  168.  
  169.             ReDim Buffer(Input.Length - 1)
  170.             Input.Read(Buffer, 0, Input.Length)
  171.             Zipped.Write(Buffer, 0, Buffer.Length)
  172.  
  173.             'Trasferisce  dati compressi sullo stream
  174.             Zipped.Flush()
  175.             ReDim Result(Output.Length - 1)
  176.             Output.Seek(0, SeekOrigin.Begin)
  177.             Output.Read(Result, 0, Output.Length)
  178.  
  179.             'Quindi chiude tutti gli stream
  180.             Zipped.Close()
  181.             Output.Close()
  182.             Input.Close()
  183.  
  184.             Return Result
  185.         End Function
  186.  
  187.         Public Sub Write(ByVal File As String)
  188.             'Il writer principale
  189.             Dim Writer As New BinaryWriter(New FileStream(File, FileMode.Create))
  190.  
  191.             'Scrive TLT
  192.             Dim b() As Byte = UTF8.GetBytes("TLT")
  193.             Writer.Write(UTF8.GetBytes("TLT"))
  194.  
  195.             'Scrive ogni chunk
  196.             For Each C As TextChunk In Me.Chunks
  197.                 'Questo byte contiene tutte le informazione, come
  198.                 'descritto dalle specificazioni che ho inventato
  199.                 Dim Flags As Byte = 0
  200.  
  201.                 'Aggiungere 128 significa impostare a 1 il primo bit
  202.                 'Infatti 128 in binario è 10000000
  203.                 If C.IsBold Then
  204.                     Flags += 128
  205.                 End If
  206.                 If C.IsItalic Then
  207.                     Flags += 64
  208.                 End If
  209.                 If C.IsUnderlined Then
  210.                     Flags += 32
  211.                 End If
  212.  
  213.                 'Se il colore non è quello predefinito,
  214.                 'imposta il bit su 1
  215.                 If C.Color <> Color.Black Then
  216.                     Flags += 16
  217.                 End If
  218.  
  219.                 'Lo stesso per la grandezza
  220.                 If C.Size <> 12 Then
  221.                     Flags += 8
  222.                 End If
  223.  
  224.                 'E per il font
  225.                 If C.FontName <> "Times New Roman" Then
  226.                     Flags += 4
  227.                 End If
  228.  
  229.                 'Poi controlla l'allineamento
  230.                 Select Case C.Align
  231.                     Case TextChunk.Alignment.Left
  232.                         Flags += 0 'Non sono matto, eh!
  233.                     Case TextChunk.Alignment.Right
  234.                         Flags += 1
  235.                     Case TextChunk.Alignment.Center
  236.                         Flags += 2
  237.                     Case TextChunk.Alignment.Justify
  238.                         Flags += 3
  239.                 End Select
  240.  
  241.                 'Scrive i flags
  242.                 Writer.Write(CByte(Flags))
  243.  
  244.                 'Ora, se il colore non è quello predefinito,
  245.                 'lo scrive
  246.                 If C.Color <> Color.Black Then
  247.                     'In ordine, A, R, G, B
  248.                     Writer.Write(C.Color.A)
  249.                     Writer.Write(C.Color.R)
  250.                     Writer.Write(C.Color.G)
  251.                     Writer.Write(C.Color.B)
  252.                 End If
  253.  
  254.                 'Poi scrive la grandezza
  255.                 If C.Size <> 12 Then
  256.                     Writer.Write(C.Size)
  257.                 End If
  258.  
  259.                 'E infine il nome del font
  260.                 If C.FontName <> "Times New Roman" Then
  261.                     Writer.Write(UTF8.GetBytes(C.FontName))
  262.                     Writer.Write(CByte(0)) 'Byte nullo
  263.                 End If
  264.  
  265.                 'Poi la dimensione e il testo
  266.                 Dim Bytes() As Byte = UTF8.GetBytes(C.Text)
  267.                 Writer.Write(CInt(Bytes.Length))
  268.                 Writer.Write(Bytes)
  269.             Next
  270.             Writer.Close()
  271.         End Sub
  272.     End Class
  273.  
  274.     Public Class Reader
  275.         Private _Chunks As New List(Of TextChunk)
  276.  
  277.         Public ReadOnly Property Chunks() As List(Of TextChunk)
  278.             Get
  279.                 Return _Chunks
  280.             End Get
  281.         End Property
  282.  
  283.         Public Sub Read(ByVal File As String)
  284.             'Lo stream di lettura
  285.             Dim Reader As New BinaryReader(New FileStream(File, FileMode.Open))
  286.  
  287.             'Legge i primi 3 bytes
  288.             Dim Buffer(2) As Byte
  289.             Buffer = Reader.ReadBytes(3)
  290.  
  291.             'Se non sono "TLT", allora esce
  292.             If UTF8.GetString(Buffer) <> "TLT" Then
  293.                 Reader.Close()
  294.                 Exit Sub
  295.             End If
  296.  
  297.             Do
  298.                 'Legge il byte dei flags
  299.                 Dim Flags As Byte = Reader.ReadByte
  300.                 Dim C As New TextChunk
  301.  
  302.                 'Estrapola i dati
  303.                 C.IsBold = ((Flags And 128) = 128)
  304.                 C.IsItalic = ((Flags And 64) = 64)
  305.                 C.IsUnderlined = ((Flags And 32) = 32)
  306.  
  307.                 If (Flags And 16) = 16 Then
  308.                     'In ordine, A, R, G, B
  309.                     'Dopo tutto, essendo 3 bytes, li si
  310.                     'può trattare come un Int32
  311.                     Dim A, R, G, B As Byte
  312.                     A = Reader.ReadByte
  313.                     R = Reader.ReadByte
  314.                     G = Reader.ReadByte
  315.                     B = Reader.ReadByte
  316.                     C.Color = Color.FromArgb(A, R, G, B)
  317.                 Else
  318.                     C.Color = Color.Black
  319.                 End If
  320.  
  321.                 'Poi scrive la grandezza
  322.                 If (Flags And 8) = 8 Then
  323.                     C.Size = Reader.ReadByte
  324.                 Else
  325.                     C.Size = 12
  326.                 End If
  327.  
  328.                 'E infine il nome del font
  329.                 If (Flags And 4) = 4 Then
  330.                     Dim Temp As New List(Of Byte)
  331.                     Dim B As Byte = Reader.ReadByte
  332.                     'Legge i bytes fino ad incontrare il
  333.                     'byte nullo di fine stringa
  334.                     Do While B <> 0
  335.                         Temp.Add(B)
  336.                         B = Reader.ReadByte
  337.                     Loop
  338.                     C.FontName = UTF8.GetString(Temp.ToArray)
  339.                 End If
  340.  
  341.                 If (Flags And 2) = 2 Then
  342.                     If (Flags And 1) = 1 Then
  343.                         '11 - giustificato
  344.                         C.Align = TextChunk.Alignment.Justify
  345.                     Else
  346.                         '10 - centrato
  347.                         C.Align = TextChunk.Alignment.Center
  348.                     End If
  349.                 Else
  350.                     If (Flags And 1) = 1 Then
  351.                         '01 - destra
  352.                         C.Align = TextChunk.Alignment.Right
  353.                     Else
  354.                         '00 - sinistra
  355.                         C.Align = TextChunk.Alignment.Left
  356.                     End If
  357.                 End If
  358.  
  359.                 'Poi la dimensione e il testo
  360.                 Dim Size As Int32
  361.                 Size = Reader.ReadInt32
  362.                 Buffer = Reader.ReadBytes(Size)
  363.                 C.Text = UTF8.GetString(Buffer)
  364.                 Me.Chunks.Add(C)
  365.             Loop While Reader.BaseStream.Position < Reader.BaseStream.Length
  366.  
  367.             Reader.Close()
  368.         End Sub
  369.     End Class
  370. End Namespace