| File: MS\Internal\TextFormatting\LexicalChunk.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // // // Contents: Lexical chunk represents the character analysis of a piece of raw character string. // // using System.Windows.Media.TextFormatting; using MS.Internal.Generic; namespace MS.Internal.TextFormatting { /// <summary> /// Lexical chunk represents the character analysis of a piece of raw character string. /// It contains the analyzing result of the string by the lexical services component i.e. /// word-breaker or hyphenator or both. /// /// The number of character indices represented by a chunk may not map exactly to the same number /// of LSCP in the LS character position space. This is because two adjacent character indices in /// a chunk may be mapped by two non-adjacent LSCP in the LS positions. Between two LSRun could /// exist a hidden-run which occupies real LSCP but represents no actual displayable character. /// /// The mapping between the character offsets and the offsets to the correspondent LSCP is retained /// in a span vector that is indexed by the character offsets. /// </summary> internal struct LexicalChunk { private TextLexicalBreaks _breaks; // lexical breaks of chunk characters private SpanVector<int> _ichVector; // spans of offsets to the ich-correspondence LSCP internal TextLexicalBreaks Breaks { get { return _breaks; } } /// <summary> /// Boolean value indicates whether this chunk contains no valid break info /// </summary> internal bool IsNoBreak { get { return _breaks == null; } } /// <summary> /// Contruct lexical chunk from character analysis /// </summary> internal LexicalChunk( TextLexicalBreaks breaks, SpanVector<int> ichVector ) { Invariant.Assert(breaks != null); _breaks = breaks; _ichVector = ichVector; } /// <summary> /// Convert the specified LSCP to character index /// </summary> internal int LSCPToCharacterIndex(int lsdcp) { if (_ichVector.Count > 0) { int ich = 0; int cchLast = 0; int lsdcpLast = 0; for (int i = 0; i < _ichVector.Count; i++) { MS.Internal.Generic.Span<int> span = _ichVector[i]; int lsdcpCurrent = span.Value; if (lsdcpCurrent > lsdcp) { return ich - cchLast + Math.Min(cchLast, lsdcp - lsdcpLast); } ich += span.Length; cchLast = span.Length; lsdcpLast = lsdcpCurrent; } return ich - cchLast + Math.Min(cchLast, lsdcp - lsdcpLast); } return lsdcp; } /// <summary> /// Convert the specified character index to LSCP /// </summary> internal int CharacterIndexToLSCP(int ich) { if (_ichVector.Count > 0) { SpanRider<int> ichRider = new SpanRider<int>(_ichVector); ichRider.At(ich); return ichRider.CurrentValue + ich - ichRider.CurrentSpanStart; } return ich; } } }