Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Documents / documentsequencetextview.cs / 1 / documentsequencetextview.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description:
// DocumentSequenceTextView implements TextView for DocumentSequence
// to support text editing (e.g Selection).
//
// History:
// 07/20/2004 : zhenbinx - Created
//
//---------------------------------------------------------------------------
namespace System.Windows.Documents
{
using MS.Internal.Documents;
using MS.Internal;
using MS.Utility;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
///
/// DocumentSequenceTextView implements TextView for DocumentSequence
/// to support text editing (e.g Selection).
///
internal sealed class DocumentSequenceTextView : TextViewBase
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Constructor.
///
internal DocumentSequenceTextView(FixedDocumentSequenceDocumentPage docPage)
{
_docPage = docPage;
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
///
/// Retrieves a position matching a point.
///
///
/// Point in pixel coordinates to test.
///
///
/// If true, this method must always return a positioned text position
/// (the closest position as calculated by the control's heuristics).
/// If false, this method should return null position, if the test
/// point does not fall within any character bounding box.
///
///
/// A text position and its orientation matching or closest to the point.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetTextPositionFromPoint {0}-{1}", point, snapToText));
DocumentSequenceTextPointer tp = null;
LogicalDirection edge = LogicalDirection.Forward;
if (ChildTextView != null)
{
ITextPointer childOTP = ChildTextView.GetTextPositionFromPoint(point, snapToText);
if (childOTP != null)
{
tp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
edge = childOTP.LogicalDirection;
}
}
// When snapToText is true, ChildTextView.GetTextPositionFromPoint will guranttee to
// return a non-null position.
// In current code, ChildTextView can't be null.
return tp == null ? null : DocumentSequenceTextPointer.CreatePointer(tp, edge);
}
///
/// Retrieves the height and offset, in pixels, of the edge of
/// the object/character represented by position.
///
///
/// Position of an object/character.
///
///
/// Transform to be applied to returned rect
///
///
/// The height, in pixels, of the edge of the object/character
/// represented by position.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// Rect.Width is always 0.
///
/// If the document is empty, then this method returns the expected
/// height of a character, if placed at the specified position.
///
internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetRawRectangleFromTextPosition {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tp = null;
// Initialize transform to identity
transform = Transform.Identity;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
return ChildTextView.GetRawRectangleFromTextPosition(tp.ChildPointer.CreatePointer(position.LogicalDirection), out transform);
}
}
}
return Rect.Empty;
}
///
///
///
internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
{
if (startPosition != null && endPosition != null && ChildTextView != null)
{
DocumentSequenceTextPointer startTp = null;
DocumentSequenceTextPointer endTp = null;
startTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(startPosition);
endTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(endPosition);
if (startTp != null && endTp != null)
{
return ChildTextView.GetTightBoundingGeometryFromTextPositions(startTp.ChildPointer, endTp.ChildPointer);
}
}
return (new PathGeometry());;
}
///
/// Retrieves an oriented text position matching position advanced by
/// a number of lines from its initial position.
///
///
/// Initial text position of an object/character.
///
///
/// The suggested X offset, in pixels, of text position on the destination
/// line. If suggestedX is set to Double.NaN it will be ignored, otherwise
/// the method will try to find a position on the destination line closest
/// to suggestedX.
///
///
/// Number of lines to advance. Negative means move backwards.
///
///
/// newSuggestedX is the offset at the position moved (useful when moving
/// between columns or pages).
///
///
/// linesMoved indicates the number of lines moved, which may be less
/// than count if there is no more content.
///
///
/// A TextPointer and its orientation matching suggestedX on the
/// destination line.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
{
newSuggestedX = suggestedX;
linesMoved = count;
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetPositionAtNextLine {0} {1} {2} {3} ", position, position.LogicalDirection, suggestedX, count));
DocumentSequenceTextPointer newTp = null;
LogicalDirection newEdge = LogicalDirection.Forward;
DocumentSequenceTextPointer tp = null;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
// Note we do not handle cross page navigation
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
ITextPointer childOTP = ChildTextView.GetPositionAtNextLine(tp.ChildPointer.CreatePointer(position.LogicalDirection), suggestedX, count, out newSuggestedX, out linesMoved);
if (childOTP != null)
{
newTp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
newEdge = childOTP.LogicalDirection;
}
}
}
}
return DocumentSequenceTextPointer.CreatePointer(newTp, newEdge);
}
///
/// Determines if a position is located between two caret units.
///
///
/// Position to test.
///
///
/// Returns true if the specified position precedes or follows
/// the first or last code point of a caret unit, respectively.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// In the context of this method, "caret unit" refers to a group
/// of one or more Unicode code points that map to a single rendered
/// glyph.
///
internal override bool IsAtCaretUnitBoundary(ITextPointer position)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.IsAtCaretUnitBoundary(ftp.ChildPointer);
}
///
/// Finds the next position at the edge of a caret unit in
/// specified direction.
///
///
/// Initial text position of an object/character.
///
///
/// If Forward, this method returns the "caret unit" position following
/// the initial position.
/// If Backward, this method returns the caret unit" position preceding
/// the initial position.
///
///
/// The next caret unit break position in specified direction.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// In the context of this method, "caret unit" refers to a group of one
/// or more Unicode code points that map to a single rendered glyph.
///
/// If position is located between two caret units, this method returns
/// a new position located at the opposite edge of the caret unit in
/// the indicated direction.
/// If position is located within a group of Unicode code points that map
/// to a single caret unit, this method returns a new position at
/// the indicated edge of the containing caret unit.
/// If position is located at the beginning of end of content -- there is
/// no content in the indicated direction -- then this method returns
/// a position located at the same location as initial position.
///
internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.GetNextCaretUnitPosition(ftp.ChildPointer, direction);
}
///
/// Finds the previous position at the edge of a caret after backspacing.
///
///
/// Initial text position of an object/character.
///
///
/// The previous caret unit break position after backspacing.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.GetBackspaceCaretUnitPosition(ftp.ChildPointer);
}
///
/// Returns a TextSegment that spans the line on which position is located.
///
///
/// Any oriented text position on the line.
///
///
/// TextSegment that spans the line on which position is located.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override TextSegment GetLineRange(ITextPointer position)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetLineRange {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tpStart = null;
DocumentSequenceTextPointer tpEnd = null;
DocumentSequenceTextPointer tpLine = null;
if (position != null)
{
if (ChildTextView != null)
{
tpLine = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
if (ChildTextView.TextContainer == tpLine.ChildBlock.ChildContainer)
{
TextSegment childTR = ChildTextView.GetLineRange(tpLine.ChildPointer.CreatePointer(position.LogicalDirection));
if (!childTR.IsNull)
{
tpStart = new DocumentSequenceTextPointer(ChildBlock, childTR.Start);
tpEnd = new DocumentSequenceTextPointer(ChildBlock, childTR.End);
return new TextSegment(tpStart, tpEnd, true);
}
}
}
}
return TextSegment.Null;
}
///
/// Provides a collection of glyph properties corresponding to runs
/// of Unicode code points.
///
///
/// A position preceding the first code point to examine.
///
///
/// A position following the last code point to examine.
///
///
/// A collection of glyph property runs.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// A "glyph" in this context is the lowest level rendered representation
/// of text. Each entry in the output array describes a constant run of
/// properties on the glyphs corresponding to a range of Unicode code points.
/// With this array, it's possible to enumerate the glpyh properties for
/// each code point in the specified text run.
///
internal override ReadOnlyCollection GetGlyphRuns(ITextPointer start, ITextPointer end)
{
throw new NotImplementedException();
}
///
/// Determines whenever TextView contains specified position.
///
///
/// A position to test.
///
///
/// True if TextView contains specified text position.
/// Otherwise returns false.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override bool Contains(ITextPointer position)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("Contains {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tp = null;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
// Note we do not handle cross page navigation
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
return ChildTextView.Contains(tp.ChildPointer.CreatePointer(position.LogicalDirection));
}
}
}
return false;
}
///
/// Makes sure that TextView is in a clean layout state and it is
/// possible to retrieve layout related data.
///
///
/// If IsValid returns false, it is required to call this method
/// before calling any other method on TextView.
/// Validate method might be very expensive, because it may lead
/// to full layout update.
///
internal override bool Validate()
{
if (ChildTextView != null)
{
ChildTextView.Validate();
}
return ((ITextView)this).IsValid;
}
///
internal override bool Validate(Point point)
{
if (ChildTextView != null)
{
ChildTextView.Validate(point);
}
return ((ITextView)this).IsValid;
}
#endregion Internal Methods
//------------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
///
///
internal override UIElement RenderScope
{
get
{
Visual visual = _docPage.Visual;
while (visual != null && !(visual is UIElement))
{
visual = VisualTreeHelper.GetParent(visual) as Visual;
}
return visual as UIElement;
}
}
///
/// TextContainer that stores content.
///
internal override ITextContainer TextContainer
{
get
{
return this._docPage.FixedDocumentSequence.TextContainer;
}
}
///
/// Determines whenever layout is in clean state and it is possible
/// to retrieve layout related data.
///
internal override bool IsValid
{
get
{
if (ChildTextView != null)
{
return ChildTextView.IsValid;
}
return true;
}
}
///
///
///
internal override bool RendersOwnSelection
{
get
{
return true;
}
}
///
/// Collection of TextSegments representing content of the TextView.
///
internal override ReadOnlyCollection TextSegments
{
get
{
if (_textSegments == null)
{
ReadOnlyCollection childSegments = ChildTextView.TextSegments;
if (childSegments != null)
{
List parentSegments = new List(childSegments.Count);
foreach (TextSegment segment in childSegments)
{
DocumentSequenceTextPointer ptpStart, ptpEnd;
ptpStart = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.Start);
ptpEnd = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.End);
parentSegments.Add(new TextSegment(ptpStart, ptpEnd,true));
}
_textSegments = new ReadOnlyCollection(parentSegments);
}
}
return _textSegments;
}
}
#endregion Internal Properties
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
#region Private Properties
private ITextView ChildTextView
{
get
{
if (_childTextView == null)
{
IServiceProvider isp = _docPage.ChildDocumentPage as IServiceProvider;
if (isp != null)
{
_childTextView = (ITextView)isp.GetService(typeof(ITextView));
}
}
return _childTextView;
}
}
private ChildDocumentBlock ChildBlock
{
get
{
if (_childBlock == null)
{
_childBlock = _docPage.FixedDocumentSequence.TextContainer.FindChildBlock(_docPage.ChildDocumentReference);
}
return _childBlock;
}
}
private DocumentSequenceTextContainer DocumentSequenceTextContainer
{
get
{
return _docPage.FixedDocumentSequence.TextContainer;
}
}
#endregion Private Properties
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
// The FixedDocumentSequenceDocumentPage for this TextView
private readonly FixedDocumentSequenceDocumentPage _docPage;
private ITextView _childTextView;
private ReadOnlyCollection _textSegments;
private ChildDocumentBlock _childBlock;
}
}
// 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:
// DocumentSequenceTextView implements TextView for DocumentSequence
// to support text editing (e.g Selection).
//
// History:
// 07/20/2004 : zhenbinx - Created
//
//---------------------------------------------------------------------------
namespace System.Windows.Documents
{
using MS.Internal.Documents;
using MS.Internal;
using MS.Utility;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
///
/// DocumentSequenceTextView implements TextView for DocumentSequence
/// to support text editing (e.g Selection).
///
internal sealed class DocumentSequenceTextView : TextViewBase
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Constructor.
///
internal DocumentSequenceTextView(FixedDocumentSequenceDocumentPage docPage)
{
_docPage = docPage;
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
///
/// Retrieves a position matching a point.
///
///
/// Point in pixel coordinates to test.
///
///
/// If true, this method must always return a positioned text position
/// (the closest position as calculated by the control's heuristics).
/// If false, this method should return null position, if the test
/// point does not fall within any character bounding box.
///
///
/// A text position and its orientation matching or closest to the point.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetTextPositionFromPoint {0}-{1}", point, snapToText));
DocumentSequenceTextPointer tp = null;
LogicalDirection edge = LogicalDirection.Forward;
if (ChildTextView != null)
{
ITextPointer childOTP = ChildTextView.GetTextPositionFromPoint(point, snapToText);
if (childOTP != null)
{
tp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
edge = childOTP.LogicalDirection;
}
}
// When snapToText is true, ChildTextView.GetTextPositionFromPoint will guranttee to
// return a non-null position.
// In current code, ChildTextView can't be null.
return tp == null ? null : DocumentSequenceTextPointer.CreatePointer(tp, edge);
}
///
/// Retrieves the height and offset, in pixels, of the edge of
/// the object/character represented by position.
///
///
/// Position of an object/character.
///
///
/// Transform to be applied to returned rect
///
///
/// The height, in pixels, of the edge of the object/character
/// represented by position.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// Rect.Width is always 0.
///
/// If the document is empty, then this method returns the expected
/// height of a character, if placed at the specified position.
///
internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetRawRectangleFromTextPosition {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tp = null;
// Initialize transform to identity
transform = Transform.Identity;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
return ChildTextView.GetRawRectangleFromTextPosition(tp.ChildPointer.CreatePointer(position.LogicalDirection), out transform);
}
}
}
return Rect.Empty;
}
///
///
///
internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
{
if (startPosition != null && endPosition != null && ChildTextView != null)
{
DocumentSequenceTextPointer startTp = null;
DocumentSequenceTextPointer endTp = null;
startTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(startPosition);
endTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(endPosition);
if (startTp != null && endTp != null)
{
return ChildTextView.GetTightBoundingGeometryFromTextPositions(startTp.ChildPointer, endTp.ChildPointer);
}
}
return (new PathGeometry());;
}
///
/// Retrieves an oriented text position matching position advanced by
/// a number of lines from its initial position.
///
///
/// Initial text position of an object/character.
///
///
/// The suggested X offset, in pixels, of text position on the destination
/// line. If suggestedX is set to Double.NaN it will be ignored, otherwise
/// the method will try to find a position on the destination line closest
/// to suggestedX.
///
///
/// Number of lines to advance. Negative means move backwards.
///
///
/// newSuggestedX is the offset at the position moved (useful when moving
/// between columns or pages).
///
///
/// linesMoved indicates the number of lines moved, which may be less
/// than count if there is no more content.
///
///
/// A TextPointer and its orientation matching suggestedX on the
/// destination line.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
{
newSuggestedX = suggestedX;
linesMoved = count;
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetPositionAtNextLine {0} {1} {2} {3} ", position, position.LogicalDirection, suggestedX, count));
DocumentSequenceTextPointer newTp = null;
LogicalDirection newEdge = LogicalDirection.Forward;
DocumentSequenceTextPointer tp = null;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
// Note we do not handle cross page navigation
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
ITextPointer childOTP = ChildTextView.GetPositionAtNextLine(tp.ChildPointer.CreatePointer(position.LogicalDirection), suggestedX, count, out newSuggestedX, out linesMoved);
if (childOTP != null)
{
newTp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
newEdge = childOTP.LogicalDirection;
}
}
}
}
return DocumentSequenceTextPointer.CreatePointer(newTp, newEdge);
}
///
/// Determines if a position is located between two caret units.
///
///
/// Position to test.
///
///
/// Returns true if the specified position precedes or follows
/// the first or last code point of a caret unit, respectively.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// In the context of this method, "caret unit" refers to a group
/// of one or more Unicode code points that map to a single rendered
/// glyph.
///
internal override bool IsAtCaretUnitBoundary(ITextPointer position)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.IsAtCaretUnitBoundary(ftp.ChildPointer);
}
///
/// Finds the next position at the edge of a caret unit in
/// specified direction.
///
///
/// Initial text position of an object/character.
///
///
/// If Forward, this method returns the "caret unit" position following
/// the initial position.
/// If Backward, this method returns the caret unit" position preceding
/// the initial position.
///
///
/// The next caret unit break position in specified direction.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// In the context of this method, "caret unit" refers to a group of one
/// or more Unicode code points that map to a single rendered glyph.
///
/// If position is located between two caret units, this method returns
/// a new position located at the opposite edge of the caret unit in
/// the indicated direction.
/// If position is located within a group of Unicode code points that map
/// to a single caret unit, this method returns a new position at
/// the indicated edge of the containing caret unit.
/// If position is located at the beginning of end of content -- there is
/// no content in the indicated direction -- then this method returns
/// a position located at the same location as initial position.
///
internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.GetNextCaretUnitPosition(ftp.ChildPointer, direction);
}
///
/// Finds the previous position at the edge of a caret after backspacing.
///
///
/// Initial text position of an object/character.
///
///
/// The previous caret unit break position after backspacing.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
{
Invariant.Assert(position != null);
if (position == null)
{
throw new ArgumentNullException("position");
}
//Verify the position and propagate the call to the child text view
Invariant.Assert(ChildTextView != null);
DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);
return this.ChildTextView.GetBackspaceCaretUnitPosition(ftp.ChildPointer);
}
///
/// Returns a TextSegment that spans the line on which position is located.
///
///
/// Any oriented text position on the line.
///
///
/// TextSegment that spans the line on which position is located.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override TextSegment GetLineRange(ITextPointer position)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetLineRange {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tpStart = null;
DocumentSequenceTextPointer tpEnd = null;
DocumentSequenceTextPointer tpLine = null;
if (position != null)
{
if (ChildTextView != null)
{
tpLine = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
if (ChildTextView.TextContainer == tpLine.ChildBlock.ChildContainer)
{
TextSegment childTR = ChildTextView.GetLineRange(tpLine.ChildPointer.CreatePointer(position.LogicalDirection));
if (!childTR.IsNull)
{
tpStart = new DocumentSequenceTextPointer(ChildBlock, childTR.Start);
tpEnd = new DocumentSequenceTextPointer(ChildBlock, childTR.End);
return new TextSegment(tpStart, tpEnd, true);
}
}
}
}
return TextSegment.Null;
}
///
/// Provides a collection of glyph properties corresponding to runs
/// of Unicode code points.
///
///
/// A position preceding the first code point to examine.
///
///
/// A position following the last code point to examine.
///
///
/// A collection of glyph property runs.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
///
/// A "glyph" in this context is the lowest level rendered representation
/// of text. Each entry in the output array describes a constant run of
/// properties on the glyphs corresponding to a range of Unicode code points.
/// With this array, it's possible to enumerate the glpyh properties for
/// each code point in the specified text run.
///
internal override ReadOnlyCollection GetGlyphRuns(ITextPointer start, ITextPointer end)
{
throw new NotImplementedException();
}
///
/// Determines whenever TextView contains specified position.
///
///
/// A position to test.
///
///
/// True if TextView contains specified text position.
/// Otherwise returns false.
///
///
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
///
internal override bool Contains(ITextPointer position)
{
DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("Contains {0} {1}", position, position.LogicalDirection));
DocumentSequenceTextPointer tp = null;
if (position != null)
{
tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
}
// Note we do not handle cross page navigation
if (tp != null)
{
if (ChildTextView != null)
{
if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
{
return ChildTextView.Contains(tp.ChildPointer.CreatePointer(position.LogicalDirection));
}
}
}
return false;
}
///
/// Makes sure that TextView is in a clean layout state and it is
/// possible to retrieve layout related data.
///
///
/// If IsValid returns false, it is required to call this method
/// before calling any other method on TextView.
/// Validate method might be very expensive, because it may lead
/// to full layout update.
///
internal override bool Validate()
{
if (ChildTextView != null)
{
ChildTextView.Validate();
}
return ((ITextView)this).IsValid;
}
///
internal override bool Validate(Point point)
{
if (ChildTextView != null)
{
ChildTextView.Validate(point);
}
return ((ITextView)this).IsValid;
}
#endregion Internal Methods
//------------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
///
///
internal override UIElement RenderScope
{
get
{
Visual visual = _docPage.Visual;
while (visual != null && !(visual is UIElement))
{
visual = VisualTreeHelper.GetParent(visual) as Visual;
}
return visual as UIElement;
}
}
///
/// TextContainer that stores content.
///
internal override ITextContainer TextContainer
{
get
{
return this._docPage.FixedDocumentSequence.TextContainer;
}
}
///
/// Determines whenever layout is in clean state and it is possible
/// to retrieve layout related data.
///
internal override bool IsValid
{
get
{
if (ChildTextView != null)
{
return ChildTextView.IsValid;
}
return true;
}
}
///
///
///
internal override bool RendersOwnSelection
{
get
{
return true;
}
}
///
/// Collection of TextSegments representing content of the TextView.
///
internal override ReadOnlyCollection TextSegments
{
get
{
if (_textSegments == null)
{
ReadOnlyCollection childSegments = ChildTextView.TextSegments;
if (childSegments != null)
{
List parentSegments = new List(childSegments.Count);
foreach (TextSegment segment in childSegments)
{
DocumentSequenceTextPointer ptpStart, ptpEnd;
ptpStart = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.Start);
ptpEnd = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.End);
parentSegments.Add(new TextSegment(ptpStart, ptpEnd,true));
}
_textSegments = new ReadOnlyCollection(parentSegments);
}
}
return _textSegments;
}
}
#endregion Internal Properties
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
#region Private Properties
private ITextView ChildTextView
{
get
{
if (_childTextView == null)
{
IServiceProvider isp = _docPage.ChildDocumentPage as IServiceProvider;
if (isp != null)
{
_childTextView = (ITextView)isp.GetService(typeof(ITextView));
}
}
return _childTextView;
}
}
private ChildDocumentBlock ChildBlock
{
get
{
if (_childBlock == null)
{
_childBlock = _docPage.FixedDocumentSequence.TextContainer.FindChildBlock(_docPage.ChildDocumentReference);
}
return _childBlock;
}
}
private DocumentSequenceTextContainer DocumentSequenceTextContainer
{
get
{
return _docPage.FixedDocumentSequence.TextContainer;
}
}
#endregion Private Properties
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
// The FixedDocumentSequenceDocumentPage for this TextView
private readonly FixedDocumentSequenceDocumentPage _docPage;
private ITextView _childTextView;
private ReadOnlyCollection _textSegments;
private ChildDocumentBlock _childBlock;
}
}
// 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
- ConfigurationSection.cs
- PrincipalPermission.cs
- TextContainerHelper.cs
- ContractReference.cs
- Run.cs
- ProcessHostConfigUtils.cs
- ComboBoxDesigner.cs
- SimpleWebHandlerParser.cs
- Int64AnimationBase.cs
- TypeListConverter.cs
- RSACryptoServiceProvider.cs
- ImageListUtils.cs
- ThicknessAnimationBase.cs
- AndMessageFilter.cs
- UserControlBuildProvider.cs
- DataGridViewCellStyle.cs
- ColumnMapProcessor.cs
- UInt16Converter.cs
- IISUnsafeMethods.cs
- HttpStreamXmlDictionaryWriter.cs
- SplitterPanel.cs
- XmlNamespaceDeclarationsAttribute.cs
- ListViewInsertionMark.cs
- SyndicationSerializer.cs
- UserNamePasswordClientCredential.cs
- BitmapMetadataEnumerator.cs
- ExceptionHandlersDesigner.cs
- TreeSet.cs
- DataGridViewRow.cs
- DesignerActionHeaderItem.cs
- MsmqInputSessionChannel.cs
- InteropAutomationProvider.cs
- HttpCacheVaryByContentEncodings.cs
- AnnotationAuthorChangedEventArgs.cs
- ConnectionsZone.cs
- Int64KeyFrameCollection.cs
- CodeTypeReferenceExpression.cs
- SqlStream.cs
- IDQuery.cs
- SqlNotificationRequest.cs
- ObjectListGeneralPage.cs
- CopyCodeAction.cs
- OutputCacheProviderCollection.cs
- RepeatButton.cs
- MediaSystem.cs
- TextEvent.cs
- ListenerBinder.cs
- DataIdProcessor.cs
- ToolboxItemWrapper.cs
- OdbcHandle.cs
- ViewgenGatekeeper.cs
- SchemaCollectionCompiler.cs
- PagesSection.cs
- OptimizedTemplateContent.cs
- EventMappingSettings.cs
- OpacityConverter.cs
- BuildProvidersCompiler.cs
- KeyProperty.cs
- XmlKeywords.cs
- SecurityChannelListener.cs
- WindowsListViewItem.cs
- TabletDeviceInfo.cs
- GridViewSortEventArgs.cs
- CrossContextChannel.cs
- MethodBuilder.cs
- ParameterCollectionEditor.cs
- ListViewItemSelectionChangedEvent.cs
- HtmlInputText.cs
- TextRange.cs
- StructuredTypeEmitter.cs
- TypeElement.cs
- MimeTypePropertyAttribute.cs
- SynchronousChannel.cs
- ComboBoxItem.cs
- StorageEntityTypeMapping.cs
- ButtonField.cs
- DataControlLinkButton.cs
- ExpressionEvaluator.cs
- XhtmlBasicListAdapter.cs
- HttpsHostedTransportConfiguration.cs
- DataServiceClientException.cs
- StrongNameKeyPair.cs
- XmlSchemaInclude.cs
- ResourceExpressionEditorSheet.cs
- Sentence.cs
- DataServicePagingProviderWrapper.cs
- XPathAncestorIterator.cs
- ResourceReferenceKeyNotFoundException.cs
- DataServiceStreamResponse.cs
- WebContext.cs
- SqlXml.cs
- Reference.cs
- ClientData.cs
- Logging.cs
- ExpandSegmentCollection.cs
- DataServiceExpressionVisitor.cs
- SubtreeProcessor.cs
- WebZone.cs
- StylusDownEventArgs.cs
- EnterpriseServicesHelper.cs