PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Tue Dec 12, 2017 11:44 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Table Row - Get Height
PostPosted: Wed Sep 30, 2009 12:50 pm 
Offline

Joined: Fri May 15, 2009 3:28 pm
Posts: 96
Hi All,

I am building a function to allow me to get the X/Y position of a particular cell in a particular table in my pdf document, so I can then use PdfSharp's drawing functions to "draw into" the cell as if I had added an image file to it.

I originally started on this topic a few months ago under the topic "Position PdfSharp graphics in a MigraDoc table" or something like that. This what I am encountering isnt really the same problem, more a "bug" in how the row heights are calculated.

I basically have the function working, but it is behaving slightly strangely when it comes to the Y position. I Apply the following settings to each "Row" object i create:
Code:
Row _row = _table.AddRow();
_row.Height = rowHeight; // This is a parameter i pass into my buildTable function
_row.HeightRule = RowHeightRule.AtLeast;


As the table's rows are of varying height (they word wrap) I would expect the height to also vary when I get it back - but instead it always comes back as the "rowHeight" variable's value i set it to originally, and not the height which it actually is (if there is more than one line of text in one of that row's cells - as the rowHeight variable only accounts for 1 line of text).

This subsequently means that unless all the rows in my table are all exactly the same height - the positions I am trying to draw my graphics at are incorrect.

Here is the function I use to get the rendered table objects (which allows me to get their formatting information such as row height and column width):
Code:
public List<RenderedTable> getRenderedTables()
        {
            List<RenderedTable> _objs = new List<RenderedTable>();
            MigraDoc.DocumentObjectModel.Document _document = document.Clone();
            DocumentRenderer _renderer = new DocumentRenderer(_document);
            _renderer.PrepareDocument();
            int pageCount = _renderer.FormattedDocument.PageCount;
            for (int idx = 1; idx <= pageCount; idx++)
            {
                RenderInfo[] _renderInfo = _renderer.GetRenderInfoFromPage(idx);
                _renderer.PrepareDocument();
                MigraDoc.DocumentObjectModel.Tables.Table _tbl = null;
                if (_renderInfo != null && _renderInfo.Length > 0)
                {
                    for (int g = 0; g < _renderInfo.Length; g++)
                    {
                        if (_renderInfo[g].DocumentObject.GetType() == typeof(MigraDoc.DocumentObjectModel.Tables.Table))
                        {
                            List<List<int>> _colsWidth = new List<List<int>>();
                            List<int> _rowsHeight = new List<int>();
                            _tbl = (MigraDoc.DocumentObjectModel.Tables.Table)_renderInfo[g].DocumentObject;
                            if (_tbl.Tag != null)
                            {
                                for (int r = 0; r < _tbl.Rows.Count; r++)
                                {
                                    _colsWidth.Add(new List<int>());
                                    Row _row = _tbl.Rows[r];
                                    for (int c = 0; c < _row.Cells.Count; c++)
                                    {
                                        try
                                        {
                                            _colsWidth[r].Add((int)_row.Cells[c].Column.Width);
                                        }
                                        catch
                                        {

                                        }
                                    }
                                    // This is the line which is causing problems as it is not getting the actual row height once text is added
                                    _rowsHeight.Add(((int)_tbl.Rows[r].Height));
                                }
                            }
                            if (_colsWidth.Count > 0 && _rowsHeight.Count > 0)
                            {
                                _objs.Add(new RenderedTable(_colsWidth, _rowsHeight, (int)_renderInfo[g].LayoutInfo.ContentArea.Height, (float)_renderInfo[g].LayoutInfo.ContentArea.X.Point, (float)_renderInfo[g].LayoutInfo.ContentArea.Y.Point, _tbl));
                            }
                        }
                    }
                }
            }
            return _objs;
        }

I dont know if the ability to do what I am doing here is included with the newest release of PdfSharp/MigraDoc, but Thomas Hoevel was kind enough to help me out a lot in the topic I mentioned earlier to "unlock" this functionality from the existing 1.2 release.

And this is the function I then use to find the position of the appropriate cell in the table:
Code:
public static System.Drawing.RectangleF GetContainerCellPosition(List<RenderedTable> renderedTables, string identifier)
        {
            System.Drawing.RectangleF _rect = new System.Drawing.RectangleF();
            foreach (RenderedTable rt in renderedTables)
            {
                float _x = rt.x + rt.table.LeftPadding;
                float _y = rt.y + rt.table.TopPadding;
                if (_x > -1 && _y > -1)
                {
                    for (int r = 0; r < rt.rowHeights.Count; r++)
                    {
                        for (int c = 0; c < rt.colWidths[r].Count; c++)
                        {
                            CellContainer _cellContainer = null;
                            try
                            {
                                _cellContainer = (CellContainer)rt.table[r, c].Elements[0].Tag;
                            }
                            catch
                            {

                            }
                            if (_cellContainer != null)
                            {
                                if (_cellContainer.type == identifier)
                                {
                                    _rect.X = (float)Math.Floor(_x);
                                    _rect.Y = (float)Math.Floor(_y);
                                    _rect.Width = rt.table[r, c].Column.Width;
                                    _rect.Height = rt.table[r, c].Row.Height;
                                }
                            }
                            _x += rt.colWidths[r][c];
                        }
                        if (r == 0)
                        {
                            _y += rt.rowHeights[r];
                        }
                        else
                        {
                            _y += rt.rowHeights[r] + 1;
                        }
                        _x = 0;
                    }
                }
            }
            return _rect;
        }

All I am doing it creating a List of all the row heights in the first function, then using a loop - adding those list values together until I have found the appropriate cell which should give me the height - and it kind of is, but as I said the heights are all what I originally set it to, rather than the "expanded" height becuase some text in one of the row's cells is on multiple lines.

Does anyone know how I can get the "true" height of the row once text has been added and wrapped etc.etc.?

Thanks,

Mike


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 30, 2009 1:03 pm 
Offline
empira Employee
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 2740
Location: Cologne, Germany
mikesowerbutts wrote:
As the table's rows are of varying height (they word wrap) I would expect the height to also vary when I get it back - but instead it always comes back as the "rowHeight" variable's value i set it to originally, and not the height which it actually is (if there is more than one line of text in one of that row's cells - as the rowHeight variable only accounts for 1 line of text).

This is by design.

Don't query rowHeight (it will never change), take the height from the RenderInfo (this is the height calculated during rendering).
viewtopic.php?p=1960#p1960

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 02, 2009 9:07 am 
Offline

Joined: Fri May 15, 2009 3:28 pm
Posts: 96
Hi,

I am unsure of how to the the RenderInfo for a individual row/column in a table - I can get the Table as a DocumentObject object using RenderInfo[idx].DocumentObject. I then cast the DocumentObject to a table to access it's rows/columns, but this then gives me the widths etc. as I am currently getting them - Can I get the RenderInfo for indivudual cells etc.? As this seems the only way to get the true height.

Mike


Top
 Profile  
Reply with quote  
PostPosted: Tue May 16, 2017 9:24 am 
Offline

Joined: Tue May 16, 2017 9:20 am
Posts: 1
Just forget about everything and use below code after rendering page and iterating over all rows summing result of realRowHeight (below) until you find desired row.
Code:
var formattedCellProperties = typeof(FormattedCell).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).ToArray();
var formattedCellInnerWidth = formattedCellProperties.FirstOrDefault(p => p.Name == "InnerWidth");
var formattedCellInnerHeight = formattedCellProperties.FirstOrDefault(p => p.Name == "InnerHeight");
Func<MigraDocTables.Row, TableFormatInfo, Unit> realRowHeight = (row, formatInfo) =>
{
    XUnit maxHeight = 0;
    foreach (MigraDocTables.Cell cell in row.Cells)
    {
        var formattedCell = formatInfo.FormattedCells[cell];
        var cellInnerHeight = (XUnit)formattedCellInnerHeight.GetValue(formattedCell);
        cellInnerHeight += XUnit.FromPoint(cell.Borders.Top.Width.Point);
        cellInnerHeight += XUnit.FromPoint(cell.Borders.Bottom.Width.Point);
        maxHeight = Math.Max(cellInnerHeight, maxHeight);
    }
    return Unit.FromPoint(maxHeight.Point);
};


works for 1.50


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: Bing [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group