1

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

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
fedeteka
  • 943
  • 1
  • 14
  • 33
  • 1
    I am not exactly sure what the problem is, but you should know that a) *where* you declare (Dim, Private, Public) a variable determines the `scope`; b) everything which results in indentation creates a block scope (second example, those fonts only live inside the If). You dont need to use new with Dim/Private - you can declare at one level and initialize at another. Not sure what the problem is with immutability unless it is a mischaracterisation – Ňɏssa Pøngjǣrdenlarp Sep 26 '16 at 16:50
  • @Plutonix Scope!!! I didn´t knew about the scope of a Dim inside a block! – fedeteka Sep 27 '16 at 00:17
  • 1
    Since it was an issue of scope I am going to Close this as a dupe of the answer linked to - it wasnt entirely clear that was The Main issue. The other answer has a more complete answer. Please upvote it if it helps. – Ňɏssa Pøngjǣrdenlarp Sep 27 '16 at 12:42
  • @Plutonix "Please upvote it if it helps." upvoted this comment? Done. The complete answer done too. – fedeteka Sep 27 '16 at 12:55
  • @Plutonix done! – fedeteka Sep 28 '16 at 09:20

1 Answers1

1
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 Enum
...
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"
Community
  • 1
  • 1
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • Just a little typo mistake the first "End If" must be "End Enum". All the other code works perfect. A really clean solution because it's really easy to add more themes to the code. "the code in general seems to be in a battle with itself over scope", yes that was the case! Now I learned about scope (again!), enums, and more. fontLetterSeparator.Dispose() is not working, I get a message "Dispose is not a member of Font" maybe is something of iTextSharp because Visual Studio say Form1.fontLetterSeparator As iTextsharp.Text.Font – fedeteka Sep 27 '16 at 01:46
  • Chunk is part of iTextSharp code, not SQlite. Thanks for the support and the links. – fedeteka Sep 27 '16 at 01:46
  • 1
    Fixed the typo - thanks. `Dispose` is a member of `System.Drawing.Font` a TextSharp Font is something different (and explains the BaseFont.Create syntax). They must be handling the disposal. – Ňɏssa Pøngjǣrdenlarp Sep 27 '16 at 12:39
  • Thanks for the info. – fedeteka Sep 27 '16 at 12:43
  • 1
    The first If need the End If and Public Enum need the End Enum, that part still need correction. :) – fedeteka Oct 01 '16 at 04:02