File: src\Framework\MS\Internal\PtsHost\CellParagraph.cs
Project: wpf\PresentationFramework.csproj (PresentationFramework)
//---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
// 
// File: CellParagraph.cs
//
// Description: CellParagraph represents a single list item.
//
// History:  
//  06/01/2004 : Microsoft - moving from Avalon branch.
//
//---------------------------------------------------------------------------
 
using System;
using System.Diagnostics;
using System.Security;
using System.Windows;
using System.Windows.Documents;
using MS.Internal.PtsHost;
using MS.Internal.Text;
using MS.Internal.PtsHost.UnsafeNativeMethods;
 
namespace MS.Internal.PtsHost
{
    // ----------------------------------------------------------------------
    // CellParagraph represents a single cell.
    // ----------------------------------------------------------------------
    internal sealed class CellParagraph : SubpageParagraph
    {
        // ------------------------------------------------------------------
        // Constructor.
        //
        //      element - Element associated with paragraph.
        //      structuralCache - Content's structural cache
        // ------------------------------------------------------------------
        internal CellParagraph(DependencyObject element, StructuralCache structuralCache)
            : base(element, structuralCache)
        {
            _isInterruptible = false;
        }
 
        /// <summary>
        /// Table owner accessor
        /// </summary>
        internal TableCell Cell { get { return (TableCell)Element; } }
 
        /// <summary>
        /// FormatCellFinite
        /// </summary>
        /// <param name="tableParaClient">Table para client</param>
        /// <param name="pfsbrkcellIn">Subpage break record - not NULL if cell broken from previous page/column</param>
        /// <param name="pfsFtnRejector">Footnote rejector</param>
        /// <param name="fEmptyOK">Allow empty cell</param>
        /// <param name="fswdirTable">Table direction</param>
        /// <param name="dvrAvailable">Available vertical space</param>
        /// <param name="pfmtr">Formatting result</param>
        /// <param name="ppfscell">Cell para client</param>
        /// <param name="pfsbrkcellOut">Break record for the current cell</param>
        /// <param name="dvrUsed">Ised vertical space</param>
        /// <SecurityNote>
        /// Critical - as this calls Critical function CellParaClient.FormatCellFinite.
        /// </SecurityNote>
        [SecurityCritical]
        internal void FormatCellFinite(
            TableParaClient tableParaClient,        // IN:  
            IntPtr pfsbrkcellIn,                    // IN:  not NULL if cell broken from previous page/column
            IntPtr pfsFtnRejector,                  // IN:  
            int fEmptyOK,                           // IN:  
            uint fswdirTable,                       // IN:  
            int dvrAvailable,                       // IN:  
            out PTS.FSFMTR pfmtr,                   // OUT: 
            out IntPtr ppfscell,                    // OUT: cell object
            out IntPtr pfsbrkcellOut,               // OUT: break if cell does not fit in dvrAvailable
            out int dvrUsed)                        // OUT: height -- min height required 
    
        {
            Debug.Assert(Cell.Index != -1 && Cell.ColumnIndex != -1, 
                "Cell is not in a table");
    
            CellParaClient cellParaClient;
            Size subpageSize;
    
            Debug.Assert(Cell.Table != null);
 
            cellParaClient = new CellParaClient(this, tableParaClient);
 
            subpageSize = new Size(
                cellParaClient.CalculateCellWidth(tableParaClient), 
                Math.Max(TextDpi.FromTextDpi(dvrAvailable), 0));
    
    
            cellParaClient.FormatCellFinite(subpageSize,
                                            pfsbrkcellIn,
                                            PTS.ToBoolean(fEmptyOK),
                                            fswdirTable, 
                                            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA.fsksuppresshardbreakbeforefirstparaNone,
                                            out pfmtr, 
                                            out dvrUsed,
                                            out pfsbrkcellOut);
    
            //  initialize output parameters
            ppfscell = cellParaClient.Handle;
    
            if(pfmtr.kstop == PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)
            {
                cellParaClient.Dispose();
                ppfscell = IntPtr.Zero;
                dvrUsed = 0;
            }
    
            if (dvrAvailable < dvrUsed)
            {
                if (PTS.ToBoolean(fEmptyOK))
                {
                    if (cellParaClient != null)     { cellParaClient.Dispose(); }
                    if (pfsbrkcellOut != IntPtr.Zero)
                    {
                        PTS.Validate(PTS.FsDestroySubpageBreakRecord(cellParaClient.PtsContext.Context, pfsbrkcellOut), cellParaClient.PtsContext);
                        pfsbrkcellOut = IntPtr.Zero;
                    }
    
                    ppfscell = IntPtr.Zero;
                    pfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace;
                    dvrUsed = 0;
                }
                else
                {
                    pfmtr.fForcedProgress = PTS.True;
                }
            }
        }
    
        /// <summary>
        /// FormatCellBottomless
        /// </summary>
        /// <param name="tableParaClient">Table para client</param>
        /// <param name="fswdirTable">Flow direction</param>
        /// <param name="fmtrbl">Formatting result</param>
        /// <param name="ppfscell">Cell para client</param>
        /// <param name="dvrUsed">Height consumed</param>
        internal void FormatCellBottomless(
            TableParaClient tableParaClient,    // IN:  
            uint fswdirTable,                   // IN:  
            out PTS.FSFMTRBL fmtrbl,            // OUT: 
            out IntPtr ppfscell,                // OUT: cell object
            out int dvrUsed)                    // OUT: height -- min height 
                                                //      required 
        {
            Debug.Assert(Cell.Index != -1 && Cell.ColumnIndex != -1, 
                "Cell is not in a table");
    
            Debug.Assert(Cell.Table != null);
    
            CellParaClient cellParaClient = new CellParaClient(this, tableParaClient);
    
            cellParaClient.FormatCellBottomless(fswdirTable, cellParaClient.CalculateCellWidth(tableParaClient), out fmtrbl, out dvrUsed);
             
    
            //  initialize output parameters
            ppfscell = cellParaClient.Handle;
        }
    
        /// <summary>
        /// UpdateBottomlessCell
        /// </summary>
        /// <param name="cellParaClient">Current cell para client</param>
        /// <param name="tableParaClient">Table para cleint</param>
        /// <param name="fswdirTable">Flow direction</param>
        /// <param name="fmtrbl">Formatting result</param>
        /// <param name="dvrUsed">Height consumed</param>
        internal void UpdateBottomlessCell(
            CellParaClient cellParaClient,          // IN:  
            TableParaClient tableParaClient,        // IN:  
            uint fswdirTable,                       // IN:  
            out PTS.FSFMTRBL fmtrbl,                // OUT: 
            out int dvrUsed)                        // OUT: height -- min height required 
        {
            Debug.Assert(Cell.Index != -1 && Cell.ColumnIndex != -1, 
                "Cell is not in a table");
    
            Debug.Assert(Cell.Table != null);
    
            cellParaClient.UpdateBottomlessCell(fswdirTable, cellParaClient.CalculateCellWidth(tableParaClient), out fmtrbl, out dvrUsed);
        }
 
        /// <summary>
        /// SetCellHeight
        /// </summary>
        /// <param name="cellParaClient">Cell para client</param>
        /// <param name="tableParaClient">Table para client</param>
        /// <param name="subpageBreakRecord">Break record if cell is broken</param>
        /// <param name="fBrokenHere">Cell broken on this page/column</param>
        /// <param name="fswdirTable">Flow direction</param>
        /// <param name="dvrActual">Actual height</param>
        internal void SetCellHeight(
            CellParaClient cellParaClient,          // IN: cell object
            TableParaClient tableParaClient,        // table's para client
            IntPtr subpageBreakRecord,              // not NULL if cell broken from previous page/column
            int fBrokenHere,                        // TRUE if cell broken on this page/column: no reformatting
            uint fswdirTable, 
            int dvrActual)
        {
            cellParaClient.ArrangeHeight = TextDpi.FromTextDpi(dvrActual);
        }
 
 
        /// <summary>
        /// UpdGetCellChange
        /// </summary>
        /// <param name="fWidthChanged">Indication that cell's width changed
        /// </param>
        /// <param name="fskchCell">Change kind. One of: None, New, Inside
        /// </param>
        internal void UpdGetCellChange(
            out int fWidthChanged,                  // OUT: 
            out PTS.FSKCHANGE fskchCell)            // OUT: 
        {
            //  calculate state change
            fWidthChanged = PTS.True;
            fskchCell = PTS.FSKCHANGE.fskchNew;
        }
 
 
    }
}