// ------------------------------------------------------------------ // Dump Cell specific data. // ------------------------------------------------------------------ private static void DumpTableCell(XmlTextWriter writer, ParagraphResult paragraph, Visual cellVisual, Visual tableVisual) { Type paragraphResultType = paragraph.GetType(); System.Reflection.FieldInfo fieldOfParaClient = paragraphResultType.GetField("_paraClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (fieldOfParaClient == null) { return; } CellParaClient cellParaClient = (CellParaClient) fieldOfParaClient.GetValue(paragraph); CellParagraph cellParagraph = cellParaClient.CellParagraph; TableCell cell = cellParagraph.Cell; writer.WriteStartElement("Cell"); Type typeOfCell = cell.GetType(); System.Reflection.PropertyInfo propOfColumnIndex = typeOfCell.GetProperty("ColumnIndex", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly); if (propOfColumnIndex != null) { int columnIndex = (int)propOfColumnIndex.GetValue(cell, null); writer.WriteAttributeString("ColumnIndex", columnIndex.ToString(CultureInfo.InvariantCulture)); } System.Reflection.PropertyInfo propOfRowIndex = typeOfCell.GetProperty("RowIndex", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly); if (propOfRowIndex != null) { int rowIndex = (int)propOfRowIndex.GetValue(cell, null); writer.WriteAttributeString("RowIndex", rowIndex.ToString(CultureInfo.InvariantCulture)); } writer.WriteAttributeString("ColumnSpan", cell.ColumnSpan.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("RowSpan", cell.RowSpan.ToString(CultureInfo.InvariantCulture)); Rect rect = cellParaClient.Rect.FromTextDpi(); DumpRect(writer, "LayoutBox", rect); bool hasTextContent; DumpParagraphResults(writer, "Paragraphs", cellParaClient.GetColumnResults(out hasTextContent)[0].Paragraphs, cellParaClient.Visual); writer.WriteEndElement(); }
/// <summary> /// Retrieves a position matching a point from a given paragraph /// </summary> /// <param name="paragraph"> /// Para containing position /// </param> /// <param name="point"> /// Point in pixel coordinates to test. /// </param> /// <param name="snapToText"> /// If true, this method must always return a positioned text position /// (the closest position as calculated by the control's heuristics). /// If false, this method should return null position, if the test /// point does not fall within any character bounding box. /// </param> private ITextPointer GetTextPositionFromPoint(ParagraphResult paragraph, Point point, bool snapToText) { ITextPointer position = null; Rect paragraphBox = paragraph.LayoutBox; // Position is retrieved differently for different paragraph types: // a) ContainerParagraph, FigureParagraph, FloaterParagraph - hittest colleciton of nested paragraphs. // b) TextParagraph - hittest line collection. // c) TableParagraph - hittest in table // d) Other paragraphs - return position before/after paragraph element. if (paragraph is ContainerParagraphResult) { // a) ContainerParagraph - hittest colleciton of nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; // Paragraphs collection may be null in case of empty List element, Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { position = GetTextPositionFromPoint(nestedParagraphs, _emptyParagraphCollection, point, snapToText, /* snap to text for floating elements*/ false); } else { // Return position before/after paragraph element. if (point.X <= paragraphBox.Width) { position = paragraph.StartPosition.CreatePointer(LogicalDirection.Forward); } else { position = paragraph.EndPosition.CreatePointer(LogicalDirection.Backward); } } } else if (paragraph is TextParagraphResult) { // b) TextParagraph - hittest line collection. ReadOnlyCollection<LineResult> lines = ((TextParagraphResult)paragraph).Lines; Invariant.Assert(lines != null, "Lines collection is null"); if (!((TextParagraphResult)paragraph).HasTextContent) { position = null; } else { position = TextParagraphView.GetTextPositionFromPoint(lines, point, snapToText); } } else if (paragraph is TableParagraphResult) { ReadOnlyCollection<ParagraphResult> rowParagraphs = ((TableParagraphResult)paragraph).Paragraphs; Invariant.Assert(rowParagraphs != null, "Paragraph collection is null."); int index = GetParagraphFromPoint(rowParagraphs, point, snapToText); if (index != -1) { ParagraphResult rowResult = rowParagraphs[index]; if (point.X > rowResult.LayoutBox.Right) { position = ((TextElement)rowResult.Element).ElementEnd; } else { ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPoint(point, snapToText); position = GetTextPositionFromPoint(nestedParagraphs, _emptyParagraphCollection, point, snapToText, false); } } else { // Table is empty. position = null; // When snap to text is enabled a valid text position is required. if (snapToText) { position = ((TextElement)paragraph.Element).ContentStart; } } } else if (paragraph is SubpageParagraphResult) { // Subpage implies new coordinate system. SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph; point.X -= subpageParagraphResult.ContentOffset.X; point.Y -= subpageParagraphResult.ContentOffset.Y; // WOOT! COLUMNS! position = GetTextPositionFromPoint(subpageParagraphResult.Columns, subpageParagraphResult.FloatingElements, point, snapToText); } else if (paragraph is FigureParagraphResult || paragraph is FloaterParagraphResult) { ReadOnlyCollection<ColumnResult> columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements; if (paragraph is FloaterParagraphResult) { FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph; columns = floaterParagraphResult.Columns; nestedFloatingElements = floaterParagraphResult.FloatingElements; TransformToSubpage(ref point, floaterParagraphResult.ContentOffset); } else { FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph; columns = figureParagraphResult.Columns; nestedFloatingElements = figureParagraphResult.FloatingElements; TransformToSubpage(ref point, figureParagraphResult.ContentOffset); } // Paragraphs collection may be null in case of empty List element, Invariant.Assert(columns != null, "Columns collection is null."); Invariant.Assert(nestedFloatingElements != null, "Floating elements collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { position = GetTextPositionFromPoint(columns, nestedFloatingElements, point, snapToText); } else { position = null; } } else if (paragraph is UIElementParagraphResult) { BlockUIContainer blockUIContainer = paragraph.Element as BlockUIContainer; if (blockUIContainer != null) { position = null; if (paragraphBox.Contains(point) || snapToText) { // Point is with BUIC's layout box. Return paragraph's ContentStart/End as appropriate if (DoubleUtil.LessThanOrClose(point.X, paragraphBox.X + paragraphBox.Width / 2)) { position = blockUIContainer.ContentStart.CreatePointer(LogicalDirection.Forward); } else { position = blockUIContainer.ContentEnd.CreatePointer(LogicalDirection.Backward); } } } } else { // d) Other paragraphs - return position before/after paragraph element. if (point.X <= paragraphBox.Width) { position = paragraph.StartPosition.CreatePointer(LogicalDirection.Forward); } else { position = paragraph.EndPosition.CreatePointer(LogicalDirection.Backward); } } return position; }
// ------------------------------------------------------------------ // Dump paragraph offset. // ------------------------------------------------------------------ private static Visual DumpParagraphOffset(XmlTextWriter writer, ParagraphResult paragraph, Visual visualParent) { Type paragraphResultType = paragraph.GetType(); System.Reflection.FieldInfo field = paragraphResultType.GetField("_paraClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); object paraClient = field.GetValue(paragraph); Type paraClientType = paraClient.GetType(); System.Reflection.PropertyInfo prop = paraClientType.GetProperty("Visual", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); Visual visual = (Visual)prop.GetValue(paraClient, null); // Dump transform relative to its parent if(visualParent.IsAncestorOf(visual)) { GeneralTransform g = visual.TransformToAncestor(visualParent); Point point = new Point(0.0f, 0.0f); g.TryTransform(point, out point); if (point.X != 0 || point.Y != 0) { DumpPoint(writer, "Origin", point); } } return visual; }
/// <summary> /// Returns the layout box edge associated with this block if a text position is located at the end of the block element with appropriate /// Logical direction. /// </summary> /// <param name="paragraphResult">Result to check edges.</param> /// <param name="textPointer">Text Pointer to compare against</param> /// <returns> /// Returns rect for edge, or Rect.Empty if textposition not on edge /// </returns> private Rect GetRectangleFromEdge(ParagraphResult paragraphResult, ITextPointer textPointer) { TextElement textElement = paragraphResult.Element as TextElement; if (textElement != null) { if (textPointer.LogicalDirection == LogicalDirection.Forward && textPointer.CompareTo(textElement.ElementStart) == 0) { return new Rect(paragraphResult.LayoutBox.Left, paragraphResult.LayoutBox.Top, 0.0, paragraphResult.LayoutBox.Height); } if (textPointer.LogicalDirection == LogicalDirection.Backward && textPointer.CompareTo(textElement.ElementEnd) == 0) { return new Rect(paragraphResult.LayoutBox.Right, paragraphResult.LayoutBox.Top, 0.0, paragraphResult.LayoutBox.Height); } } return Rect.Empty; }
/// <summary> /// Returns the layout box edge associated with this block if a text position is located at the end of the block content /// This is for elements like BlockUIContainer where the content start/end (regardless of direction)has the same rectangle as /// the element start/end, we treat BUC as a line with 2 positions at start and end /// </summary> /// <param name="paragraphResult">Result to check edges.</param> /// <param name="textPointer">Text Pointer to compare against</param> /// <returns> /// Returns rect for edge, or Rect.Empty if textposition not on edge /// </returns> private Rect GetRectangleFromContentEdge(ParagraphResult paragraphResult, ITextPointer textPointer) { TextElement textElement = paragraphResult.Element as TextElement; if (textElement != null) { // We enable this only for BlockUIContainer, it would be wrong to return layout box Rect from other elements' Content start/end Invariant.Assert(textElement is BlockUIContainer, "Expecting BlockUIContainer"); // No need to consider position's LogicalDirection here, ContentStart's backward context for BUIC should be ElementStart, for which // we also want the same rectangle; the same applies to ContentEnd if (textPointer.CompareTo(textElement.ContentStart) == 0) { return new Rect(paragraphResult.LayoutBox.Left, paragraphResult.LayoutBox.Top, 0.0, paragraphResult.LayoutBox.Height); } if (textPointer.CompareTo(textElement.ContentEnd) == 0) { return new Rect(paragraphResult.LayoutBox.Right, paragraphResult.LayoutBox.Top, 0.0, paragraphResult.LayoutBox.Height); } } return Rect.Empty; }
/// <summary> /// Returns a TextSegment that spans the line on which position is located. /// </summary> /// <param name="paragraph">Paragraph to search</param> /// <param name="position">Any oriented text position on the line.</param> private TextSegment GetLineRangeFromPosition(ParagraphResult paragraph, ITextPointer position) { TextSegment lineRange = TextSegment.Null; // Each paragraph type is handled differently: // a) ContainerParagraph - process nested paragraphs. // b) TextParagraph - find line index of a line containing input text position // and then return its range. // c) TableParagraph - process nested paragraphs. if (paragraph is ContainerParagraphResult) { // a) ContainerParagraph - process nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; // Paragraphs collection may be null in case of empty List. Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { lineRange = GetLineRangeFromPosition(nestedParagraphs, _emptyParagraphCollection, position); } } else if (paragraph is TextParagraphResult) { // b) TextParagraph - find line index of a line containing input text position // and then return its range. ReadOnlyCollection<LineResult> lines = ((TextParagraphResult)paragraph).Lines; Invariant.Assert(lines != null, "Lines collection is null"); if (!((TextParagraphResult)paragraph).HasTextContent) { // Paragraph has no lines. // lineRange = new TextSegment(((TextParagraphResult)paragraph).EndPosition, ((TextParagraphResult)paragraph).EndPosition, true); } else { // Get index of the line that contains position. int lineIndex = TextParagraphView.GetLineFromPosition(lines, position); Invariant.Assert(lineIndex >= 0 && lineIndex < lines.Count, "Line not found."); lineRange = new TextSegment(lines[lineIndex].StartPosition, lines[lineIndex].GetContentEndPosition(), true); } } else if (paragraph is TableParagraphResult) { // c) TableParagraph - process nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPosition(position); // Paragraphs collection may be null in case of empty List. Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { lineRange = GetLineRangeFromPosition(nestedParagraphs, _emptyParagraphCollection, position); } } else if (paragraph is SubpageParagraphResult) { SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = subpageParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = subpageParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position); } } else if (paragraph is FigureParagraphResult) { FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = figureParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = figureParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position); } } else if (paragraph is FloaterParagraphResult) { FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = floaterParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = floaterParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position); } } else if (paragraph is UIElementParagraphResult) { // UIElement paragraph result - return content range between BlockUIContainer.ContentStart and ContentEnd BlockUIContainer blockUIContainer = paragraph.Element as BlockUIContainer; if (blockUIContainer != null) { lineRange = new TextSegment(blockUIContainer.ContentStart.CreatePointer(LogicalDirection.Forward), blockUIContainer.ContentEnd.CreatePointer(LogicalDirection.Backward)); } } return lineRange; }
/// <summary> /// Finds and returns the backspace position of a caret unit /// </summary> /// <param name="paragraph">Paragraph to search.</param> /// <param name="position">Position of an object/character.</param> private ITextPointer GetBackspaceCaretUnitPosition(ParagraphResult paragraph, ITextPointer position) { ITextPointer backspaceCaretPosition = position; if (paragraph is ContainerParagraphResult) { // a) ContainerParagraph - go to collection of nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; // Paragraphs collection may be null in case of empty List. Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { backspaceCaretPosition = GetBackspaceCaretUnitPosition(nestedParagraphs, _emptyParagraphCollection, position); } } else if (paragraph is TextParagraphResult) { // b) TextParagraph - search inside it backspaceCaretPosition = ((TextParagraphResult)paragraph).GetBackspaceCaretUnitPosition(position); } else if (paragraph is TableParagraphResult) { ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPosition(position); Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { backspaceCaretPosition = GetBackspaceCaretUnitPosition(nestedParagraphs, _emptyParagraphCollection, position); } } else if (paragraph is SubpageParagraphResult) { SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = subpageParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = subpageParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { backspaceCaretPosition = GetBackspaceCaretUnitPosition(columns, nestedFloatingElements, position); } } else if (paragraph is FigureParagraphResult) { FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = figureParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = figureParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { backspaceCaretPosition = GetBackspaceCaretUnitPosition(columns, nestedFloatingElements, position); } } else if (paragraph is FloaterParagraphResult) { FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = floaterParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = floaterParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Column collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (columns.Count > 0 || nestedFloatingElements.Count > 0) { backspaceCaretPosition = GetBackspaceCaretUnitPosition(columns, nestedFloatingElements, position); } } return backspaceCaretPosition; }
// Retreives a layout box for the paragraphResult private static Rect GetLayoutBox(ParagraphResult paragraph) { if (!(paragraph is SubpageParagraphResult) && !(paragraph is RowParagraphResult)) { return paragraph.LayoutBox; } return Rect.Empty; }
/// <summary> /// Retrieves the height and offset, in pixels, of the edge of /// the object/character represented by position. /// </summary> /// <param name="paragraph">Paragraph to search</param> /// <param name="position">Position of an object/character.</param> private Rect GetRectangleFromTextPosition(ParagraphResult paragraph, ITextPointer position) { Rect rect = Rect.Empty; // Rectangle is retrieved differently for different paragraph types: // a) ContainerParagraph - get rectangle from nested paragraphs. // b) TextParagraph - get rectangle from text paragraph's content. // c) TableParagraph - get rectangle from nested paras if (paragraph is ContainerParagraphResult) { rect = GetRectangleFromEdge(paragraph, position); if (rect == Rect.Empty) { // a) ContainerParagraph - check collection of nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { rect = GetRectangleFromTextPosition(nestedParagraphs, _emptyParagraphCollection, position); } } } else if (paragraph is TextParagraphResult) { rect = ((TextParagraphResult)paragraph).GetRectangleFromTextPosition(position); } else if (paragraph is TableParagraphResult) { // c) TableParagraph - get rectangle from nested paras rect = GetRectangleFromEdge(paragraph, position); if (rect == Rect.Empty) { ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPosition(position); Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); if (nestedParagraphs.Count > 0) { rect = GetRectangleFromTextPosition(nestedParagraphs, _emptyParagraphCollection, position); } else if (position is TextPointer && ((TextPointer)position).IsAtRowEnd) { rect = ((TableParagraphResult)paragraph).GetRectangleFromRowEndPosition(position); } } } else if (paragraph is SubpageParagraphResult) { // Subpage implies new coordinate system. SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph; rect = GetRectangleFromTextPosition(subpageParagraphResult.Columns, subpageParagraphResult.FloatingElements, position); if (rect != Rect.Empty) { rect.X += subpageParagraphResult.ContentOffset.X; rect.Y += subpageParagraphResult.ContentOffset.Y; } } else if (paragraph is FloaterParagraphResult) { FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = floaterParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = floaterParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Columns collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (nestedFloatingElements.Count > 0 || columns.Count > 0) { rect = GetRectangleFromTextPosition(columns, nestedFloatingElements, position); // Add content offset to rect TransformFromSubpage(ref rect, floaterParagraphResult.ContentOffset); } } else if (paragraph is FigureParagraphResult) { FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph; ReadOnlyCollection<ColumnResult> columns = figureParagraphResult.Columns; ReadOnlyCollection<ParagraphResult> nestedFloatingElements = figureParagraphResult.FloatingElements; Invariant.Assert(columns != null, "Columns collection is null."); Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); if (nestedFloatingElements.Count > 0 || columns.Count > 0) { rect = GetRectangleFromTextPosition(columns, nestedFloatingElements, position); // Add content offset to rect TransformFromSubpage(ref rect, figureParagraphResult.ContentOffset); } } else if (paragraph is UIElementParagraphResult) { rect = GetRectangleFromEdge(paragraph, position); if (rect == Rect.Empty) { // For a UIElementParagraph, we should check if element is either at Element start/end or Content Start end // This is needed to enable selection of embedded object w/ mouse click rect = GetRectangleFromContentEdge(paragraph, position); } } return rect; }
/// <summary> /// Returns a cellinfo class for a point that may be inside of a cell /// </summary> /// <param name="paragraph"> /// Para to hit test into /// </param> /// <param name="point"> /// Point to hit test /// </param> /// <param name="tableFilter"> /// Filter out all results not specific to a given table /// </param> private CellInfo GetCellInfoFromPoint(ParagraphResult paragraph, Point point, Table tableFilter) { // Figure out which paragraph is the closest to the input pixel position. CellInfo cellInfo = null; if (paragraph is ContainerParagraphResult) { // a) ContainerParagraph - hittest colleciton of nested paragraphs. ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; // Paragraphs collection may be empty, but should never be null Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null"); if (nestedParagraphs.Count > 0) { cellInfo = GetCellInfoFromPoint(nestedParagraphs, _emptyParagraphCollection, point, tableFilter); } } else if (paragraph is TableParagraphResult) { ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPoint(point, false); Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null"); if (nestedParagraphs.Count > 0) { cellInfo = GetCellInfoFromPoint(nestedParagraphs, _emptyParagraphCollection, point, tableFilter); } if (cellInfo == null) { cellInfo = ((TableParagraphResult)paragraph).GetCellInfoFromPoint(point); } } else if (paragraph is SubpageParagraphResult) { // Subpage implies new coordinate system. SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph; point.X -= subpageParagraphResult.ContentOffset.X; point.Y -= subpageParagraphResult.ContentOffset.Y; // WOOT! COLUMNS! cellInfo = GetCellInfoFromPoint(subpageParagraphResult.Columns, subpageParagraphResult.FloatingElements, point, tableFilter); if (cellInfo != null) { cellInfo.Adjust(new Point(subpageParagraphResult.ContentOffset.X, subpageParagraphResult.ContentOffset.Y)); } } else if (paragraph is FigureParagraphResult) { // Subpage implies new coordinate system. FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph; TransformToSubpage(ref point, figureParagraphResult.ContentOffset); cellInfo = GetCellInfoFromPoint(figureParagraphResult.Columns, figureParagraphResult.FloatingElements, point, tableFilter); if (cellInfo != null) { cellInfo.Adjust(new Point(figureParagraphResult.ContentOffset.X, figureParagraphResult.ContentOffset.Y)); } } else if (paragraph is FloaterParagraphResult) { // Subpage implies new coordinate system. FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph; TransformToSubpage(ref point, floaterParagraphResult.ContentOffset); cellInfo = GetCellInfoFromPoint(floaterParagraphResult.Columns, floaterParagraphResult.FloatingElements, point, tableFilter); if (cellInfo != null) { cellInfo.Adjust(new Point(floaterParagraphResult.ContentOffset.X, floaterParagraphResult.ContentOffset.Y)); } } if (tableFilter != null && cellInfo != null && cellInfo.Cell.Table != tableFilter) { cellInfo = null; // Clear out result if not matching input filter } return cellInfo; }