Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / documents / DocumentPageTextView.cs / 1305600 / 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 != null && _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
- ListMarkerLine.cs
- RsaKeyIdentifierClause.cs
- DataSourceXmlSubItemAttribute.cs
- ProtocolElement.cs
- MessageLogTraceRecord.cs
- UxThemeWrapper.cs
- MethodCallConverter.cs
- PersistenceProviderFactory.cs
- XPathNavigatorReader.cs
- WindowInteractionStateTracker.cs
- RTTrackingProfile.cs
- TrustManagerPromptUI.cs
- wgx_commands.cs
- FastEncoder.cs
- RequestResizeEvent.cs
- Geometry3D.cs
- MergeFilterQuery.cs
- MarkupWriter.cs
- CodeMemberEvent.cs
- MessageUtil.cs
- CustomGrammar.cs
- SqlHelper.cs
- UriSection.cs
- EventTask.cs
- InternalRelationshipCollection.cs
- OrderedDictionary.cs
- ResXResourceReader.cs
- BindToObject.cs
- InfoCardSchemas.cs
- DurableInstanceManager.cs
- CachedCompositeFamily.cs
- FixedDocumentSequencePaginator.cs
- TextMarkerSource.cs
- BuildManagerHost.cs
- SqlBuilder.cs
- PhysicalFontFamily.cs
- CodeObjectCreateExpression.cs
- FixedBufferAttribute.cs
- PerformanceCounterPermissionEntry.cs
- ReadingWritingEntityEventArgs.cs
- TokenBasedSet.cs
- SpellerHighlightLayer.cs
- TagNameToTypeMapper.cs
- CatalogPartChrome.cs
- SBCSCodePageEncoding.cs
- BindingSource.cs
- WindowVisualStateTracker.cs
- XmlSiteMapProvider.cs
- Debug.cs
- DataChangedEventManager.cs
- DataContractSet.cs
- EdmError.cs
- BamlLocalizableResourceKey.cs
- Effect.cs
- TextChange.cs
- Propagator.JoinPropagator.cs
- HtmlTable.cs
- HtmlInputCheckBox.cs
- KnownTypesProvider.cs
- CodeNamespaceCollection.cs
- PropertyPathWorker.cs
- DbConnectionPool.cs
- TreeWalkHelper.cs
- SafeSecurityHandles.cs
- FixedTextBuilder.cs
- FormViewInsertEventArgs.cs
- ResourceDefaultValueAttribute.cs
- EnvelopedPkcs7.cs
- FactoryGenerator.cs
- TextRange.cs
- GeneralTransform3D.cs
- UnmanagedHandle.cs
- CodeDelegateCreateExpression.cs
- SqlBooleanizer.cs
- ProfileEventArgs.cs
- OrderedHashRepartitionStream.cs
- RangeValueProviderWrapper.cs
- PrintPreviewDialog.cs
- CodeIdentifier.cs
- ServiceObjectContainer.cs
- SqlMetaData.cs
- FileSystemInfo.cs
- HMACSHA256.cs
- DataTableNewRowEvent.cs
- WinFormsSpinner.cs
- Signature.cs
- RuntimeConfig.cs
- CommandField.cs
- ListBox.cs
- Journaling.cs
- TransformGroup.cs
- DataGridCellAutomationPeer.cs
- BindingUtils.cs
- GeneralTransformCollection.cs
- HttpModuleCollection.cs
- DocumentGridContextMenu.cs
- ipaddressinformationcollection.cs
- DataGridViewRowsRemovedEventArgs.cs
- SqlConnectionHelper.cs
- DispatcherProcessingDisabled.cs