Spire.PDF is a professional PDF library applied to creating, writing, editing, handling and reading PDF files without any external dependencies. Get free and professional technical support for Spire.PDF for .NET, Java, Android, C++, Python.

Wed Jan 31, 2018 5:10 pm

I have some (multi threaded) code where by a Spire PDF Grid is populated with some data, by row and column, and the content is rendered using a variety of fonts.

If I run the same code with the same data, I get inconsistent results: it appears that data in a cell with a Style.Font of Calibri 9pt regular occasionally stops being rendered when the Grid.Draw method is executed, but if I change the cell to render as Calibri 9pt Bold, for example, it will actually render fine when Grid.Draw is executed, while other cells are not rendered because of the use of the regular font.

Also it tends to be an all or nothing problem: I generally create 4 different Grids on the document, and when this fails, it always fails on all the Grids in the document.

I populate the data by row and column, and have dumped the data and a description of the appropriate Cell fonts after the draw, and they all appear exactly as they do when it works.

I cannot guarantee a reproduction of the bug, but if I generate enough versions of the document, it will eventually break. On our live system this is proving a real problem. I can't put all the code up here at the moment to reproduce the problem, but I can show you the basic outline.

I have a PDFWriter class, which contains a method that effectively caches the fonts in a list, but I started off just creating new instances of the font as required:
Code: Select all
public PdfTrueTypeFont GetFont(string EncodedFontName)
        {
            if (!Fonts.ContainsKey(EncodedFontName))
            {

                string fontName = "";
                int j = 0;
                string sizeString = "";
                int fontSize = 9;
                bool doName = true;
                foreach (char C in EncodedFontName)
                {
                    if (doName)
                    {
                        if (!char.IsDigit(C))
                            fontName = fontName + EncodedFontName.Substring(j, 1);
                        else
                        {
                            doName = false;
                            sizeString = sizeString + EncodedFontName.Substring(j, 1);
                        }
                    }
                    else
                    {
                        if (char.IsDigit(C))
                            sizeString = sizeString + EncodedFontName.Substring(j, 1);
                        else
                            break;
                    }
                    j++;
                }
                if (sizeString != "")
                    fontSize = int.Parse(sizeString);

                FontStyle fontStyle = FontStyle.Regular;
                if (EncodedFontName.ToLower().EndsWith("bold"))
                {
                    fontStyle = FontStyle.Bold;
                }
                else if (EncodedFontName.ToLower().EndsWith("italic"))
                {
                    fontStyle = FontStyle.Italic;
                }
                PdfTrueTypeFont ActualFont = new PdfTrueTypeFont(new Font(fontName, fontSize, fontStyle));

                Fonts.Add(EncodedFontName, ActualFont);
            }
           
            return Fonts[EncodedFontName];
        }


And the class uses the following function to write the grid to the pdf file:

Code: Select all
  public void WriteTable(string[][] dataSource, DMSPDFTableTypes TableType, string TableTitle = null, bool AllowBreak = true)
        {
            //DataDump(dataSource);

            float TempY = Y;
            //Cache this for the total is shown on the RHS.
            float TempLeft = Left;

            int HeaderOffset = 0;
            if ((TableType == DMSPDFTableTypes.OddCellTitles & TableTitle != null) | (TableType == DMSPDFTableTypes.Guests) | (TableType == DMSPDFTableTypes.TitleOneColumn))
            {
                HeaderOffset = 1;
                TempY = TempY + 12f; //title row height
            }

            int ColumnCount = -1;
            if (dataSource != null)
                if (dataSource.Length > 0)
                    ColumnCount = dataSource[0].Length;

            if (ColumnCount == -1)
            {
                switch (TableType)
                {
                    case DMSPDFTableTypes.SupplierCosts:
                        ColumnCount = 3;
                        break;
                    case DMSPDFTableTypes.Guests:
                        ColumnCount = 4;
                        break;
                    default:
                        ColumnCount = 2;
                        break;
                }
            }

            lock (GridLock)
            {

                PdfGrid grid = CreateGridWithHeading(TableType, ColumnCount, TableTitle, HeaderOffset);
                bool bHeaderOnly = true;
                for (int r = 0; r < dataSource.Length; r++)
                {

                    TempY = TempY + 12f;
                    if ((TempY > Height - BottomMargin) && AllowBreak)
                    {
                        if (!bHeaderOnly)
                        {
                            grid.Draw(PageBase, new RectangleF(Left, Y, Width - Left, Height - Y));
                            //DumpGrid(grid);
                        }
                            PageBase = Section.Pages.Add();
                        StartPage();
                        Top = LowerTopMargin;
                        TempY = Y + 12f; //Cover header
                        grid = CreateGridWithHeading(TableType, ColumnCount, TableTitle, HeaderOffset);
                       
                        TempY = TempY + 12f; //Cover this new line.
                    }
                    PdfGridRow row = grid.Rows.Add();
                    bHeaderOnly = false;
                    row.Height = 12f;

                    for (int c = 0; c < dataSource[r].Length; c++)
                    {
                        row.Cells[c].Value = dataSource[r][c];
                        row.Cells[c].Style.TextBrush = PdfBrushes.Black;
                        switch (TableType)
                        {
                            case DMSPDFTableTypes.OddCellTitles:
                                if (c % 2 == 0)
                                    row.Cells[c].Style.Font = GetFont("Calibri9ptBold");
                                else
                                    row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                break;
                            case DMSPDFTableTypes.OddCellTitleTotals:
                                if (c % 2 == 0)
                                    row.Cells[c].Style.Font = GetFont("Calibri9ptBold");
                                else
                                {
                                    row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                    row.Cells[c].Style.BackgroundBrush = PdfBrushes.LightSteelBlue;
                                }
                                break;
                            case DMSPDFTableTypes.Guests:
                                if ((c == 0) && (r == 0))
                                    row.Cells[c].Style.Font = GetFont("Calibri9ptBold");
                                else if (c == 1)
                                {
                                    row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                    row.Cells[c].Style.Borders.Top = new PdfPen(Color.Transparent);
                                    row.Cells[c].Style.Borders.Bottom = new PdfPen(Color.Transparent);
                                }
                                else
                                    row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                break;
                            case DMSPDFTableTypes.SupplierCosts:
                                if (r == 0)
                                {
                                    row.Cells[c].Style.Font = GetFont("Calibri9ptBold");
                                    row.Cells[c].Style.BackgroundBrush = PdfBrushes.LightSteelBlue;
                                }
                                else
                                    row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                break;
                            default:
                                row.Cells[c].Style.Font = GetFont("Calibri9pt");
                                break;
                        }
                    }
                }

                grid.Draw(PageBase, new RectangleF(Left, Y, Width - Left, Height - Y));
                Y = TempY;
                //replace this for the total is shown on the RHS.
                Left = TempLeft;
                //DumpGrid(grid);
            }
        }


For reasons I do not particularly want to go in to, but concerning presenting a header and footer optionally on the document, the page has margins of 0, and I maintain the actual position on the page, and margins in internal properties, hence the Height/Width/Y, etc.

Is there anything anybody else can see that is obviously going to be problematic here? Has anybody else experienced similar problems? Does anybody else have a similar issue, and hence a solution?

I will endeavour to create a smaller but fuller version of the code that exhibits the same problem, so you could try running it, but apart from the fact that this is being run over multiple threads, there's little else I can say. The Grid looks ok, but sometimes one particular font just no longer renders. And If I change the line of code for OddCellTitles from
Code: Select all
row.Cells[c].Style.Font = GetFont("Calibri9pt");
to
Code: Select all
row.Cells[c].Style.Font = GetFont("Calibri9ptBold");
it renders when other Calibri 9pt's don't.

BrianROL
 
Posts: 2
Joined: Wed Mar 02, 2016 3:47 pm

Thu Feb 01, 2018 7:51 am

Dear BrianROL,

Thanks for your inquiry.
After an initial testing with the latest Spire.PDF Pack Version:3.10, sorry that I cannot reproduce the issue you mentioned on my side. Could you please provide us with following information for further investigation ?
1. a sample project which could demonstrate the issue.
2. OS and Region information, e.g. Win7 64bit, China/Chinese

Thanks,
Betsy
E-iceblue support team
User avatar

Betsy.jiang
 
Posts: 3099
Joined: Tue Sep 06, 2016 8:30 am

Mon Feb 05, 2018 8:42 am

Dear BrianROL,

Greetings from E-iceblue.
Has your issue been resolved ? If not, please provide the information I mentioned in last post.

Thanks,
Betsy
E-iceblue support team
User avatar

Betsy.jiang
 
Posts: 3099
Joined: Tue Sep 06, 2016 8:30 am

Fri Feb 09, 2018 11:51 am

Hi

I changed the font size down by one, and the issue is much less prevalent, but it does still happen. It happened this morning twice, but it hasn't for a few days.

Our systems are Win 64, Windows Server 2012 R2, UK configuration.

I am having trouble taking the code out of our system and in to a smaller project where I can still reproduce it. But when I can I will let you know.

BrianROL
 
Posts: 2
Joined: Wed Mar 02, 2016 3:47 pm

Sun Feb 11, 2018 6:40 am

Dear BrianROL,

Thanks for your feedback.
I am looking forward to your sample project.

Sincerely,
Betsy
E-iceblue support team
User avatar

Betsy.jiang
 
Posts: 3099
Joined: Tue Sep 06, 2016 8:30 am

Mon Feb 26, 2018 8:01 am

Dear BrianROL,

Greetings from E-iceblue.
How is your issue going now ? Could you please provide us with your smaller project which could reproduce your issue ?

Many thanks,
Betsy
E-iceblue support team
User avatar

Betsy.jiang
 
Posts: 3099
Joined: Tue Sep 06, 2016 8:30 am

Return to Spire.PDF