JSON
JSON

Reputation: 1182

ITextSharp using multiple font styles together. ie Bold, Underlined, italic... etc

I am attempting to use Itextsharp.dll (not sure which version) to write a dynamic PDF. Everything was going great until I needed to write a phrase with that is bold and underlined. However it appears that itextSharp's font class does not allow for this. It allows for bold/italic, but not bold/underline, italic/ underline, or all three. You cannot combine underlined with any other style. It seems rather silly to not allow for a font to be both underlined and something else. I have looked everywhere and see nothing that mentions it. Does anyone know a way around this or am I missing something obvious here?

I would generally build my Font like so.

iTextSharp.text.Font myFont = new Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 9, iTextSharp.text.Font.BOLDITALIC, BaseColor.BLACK);

You can see the 3rd parameter is an integer signifying the FontStyle for the font, however there are no enums available to make something underlined AND bold ,underlined AND italic, or all three. There has to be a way to do this. I find it hard to believe that ITextSharp would not account for underlined and bold text. Any ideas?

Upvotes: 2

Views: 2616

Answers (1)

Chris Haas
Chris Haas

Reputation: 55417

If you look at the definition for BOLDITALIC you'll see:

public const int BOLDITALIC    = BOLD | ITALIC;

This shows you how to combine these styles using a bitwise | (or) operator. You are of course free to redefine these however you want but you'll usually see them used like this:

var myFont = new Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 9, Font.BOLD | Font.UNDERLINE, BaseColor.BLACK);

EDIT

Looking at the source, BOLD is 1 and UNDERLINE is 4 and when you | them together you get 5 which is the same value that you posted. You can test every single combination of all 5 styles using the code below.

//Create a test file on our desktop
var testFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");

//Possible styles
var styles = new Dictionary<string, int>() {
    { "NORMAL" , iTextSharp.text.Font.NORMAL },
    { "BOLD" , iTextSharp.text.Font.BOLD },
    { "ITALIC" , iTextSharp.text.Font.ITALIC },
    { "UNDERLINE" , iTextSharp.text.Font.UNDERLINE },
    { "STRIKETHRU",  iTextSharp.text.Font.STRIKETHRU }
};

//Standard iText bootstrap
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using(var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            //We're going to try every possible unique combination of constants, store the
            //previously used ones in this dictionary
            var used = new Dictionary<int, string>();

            //Fixed-number combination hack, just create 5 nested loops.
            foreach (var a in styles) {
                foreach (var b in styles) {
                    foreach (var c in styles) {
                        foreach (var d in styles) {
                            foreach (var g in styles) {

                                //Bitwise OR the values together
                                var k = a.Value | b.Value | c.Value | d.Value | g.Value;

                                //If we didn't previously use this OR'd value
                                if (!used.ContainsKey(k)) {

                                    //Get all of the unique names exclude duplicates
                                    var names = new string[] { a.Key, b.Key, c.Key, d.Key, g.Key }.Distinct().OrderBy(s => s).ToList();

                                    //NORMAL is the "default" and although NORMAL | BOLD is totally valid it just
                                    //messes with your brain when you see it. So remove NORMAL from the description
                                    //when it is used with anything else. This part is optional
                                    if (names.Count() > 1 && names.Contains("NORMAL")) {
                                        names = names.Where(n => n != "NORMAL").ToList();
                                    }

                                    //Merge our names into a comma-separated string
                                    var v = String.Join(", ", names);

                                    //Store it so we don't use it again
                                    used.Add(k, v);

                                    //Create a font using this loop's value
                                    var myFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 12, k, BaseColor.BLACK);

                                    //Add it to our document
                                    doc.Add(new Paragraph(k.ToString() + "=" + v, myFont));
                                }
                            }
                        }
                    }
                }
            }

            doc.Close();
        }
    }
}

This code produces this text:

enter image description here

Upvotes: 5

Related Questions