RowParagraph.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / PtsHost / RowParagraph.cs / 1 / RowParagraph.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// File: RowParagraph.cs 
//
// Description: RowParagraph represents a single row in a table 
// 
// History:
//  10/04/2005 : [....] - created 
//
//---------------------------------------------------------------------------

using System; 
using System.Diagnostics;
using System.Security; 
using System.Windows; 
using System.Windows.Documents;
using MS.Internal.PtsTable; 
using MS.Internal.Text;
using MS.Internal.PtsHost.UnsafeNativeMethods;

namespace MS.Internal.PtsHost 
{
    // --------------------------------------------------------------------- 
    // RowParagraph represents a single row. 
    // ---------------------------------------------------------------------
    internal sealed class RowParagraph : BaseParagraph 
    {

        //------------------------------------------------------
        // 
        //  Constructors
        // 
        //----------------------------------------------------- 

        #region Constructors 

        // ------------------------------------------------------------------
        // Constructor.
        // 
        //      element - Element associated with paragraph.
        //      structuralCache - Content's structural cache 
        // ------------------------------------------------------------------ 
        internal RowParagraph(DependencyObject element, StructuralCache structuralCache)
            : base(element, structuralCache) 
        {
        }

        // ----------------------------------------------------------------- 
        // IDisposable.Dispose
        // ------------------------------------------------------------------ 
        public override void Dispose() 
        {
            if(_cellParagraphs != null) 
            {
                for(int index = 0; index < _cellParagraphs.Length; index++)
                {
                    _cellParagraphs[index].Dispose(); 
                }
            } 
            _cellParagraphs = null; 

            base.Dispose(); 
        }

        #endregion Constructors
 

        //----------------------------------------------------- 
        // 
        //  Internal Methods
        // 
        //-----------------------------------------------------

        #region Internal Methods
 
        //-------------------------------------------------------------------
        // GetParaProperties 
        //-------------------------------------------------------------------- 
        internal override void GetParaProperties(
            ref PTS.FSPAP fspap)                // OUT: paragraph properties 
        {
            Invariant.Assert(false); // No para properties for row.
        }
 
        //-------------------------------------------------------------------
        // CreateParaclient 
        //-------------------------------------------------------------------- 
        internal override void CreateParaclient(
            out IntPtr paraClientHandle)        // OUT: opaque to PTS paragraph client 
        {
            Invariant.Assert(false); // No valid para client for a row paragraph.
            paraClientHandle = IntPtr.Zero;
        } 

        // ------------------------------------------------------------------ 
        // UpdGetParaChange - RowParagraph is always new 
        // -----------------------------------------------------------------
        internal override void UpdGetParaChange( 
            out PTS.FSKCHANGE fskch,            // OUT: kind of change
            out int fNoFurtherChanges)          // OUT: no changes after?
        {
            base.UpdGetParaChange(out fskch, out fNoFurtherChanges); 

            fskch = PTS.FSKCHANGE.fskchNew; 
        } 

        ///  
        /// GetRowProperties
        /// 
        /// Flow direction for table
        /// Row properties structure 
        internal void GetRowProperties(
            uint fswdirTable,                       // IN: 
            out PTS.FSTABLEROWPROPS rowprops)       // OUT: 
        {
            // local variables 
            PTS.FSKROWHEIGHTRESTRICTION fskrowheight;
            int                         dvrAboveBelow;
            bool isLastRowOfRowGroup = (Row.Index == Row.RowGroup.Rows.Count - 1);
 
            //  Note: PTS generally does not accept rows with no real cells
            //  (Defintinion: real cell is 
            //      a) cell with no vertical merge; 
            //      OR
            //      b) vertically merged cell ending in this row) 
            //  However PTS accepts a row with no real cells if it has explicit height set.
            //  So fskrowheight is set to "0" if
            //      a) user said so;
            //      b) no real cells found; 

            GetRowHeight(out fskrowheight, out dvrAboveBelow); 
 
            // initialize output parameter(s)
            rowprops = new PTS.FSTABLEROWPROPS(); 

            rowprops.fskrowbreak = PTS.FSKROWBREAKRESTRICTION.fskrowbreakAnywhere;
            rowprops.fskrowheight = fskrowheight;
            rowprops.dvrRowHeightRestriction = 0; 
            rowprops.dvrAboveRow = dvrAboveBelow;
            rowprops.dvrBelowRow = dvrAboveBelow; 
 

            int cellSpacing = TextDpi.ToTextDpi(Table.InternalCellSpacing); 

            // Clip MBP values to structural cache's current format context size. Also use current format context's page height to
            // clip cell spacing
            MbpInfo mbpInfo = MbpInfo.FromElement(Table); 

            if (Row.Index == 0 && Table.IsFirstNonEmptyRowGroup(Row.RowGroup.Index)) 
            { 
                rowprops.dvrAboveTopRow = mbpInfo.BPTop + cellSpacing / 2;
            } 
            else
            {
                rowprops.dvrAboveTopRow = dvrAboveBelow;
            } 

            if (isLastRowOfRowGroup && Table.IsLastNonEmptyRowGroup(Row.RowGroup.Index)) 
            { 
                rowprops.dvrBelowBottomRow = mbpInfo.BPBottom + cellSpacing / 2;
            } 
            else
            {
                rowprops.dvrBelowBottomRow = dvrAboveBelow;
            } 

            rowprops.dvrAboveRowBreak = cellSpacing / 2; 
            rowprops.dvrBelowRowBreak = cellSpacing / 2; 

            rowprops.cCells = Row.FormatCellCount; 
        }

        /// 
        /// FInterruptFormattingTable 
        /// 
        /// Current height progress 
        /// Do interrupt? 
        internal void FInterruptFormattingTable(
            int dvr, 
            out int fInterrupt)
        {
            fInterrupt = PTS.False;
        } 

        ///  
        /// CalcHorizontalBBoxOfRow 
        /// 
        /// Cell amount 
        /// Cell names
        /// Cell clients
        /// Bounding box
        /// Bounding box 
        /// 
        /// Critical, because it is unsafe method. 
        ///  
        [SecurityCritical]
        internal unsafe void CalcHorizontalBBoxOfRow( 
            int cCells,
            IntPtr* rgnmCell,
            IntPtr* rgpfsCell,
            out int urBBox, 
            out int durBBox)
        { 
            Debug.Assert(cCells == Row.FormatCellCount); 

            urBBox = 0; 
            durBBox = 0;

            for(int index = 0; index < cCells; index++)
            { 
                if(rgpfsCell[index] != IntPtr.Zero)
                { 
                    CellParaClient cellParaClient = PtsContext.HandleToObject(rgpfsCell[index]) as CellParaClient; 
                    PTS.ValidateHandle(cellParaClient);
 
                    durBBox = TextDpi.ToTextDpi(cellParaClient.TableParaClient.TableDesiredWidth);
                    break;
                }
            } 

        } 
 
        /// 
        /// GetCells 
        /// 
        /// Cell amount reserves by PTS for the row
        /// Array of cell names
        /// Array of vertical merge flags 
        /// 
        /// Critical - takes pointers that cannot be validated by this method 
        ///  
        [SecurityCritical]
        internal unsafe void GetCells( 
            int cCells,
            IntPtr* rgnmCell,
            PTS.FSTABLEKCELLMERGE* rgkcellmerge)
        { 
            Invariant.Assert(cCells == Row.FormatCellCount);
 
            // To protect against a buffer overflow, we must check that we aren't writing more 
            // cells than were allocated.  So we check against the cell count we have -
            // Row.FormatCellCount.  But that's calculated elsewhere.  What if it's stale? 
            // There aren't any direct values available to compare against at the start of
            // this function, so we need two separate asserts.  Bug 1149633.
            Invariant.Assert(cCells >= Row.Cells.Count); // Protect against buffer overflow
 

            int i = 0; 
 
            //  first, submit all non vertically merged cells
            for (int j = 0; j < Row.Cells.Count; ++j) 
            {
                TableCell cell = Row.Cells[j];
                if (cell.RowSpan == 1)
                { 
                    rgnmCell[i] = _cellParagraphs[j].Handle;
                    rgkcellmerge[i] = PTS.FSTABLEKCELLMERGE.fskcellmergeNo; 
                    i++; 
                }
            } 

            // i now contains the exact number of non-rowspan cells on this row.  Use it to verify
            // total number of cells, before we possibly write off end of allocated array.
            Invariant.Assert(cCells == i + _spannedCells.Length); // Protect against buffer overflow 

            //  second, submit all vertically merged cells 
            if (_spannedCells.Length > 0) 
            {
                bool lastRow = Row.Index == Row.RowGroup.Rows.Count - 1; 

                for (int j = 0; j < _spannedCells.Length; ++j)
                {
                    Debug.Assert (_spannedCells[j] != null); 

                    TableCell cell = _spannedCells[j].Cell; 
                    rgnmCell[i] = _spannedCells[j].Handle; 

                    if (cell.RowIndex == Row.Index) 
                    {
                        rgkcellmerge[i] = lastRow
                            ? PTS.FSTABLEKCELLMERGE.fskcellmergeNo
                            : PTS.FSTABLEKCELLMERGE.fskcellmergeFirst; 
                    }
                    else if (Row.Index - cell.RowIndex + 1 < cell.RowSpan) 
                    { 
                        rgkcellmerge[i] = lastRow
                            ? PTS.FSTABLEKCELLMERGE.fskcellmergeLast 
                            : PTS.FSTABLEKCELLMERGE.fskcellmergeMiddle;
                    }
                    else
                    { 
                        Debug.Assert(Row.Index - cell.RowIndex + 1 == cell.RowSpan);
                        rgkcellmerge[i] = PTS.FSTABLEKCELLMERGE.fskcellmergeLast; 
                    } 

                    i++; 
                }
            }
        }
 
        /// 
        /// Calculates the spanned cells for this paragraph from the spanned cells for the previous paragraph. 
        /// This needs to be done to share the spanned cell paragraphs. 
        /// 
        internal void CalculateRowSpans() 
        {
            RowParagraph rowPrevious = null;

            if(Row.Index != 0 && Previous != null) 
            {
                rowPrevious = ((RowParagraph)Previous); 
            } 

            Invariant.Assert(_cellParagraphs == null); 

            _cellParagraphs = new CellParagraph[Row.Cells.Count];

            for(int cellIndex = 0; cellIndex < Row.Cells.Count; cellIndex++) 
            {
                _cellParagraphs[cellIndex] = new CellParagraph(Row.Cells[cellIndex], StructuralCache); 
            } 

            Invariant.Assert(_spannedCells == null); 

            _spannedCells = new CellParagraph[Row.SpannedCells.Length];

            for(int index = 0; index < _spannedCells.Length; index++) 
            {
                _spannedCells[index] = FindCellParagraphForCell(rowPrevious, Row.SpannedCells[index]); 
            } 
        }
 
        /// 
        /// Returns row height for this row, depending on cell content (Real/Foreign/Etc)
        /// 
        internal void GetRowHeight(out PTS.FSKROWHEIGHTRESTRICTION fskrowheight, out int dvrAboveBelow) 
        {
            bool isLastRowOfRowGroup = (Row.Index == Row.RowGroup.Rows.Count - 1); 
 
            if (Row.HasRealCells ||
                (isLastRowOfRowGroup && _spannedCells.Length > 0)) 
            {
                // Use current format context's page height to limit vertical cell spacing
                fskrowheight = PTS.FSKROWHEIGHTRESTRICTION.fskrowheightNatural;
                dvrAboveBelow = TextDpi.ToTextDpi(Table.InternalCellSpacing / 2.0); 
            }
            else 
            { 
                fskrowheight = PTS.FSKROWHEIGHTRESTRICTION.fskrowheightExactNoBreak;
                dvrAboveBelow = 0; 
            }
        }

        #endregion Internal Methods 

 
        //------------------------------------------------------ 
        //
        //  Internal Properties 
        //
        //-----------------------------------------------------

        #region Internal Properties 

 
        ///  
        /// Table owner accessor
        ///  
        internal TableRow Row { get { return (TableRow)Element; } }

        /// 
        /// Table 
        /// 
        internal Table Table { get { return Row.Table; } } 
 
        /// 
        /// Cell Paragraphs 
        /// 
        internal CellParagraph[] Cells { get { return _cellParagraphs; } }

 
        #endregion Internal Properties
 
 
        //-----------------------------------------------------
        // 
        //  Private Methods
        //
        //-----------------------------------------------------
 
        #region Private Methods
 
        ///  
        /// Helper method to scan our cell list for a cell paragraph, and if not found, look at the spanning cell paragraphs
        /// from previous row, if one exists. 
        /// 
        private CellParagraph FindCellParagraphForCell(RowParagraph previousRow, TableCell cell)
        {
            for(int index = 0; index < _cellParagraphs.Length; index++) 
            {
                if(_cellParagraphs[index].Cell == cell) 
                { 
                    return _cellParagraphs[index];
                } 
            }

            if(previousRow != null)
            { 
                for(int index = 0; index < previousRow._spannedCells.Length; index++)
                { 
                    if(previousRow._spannedCells[index].Cell == cell) 
                    {
                        return previousRow._spannedCells[index]; 
                    }
                }
            }
 
            Invariant.Assert(false, "Structural integrity for table not correct.");
            return null; 
        } 

        #endregion Private Methods 


        //------------------------------------------------------
        // 
        //  Private Fields
        // 
        //----------------------------------------------------- 

        #region Private Fields 

        private CellParagraph[] _cellParagraphs;     //  collection of cells belonging to the row
        private CellParagraph[] _spannedCells;        //  row spanned cell storage
 
        #endregion Private Fields
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK