Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / documents / ParagraphResult.cs / 1 / 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 : grzegorz - Moving from Avalon branch. // 06/25/2004 : grzegorz - 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 : grzegorz - Moving from Avalon branch. // 06/25/2004 : grzegorz - 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
- EditCommandColumn.cs
- IndexingContentUnit.cs
- RegexStringValidatorAttribute.cs
- bidPrivateBase.cs
- MachineKeyConverter.cs
- SiteMembershipCondition.cs
- AndCondition.cs
- Parsers.cs
- BitmapMetadataEnumerator.cs
- diagnosticsswitches.cs
- Sql8ExpressionRewriter.cs
- FormatterServicesNoSerializableCheck.cs
- XmlSchemaInferenceException.cs
- ModuleBuilder.cs
- LookupNode.cs
- CodeArrayCreateExpression.cs
- ComplusTypeValidator.cs
- Int16AnimationUsingKeyFrames.cs
- BaseDataBoundControl.cs
- ImageClickEventArgs.cs
- PropertyGridCommands.cs
- TextServicesDisplayAttributePropertyRanges.cs
- RangeValuePattern.cs
- SwitchAttribute.cs
- WebControlsSection.cs
- GenericUriParser.cs
- ViewRendering.cs
- WebUtil.cs
- XmlSchemaAnnotated.cs
- LocalizedNameDescriptionPair.cs
- CreateRefExpr.cs
- KeyEventArgs.cs
- WindowsEditBox.cs
- DataGridViewLayoutData.cs
- ApplicationException.cs
- MenuCommand.cs
- Scalars.cs
- COM2ExtendedBrowsingHandler.cs
- AffineTransform3D.cs
- TraceContextRecord.cs
- X509RawDataKeyIdentifierClause.cs
- SqlWebEventProvider.cs
- SecurityDescriptor.cs
- Int32RectConverter.cs
- ComplexPropertyEntry.cs
- RequestCachePolicyConverter.cs
- AppManager.cs
- PartialList.cs
- Shape.cs
- BitmapMetadataEnumerator.cs
- ValueConversionAttribute.cs
- DiscreteKeyFrames.cs
- CaseInsensitiveOrdinalStringComparer.cs
- mansign.cs
- PlanCompiler.cs
- AutomationPatternInfo.cs
- AutomationProperties.cs
- ResourceKey.cs
- DateRangeEvent.cs
- XmlCustomFormatter.cs
- TraceSection.cs
- Nodes.cs
- Int32RectConverter.cs
- CommandConverter.cs
- XmlReaderDelegator.cs
- IsolationInterop.cs
- HMAC.cs
- InkPresenter.cs
- SymmetricKey.cs
- AccessedThroughPropertyAttribute.cs
- RewritingPass.cs
- GAC.cs
- AssociatedControlConverter.cs
- PropertyChangeTracker.cs
- WebContext.cs
- DataSourceIDConverter.cs
- ISAPIApplicationHost.cs
- XNameConverter.cs
- PerformanceCounterLib.cs
- UnsafeNativeMethodsPenimc.cs
- ClientSideQueueItem.cs
- XPathDocument.cs
- RotateTransform.cs
- DbConnectionStringCommon.cs
- PrintDialogException.cs
- ResolveNameEventArgs.cs
- ConfigurationPermission.cs
- HierarchicalDataSourceControl.cs
- ResolveInfo.cs
- GraphicsContext.cs
- securitymgrsite.cs
- CookieParameter.cs
- GlobalizationAssembly.cs
- wgx_exports.cs
- DependencyPropertyChangedEventArgs.cs
- CombinedGeometry.cs
- mongolianshape.cs
- MasterPageParser.cs
- ClientSponsor.cs
- StringResourceManager.cs