Beispiel #1
0
        private void ValidateRowVisualComplex(
            RowVisual rowVisual,
            IntPtr pfstablerow,
            int tableColumnCount,
            PTS.FSKUPDATE fskupdRow,
            CalculatedColumn[] calculatedColumns)
        {
            PTS.FSKUPDATE[] arrayUpdate;
            IntPtr[] arrayFsCell;
            PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge;
            CellParaClientEntry[] arrayCellParaClients;
            VisualCollection cellVisualsCollection;
            int sourceIndex;

            QueryRowDetails(
                pfstablerow,
                out arrayFsCell,
                out arrayUpdate,
                out arrayTableCellMerge);

            //  arrayFsCell lists cells in order different from one we want to maintain in visual collection.
            //  before going to update visual collection it is necessary to reorder ascending by cell's column index.
            //  knowing the following facts:
            //  * total number of columns the row holds (including row spanned cells from previous rows) less or equal to tableColumnCount;
            //  * total number of cells (including row spanned cells from previous rows) is less or equal to tableColumnCount;
            //  * cells do not overlap - no two cells have the same column index;
            //  * cells' column indices fall into the range [0, tableColumnCount - 1];
            //  it is possible to write custom and optimized sorting routine:
            //  * iterate through arrayFsCell;
            //  * for each item record its CellParaClient value into arrayCellParaClients[CellParaClient.ColumnIndex];
            //  once complete, arrayCellParaClients will contain CellParaClients in correct order. some entries however will be null
            //  due to potential column spanning of cells.
            arrayCellParaClients = new CellParaClientEntry[tableColumnCount];

            for (int iC = 0; iC < arrayFsCell.Length; ++iC)
            {
                CellParaClient cellParaClient;
                PTS.FSKUPDATE fskupdCell;
                int columnIndex;

                if (arrayFsCell[iC] == IntPtr.Zero)
                {
                    //  paginated case - cell may be null
                    continue;
                }

                fskupdCell = (arrayUpdate[iC] != PTS.FSKUPDATE.fskupdInherited)
                    ? arrayUpdate[iC]
                    : fskupdRow;

                cellParaClient = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));
                columnIndex = cellParaClient.ColumnIndex;
                arrayCellParaClients[columnIndex].cellParaClient = cellParaClient;
                arrayCellParaClients[columnIndex].fskupdCell = fskupdCell;
            }

            cellVisualsCollection = rowVisual.Children;
            sourceIndex = 0;

            for (int columnIndex = 0; columnIndex < arrayCellParaClients.Length; ++columnIndex)
            {
                CellParaClient cellParaClient;
                double urCellOffset;
                PTS.FSKUPDATE fskupdCell;

                cellParaClient = arrayCellParaClients[columnIndex].cellParaClient;
                if (cellParaClient == null)
                {
                    //  paginated case - cell may be null
                    continue;
                }

                fskupdCell = arrayCellParaClients[columnIndex].fskupdCell;

                if (fskupdCell != PTS.FSKUPDATE.fskupdNoChange)
                {
                    urCellOffset = calculatedColumns[columnIndex].UrOffset;
                    cellParaClient.ValidateVisual();

                    if (fskupdCell == PTS.FSKUPDATE.fskupdNew)
                    {
                        cellVisualsCollection.Insert(sourceIndex, cellParaClient.Visual);
                    }
                    else
                    {
                        Debug.Assert(   cellParaClient.Visual != null
                                    //  If the check below fails, then PTS cheats by reporting "ChangInside" for
                                    //  a cell that in fact was re-Formatted.
                                    &&  VisualTreeHelper.GetParent(cellParaClient.Visual) != null   );

                        SynchronizeCellVisualsCollection(cellVisualsCollection, sourceIndex, cellParaClient.Visual);
                    }
                }
                sourceIndex++;
            }

            if (cellVisualsCollection.Count > sourceIndex)
            {
                cellVisualsCollection.RemoveRange(
                    sourceIndex,
                    cellVisualsCollection.Count - sourceIndex);
            }

            #if DEBUGDEBUG
            for (int columnIndex = 0, sourceIndex = 0; columnIndex < arrayCellParaClients.Length; ++columnIndex)
            {
                CellParaClient cellParaClient = arrayCellParaClients[columnIndex].cellParaClient;
                if (cellParaClient != null)
                {
                    Debug.Assert(rowVisual.Children.IndexOf(cellParaClient.Visual) == sourceIndex);
                    sourceIndex++;
                }
            }
            #endif // DEBUGDEBUG
        }
Beispiel #2
0
        internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited)
        {
            Invariant.Assert( fskupdInherited != PTS.FSKUPDATE.fskupdInherited );
            Invariant.Assert( TableParagraph.Table != null && CalculatedColumns != null );

            PTS.FSTABLEROWDESCRIPTION[] arrayTableRowDesc;
            PTS.FSKUPDATE fskupdTable;
            PTS.FSRECT rect;
            Table table = TableParagraph.Table;

            Visual.Clip = new RectangleGeometry(_columnRect.FromTextDpi());

            if (!QueryTableDetails(out arrayTableRowDesc, out fskupdTable, out rect))
            {
                //  table has no rows thus no cell to validate
                _visual.Children.Clear();
                return;
            }

            MbpInfo mbpInfo = MbpInfo.FromElement(TableParagraph.Element);
            if (ThisFlowDirection != PageFlowDirection)
            {
                mbpInfo.MirrorBP();
            }

            if (fskupdTable == PTS.FSKUPDATE.fskupdInherited)
            {
                fskupdTable = fskupdInherited;
            }

            if (fskupdTable == PTS.FSKUPDATE.fskupdNoChange)
            {
                //  no need to arrange because nothing changed
                return;
            }

            if (fskupdTable == PTS.FSKUPDATE.fskupdShifted)
            {
                fskupdTable = PTS.FSKUPDATE.fskupdNew;
            }

            VisualCollection rowVisualsCollection = _visual.Children;
            if (fskupdTable == PTS.FSKUPDATE.fskupdNew)
            {
                rowVisualsCollection.Clear();
            }

            // Draw border and background info.
            Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);

            using (DrawingContext dc = _visual.RenderOpen())
            {
                Rect tableContentRect = GetTableContentRect(mbpInfo).FromTextDpi();

                _visual.DrawBackgroundAndBorderIntoContext(dc, backgroundBrush, mbpInfo.BorderBrush, mbpInfo.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk);

                DrawColumnBackgrounds(dc, tableContentRect);
                DrawRowGroupBackgrounds(dc, arrayTableRowDesc, tableContentRect, mbpInfo);
                DrawRowBackgrounds(dc, arrayTableRowDesc, tableContentRect, mbpInfo);
            }

            TableRow rowPrevious = null;

            for (int iR = 0; iR < arrayTableRowDesc.Length; ++iR)
            {
                PTS.FSKUPDATE fskupdRow;
                RowParagraph rowParagraph;
                TableRow row;

                fskupdRow = (arrayTableRowDesc[iR].fsupdinf.fskupd != PTS.FSKUPDATE.fskupdInherited)
                    ? arrayTableRowDesc[iR].fsupdinf.fskupd
                    : fskupdTable;


                rowParagraph = (RowParagraph)(PtsContext.HandleToObject(arrayTableRowDesc[iR].fsnmRow));
                row = rowParagraph.Row;

                //
                //  STEP 1 SYNCHRONIZATION
                //  ---------------------------------------------------------
                //  synchronize rowVisualCollection.
                //  for newly created rows visual is inserted;
                //  otherwise for removed rows (if any) corresponding visuals are removed
                //
                if (fskupdRow == PTS.FSKUPDATE.fskupdNew)
                {
                    RowVisual rowVisual = new RowVisual(row);
                    rowVisualsCollection.Insert(iR, rowVisual);
                }
                else
                {
                    SynchronizeRowVisualsCollection(rowVisualsCollection, iR, row);
                }

                Invariant.Assert(((RowVisual)rowVisualsCollection[iR]).Row == row);

                //
                //  STEP 2 CELL VISUALS VALIDATION
                //  ---------------------------------------------------------
                //  for new or changed rows go inside and validate cells
                //
                if (    fskupdRow == PTS.FSKUPDATE.fskupdNew
                    ||  fskupdRow == PTS.FSKUPDATE.fskupdChangeInside   )
                {
                    // paginated case - if first row of a given rowgroup for this para client has foreign cells, they need to
                    // be rendered regardless of merge state
                    if(rowParagraph.Row.HasForeignCells && (rowPrevious == null || rowPrevious.RowGroup != row.RowGroup))
                    {
                        ValidateRowVisualComplex(
                            (RowVisual)(rowVisualsCollection[iR]),
                            arrayTableRowDesc[iR].pfstablerow,
                            CalculatedColumns.Length,
                            fskupdRow,
                            CalculatedColumns);
                    }
                    else
                    {
                        ValidateRowVisualSimple(
                            (RowVisual)(rowVisualsCollection[iR]),
                            arrayTableRowDesc[iR].pfstablerow,
                            fskupdRow,
                            CalculatedColumns);
                    }
                }

                rowPrevious = row;
            }

            //
            //  STEP 4 


            if (rowVisualsCollection.Count > arrayTableRowDesc.Length)
            {
                rowVisualsCollection.RemoveRange(
                    arrayTableRowDesc.Length,
                    rowVisualsCollection.Count - arrayTableRowDesc.Length);
            }
        }
Beispiel #3
0
        private void ValidateRowVisualSimple(
            RowVisual rowVisual,
            IntPtr pfstablerow,
            PTS.FSKUPDATE fskupdRow,
            CalculatedColumn[] calculatedColumns)
        {
            PTS.FSKUPDATE[] arrayUpdate;
            IntPtr[] arrayFsCell;
            PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge;
            VisualCollection cellVisualsCollection;
            int sourceIndex;

            QueryRowDetails(
                pfstablerow,
                out arrayFsCell,
                out arrayUpdate,
                out arrayTableCellMerge);

            cellVisualsCollection = rowVisual.Children;
            sourceIndex = 0;

            for (int iC = 0; iC < arrayFsCell.Length; ++iC)
            {
                CellParaClient cellParaClient;
                double urCellOffset;
                PTS.FSKUPDATE fskupdCell;

                if (    //  paginated case - cell may be null
                        arrayFsCell[iC] == IntPtr.Zero
                        //  exclude hanging cells
                    ||  arrayTableCellMerge[iC] == PTS.FSTABLEKCELLMERGE.fskcellmergeMiddle
                    ||  arrayTableCellMerge[iC] == PTS.FSTABLEKCELLMERGE.fskcellmergeLast   )
                {
                    continue;
                }

                fskupdCell = (arrayUpdate[iC] != PTS.FSKUPDATE.fskupdInherited)
                    ? arrayUpdate[iC]
                    : fskupdRow;

                if (fskupdCell != PTS.FSKUPDATE.fskupdNoChange)
                {
                    cellParaClient = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));
                    urCellOffset = calculatedColumns[cellParaClient.ColumnIndex].UrOffset;

                    cellParaClient.ValidateVisual();

                    if (    fskupdCell == PTS.FSKUPDATE.fskupdNew
                        //  PTS bug is a suspect here - this is a temp workaround:
                        ||  VisualTreeHelper.GetParent(cellParaClient.Visual) == null   )
                    {
                        Visual currentParent = VisualTreeHelper.GetParent(cellParaClient.Visual) as Visual;
                        if(currentParent != null)
                        {
                            ContainerVisual parent = currentParent as ContainerVisual;
                            Invariant.Assert(parent != null, "parent should always derives from ContainerVisual");
                            parent.Children.Remove(cellParaClient.Visual);
                        }
                        cellVisualsCollection.Insert(sourceIndex, cellParaClient.Visual);
                    }
                    else
                    {
                        Debug.Assert(   cellParaClient.Visual != null
                                    //  If the check below fails, then PTS cheats by reporting "ChangInside" for
                                    //  a cell that in fact was re-Formatted.
                                    &&  VisualTreeHelper.GetParent(cellParaClient.Visual) != null   );

                        SynchronizeCellVisualsCollection(cellVisualsCollection, sourceIndex, cellParaClient.Visual);
                    }
                }
                sourceIndex++;
            }

            if (cellVisualsCollection.Count > sourceIndex)
            {
                cellVisualsCollection.RemoveRange(
                    sourceIndex,
                    cellVisualsCollection.Count - sourceIndex);
            }

            #if DEBUGDEBUG
            for (int iC = 0, sourceIndex = 0; iC < arrayFsCell.Length; ++iC)
            {
                if (    arrayFsCell[iC] != IntPtr.Zero
                    &&  arrayTableCellMerge[iC] != PTS.FSTABLEKCELLMERGE.fskcellmergeMiddle
                    &&  arrayTableCellMerge[iC] != PTS.FSTABLEKCELLMERGE.fskcellmergeLast   )
                {
                    CellParaClient cellParaClient = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));
                    Debug.Assert(rowVisual.Children.IndexOf(cellParaClient.Visual) == sourceIndex);
                    sourceIndex++;
                }
            }
            #endif // DEBUGDEBUG
        }