Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / documents / TextContainerHelper.cs / 1305600 / TextContainerHelper.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Helper services for TextContainer. // // History: // 07/26/2004 : [....] - Created. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Automation.Peers; // AutomationPeer using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; using MS.Internal.Text; namespace MS.Internal.Documents { internal sealed class TextContentRange { internal TextContentRange() { } internal TextContentRange(int cpFirst, int cpLast, ITextContainer textContainer) { Invariant.Assert(cpFirst <= cpLast); Invariant.Assert(cpFirst >= 0); Invariant.Assert(textContainer != null); Invariant.Assert(cpLast <= textContainer.SymbolCount); _cpFirst = cpFirst; _cpLast = cpLast; _size = 0; _ranges = null; _textContainer = textContainer; } internal void Merge(TextContentRange other) { Invariant.Assert(other != null); // Skip merge operation if we're merging an empty text content range. if(other._textContainer == null) { return; } if (_textContainer == null) { _cpFirst = other._cpFirst; _cpLast = other._cpLast; _textContainer = other._textContainer; _size = other._size; if (_size != 0) { Invariant.Assert(other._ranges != null); Invariant.Assert(other._ranges.Length >= (other._size * 2)); _ranges = new int[_size * 2]; for (int i = 0; i < _ranges.Length; i++) { _ranges[i] = other._ranges[i]; } } } else { Invariant.Assert(_textContainer == other._textContainer); if (other.IsSimple) { Merge(other._cpFirst, other._cpLast); } else { for (int i = 0; i < other._size; i++) { Merge(other._ranges[i * 2], other._ranges[i * 2 + 1]); } } } Normalize(); } internal ReadOnlyCollectionGetTextSegments() { List segments; if (_textContainer == null) { segments = new List (); } else { if (IsSimple) { segments = new List (1); segments.Add(new TextSegment( _textContainer.CreatePointerAtOffset(_cpFirst, LogicalDirection.Forward), _textContainer.CreatePointerAtOffset(_cpLast, LogicalDirection.Backward), true)); } else { segments = new List (_size); for (int i = 0; i < _size; i++) { segments.Add(new TextSegment( _textContainer.CreatePointerAtOffset(_ranges[i * 2], LogicalDirection.Forward), _textContainer.CreatePointerAtOffset(_ranges[i * 2 + 1], LogicalDirection.Backward), true)); } } } return new ReadOnlyCollection (segments); } internal bool Contains(ITextPointer position, bool strict) { bool contains = false; int cpPos = position.Offset; if (IsSimple) { if (cpPos >= _cpFirst && cpPos <= _cpLast) { contains = true; if (strict && (_cpFirst != _cpLast)) { if (cpPos == _cpFirst && position.LogicalDirection == LogicalDirection.Backward || cpPos == _cpLast && position.LogicalDirection == LogicalDirection.Forward) { contains = false; } } } } else { for (int i = 0; i < _size; i++) { if (cpPos >= _ranges[i * 2] && cpPos <= _ranges[i * 2 + 1]) { contains = true; if (strict) { if (cpPos == _ranges[i * 2] && position.LogicalDirection == LogicalDirection.Backward || cpPos == _ranges[i * 2 + 1] && position.LogicalDirection == LogicalDirection.Forward) { contains = false; } } break; } } } return contains; } internal ITextPointer StartPosition { get { ITextPointer startPosition = null; if (_textContainer != null) { startPosition = _textContainer.CreatePointerAtOffset(IsSimple ? _cpFirst : _ranges[0], LogicalDirection.Forward); } return startPosition; } } internal ITextPointer EndPosition { get { ITextPointer endPosition = null; if (_textContainer != null) { endPosition = _textContainer.CreatePointerAtOffset(IsSimple ? _cpLast : _ranges[(_size - 1) * 2 + 1], LogicalDirection.Backward); } return endPosition; } } private void Merge(int cpFirst, int cpLast) { if (IsSimple) { if (cpFirst > _cpLast || cpLast < _cpFirst) { _size = 2; _ranges = new int[8]; // 4 entries if (cpFirst > _cpLast) { _ranges[0] = _cpFirst; _ranges[1] = _cpLast; _ranges[2] = cpFirst; _ranges[3] = cpLast; } else { _ranges[0] = cpFirst; _ranges[1] = cpLast; _ranges[2] = _cpFirst; _ranges[3] = _cpLast; } } else { _cpFirst = Math.Min(_cpFirst, cpFirst); _cpLast = Math.Max(_cpLast, cpLast); } } else { int i = 0; while (i < _size) { if (cpLast < _ranges[i * 2]) { // Insert before the current position EnsureSize(); for (int j = _size * 2 - 1; j >= i * 2; j--) { _ranges[j + 2] = _ranges[j]; } _ranges[i * 2] = cpFirst; _ranges[i * 2 + 1] = cpLast; ++_size; break; } else if (cpFirst <= _ranges[i * 2 + 1]) { // Merge with the current position _ranges[i * 2] = Math.Min(_ranges[i * 2], cpFirst); _ranges[i * 2 + 1] = Math.Max(_ranges[i * 2 + 1], cpLast); while (MergeWithNext(i)) { } break; } ++i; } if (i >= _size) { // Insert at the last position EnsureSize(); _ranges[_size * 2] = cpFirst; _ranges[_size * 2 + 1] = cpLast; ++_size; } } } private bool MergeWithNext(int pos) { if (pos < _size - 1) { if (_ranges[pos * 2 + 1] >= _ranges[(pos + 1) * 2]) { _ranges[pos * 2 + 1] = Math.Max(_ranges[pos * 2 + 1], _ranges[(pos + 1) * 2 + 1]); for (int i = (pos + 1) * 2; i < (_size - 1) * 2; i++) { _ranges[i] = _ranges[i + 2]; } --_size; return true; } } return false; } private void EnsureSize() { Invariant.Assert(_size > 0); Invariant.Assert(_ranges != null); if (_ranges.Length < (_size + 1) * 2) { int[] ranges = new int[_ranges.Length * 2]; for (int i = 0; i < _size * 2; i++) { ranges[i] = _ranges[i]; } _ranges = ranges; } } private void Normalize() { if (_size == 1) { _cpFirst = _ranges[0]; _cpLast = _ranges[1]; _size = 0; _ranges = null; } } private bool IsSimple { get { return (_size == 0); } } private int _cpFirst; private int _cpLast; private int _size; private int[] _ranges; private ITextContainer _textContainer; } /// /// Helper services for TextContainer. /// internal static class TextContainerHelper { //------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Retrieves a collection of AutomationPeers that fall within the range. /// Children that overlap with the range but are not entirely enclosed by /// it will also be included in the collection. /// internal static ListGetAutomationPeersFromRange(ITextPointer start, ITextPointer end, ITextPointer ownerContentStart) { bool positionMoved; AutomationPeer peer = null; object element; List peers = new List (); start = start.CreatePointer(); while (start.CompareTo(end) < 0) { // Indicate that 'start' position is not moved yet. positionMoved = false; if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) { // Get adjacent element and try to retrive AutomationPeer for it. element = start.GetAdjacentElement(LogicalDirection.Forward); if (element is ContentElement) { peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element); // If AutomationPeer has been retrieved, add it to the collection. // And skip entire element. if (peer != null) { if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) { peers.Add(peer); } start.MoveToNextContextPosition(LogicalDirection.Forward); start.MoveToElementEdge(ElementEdge.AfterEnd); positionMoved = true; } } } else if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement) { // Get adjacent element and try to retrive AutomationPeer for it. element = start.GetAdjacentElement(LogicalDirection.Forward); if (element is UIElement) { if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) { peer = UIElementAutomationPeer.CreatePeerForElement((UIElement)element); // If AutomationPeer has been retrieved, add it to the collection. if (peer != null) { peers.Add(peer); } else { iterate((Visual)element, peers); } } } else if (element is ContentElement) { peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element); // If AutomationPeer has been retrieved, add it to the collection. if (peer != null) { if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) { peers.Add(peer); } } } } // Move to the next content position, if position has not been moved already. if (!positionMoved) { if (!start.MoveToNextContextPosition(LogicalDirection.Forward)) { break; } } } return peers; } /// /// Is AutometionPeer represented by 'elementStart' is immediate child of AutomationPeer /// represented by 'ownerContentStart'. /// internal static bool IsImmediateAutomationChild(ITextPointer elementStart, ITextPointer ownerContentStart) { Invariant.Assert(elementStart.CompareTo(ownerContentStart) >= 0); bool immediateChild = true; // Walk element tree up looking for AutomationPeers. ITextPointer position = elementStart.CreatePointer(); while (typeof(TextElement).IsAssignableFrom(position.ParentType)) { position.MoveToElementEdge(ElementEdge.BeforeStart); if (position.CompareTo(ownerContentStart) <= 0) { break; } AutomationPeer peer = null; object element = position.GetAdjacentElement(LogicalDirection.Forward); if (element is UIElement) { peer = UIElementAutomationPeer.CreatePeerForElement((UIElement)element); } else if (element is ContentElement) { peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element); } if (peer != null) { immediateChild = false; break; } } return immediateChild; } ////// Returns the common ancestor of two positions. This ancestor needs to have /// AutomationPeer associated with it. /// internal static AutomationPeer GetEnclosingAutomationPeer(ITextPointer start, ITextPointer end, out ITextPointer elementStart, out ITextPointer elementEnd) { object element; AutomationPeer peer; ITextPointer position; List
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProxyElement.cs
- Cursor.cs
- ControlPropertyNameConverter.cs
- Pts.cs
- CompositeScriptReferenceEventArgs.cs
- DbSetClause.cs
- DependencyPropertyHelper.cs
- TemplateParser.cs
- CAGDesigner.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- CellLabel.cs
- XmlNodeChangedEventManager.cs
- ParseChildrenAsPropertiesAttribute.cs
- Empty.cs
- Transform3DGroup.cs
- WindowsStatic.cs
- ContextMenuStripGroup.cs
- DetailsViewModeEventArgs.cs
- codemethodreferenceexpression.cs
- PageContent.cs
- CompilerGlobalScopeAttribute.cs
- CollectionType.cs
- BaseDataList.cs
- CodeDelegateInvokeExpression.cs
- OutOfMemoryException.cs
- CultureMapper.cs
- XpsFilter.cs
- ControlDesigner.cs
- ConfigsHelper.cs
- RemotingSurrogateSelector.cs
- RIPEMD160.cs
- DesignerProperties.cs
- SafeFreeMibTable.cs
- SystemIcmpV6Statistics.cs
- JsonCollectionDataContract.cs
- OutputCacheProfileCollection.cs
- BuildResultCache.cs
- PointCollection.cs
- PolygonHotSpot.cs
- ExceptionTrace.cs
- RegexBoyerMoore.cs
- BinHexDecoder.cs
- RelationshipType.cs
- RepeatButton.cs
- DataGridViewRowsRemovedEventArgs.cs
- TrustManager.cs
- UpdateRecord.cs
- MenuItemStyleCollectionEditor.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- ItemContainerPattern.cs
- SqlUtils.cs
- SizeConverter.cs
- OpenTypeLayout.cs
- MsmqException.cs
- DrawListViewSubItemEventArgs.cs
- PagesSection.cs
- GlobalEventManager.cs
- UnmanagedHandle.cs
- SplitterCancelEvent.cs
- SettingsPropertyIsReadOnlyException.cs
- SoapIncludeAttribute.cs
- SqlException.cs
- TemplateEditingVerb.cs
- CompilerCollection.cs
- ECDiffieHellman.cs
- HttpAsyncResult.cs
- CodeDirectiveCollection.cs
- Canvas.cs
- DebugHandleTracker.cs
- Run.cs
- SelectingProviderEventArgs.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- DataPointer.cs
- ColumnResizeUndoUnit.cs
- ParameterRefs.cs
- WorkflowTerminatedException.cs
- PermissionSetEnumerator.cs
- Set.cs
- XmlNodeChangedEventArgs.cs
- EntityStoreSchemaGenerator.cs
- XmlArrayAttribute.cs
- AddInToken.cs
- SemaphoreSecurity.cs
- DrawingContextWalker.cs
- RepeatInfo.cs
- ParsedAttributeCollection.cs
- UrlPath.cs
- sqlser.cs
- PersistenceTypeAttribute.cs
- LocalizationParserHooks.cs
- TypeGeneratedEventArgs.cs
- PermissionListSet.cs
- Token.cs
- VideoDrawing.cs
- HttpModuleCollection.cs
- WebPartExportVerb.cs
- XmlSchemaAll.cs
- mediapermission.cs
- OTFRasterizer.cs
- RefType.cs