Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / documents / DocumentPageTextView.cs / 1 / DocumentPageTextView.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: DocumentPageTextView.cs // // Description: TextView implementation for DocumentPageView. // //--------------------------------------------------------------------------- using System; // InvalidOperationException, ... using System.Collections.Generic; // Listusing System.Collections.ObjectModel; // ReadOnlyCollection using System.Windows; // Point, Rect, ... using System.Windows.Controls.Primitives; // DocumentPageView using System.Windows.Documents; // ITextView, ITextContainer using System.Windows.Media; // VisualTreeHelper using MS.Internal.PtsHost; // BackgroundFormatInfo namespace MS.Internal.Documents { /// /// TextView implementation for DocumentPageView. /// internal class DocumentPageTextView : TextViewBase { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// /// Root of layout structure visualizing content of a page. /// /// /// TextContainer representing content. /// internal DocumentPageTextView(DocumentPageView owner, ITextContainer textContainer) { Invariant.Assert(owner != null && textContainer != null); _owner = owner; _page = owner.DocumentPageInternal; _textContainer = textContainer; // Retrive inner TextView if (_page is IServiceProvider) { _pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView; } if (_pageTextView != null) { _pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated); } } ////// Constructor. /// /// /// Root of layout structure visualizing content of a page. /// /// /// TextContainer representing content. /// internal DocumentPageTextView(FlowDocumentView owner, ITextContainer textContainer) { Invariant.Assert(owner != null && textContainer != null); _owner = owner; _page = owner.DocumentPage; _textContainer = textContainer; // Retrive inner TextView if (_page is IServiceProvider) { _pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView; } if (_pageTextView != null) { _pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated); } } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return null; } // Transform to page coordinates. point = TransformToDescendant(point); return _pageTextView.GetTextPositionFromPoint(point, snapToText); } ////// /// internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform) { Rect rect; Transform pageTextViewTransform, ancestorTransform; // Initialize transform to identity transform = Transform.Identity; // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return Rect.Empty; } rect = _pageTextView.GetRawRectangleFromTextPosition(position, out pageTextViewTransform); Invariant.Assert(pageTextViewTransform != null); ancestorTransform = GetTransformToAncestor(); transform = GetAggregateTransform(pageTextViewTransform, ancestorTransform); return rect; } ////// /// internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) { // verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } Geometry geometry = null; if (!IsPageMissing) { geometry = _pageTextView.GetTightBoundingGeometryFromTextPositions(startPosition, endPosition); if (geometry != null) { Transform transform = GetTransformToAncestor().AffineTransform; CaretElement.AddTransformToGeometry(geometry, transform); } } return (geometry); } ////// /// internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved) { ITextPointer positionOut; Point offset; // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { newSuggestedX = suggestedX; linesMoved = 0; return position; } offset = TransformToDescendant(new Point(suggestedX, 0)); suggestedX = offset.X; positionOut = _pageTextView.GetPositionAtNextLine(position, suggestedX, count, out newSuggestedX, out linesMoved); offset = TransformToAncestor(new Point(newSuggestedX, 0)); newSuggestedX = offset.X; return positionOut; } ////// /// internal override ITextPointer GetPositionAtNextPage(ITextPointer position, Point suggestedOffset, int count, out Point newSuggestedOffset, out int pagesMoved) { ITextPointer positionOut = position; newSuggestedOffset = suggestedOffset; Point offset = suggestedOffset; pagesMoved = 0; if (count == 0) { return positionOut; } // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return position; } // Calculate distance from current position offset.Y = GetYOffsetAtNextPage(offset.Y, count, out pagesMoved); if (pagesMoved != 0) { // Transfrom offset to _pageTextView's coordinate position, obtain position from _pageTextView and convert back offset = TransformToDescendant(offset); positionOut = _pageTextView.GetTextPositionFromPoint(offset, true); Invariant.Assert(positionOut != null); Rect rect = _pageTextView.GetRectangleFromTextPosition(position); newSuggestedOffset = TransformToAncestor(new Point(rect.X, rect.Y)); } return positionOut; } ////// /// internal override bool IsAtCaretUnitBoundary(ITextPointer position) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return false; } return _pageTextView.IsAtCaretUnitBoundary(position); } ////// /// internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return null; } return _pageTextView.GetNextCaretUnitPosition(position, direction); } ////// /// internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return null; } return _pageTextView.GetBackspaceCaretUnitPosition(position); } ////// /// internal override TextSegment GetLineRange(ITextPointer position) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return TextSegment.Null; } return _pageTextView.GetLineRange(position); } ////// /// internal override ReadOnlyCollection/// GetGlyphRuns(ITextPointer start, ITextPointer end) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return new ReadOnlyCollection (new List ()); } return _pageTextView.GetGlyphRuns(start, end); } /// /// internal override bool Contains(ITextPointer position) { // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (IsPageMissing) { return false; } return _pageTextView.Contains(position); } ////// /// Handler for PageConnected raised by the DocumentPageView. /// internal void OnPageConnected() { OnPageDisconnected(); if (_owner is DocumentPageView) { _page = ((DocumentPageView)_owner).DocumentPageInternal; } else if (_owner is FlowDocumentView) { _page = ((FlowDocumentView)_owner).DocumentPage; } if (_page is IServiceProvider) { _pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView; } if (_pageTextView != null) { _pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated); } if (IsValid) { OnUpdated(EventArgs.Empty); } } ////// Handler for PageDisconnected raised by the DocumentPageView. /// internal void OnPageDisconnected() { if (_pageTextView != null) { _pageTextView.Updated -= new EventHandler(HandlePageTextViewUpdated); } _pageTextView = null; _page = null; } ////// Handler for TransformChanged raised by the DocumentPageView. /// internal void OnTransformChanged() { if (IsValid) { OnUpdated(EventArgs.Empty); } } ////// internal override bool Validate() { if (!_owner.IsMeasureValid || !_owner.IsArrangeValid) { _owner.UpdateLayout(); } return _pageTextView.Validate(); } ////// /// internal override bool Validate(ITextPointer position) { FlowDocumentView owner = _owner as FlowDocumentView; bool isValid; if (owner == null || owner.Document == null) { isValid = base.Validate(position); } else { if (Validate()) { BackgroundFormatInfo backgroundFormatInfo = owner.Document.StructuralCache.BackgroundFormatInfo; FlowDocumentFormatter formatter = owner.Document.BottomlessFormatter; int lastCPInterrupted = -1; while (this.IsValid && !Contains(position)) { backgroundFormatInfo.BackgroundFormat(formatter, true /* ignoreThrottle */); _owner.UpdateLayout(); // May invalidate the view. // Break if background layout is not progressing. // There are some edge cases where Validate() == true, but background // layout will not progress (such as collapsed text in a tree view). if (backgroundFormatInfo.CPInterrupted <= lastCPInterrupted) { // CPInterrupted is reset to -1 when background layout finishes, so // check explicitly below to see if the position is valid or not. break; } lastCPInterrupted = backgroundFormatInfo.CPInterrupted; } } isValid = this.IsValid && Contains(position); } return isValid; } ////// /// internal override void ThrottleBackgroundTasksForUserInput() { FlowDocumentView owner = _owner as FlowDocumentView; if (owner != null && owner.Document != null) { owner.Document.StructuralCache.ThrottleBackgroundFormatting(); } } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// /// internal override UIElement RenderScope { get { return _owner; } } ////// /// internal override ITextContainer TextContainer { get { return _textContainer; } } ////// /// internal override bool IsValid { get { if (!_owner.IsMeasureValid || !_owner.IsArrangeValid || _page == null) { return false; } if (IsPageMissing) { return true; } return (_pageTextView != null && _pageTextView.IsValid); } } ////// /// internal override bool RendersOwnSelection { get { if (_pageTextView != null) { return _pageTextView.RendersOwnSelection; } return false; } } ////// /// internal override ReadOnlyCollection/// TextSegments { get { if (!IsValid || IsPageMissing) { return new ReadOnlyCollection (new List ()); } return _pageTextView.TextSegments; } } /// /// DocumentPageView associated with this TextView. /// internal DocumentPageView DocumentPageView { get { return _owner as DocumentPageView; } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Handler for Updated event raised by the inner TextView. /// private void HandlePageTextViewUpdated(object sender, EventArgs e) { Invariant.Assert(_pageTextView != null); if (sender == _pageTextView) { OnUpdated(EventArgs.Empty); } } ////// Gets transform to ancestor /// private Transform GetTransformToAncestor() { Invariant.Assert(IsValid && !IsPageMissing); // NOTE: TransformToAncestor is safe (will never throw an exception). Transform transform = _page.Visual.TransformToAncestor(_owner) as Transform; if (transform == null) { transform = Transform.Identity; } return transform; } ////// Transforms point from inner scope. /// private Point TransformToAncestor(Point point) { Invariant.Assert(IsValid && !IsPageMissing); // NOTE: TransformToAncestor is safe (will never throw an exception). GeneralTransform transform = _page.Visual.TransformToAncestor(_owner); if (transform != null) { point = transform.Transform(point); } return point; } ////// Transforms rectangle from inner scope /// private Point TransformToDescendant(Point point) { Invariant.Assert(IsValid && !IsPageMissing); // NOTE: TransformToAncestor is safe (will never throw an exception). GeneralTransform transform = _page.Visual.TransformToAncestor(_owner); if (transform != null) { transform = transform.Inverse; if (transform != null) { point = transform.Transform(point); } } return point; } ////// Gets updated offset at next page /// /// /// Current value of offset /// /// Number of pages to move /// /// /// Number of pages actually moved /// private double GetYOffsetAtNextPage(double offset, int count, out int pagesMoved) { double newOffset = offset; pagesMoved = 0; if (_owner is IScrollInfo && ((IScrollInfo)_owner).ScrollOwner != null) { IScrollInfo scrollInfo = (IScrollInfo)_owner; double viewportHeight = scrollInfo.ViewportHeight; double extentHeight = scrollInfo.ExtentHeight; if (count > 0) { while (pagesMoved < count) { if (DoubleUtil.LessThanOrClose(offset + viewportHeight, extentHeight)) { newOffset += viewportHeight; pagesMoved++; } else { break; } } } else { while (Math.Abs(pagesMoved) < Math.Abs(count)) { if (DoubleUtil.GreaterThanOrClose(offset - viewportHeight, 0)) { newOffset -= viewportHeight; pagesMoved--; } else { break; } } } } return newOffset; } #endregion Private Methods //------------------------------------------------------------------- // // Private Properties // //------------------------------------------------------------------- #region Private Properties ////// Whether page is missing. /// private bool IsPageMissing { get { return (_page == DocumentPage.Missing); } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields ////// Root of layout structure visualizing content. /// private readonly UIElement _owner; ////// TextContainer representing content. /// private readonly ITextContainer _textContainer; ////// DocumentPage associated with this view. /// private DocumentPage _page; ////// TextView associated with DocumentPage. /// private ITextView _pageTextView; #endregion Private Fields } } // 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
- DispatchChannelSink.cs
- WorkflowInstanceRecord.cs
- CryptoStream.cs
- ISFClipboardData.cs
- LinkButton.cs
- ComponentEditorPage.cs
- DataGridViewComboBoxColumn.cs
- SynchronousChannel.cs
- XmlIlTypeHelper.cs
- ResolveNameEventArgs.cs
- XhtmlTextWriter.cs
- SpecialNameAttribute.cs
- ItemsPanelTemplate.cs
- OracleException.cs
- Control.cs
- COM2ComponentEditor.cs
- StrokeNode.cs
- FixedTextView.cs
- QilExpression.cs
- PnrpPeerResolverElement.cs
- codemethodreferenceexpression.cs
- LineServicesCallbacks.cs
- CookieProtection.cs
- ImageInfo.cs
- TextSpanModifier.cs
- ExpressionBinding.cs
- datacache.cs
- DataGridViewButtonCell.cs
- SafeUserTokenHandle.cs
- TemplatePropertyEntry.cs
- StreamingContext.cs
- TypeSystem.cs
- XmlDesigner.cs
- SpecialNameAttribute.cs
- XmlUrlResolver.cs
- MenuItemCollection.cs
- DependencyObject.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- StartUpEventArgs.cs
- ParserExtension.cs
- StringUtil.cs
- Path.cs
- AudienceUriMode.cs
- ToolboxBitmapAttribute.cs
- DiscreteKeyFrames.cs
- Paragraph.cs
- XmlSiteMapProvider.cs
- AssociationType.cs
- ConstraintManager.cs
- ColorContext.cs
- ScrollItemProviderWrapper.cs
- Splitter.cs
- XhtmlTextWriter.cs
- TokenCreationParameter.cs
- StickyNoteHelper.cs
- DataMember.cs
- Tile.cs
- SecurityElement.cs
- TransformerTypeCollection.cs
- ListViewTableRow.cs
- ImageSourceValueSerializer.cs
- ByteAnimationBase.cs
- Line.cs
- GroupDescription.cs
- PeerName.cs
- CodeMethodReturnStatement.cs
- AsymmetricKeyExchangeFormatter.cs
- EdmComplexPropertyAttribute.cs
- XmlSchemaComplexType.cs
- BigInt.cs
- BitmapEffectGeneralTransform.cs
- FilterElement.cs
- XmlLanguage.cs
- ImageIndexConverter.cs
- FragmentQueryProcessor.cs
- ServiceInfo.cs
- NameValueFileSectionHandler.cs
- WindowsListViewItemStartMenu.cs
- MsmqIntegrationProcessProtocolHandler.cs
- DataGridPageChangedEventArgs.cs
- FilteredAttributeCollection.cs
- Calendar.cs
- ListViewItem.cs
- ReturnEventArgs.cs
- WebPartsSection.cs
- invalidudtexception.cs
- NotImplementedException.cs
- SqlRowUpdatedEvent.cs
- MaskInputRejectedEventArgs.cs
- AssociationType.cs
- SQLMoney.cs
- DbBuffer.cs
- HotSpotCollection.cs
- ExpressionPrefixAttribute.cs
- EntityUtil.cs
- Wildcard.cs
- OdbcConnectionHandle.cs
- PrePrepareMethodAttribute.cs
- VarRefManager.cs
- IncrementalCompileAnalyzer.cs