Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / documents / TextContainerHelper.cs / 1 / 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
- SqlInternalConnection.cs
- TemplateXamlParser.cs
- SecurityChannelFaultConverter.cs
- Size.cs
- LOSFormatter.cs
- SemanticBasicElement.cs
- HwndStylusInputProvider.cs
- ShaderEffect.cs
- XhtmlBasicValidatorAdapter.cs
- XmlAtomicValue.cs
- Container.cs
- SqlDelegatedTransaction.cs
- ObjectManager.cs
- HttpCapabilitiesSectionHandler.cs
- EndpointBehaviorElementCollection.cs
- KeySplineConverter.cs
- ExceptionUtility.cs
- SizeKeyFrameCollection.cs
- HttpException.cs
- BamlCollectionHolder.cs
- SqlMethodCallConverter.cs
- HttpClientChannel.cs
- FormCollection.cs
- DefaultEventAttribute.cs
- SoapExtensionReflector.cs
- ComplexType.cs
- JsonUriDataContract.cs
- MemberListBinding.cs
- NotifyCollectionChangedEventArgs.cs
- EncryptedKey.cs
- Region.cs
- GACMembershipCondition.cs
- BooleanAnimationUsingKeyFrames.cs
- BinaryReader.cs
- FlowLayout.cs
- DataObjectAttribute.cs
- DockPatternIdentifiers.cs
- VariantWrapper.cs
- CodeRemoveEventStatement.cs
- SafeRightsManagementHandle.cs
- XamlContextStack.cs
- XmlSchemaSimpleTypeList.cs
- MailHeaderInfo.cs
- ControlPaint.cs
- ParserOptions.cs
- DataBindingCollectionConverter.cs
- ActivityExecutorOperation.cs
- PropertyKey.cs
- ColumnMapTranslator.cs
- RtfToXamlReader.cs
- TextEditorCopyPaste.cs
- ExtentKey.cs
- XmlHierarchicalEnumerable.cs
- TokenizerHelper.cs
- TracingConnection.cs
- TdsValueSetter.cs
- CancelEventArgs.cs
- XmlSchemaCompilationSettings.cs
- IListConverters.cs
- CapabilitiesPattern.cs
- Tuple.cs
- ProjectionCamera.cs
- SQLMoney.cs
- _HTTPDateParse.cs
- MasterPageBuildProvider.cs
- SortQuery.cs
- DigestComparer.cs
- MenuItemCollection.cs
- BStrWrapper.cs
- HttpSocketManager.cs
- MimeBasePart.cs
- DebugHandleTracker.cs
- QueryOutputWriterV1.cs
- Grammar.cs
- LocatorGroup.cs
- RuntimeResourceSet.cs
- SmiTypedGetterSetter.cs
- ToolStripContainer.cs
- Component.cs
- CreateUserErrorEventArgs.cs
- ProcessModelInfo.cs
- ConfigurationSection.cs
- EditorPart.cs
- Quaternion.cs
- ValueUtilsSmi.cs
- ViewPort3D.cs
- Matrix.cs
- LinkClickEvent.cs
- SamlDoNotCacheCondition.cs
- DbExpressionRules.cs
- JsonGlobals.cs
- TextEditorTyping.cs
- FileFormatException.cs
- TextEffect.cs
- ThicknessKeyFrameCollection.cs
- FocusChangedEventArgs.cs
- ToolStripManager.cs
- CategoryAttribute.cs
- LogicalExpr.cs
- AvTraceDetails.cs