fedeteka fedeteka - 2 months ago 11
Vb.net Question

Fonts instances: how to simplify document creation with different fonts styles

I create a simple PDF file using iTextSharp. Is working fine.

Now I want the user can change the style or theme. The user choose from a dialog box: Normal, Elegant, Modern and then some fonts of the PDF needs to change to suit the style or theme desired.

The PDF create Sub have something like:

'Define fontLetterSeparator
Dim fontLetterSeparator As New Font(BaseFont.CreateFont("c:/windows/fonts/comic.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 18)

'Define letter separator paragraph
Dim letterSeparator As New Chunk(ActualLetter, fontLetterSeparator)


Where ActualLetter is just a letter like A, B, C... (reading from the SQLite database, no problem whit this)

One way I think I can manage the 3 styles or themes is with code like

If PDFTheme = "Normal" Then
Dim fontLetterSeparator As New Font(BaseFont.CreateFont("c:/windows/fonts/arial.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 20)
End If

If PDFTheme = "Elegant" Then
Dim fontLetterSeparator As New Font(BaseFont.CreateFont("c:/windows/fonts/verdana.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 20)
End If

If PDFTheme = "Modern" Then
Dim fontLetterSeparator As New Font(BaseFont.CreateFont("c:/windows/fonts/comic.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 60)
End If


But this didn't work, I think is because of font immutable condition. So I think the solution is with 3 new fonts or new instances instead

Dim fontLetterSeparatorNormal As New fontLetterSeparator
fontLetterSeparatorNormal.Name = "Arial"

Dim fontLetterSeparatorElegant As New fontLetterSeparator
fontLetterSeparatorElegant.Name = "Verdana"

Dim fontLetterSeparatorModern As New fontLetterSeparator
fontLetterSeparatorModern.Name = "Comic"


and so on with the size condition but this makes the original line

'Define letter separator paragraph
'Dim letterSeparator As New Chunk(ActualLetter, fontLetterSeparator)


more complicated because now I need another block of 3 IF - Then to choose the right font for each style or theme...

I'm sure there's gonna be a more simple and clean solution but I canĀ“t figure it out

Answer
If PDFTheme = "Normal" Then
    Dim fontLetterSeparator As New Font(BaseFont.CreateFont("c:/windows/fonts/arial.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 20)
End If

But this didn't work, I think is because of font immutable condition.

You did not describe an error, but the code in general seems to be in a battle with itself over scope. Almost everything which cause code indentation (If/End If, For Each/Next) results in a new block scope. As a result, those font object only exist until the End If.

If the issue is that you declared the font variable elsewhere, and you cannot understand it isnt changed, this is why; you are accidentally using 2 different font variables in 2 different scopes.

Also, New and Dim | Private | Public do 2 different things and do not have to be used together every time. New creates the object instance while the others declare a variable (and usually the type) with the Scope determined by where that declaration is.

' first, I would use an Enum for the style
Public Enum PDFSytles
    [Default]                  ' its a reserved word
    Elegant
    Modern
End If
...
Private PDFStyle As PDFStyles  ' will default to Default (0)
Private fontLetterSeparator As Font   

This font variable is simply declared. Trying to use it will result in a NullReference Exception, but because it is declared at the Form/Class level is will be usable anywhere in the form.

If fontLetterSeparator IsNot Nothing Then
    fontLetterSeparator.Dispose()
End If 

Select Case PDFStyle 
    Case PDFStyles.Elegant
        fontLetterSeparator = New Font("Verdana"...)
    Case PDFStyles.Modern
        ...
End Select

First the code disposes of the old font to prevent leaking resources. Then it creates a New font and assigns it to the variable. The variable was declared long ago and far away elsewhere in the code so it need not be declared again.

I dont know what SQLite has to do with this or what New Chunk(...) does, but the code and part of the description sounds like you are running into a wall with the Scope.

More:


That said, NET Font objects are immutable. But that means you cant change doing something like:

myFancyFont.Name = "Elabora Special"