Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / documents / ParagraphResult.cs / 1305600 / ParagraphResult.cs
//-------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: The ParagraphResult class provides access to layout-calculated // information for a paragraph. // // History: // 05/20/2003 : [....] - Moving from Avalon branch. // 06/25/2004 : [....] - Performance work. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using System.Windows.Documents; using System.Windows.Media; using MS.Internal.PtsHost; using MS.Internal.Text; namespace MS.Internal.Documents { ////// The ParagraphResult class provides access to layout-calculated /// information for a paragraph. /// internal abstract class ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal ParagraphResult(BaseParaClient paraClient) { _paraClient = paraClient; _layoutBox = _paraClient.Rect.FromTextDpi(); _element = paraClient.Paragraph.Element; } ////// Constructor. /// /// Object representing a paragraph. /// Layout box for paragraph. /// Element associated with this paragraph result. internal ParagraphResult(BaseParaClient paraClient, Rect layoutBox, DependencyObject element) : this(paraClient) { _layoutBox = layoutBox; _element = element; } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Returns whether the position is contained in this paragraph. /// /// A position to test. /// Apply strict validation rules. ////// True if column contains specified text position. /// Otherwise returns false. /// internal virtual bool Contains(ITextPointer position, bool strict) { EnsureTextContentRange(); return _contentRange.Contains(position, strict); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Represents the beginning of the paragraph’s contents. /// internal ITextPointer StartPosition { get { EnsureTextContentRange(); return _contentRange.StartPosition; } } ////// Represents the end of the paragraph’s contents. /// internal ITextPointer EndPosition { get { EnsureTextContentRange(); return _contentRange.EndPosition; } } ////// The bounding rectangle of the paragraph; this is relative /// to the parent bounding box. /// internal Rect LayoutBox { get { return _layoutBox; } } ////// Element associated with the paragraph. /// internal DependencyObject Element { get { return _element; } } ////// In derived classes, will return the _hasTextContent member whose value is set if the paragraph /// has text content. /// internal virtual bool HasTextContent { get { return false; } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Retrive TextContentRange if necessary. /// private void EnsureTextContentRange() { if (_contentRange == null) { _contentRange = _paraClient.GetTextContentRange(); Invariant.Assert(_contentRange != null); } } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// Object representing a paragraph. /// protected readonly BaseParaClient _paraClient; ////// Layout rectangle of the paragraph. /// protected readonly Rect _layoutBox; ////// Element paragraph is associated with /// protected readonly DependencyObject _element; ////// TextContentRanges representing the column's contents. /// private TextContentRange _contentRange; ////// True if the paragraph or any nested paragraphs has text content /// protected bool _hasTextContent; #endregion Private Fields } ////// The ParagraphResult for a paragraph which only contains other /// paragraphs. /// internal sealed class ContainerParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal ContainerParagraphResult(ContainerParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) { return (((ContainerParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect)); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //------------------------------------------------------------------- #region Internal Properties ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionParagraphs { get { if (_paragraphs == null) { // While getting children paragraph results, each paragraph is queried for text content _paragraphs = ((ContainerParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent); } Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); return _paragraphs; } } /// /// True if the paragraph has text content, i.e. not just figures and floaters. For a container paragraph, this is /// true if any of its children paras has text content /// internal override bool HasTextContent { get { if (_paragraphs == null) { // Getting Paragraphs collection queries each paragraph for text content and sets the value ReadOnlyCollectionparagraphs = Paragraphs; } return _hasTextContent; } } #endregion Internal Properties //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_paragraphs; #endregion Private Fields } /// /// The ParagraphResult for a paragraph which contains Text, Figures, /// and Floaters (no nested paragraphs). /// internal sealed class TextParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal TextParagraphResult(TextParaClient paraClient) : base(paraClient) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Retrieves the height and offset, in pixels, of the edge of /// the object/character represented by position. /// /// Position of an object/character. ////// The height, in pixels, of the edge of the object/character /// represented by position. /// internal Rect GetRectangleFromTextPosition(ITextPointer position) { return ((TextParaClient)_paraClient).GetRectangleFromTextPosition(position); } ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Paragraph's top space. /// Visible clipping rectangle ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, double paragraphTopSpace, Rect visibleRect) { return ((TextParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, paragraphTopSpace, visibleRect); } ////// Returns true if caret is at unit boundary /// /// Position of an object/character. internal bool IsAtCaretUnitBoundary(ITextPointer position) { return ((TextParaClient)_paraClient).IsAtCaretUnitBoundary(position); } ////// Retrieves next caret unit position /// /// Position of an object/character. /// /// LogicalDirection in which we seek the next caret unit position /// internal ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction) { return ((TextParaClient)_paraClient).GetNextCaretUnitPosition(position, direction); } ////// Retrieves caret unit position after backspace /// /// Position of an object/character. internal ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position) { return ((TextParaClient)_paraClient).GetBackspaceCaretUnitPosition(position); } ////// Retrieves collection of GlyphRuns from a range of text. /// /// /// Preallocated collection of GlyphRuns. /// May already contain runs and new runs need to be appended. /// /// The beginning of the range. /// The end of the range. internal void GetGlyphRuns(ListglyphRuns, ITextPointer start, ITextPointer end) { ((TextParaClient)_paraClient).GetGlyphRuns(glyphRuns, start, end); } /// /// Returns whether the position is contained in this paragraph. /// /// A position to test. /// Apply strict validation rules. ////// True if column contains specified text position. /// Otherwise returns false. /// internal override bool Contains(ITextPointer position, bool strict) { bool contains = base.Contains(position, strict); // If the last line of text paragraph does not have content (example: some text), // position after LineBreak with Forward direction belongs to this text paragraph and indicates // the last line of it. // Because of that, always treat position after th last character of text paragraph as a valid // position for it. It is safe to do it because it is impossible to get 2 adjacent text paragraphs. if (!contains && strict) { contains = (position.CompareTo(this.EndPosition) == 0); } return contains; } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties /// /// Collection of lines in this paragraph. /// internal ReadOnlyCollectionLines { get { if (_lines == null) { _lines = ((TextParaClient)_paraClient).GetLineResults(); } Invariant.Assert(_lines != null, "Lines collection is null"); return _lines; } } /// /// Collection of floating UIElements in this paragraph. /// internal ReadOnlyCollectionFloaters { get { if (_floaters == null) { _floaters = ((TextParaClient)_paraClient).GetFloaters(); } return _floaters; } } /// /// Collection of figure UIElements in this paragraph. /// internal ReadOnlyCollectionFigures { get { if (_figures == null) { _figures = ((TextParaClient)_paraClient).GetFigures(); } return _figures; } } /// /// True if the paragraph has some text content, not only attached objects. A paragraph with no lines has no text content. /// A paragraph with just one line containing figures and/or floaters does *not* have text content. We will ignore the end of paragraph character /// in this case and not hit test the lines in the paragraph. However, an empty paragraph with no figures and floaters does have text content. /// We treat the EOP character as being on a line by itself. This is needed for editing. /// internal override bool HasTextContent { get { return (Lines.Count > 0 && !ContainsOnlyFloatingElements); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Properties // //-------------------------------------------------------------------- #region Private Properties ////// True if the paragraph contains only figures or floaters with no text. /// ////// An empty paragraph with no floating elements and just EOP character will return false. /// private bool ContainsOnlyFloatingElements { get { bool floatingElementsOnly = false; TextParagraph textParagraph = _paraClient.Paragraph as TextParagraph; Invariant.Assert(textParagraph != null); if (textParagraph.HasFiguresOrFloaters()) { if (Lines.Count == 0) { // No lines, only attached objects floatingElementsOnly = true; } else if (Lines.Count == 1) { // If this line has no content, paragraph contains only attached objects int lastDcpAttachedObjectBeforeLine = textParagraph.GetLastDcpAttachedObjectBeforeLine(0); if (lastDcpAttachedObjectBeforeLine + textParagraph.ParagraphStartCharacterPosition == textParagraph.ParagraphEndCharacterPosition) { floatingElementsOnly = true; } } } return floatingElementsOnly; } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of LineResults for for the paragraph's lines. /// private ReadOnlyCollection_lines; /// /// The collection of floating objects. /// private ReadOnlyCollection_floaters; /// /// The collection of figures. /// private ReadOnlyCollection_figures; #endregion Private Fields } /// /// The ParagraphResult for a table paragraph. /// internal sealed class TableParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal TableParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns the paragraphs for the appropriate cell, given a point /// /// Point to check for cell. /// Whether to snap to text ////// Array of paragraph results /// internal ReadOnlyCollectionGetParagraphsFromPoint(Point point, bool snapToText) { return ((TableParaClient)_paraClient).GetParagraphsFromPoint(point, snapToText); } /// /// Returns the paragraphs for the appropriate cell, given a text position /// /// Position to check for cell. ////// Array of paragraph results /// internal ReadOnlyCollectionGetParagraphsFromPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetParagraphsFromPosition(position); } /// /// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping rectangle. ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) { return ((TableParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect); } ////// Returns the para client for a cell, given a position /// /// Position to check for cell. ////// Cell para client /// internal CellParaClient GetCellParaClientFromPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetCellParaClientFromPosition(position); } ////// Returns an appropriate found cell /// /// Suggested X position for cell to find. /// RowGroupIndex to be above. /// RowIndex to be above. ////// Cell Para Client of cell /// internal CellParaClient GetCellAbove(double suggestedX, int rowGroupIndex, int rowIndex) { return ((TableParaClient)_paraClient).GetCellAbove(suggestedX, rowGroupIndex, rowIndex); } ////// Returns an appropriate found cell /// /// Suggested X position for cell to find. /// RowGroupIndex to be below. /// RowIndex to be below. ////// Cell Para Client of cell /// internal CellParaClient GetCellBelow(double suggestedX, int rowGroupIndex, int rowIndex) { return ((TableParaClient)_paraClient).GetCellBelow(suggestedX, rowGroupIndex, rowIndex); } ////// Returns a cellinfo structure for a given point /// /// Point to check for cell. ////// CellInfo class /// internal CellInfo GetCellInfoFromPoint(Point point) { return ((TableParaClient)_paraClient).GetCellInfoFromPoint(point); } ////// Returns a rect corresponding to a row end position. /// /// Position to check against. ////// Rect, area /// internal Rect GetRectangleFromRowEndPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetRectangleFromRowEndPosition(position); } ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionParagraphs { get { if (_paragraphs == null) { // While getting children paras, query each one for text content and use the result to set _hasTextContent _paragraphs = ((TableParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent); } Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); return _paragraphs; } } /// /// True if the paragraph has text content and not only figures/floaters. For Table paragraph this is true if any of its /// children paras has text content /// internal override bool HasTextContent { get { if (_paragraphs == null) { // Getting Paragraphs collection sets the value of _hasTextContent by checking each child for text content ReadOnlyCollectionparagraphs = Paragraphs; } return _hasTextContent; } } #endregion Internal Methods //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_paragraphs; #endregion Private Fields } /// /// The ParagraphResult for a table row. /// internal sealed class RowParagraphResult : ParagraphResult { //-------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. /// Index of row in paragraph. /// Rectangle of row - as rendered. /// Actual paragraph result is bound to. internal RowParagraphResult(BaseParaClient paraClient, int index, Rect rowRect, RowParagraph rowParagraph) : base(paraClient, rowRect, rowParagraph.Element) { _index = index; } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Properties ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionCellParagraphs { get { if (_cells == null) { // Check each cell for text content when getting cell paragraph results _cells = ((TableParaClient)_paraClient).GetChildrenParagraphResultsForRow(_index, out _hasTextContent); } Invariant.Assert(_cells != null, "Paragraph collection is empty"); return _cells; } } /// /// True if the table row has text content, i.e. if any of the table cells in the row has text content /// internal override bool HasTextContent { get { if (_cells == null) { // Getting cell paragraph results queries each one for text content ReadOnlyCollectioncells = CellParagraphs; } return _hasTextContent; } } #endregion Internal Properties //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_cells; /// /// Index of this row paragraph in tableparaclient's row array. /// int _index; #endregion Private Fields } ////// The ParagraphResult for a subpage paragraph. /// internal sealed class SubpageParagraphResult : ParagraphResult { //-------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal SubpageParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Check subpage columns for text content _columns = ((SubpageParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if subpage has text content, i.e. if any of its columns has text content. Checking columns for text content will /// recursively check each column's paragraph collections /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((SubpageParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a figure paragraph. /// internal sealed class FigureParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FigureParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Check figure's columns for text content _columns = ((FigureParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if the figure has text content, i.e. if its columns collection has text content. /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((FigureParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area /// True if range starts in this [ara ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success) { success = false; if (this.Contains(startPosition, true)) { // Selection starts inside this floater and must end inside it success = true; ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition; // Pass paragraph results and floating elements to para client so it doesn't have to generate them return (((FigureParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect)); } return null; } #endregion Internal Methods //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ColumnResults for nested columns. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a floater base paragraph. /// internal abstract class FloaterBaseParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FloaterBaseParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors } ////// The ParagraphResult for a floater paragraph. /// internal sealed class FloaterParagraphResult : FloaterBaseParagraphResult { //-------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FloaterParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Query floater's columns for text content _columns = ((FloaterParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if the floater has text content, i.e. if its columns collection has text content. /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((FloaterParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area /// True if the range starts in this floater paragraph ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success) { success = false; if (this.Contains(startPosition, true)) { // Selection starts inside this floater and must end inside it success = true; ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition; return (((FloaterParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect)); } return null; } #endregion Internal Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ColumnResults for nested columns. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a UIElement paragraph. /// internal sealed class UIElementParagraphResult : FloaterBaseParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal UIElementParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// True if the BUIC has text content /// internal override bool HasTextContent { get { // We always treat BlockUIContainer as a 'line' from ContentStart to ContentEnd. So HasTextContent is always true return true; } } ////// Returns tight bounding geometry for the given text range. /// internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) { return (((UIElementParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition)); } #endregion Internal Properties } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: The ParagraphResult class provides access to layout-calculated // information for a paragraph. // // History: // 05/20/2003 : [....] - Moving from Avalon branch. // 06/25/2004 : [....] - Performance work. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using System.Windows.Documents; using System.Windows.Media; using MS.Internal.PtsHost; using MS.Internal.Text; namespace MS.Internal.Documents { ////// The ParagraphResult class provides access to layout-calculated /// information for a paragraph. /// internal abstract class ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal ParagraphResult(BaseParaClient paraClient) { _paraClient = paraClient; _layoutBox = _paraClient.Rect.FromTextDpi(); _element = paraClient.Paragraph.Element; } ////// Constructor. /// /// Object representing a paragraph. /// Layout box for paragraph. /// Element associated with this paragraph result. internal ParagraphResult(BaseParaClient paraClient, Rect layoutBox, DependencyObject element) : this(paraClient) { _layoutBox = layoutBox; _element = element; } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Returns whether the position is contained in this paragraph. /// /// A position to test. /// Apply strict validation rules. ////// True if column contains specified text position. /// Otherwise returns false. /// internal virtual bool Contains(ITextPointer position, bool strict) { EnsureTextContentRange(); return _contentRange.Contains(position, strict); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Represents the beginning of the paragraph’s contents. /// internal ITextPointer StartPosition { get { EnsureTextContentRange(); return _contentRange.StartPosition; } } ////// Represents the end of the paragraph’s contents. /// internal ITextPointer EndPosition { get { EnsureTextContentRange(); return _contentRange.EndPosition; } } ////// The bounding rectangle of the paragraph; this is relative /// to the parent bounding box. /// internal Rect LayoutBox { get { return _layoutBox; } } ////// Element associated with the paragraph. /// internal DependencyObject Element { get { return _element; } } ////// In derived classes, will return the _hasTextContent member whose value is set if the paragraph /// has text content. /// internal virtual bool HasTextContent { get { return false; } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Retrive TextContentRange if necessary. /// private void EnsureTextContentRange() { if (_contentRange == null) { _contentRange = _paraClient.GetTextContentRange(); Invariant.Assert(_contentRange != null); } } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// Object representing a paragraph. /// protected readonly BaseParaClient _paraClient; ////// Layout rectangle of the paragraph. /// protected readonly Rect _layoutBox; ////// Element paragraph is associated with /// protected readonly DependencyObject _element; ////// TextContentRanges representing the column's contents. /// private TextContentRange _contentRange; ////// True if the paragraph or any nested paragraphs has text content /// protected bool _hasTextContent; #endregion Private Fields } ////// The ParagraphResult for a paragraph which only contains other /// paragraphs. /// internal sealed class ContainerParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal ContainerParagraphResult(ContainerParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) { return (((ContainerParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect)); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //------------------------------------------------------------------- #region Internal Properties ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionParagraphs { get { if (_paragraphs == null) { // While getting children paragraph results, each paragraph is queried for text content _paragraphs = ((ContainerParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent); } Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); return _paragraphs; } } /// /// True if the paragraph has text content, i.e. not just figures and floaters. For a container paragraph, this is /// true if any of its children paras has text content /// internal override bool HasTextContent { get { if (_paragraphs == null) { // Getting Paragraphs collection queries each paragraph for text content and sets the value ReadOnlyCollectionparagraphs = Paragraphs; } return _hasTextContent; } } #endregion Internal Properties //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_paragraphs; #endregion Private Fields } /// /// The ParagraphResult for a paragraph which contains Text, Figures, /// and Floaters (no nested paragraphs). /// internal sealed class TextParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal TextParagraphResult(TextParaClient paraClient) : base(paraClient) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Retrieves the height and offset, in pixels, of the edge of /// the object/character represented by position. /// /// Position of an object/character. ////// The height, in pixels, of the edge of the object/character /// represented by position. /// internal Rect GetRectangleFromTextPosition(ITextPointer position) { return ((TextParaClient)_paraClient).GetRectangleFromTextPosition(position); } ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Paragraph's top space. /// Visible clipping rectangle ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, double paragraphTopSpace, Rect visibleRect) { return ((TextParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, paragraphTopSpace, visibleRect); } ////// Returns true if caret is at unit boundary /// /// Position of an object/character. internal bool IsAtCaretUnitBoundary(ITextPointer position) { return ((TextParaClient)_paraClient).IsAtCaretUnitBoundary(position); } ////// Retrieves next caret unit position /// /// Position of an object/character. /// /// LogicalDirection in which we seek the next caret unit position /// internal ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction) { return ((TextParaClient)_paraClient).GetNextCaretUnitPosition(position, direction); } ////// Retrieves caret unit position after backspace /// /// Position of an object/character. internal ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position) { return ((TextParaClient)_paraClient).GetBackspaceCaretUnitPosition(position); } ////// Retrieves collection of GlyphRuns from a range of text. /// /// /// Preallocated collection of GlyphRuns. /// May already contain runs and new runs need to be appended. /// /// The beginning of the range. /// The end of the range. internal void GetGlyphRuns(ListglyphRuns, ITextPointer start, ITextPointer end) { ((TextParaClient)_paraClient).GetGlyphRuns(glyphRuns, start, end); } /// /// Returns whether the position is contained in this paragraph. /// /// A position to test. /// Apply strict validation rules. ////// True if column contains specified text position. /// Otherwise returns false. /// internal override bool Contains(ITextPointer position, bool strict) { bool contains = base.Contains(position, strict); // If the last line of text paragraph does not have content (example: some text), // position after LineBreak with Forward direction belongs to this text paragraph and indicates // the last line of it. // Because of that, always treat position after th last character of text paragraph as a valid // position for it. It is safe to do it because it is impossible to get 2 adjacent text paragraphs. if (!contains && strict) { contains = (position.CompareTo(this.EndPosition) == 0); } return contains; } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties /// /// Collection of lines in this paragraph. /// internal ReadOnlyCollectionLines { get { if (_lines == null) { _lines = ((TextParaClient)_paraClient).GetLineResults(); } Invariant.Assert(_lines != null, "Lines collection is null"); return _lines; } } /// /// Collection of floating UIElements in this paragraph. /// internal ReadOnlyCollectionFloaters { get { if (_floaters == null) { _floaters = ((TextParaClient)_paraClient).GetFloaters(); } return _floaters; } } /// /// Collection of figure UIElements in this paragraph. /// internal ReadOnlyCollectionFigures { get { if (_figures == null) { _figures = ((TextParaClient)_paraClient).GetFigures(); } return _figures; } } /// /// True if the paragraph has some text content, not only attached objects. A paragraph with no lines has no text content. /// A paragraph with just one line containing figures and/or floaters does *not* have text content. We will ignore the end of paragraph character /// in this case and not hit test the lines in the paragraph. However, an empty paragraph with no figures and floaters does have text content. /// We treat the EOP character as being on a line by itself. This is needed for editing. /// internal override bool HasTextContent { get { return (Lines.Count > 0 && !ContainsOnlyFloatingElements); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Properties // //-------------------------------------------------------------------- #region Private Properties ////// True if the paragraph contains only figures or floaters with no text. /// ////// An empty paragraph with no floating elements and just EOP character will return false. /// private bool ContainsOnlyFloatingElements { get { bool floatingElementsOnly = false; TextParagraph textParagraph = _paraClient.Paragraph as TextParagraph; Invariant.Assert(textParagraph != null); if (textParagraph.HasFiguresOrFloaters()) { if (Lines.Count == 0) { // No lines, only attached objects floatingElementsOnly = true; } else if (Lines.Count == 1) { // If this line has no content, paragraph contains only attached objects int lastDcpAttachedObjectBeforeLine = textParagraph.GetLastDcpAttachedObjectBeforeLine(0); if (lastDcpAttachedObjectBeforeLine + textParagraph.ParagraphStartCharacterPosition == textParagraph.ParagraphEndCharacterPosition) { floatingElementsOnly = true; } } } return floatingElementsOnly; } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of LineResults for for the paragraph's lines. /// private ReadOnlyCollection_lines; /// /// The collection of floating objects. /// private ReadOnlyCollection_floaters; /// /// The collection of figures. /// private ReadOnlyCollection_figures; #endregion Private Fields } /// /// The ParagraphResult for a table paragraph. /// internal sealed class TableParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal TableParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns the paragraphs for the appropriate cell, given a point /// /// Point to check for cell. /// Whether to snap to text ////// Array of paragraph results /// internal ReadOnlyCollectionGetParagraphsFromPoint(Point point, bool snapToText) { return ((TableParaClient)_paraClient).GetParagraphsFromPoint(point, snapToText); } /// /// Returns the paragraphs for the appropriate cell, given a text position /// /// Position to check for cell. ////// Array of paragraph results /// internal ReadOnlyCollectionGetParagraphsFromPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetParagraphsFromPosition(position); } /// /// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping rectangle. ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect) { return ((TableParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect); } ////// Returns the para client for a cell, given a position /// /// Position to check for cell. ////// Cell para client /// internal CellParaClient GetCellParaClientFromPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetCellParaClientFromPosition(position); } ////// Returns an appropriate found cell /// /// Suggested X position for cell to find. /// RowGroupIndex to be above. /// RowIndex to be above. ////// Cell Para Client of cell /// internal CellParaClient GetCellAbove(double suggestedX, int rowGroupIndex, int rowIndex) { return ((TableParaClient)_paraClient).GetCellAbove(suggestedX, rowGroupIndex, rowIndex); } ////// Returns an appropriate found cell /// /// Suggested X position for cell to find. /// RowGroupIndex to be below. /// RowIndex to be below. ////// Cell Para Client of cell /// internal CellParaClient GetCellBelow(double suggestedX, int rowGroupIndex, int rowIndex) { return ((TableParaClient)_paraClient).GetCellBelow(suggestedX, rowGroupIndex, rowIndex); } ////// Returns a cellinfo structure for a given point /// /// Point to check for cell. ////// CellInfo class /// internal CellInfo GetCellInfoFromPoint(Point point) { return ((TableParaClient)_paraClient).GetCellInfoFromPoint(point); } ////// Returns a rect corresponding to a row end position. /// /// Position to check against. ////// Rect, area /// internal Rect GetRectangleFromRowEndPosition(ITextPointer position) { return ((TableParaClient)_paraClient).GetRectangleFromRowEndPosition(position); } ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionParagraphs { get { if (_paragraphs == null) { // While getting children paras, query each one for text content and use the result to set _hasTextContent _paragraphs = ((TableParaClient)_paraClient).GetChildrenParagraphResults(out _hasTextContent); } Invariant.Assert(_paragraphs != null, "Paragraph collection is empty"); return _paragraphs; } } /// /// True if the paragraph has text content and not only figures/floaters. For Table paragraph this is true if any of its /// children paras has text content /// internal override bool HasTextContent { get { if (_paragraphs == null) { // Getting Paragraphs collection sets the value of _hasTextContent by checking each child for text content ReadOnlyCollectionparagraphs = Paragraphs; } return _hasTextContent; } } #endregion Internal Methods //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_paragraphs; #endregion Private Fields } /// /// The ParagraphResult for a table row. /// internal sealed class RowParagraphResult : ParagraphResult { //-------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. /// Index of row in paragraph. /// Rectangle of row - as rendered. /// Actual paragraph result is bound to. internal RowParagraphResult(BaseParaClient paraClient, int index, Rect rowRect, RowParagraph rowParagraph) : base(paraClient, rowRect, rowParagraph.Element) { _index = index; } #endregion Constructors //------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Properties ////// Collection of paragraphs in this paragraph. /// internal ReadOnlyCollectionCellParagraphs { get { if (_cells == null) { // Check each cell for text content when getting cell paragraph results _cells = ((TableParaClient)_paraClient).GetChildrenParagraphResultsForRow(_index, out _hasTextContent); } Invariant.Assert(_cells != null, "Paragraph collection is empty"); return _cells; } } /// /// True if the table row has text content, i.e. if any of the table cells in the row has text content /// internal override bool HasTextContent { get { if (_cells == null) { // Getting cell paragraph results queries each one for text content ReadOnlyCollectioncells = CellParagraphs; } return _hasTextContent; } } #endregion Internal Properties //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_cells; /// /// Index of this row paragraph in tableparaclient's row array. /// int _index; #endregion Private Fields } ////// The ParagraphResult for a subpage paragraph. /// internal sealed class SubpageParagraphResult : ParagraphResult { //-------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal SubpageParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Check subpage columns for text content _columns = ((SubpageParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if subpage has text content, i.e. if any of its columns has text content. Checking columns for text content will /// recursively check each column's paragraph collections /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((SubpageParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ParagraphResults for for nested paragraphs. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a figure paragraph. /// internal sealed class FigureParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FigureParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Check figure's columns for text content _columns = ((FigureParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if the figure has text content, i.e. if its columns collection has text content. /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((FigureParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area /// True if range starts in this [ara ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success) { success = false; if (this.Contains(startPosition, true)) { // Selection starts inside this floater and must end inside it success = true; ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition; // Pass paragraph results and floating elements to para client so it doesn't have to generate them return (((FigureParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect)); } return null; } #endregion Internal Methods //-------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ColumnResults for nested columns. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a floater base paragraph. /// internal abstract class FloaterBaseParagraphResult : ParagraphResult { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FloaterBaseParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors } ////// The ParagraphResult for a floater paragraph. /// internal sealed class FloaterParagraphResult : FloaterBaseParagraphResult { //-------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal FloaterParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Collection of ColumnResults for each line in the paragraph. /// internal ReadOnlyCollectionColumns { get { if (_columns == null) { // Query floater's columns for text content _columns = ((FloaterParaClient)_paraClient).GetColumnResults(out _hasTextContent); Invariant.Assert(_columns != null, "Columns collection is null"); } return _columns; } } /// /// True if the floater has text content, i.e. if its columns collection has text content. /// internal override bool HasTextContent { get { if (_columns == null) { ReadOnlyCollectioncolumns = Columns; } return _hasTextContent; } } /// /// Collection of ParagraphResults for floating elements /// internal ReadOnlyCollectionFloatingElements { get { if (_floatingElements == null) { _floatingElements = ((FloaterParaClient)_paraClient).FloatingElementResults; Invariant.Assert(_floatingElements != null, "Floating elements collection is null"); } return _floatingElements; } } /// /// Offset for contained content - New PTS coordinate system (0, 0) /// internal Vector ContentOffset { get { MbpInfo mbp = MbpInfo.FromElement(_paraClient.Paragraph.Element); return new Vector(LayoutBox.X + TextDpi.FromTextDpi(mbp.BPLeft), LayoutBox.Y + TextDpi.FromTextDpi(mbp.BPTop)); } } #endregion Internal Properties //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Returns tight bounding geometry for the given text range. /// /// Start position of the range. /// End position of the range. /// Visible clipping area /// True if the range starts in this floater paragraph ///Geometry object containing tight bound. internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect, out bool success) { success = false; if (this.Contains(startPosition, true)) { // Selection starts inside this floater and must end inside it success = true; ITextPointer endPositionInThisPara = endPosition.CompareTo(this.EndPosition) < 0 ? endPosition : this.EndPosition; return (((FloaterParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(Columns, FloatingElements, startPosition, endPositionInThisPara, visibleRect)); } return null; } #endregion Internal Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields ////// The collection of ColumnResults for nested columns. /// private ReadOnlyCollection_columns; /// /// The collection of ParagraphResults for floating elements. /// private ReadOnlyCollection_floatingElements; #endregion Private Fields } /// /// The ParagraphResult for a UIElement paragraph. /// internal sealed class UIElementParagraphResult : FloaterBaseParagraphResult { //------------------------------------------------------------------- // // Constructors // //-------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Object representing a paragraph. internal UIElementParagraphResult(BaseParaClient paraClient) : base(paraClient) { } #endregion Constructors //------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// True if the BUIC has text content /// internal override bool HasTextContent { get { // We always treat BlockUIContainer as a 'line' from ContentStart to ContentEnd. So HasTextContent is always true return true; } } ////// Returns tight bounding geometry for the given text range. /// internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) { return (((UIElementParaClient)_paraClient).GetTightBoundingGeometryFromTextPositions(startPosition, endPosition)); } #endregion Internal Properties } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PresentationTraceSources.cs
- KeyValueSerializer.cs
- TreeNodeSelectionProcessor.cs
- ByteStack.cs
- CompressionTransform.cs
- Volatile.cs
- DateTime.cs
- XmlSignatureProperties.cs
- ValueConversionAttribute.cs
- CellParagraph.cs
- PriorityChain.cs
- CaseInsensitiveComparer.cs
- Int16Converter.cs
- InputScopeNameConverter.cs
- Formatter.cs
- TextStore.cs
- DataServiceQuery.cs
- Logging.cs
- PageBuildProvider.cs
- PropertyTabAttribute.cs
- CodeDomSerializer.cs
- EdmComplexPropertyAttribute.cs
- Line.cs
- ApplicationServiceManager.cs
- GridViewSelectEventArgs.cs
- ComponentChangingEvent.cs
- KeyNotFoundException.cs
- diagnosticsswitches.cs
- PropertyIDSet.cs
- DynamicResourceExtensionConverter.cs
- FormsAuthenticationUser.cs
- ImageConverter.cs
- Bind.cs
- safex509handles.cs
- DbDataReader.cs
- DefaultBinder.cs
- DateTimePicker.cs
- SettingsPropertyCollection.cs
- Misc.cs
- CodeIterationStatement.cs
- Instrumentation.cs
- AppearanceEditorPart.cs
- PropertyChangingEventArgs.cs
- FixUp.cs
- DialogBaseForm.cs
- InProcStateClientManager.cs
- CodeAccessSecurityEngine.cs
- AutoResetEvent.cs
- MissingSatelliteAssemblyException.cs
- Scene3D.cs
- KeyValueSerializer.cs
- XmlnsPrefixAttribute.cs
- EntityTypeEmitter.cs
- OdbcConnectionStringbuilder.cs
- MSAAWinEventWrap.cs
- GridViewRowPresenter.cs
- SchemaImporterExtensionsSection.cs
- SqlRowUpdatingEvent.cs
- FormView.cs
- RSAPKCS1KeyExchangeFormatter.cs
- PriorityQueue.cs
- TabControl.cs
- QueryContinueDragEvent.cs
- HandoffBehavior.cs
- MatrixStack.cs
- MaskedTextBox.cs
- DataServiceQuery.cs
- RootBrowserWindowAutomationPeer.cs
- ZipIOModeEnforcingStream.cs
- ZipIOLocalFileBlock.cs
- SerializationBinder.cs
- FormatterConverter.cs
- DataGridViewRowPrePaintEventArgs.cs
- EntityDataSourceWizardForm.cs
- QueryOperationResponseOfT.cs
- DesignerObject.cs
- CodeComment.cs
- OdbcEnvironmentHandle.cs
- AsyncPostBackTrigger.cs
- ScrollProviderWrapper.cs
- xamlnodes.cs
- AsyncPostBackErrorEventArgs.cs
- DetailsViewCommandEventArgs.cs
- Axis.cs
- ComboBoxItem.cs
- FunctionDefinition.cs
- NavigationPropertyEmitter.cs
- ConstrainedDataObject.cs
- COM2IDispatchConverter.cs
- ObjectDataSource.cs
- Int32Storage.cs
- TraceLevelStore.cs
- SoapFormatExtensions.cs
- FindCriteria11.cs
- AppDomainUnloadedException.cs
- HostedElements.cs
- ObjectDisposedException.cs
- LogLogRecordEnumerator.cs
- EntityDataSourceContextCreatingEventArgs.cs
- InheritablePropertyChangeInfo.cs