本文整理汇总了C#中ITextPointer.GetPointerContext方法的典型用法代码示例。如果您正苦于以下问题:C# ITextPointer.GetPointerContext方法的具体用法?C# ITextPointer.GetPointerContext怎么用?C# ITextPointer.GetPointerContext使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ITextPointer
的用法示例。
在下文中一共展示了ITextPointer.GetPointerContext方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ExpandToWordBreakAndContext
private void ExpandToWordBreakAndContext(ITextPointer position, LogicalDirection direction, XmlLanguage language,
out ITextPointer contentPosition, out ITextPointer contextPosition)
{
ITextPointer start;
ITextPointer end;
ITextPointer outwardPosition;
ITextPointer inwardPosition;
TextMap textMap;
ArrayList segments;
SpellerInterop.STextRange sTextRange;
LogicalDirection inwardDirection;
int i;
contentPosition = position;
contextPosition = position;
if (position.GetPointerContext(direction) == TextPointerContext.None)
{
// There is no following context, we're at document start/end.
return;
}
// Disable spell checking functionality since we're only
// interested in word breaks here. This greatly cuts down
// the engine's workload.
_spellerInterop.SetContextOption("IsSpellChecking", false);
//
// Build an array of wordbreak offsets surrounding the position.
//
// 1. Search outward, into surrounding text. We need MinWordBreaksForContext
// word breaks to handle multi-word errors.
outwardPosition = SearchForWordBreaks(position, direction, language, MinWordBreaksForContext, true /* stopOnError */);
// 2. Search inward, towards content. We just need one word break inward.
inwardDirection = direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward;
inwardPosition = SearchForWordBreaks(position, inwardDirection, language, 1, false /* stopOnError */);
// Get combined word breaks. This may not be the same as we calculated
// in two parts above, since we don't know yet whether or not position is
// on a word break.
if (direction == LogicalDirection.Backward)
{
start = outwardPosition;
end = inwardPosition;
}
else
{
start = inwardPosition;
end = outwardPosition;
}
textMap = new TextMap(start, end, position, position);
segments = new ArrayList(MinWordBreaksForContext + 1);
_spellerInterop.EnumTextSegments(textMap.Text, textMap.TextLength, null,
new SpellerInterop.EnumTextSegmentsCallback(ExpandToWordBreakCallback), segments);
//
// Use our table of word breaks to calculate context and content positions.
//
if (segments.Count == 0)
{
// No segments. This can happen if position is surrounded by
// nothing but white space. We've already initialized contentPosition
// and contextPosition so there's nothing to do.
}
else
{
int leftWordBreak;
int rightWordBreak;
int contentOffset;
int contextOffset;
// Figure out where position lives in the segment list.
i = FindPositionInSegmentList(textMap, direction, segments, out leftWordBreak, out rightWordBreak);
// contentPosition should be an edge on the segment we found.
if (direction == LogicalDirection.Backward)
{
contentOffset = textMap.ContentStartOffset == rightWordBreak ? rightWordBreak : leftWordBreak;
}
else
{
contentOffset = textMap.ContentStartOffset == leftWordBreak ? leftWordBreak : rightWordBreak;
}
contentPosition = textMap.MapOffsetToPosition(contentOffset);
// contextPosition should be MinWordBreaksForContext - 1 words away.
if (direction == LogicalDirection.Backward)
{
i -= (MinWordBreaksForContext - 1);
sTextRange = (SpellerInterop.STextRange)segments[Math.Max(i, 0)];
// We might actually follow contentOffset if we're at the document edge.
// Don't let that happen.
contextOffset = Math.Min(sTextRange.Start, contentOffset);
}
else
{
i += MinWordBreaksForContext;
sTextRange = (SpellerInterop.STextRange)segments[Math.Min(i, segments.Count-1)];
//.........这里部分代码省略.........
示例2: if
/// <summary>
/// </summary>
void ITextSelection.SetCaretToPosition(ITextPointer caretPosition, LogicalDirection direction, bool allowStopAtLineEnd, bool allowStopNearSpace)
{
// We need a pointer with appropriate direction,
// becasue it will be used in textRangeBase.Select method for
// pointer normalization.
caretPosition = caretPosition.CreatePointer(direction);
// Normalize the position in its logical direction - to get to text content over there.
caretPosition.MoveToInsertionPosition(direction);
// We need a pointer with the reverse direction to confirm
// the line wrapping position. So we can ensure Bidi caret navigation.
// Bidi can have the different caret position by setting the
// logical direction, so we have to only set the logical direction
// as the forward for the real line wrapping position.
ITextPointer reversePosition = caretPosition.CreatePointer(direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward);
// Check line wrapping condition
if (!allowStopAtLineEnd &&
((TextPointerBase.IsAtLineWrappingPosition(caretPosition, this.TextView) &&
TextPointerBase.IsAtLineWrappingPosition(reversePosition, this.TextView)) ||
TextPointerBase.IsNextToPlainLineBreak(caretPosition, LogicalDirection.Backward) ||
TextSchema.IsBreak(caretPosition.GetElementType(LogicalDirection.Backward))))
{
// Caret is at wrapping position, and we are not allowed to stay at end of line,
// so we choose forward direction to appear in the begiinning of a second line
caretPosition.SetLogicalDirection(LogicalDirection.Forward);
}
else
{
if (caretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text &&
caretPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
// This is statistically most typical case. No "smartness" needed
// to choose standard Forward orientation for the caret.
// NOTE: By using caretPosition's direction we solve BiDi caret orientation case:
// The orietnation reflects a direction from where caret has been moved
// or orientation where mouse clicked. So we will stick with appropriate
// character.
// Nothing to do. The caretPosition is good to go.
}
else if (!allowStopNearSpace)
{
// There are some tags around, and we are not allowed to choose a side near to space.
// So we need to perform some content analysis.
char[] charBuffer = new char[1];
if (caretPosition.GetPointerContext(direction) == TextPointerContext.Text &&
caretPosition.GetTextInRun(direction, charBuffer, 0, 1) == 1 &&
Char.IsWhiteSpace(charBuffer[0]))
{
LogicalDirection oppositeDirection = direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward;
// Check formatting switch condition at this position
FlowDirection initialFlowDirection = (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty);
bool moved = caretPosition.MoveToInsertionPosition(oppositeDirection);
if (moved &&
initialFlowDirection == (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty) &&
(caretPosition.GetPointerContext(oppositeDirection) != TextPointerContext.Text ||
caretPosition.GetTextInRun(oppositeDirection, charBuffer, 0, 1) != 1 ||
!Char.IsWhiteSpace(charBuffer[0])))
{
// In the opposite direction we have a non-space
// character. So we choose that direction
direction = oppositeDirection;
caretPosition.SetLogicalDirection(direction);
}
}
}
}
// Now that orientation of a caretPosition is identified,
// build an empty selection at this position
TextRangeBase.BeginChange(this);
try
{
TextRangeBase.Select(this, caretPosition, caretPosition);
// Note how Select method works for the case of empty range:
// It creates a single instance TextPointer normalized and oriented
// in a direction taken from caretPosition:
ITextSelection thisSelection = this;
Invariant.Assert(thisSelection.Start.LogicalDirection == caretPosition.LogicalDirection); // orientation must be as passed
Invariant.Assert(this.IsEmpty);
//Invariant.Assert((object)thisSelection.Start == (object)thisSelection.End); // it must be the same instance of TextPointer
//Invariant.Assert(TextPointerBase.IsAtInsertionPosition(thisSelection.Start, caretPosition.LogicalDirection)); // normalization must be done in the same diredction as orientation
// Clear active positions when selection is empty
SetActivePositions(null, null);
}
finally
{
TextRangeBase.EndChange(this);
}
//.........这里部分代码省略.........
示例3: IsHyperlinkInvalid
/// <summary>
/// Return true if Hyperlink range is invalid.
/// Hyperlink is invalid if it include a UiElement except Image or the range end position
/// is stated before the end position of hyperlink.
/// This must be called before Hyperlink start element position.
/// </summary>
private static bool IsHyperlinkInvalid(ITextPointer textReader, ITextPointer rangeEnd)
{
// TextRead must be on the position before the element start position of Hyperlink
Invariant.Assert(textReader.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart);
Invariant.Assert(typeof(Hyperlink).IsAssignableFrom(textReader.GetElementType(LogicalDirection.Forward)));
bool hyperlinkInvalid = false;
// Get the forward adjacent element and cast Hyperlink hardly since it must be Hyperlink
Hyperlink hyperlink = (Hyperlink)textReader.GetAdjacentElement(LogicalDirection.Forward);
ITextPointer hyperlinkNavigation = textReader.CreatePointer();
ITextPointer hyperlinkEnd = textReader.CreatePointer();
hyperlinkEnd.MoveToNextContextPosition(LogicalDirection.Forward);
// Find the hyperlink end position
hyperlinkEnd.MoveToElementEdge(ElementEdge.AfterEnd);
// Hyperlink end position is stated after the range end position.
if (hyperlinkEnd.CompareTo(rangeEnd) > 0)
{
hyperlinkInvalid = true;
}
else
{
// Check whether the hyperlink having a UiElement except Image until hyperlink end position
while (hyperlinkNavigation.CompareTo(hyperlinkEnd) < 0)
{
InlineUIContainer inlineUIContainer = hyperlinkNavigation.GetAdjacentElement(LogicalDirection.Forward) as InlineUIContainer;
if (inlineUIContainer != null && !(inlineUIContainer.Child is Image))
{
hyperlinkInvalid = true;
break;
}
hyperlinkNavigation.MoveToNextContextPosition(LogicalDirection.Forward);
}
}
return hyperlinkInvalid;
}
示例4: TextPositionsFromITfRange
private void TextPositionsFromITfRange(UnsafeNativeMethods.ITfRange range, out ITextPointer start, out ITextPointer end)
{
UnsafeNativeMethods.ITfRangeACP rangeACP;
int startIndex;
int length;
rangeACP = range as UnsafeNativeMethods.ITfRangeACP;
rangeACP.GetExtent(out startIndex, out length);
start = CreatePointerAtCharOffset(startIndex, LogicalDirection.Backward);
end = CreatePointerAtCharOffset(startIndex + length, LogicalDirection.Forward);
while (start.CompareTo(end) < 0 && start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
{
start.MoveToNextContextPosition(LogicalDirection.Forward);
}
}
示例5: GetRectangleFromTextPosition
internal Rect GetRectangleFromTextPosition(ITextPointer position)
{
Rect rect = System.Windows.Rect.Empty;
int cp = Paragraph.StructuralCache.TextContainer.Start.GetOffsetToPosition((TextPointer)position);
int dcp = cp - Paragraph.ParagraphStartCharacterPosition;
int originalDcp = dcp;
if (position.LogicalDirection == LogicalDirection.Backward && dcp > 0)
{
--dcp;
}
// Query paragraph details
PTS.FSTEXTDETAILS textDetails;
PTS.Validate(PTS.FsQueryTextDetails(PtsContext.Context, _paraHandle.Value, out textDetails));
// There are 3 different types of text paragraphs:
// (a) full with simple lines
// (b) full with composite lines - when figures/floaters are present
// (c) cached - when using ParaChache
if (textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull)
{
if (textDetails.u.full.cLines > 0)
{
int vrBaseline = 0;
if (!PTS.ToBoolean(textDetails.u.full.fLinesComposite))
{
// (a) full with simple lines
RectFromDcpSimpleLines(dcp, originalDcp, position.LogicalDirection, position.GetPointerContext(position.LogicalDirection), ref textDetails.u.full, ref rect, ref vrBaseline);
}
else
{
// (b) full with composite lines - when figures/floaters are present
RectFromDcpCompositeLines(dcp, originalDcp, position.LogicalDirection, position.GetPointerContext(position.LogicalDirection), ref textDetails.u.full, ref rect, ref vrBaseline);
}
}
}
else
{
// (c) cached - when using ParaChache
Debug.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdCached);
Debug.Assert(false, "Should not get here. ParaCache is not currently used.");
}
// Mirror back to page flow direction
if(ThisFlowDirection != PageFlowDirection)
{
PTS.FSRECT pageRect = _pageContext.PageRect;
PTS.FSRECT rectTransform = new PTS.FSRECT(rect);
PTS.Validate(PTS.FsTransformRectangle(PTS.FlowDirectionToFswdir(ThisFlowDirection), ref pageRect, ref rectTransform, PTS.FlowDirectionToFswdir(PageFlowDirection), out rectTransform));
rect = rectTransform.FromTextDpi();
}
return rect;
}
示例6: MoveToNextInsertionPosition
/// <summary>
/// Advances this TextNavigator by a count number of characters.
/// </summary>
/// <param name="thisNavigator">ITextPointer to advance.</param>
/// <param name="direction">
/// A direction in which to search a next characters.
/// </param>
/// <returns>
/// True if the navigator is advanced, false if the end of document is
/// encountered and the navigator is not repositioned.
/// </returns>
/// <remarks>
/// A "character" in this context is a sequence of one or several text
/// symbols: one or more Unicode code points may be a character, every
/// embedded object is a character, a sequence of closing block tags
/// followed by opening block tags may also be a unit. Formatting tags
/// do not contribute in any unit.
/// </remarks>
internal static bool MoveToNextInsertionPosition(ITextPointer thisNavigator, LogicalDirection direction)
{
Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!");
bool moved = true;
int increment = direction == LogicalDirection.Forward ? +1 : -1;
ITextPointer initialPosition = thisNavigator.CreatePointer();
if (!IsAtInsertionPosition(thisNavigator))
{
// If the TextPointer is not currently at an insertion position,
// move the TextPointer to the next insertion position in
// the indicated direction, just like the MoveToInsertionPosition method.
if (!MoveToInsertionPosition(thisNavigator, direction))
{
// No insertion position in all content. MoveToInsertionPosition() guarantees that navigator is moved back to initial position.
moved = false;
goto Exit;
}
if ((direction == LogicalDirection.Forward && initialPosition.CompareTo(thisNavigator) < 0) ||
(direction == LogicalDirection.Backward && thisNavigator.CompareTo(initialPosition) < 0))
{
// We have found an insertion position in requested direction.
goto Exit;
}
}
// Start with skipping character formatting tags in this direction
while (TextSchema.IsFormattingType(thisNavigator.GetElementType(direction)))
{
thisNavigator.MoveByOffset(increment);
}
do
{
if (thisNavigator.GetPointerContext(direction) != TextPointerContext.None)
{
thisNavigator.MoveByOffset(increment);
}
else
{
// No insertion position in this direction; Move back
thisNavigator.MoveToPosition(initialPosition);
moved = false;
goto Exit;
}
}
while (!IsAtInsertionPosition(thisNavigator));
// We must leave position normalized in backward direction
if (direction == LogicalDirection.Backward)
{
// For this we must skip character formatting tags if we have any
while (TextSchema.IsFormattingType(thisNavigator.GetElementType(direction)))
{
thisNavigator.MoveByOffset(increment);
}
// However if it is block start we should back off
TextPointerContext context = thisNavigator.GetPointerContext(direction);
if (context == TextPointerContext.ElementStart || context == TextPointerContext.None)
{
increment = -increment;
while (TextSchema.IsFormattingType(thisNavigator.GetElementType(LogicalDirection.Forward))
&& !IsAtInsertionPosition(thisNavigator))
{
thisNavigator.MoveByOffset(increment);
}
}
}
Exit:
if (moved)
{
if (direction == LogicalDirection.Forward)
{
Invariant.Assert(thisNavigator.CompareTo(initialPosition) > 0, "thisNavigator is expected to be moved from initialPosition - 1");
}
//.........这里部分代码省略.........
示例7: WalkObjectRun
// GetText handler for object runs.
private static bool WalkObjectRun(ITextPointer navigator, ITextPointer limit, char[] text, int cchReq, ref int charsCopied, UnsafeNativeMethods.TS_RUNINFO[] runInfo, int cRunInfoReq, ref int cRunInfoRcv)
{
bool hitLimit;
Invariant.Assert(navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement);
Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);
if (limit != null && navigator.CompareTo(limit) == 0)
{
return true;
}
hitLimit = false;
navigator.MoveToNextContextPosition(LogicalDirection.Forward);
if (cchReq >= 1)
{
text[charsCopied] = UnsafeNativeMethods.TS_CHAR_EMBEDDED;
charsCopied++;
}
if (cRunInfoReq > 0)
{
// Be sure to merge this text run with the previous run, if they are both text runs.
// (A good robustness fix would be to make cicero handle this, if we ever get the chance.)
if (cRunInfoRcv > 0 && runInfo[cRunInfoRcv - 1].type == UnsafeNativeMethods.TsRunType.TS_RT_PLAIN)
{
runInfo[cRunInfoRcv - 1].count++;
}
else
{
runInfo[cRunInfoRcv].count = 1;
runInfo[cRunInfoRcv].type = UnsafeNativeMethods.TsRunType.TS_RT_PLAIN;
cRunInfoRcv++;
}
}
return hitLimit;
}
示例8: GetBorderingElementCategory
// Tests for the presence of a non-mergeable Inline bordering a position.
// Helper for IsAtNonMergeableInlineEdge.
private static BorderingElementCategory GetBorderingElementCategory(ITextPointer position, LogicalDirection direction)
{
TextPointerContext context = (direction == LogicalDirection.Forward) ? TextPointerContext.ElementEnd : TextPointerContext.ElementStart;
BorderingElementCategory category;
if (position.GetPointerContext(direction) != context ||
!typeof(Inline).IsAssignableFrom(position.ParentType))
{
category = BorderingElementCategory.NotScopingInline;
}
else if (TextSchema.IsMergeableInline(position.ParentType))
{
category = BorderingElementCategory.MergeableScopingInline;
}
else
{
category = BorderingElementCategory.NonMergeableScopingInline;
}
return category;
}
示例9: IsAtPotentialRunPosition
// Worker implementing IsAtPotentialRunPosition(position) method.
// It is used for testing whether an empty Run element is at potential run potision.
// For this purpose the method is supposed to be called with
// backwardPosition==run.ElementStart and forwardPosition==run.ElementEnd.
private static bool IsAtPotentialRunPosition(ITextPointer backwardPosition, ITextPointer forwardPosition)
{
Invariant.Assert(backwardPosition.HasEqualScope(forwardPosition));
if (TextSchema.IsValidChild(/*position*/backwardPosition, /*childType*/typeof(Run)))
{
Type forwardType = forwardPosition.GetElementType(LogicalDirection.Forward);
Type backwardType = backwardPosition.GetElementType(LogicalDirection.Backward);
if (forwardType != null && backwardType != null)
{
TextPointerContext forwardContext = forwardPosition.GetPointerContext(LogicalDirection.Forward);
TextPointerContext backwardContext = backwardPosition.GetPointerContext(LogicalDirection.Backward);
if (// Test if the position inside empty Paragraph or Span
backwardContext == TextPointerContext.ElementStart &&
forwardContext == TextPointerContext.ElementEnd
||
// Test if the position between opening tag and an embedded object
backwardContext == TextPointerContext.ElementStart && TextSchema.IsNonFormattingInline(forwardType) &&
!IsAtNonMergeableInlineStart(backwardPosition)
||
// Test if the position between an embedded object and a closing tag
forwardContext == TextPointerContext.ElementEnd && TextSchema.IsNonFormattingInline(backwardType) &&
!IsAtNonMergeableInlineEnd(forwardPosition)
||
// Test if the position between two embedded objects
backwardContext == TextPointerContext.ElementEnd && forwardContext == TextPointerContext.ElementStart &&
TextSchema.IsNonFormattingInline(backwardType) && TextSchema.IsNonFormattingInline(forwardType)
||
// Test if the position is adjacent to a non-mergeable inline (Hyperlink).
backwardContext == TextPointerContext.ElementEnd &&
typeof(Inline).IsAssignableFrom(backwardType) && !TextSchema.IsMergeableInline(backwardType) && !typeof(Run).IsAssignableFrom(forwardType) &&
(forwardContext != TextPointerContext.ElementEnd || !IsAtNonMergeableInlineEnd(forwardPosition))
||
forwardContext == TextPointerContext.ElementStart &&
typeof(Inline).IsAssignableFrom(forwardType) && !TextSchema.IsMergeableInline(forwardType) && !typeof(Run).IsAssignableFrom(backwardType) &&
(backwardContext != TextPointerContext.ElementStart || !IsAtNonMergeableInlineStart(backwardPosition))
)
{
return true;
}
}
}
return false;
}
示例10: NormalizePosition
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// Worker for MoveToNextFormatNormalizedPosition/MoveToNextInsertionPosition.
private static bool NormalizePosition(ITextPointer thisNavigator, LogicalDirection direction, bool respectCaretUnitBoundaries)
{
Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!");
int symbolCount = 0;
int increment;
LogicalDirection oppositeDirection;
TextPointerContext directEnterScope;
TextPointerContext oppositeEnterScope;
if (direction == LogicalDirection.Forward)
{
increment = +1;
oppositeDirection = LogicalDirection.Backward;
directEnterScope = TextPointerContext.ElementStart;
oppositeEnterScope = TextPointerContext.ElementEnd;
}
else
{
increment = -1;
oppositeDirection = LogicalDirection.Forward;
directEnterScope = TextPointerContext.ElementEnd;
oppositeEnterScope = TextPointerContext.ElementStart;
}
// When the pointer appears in between structural tags we need to start
// from sliding into the deepest possible position without
// leaving any structural units. We need to do that only
// if we are not at insertion position already.
if (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
{
// Go inside an innermost structured element (non-inline)
while (
thisNavigator.GetPointerContext(direction) == directEnterScope &&
!typeof(Inline).IsAssignableFrom(thisNavigator.GetElementType(direction)) &&
!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
{
thisNavigator.MoveToNextContextPosition(direction);
symbolCount += increment;
}
while (
thisNavigator.GetPointerContext(oppositeDirection) == oppositeEnterScope &&
!typeof(Inline).IsAssignableFrom(thisNavigator.GetElementType(oppositeDirection)) &&
!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
{
thisNavigator.MoveToNextContextPosition(oppositeDirection);
symbolCount -= increment;
}
}
// Get out of a Hyperlink, etc. inner edge.
symbolCount = LeaveNonMergeableInlineBoundary(thisNavigator, direction, symbolCount);
// Get out of a compound sequence if any.
if (respectCaretUnitBoundaries)
{
while (!IsAtCaretUnitBoundary(thisNavigator))
{
symbolCount += increment;
thisNavigator.MoveByOffset(increment);
}
}
// Here is the core part of this method's logic - skipping all formatting tags in the given direction.
// Skip character formatting tags if they are present in this direction.
// Even if an insertion position can be in the middle of this formatting sequence,
// we want to skip it all and reach the farthest possible insertion position in that direction.
// Such approach guarantees that repeated calls of this normalization will give the same reauls.
// In case if there is an inserrtion position in the middle (say, in empty Run),
// the loop moving in opposite direction below will find it if needed.
while (TextSchema.IsMergeableInline(thisNavigator.GetElementType(direction)))
{
thisNavigator.MoveToNextContextPosition(direction);
symbolCount += increment;
}
if (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
{
// If still not at insertion point, try skipping inline tags in the opposite direction
// now possibly stopping inside of empty element
while (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries) &&
TextSchema.IsMergeableInline(thisNavigator.GetElementType(oppositeDirection)))
{
thisNavigator.MoveToNextContextPosition(oppositeDirection);
symbolCount -= increment;
}
// If still not at insertion point, then try harder - skipping block tags
// First in "preferred" direction
while (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries) &&
thisNavigator.MoveToNextContextPosition(direction))
//.........这里部分代码省略.........
示例11: IsAtCaretUnitBoundary
// Returns true if the position is on the caret unit boundary.
// Call TextView's IsAtCaretUnitBoundary if TextView is valid for this position
// and it appears strictly within text run.
// We consider all markup-boundary positions as caret unit boundaries.
// If TextView information is not available call IsInsideCompoundSequence.
private static bool IsAtCaretUnitBoundary(ITextPointer position)
{
bool isAtCaretUnitBoundary;
TextPointerContext forwardContext = position.GetPointerContext(LogicalDirection.Forward);
TextPointerContext backwardContext = position.GetPointerContext(LogicalDirection.Backward);
if (backwardContext == TextPointerContext.Text && forwardContext == TextPointerContext.Text)
{
if (position.HasValidLayout)
{
// Check the insertion position with TextView's IsAtCaretUnitBoundary
// that will acurately check the caret unit bounday for surrogate and international
// characters
isAtCaretUnitBoundary = position.IsAtCaretUnitBoundary;
}
else
{
// Check the insertion position with the internal compound sequence
isAtCaretUnitBoundary = !IsInsideCompoundSequence(position);
}
}
else
{
isAtCaretUnitBoundary = true;
}
return isAtCaretUnitBoundary;
}
示例12: GetParagraph
/// <summary>
/// Determine paragraph type at the current TextPointer and
/// create it. Only ListItem elements are considered. Any other
/// content is skipped.
/// </summary>
/// <param name="textPointer">
/// TextPointer at which paragraph is to be created
/// </param>
/// <param name="fEmptyOk">
/// True if empty paragraph is acceptable
/// </param>
/// <returns>
/// BaseParagraph that was created
/// </returns>
protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk)
{
Invariant.Assert(textPointer is TextPointer);
BaseParagraph paragraph = null;
while (paragraph == null)
{
TextPointerContext runType = textPointer.GetPointerContext(LogicalDirection.Forward);
if (runType == TextPointerContext.ElementStart)
{
TextElement element = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
if (element is ListItem)
{
//
paragraph = new ListItemParagraph(element, StructuralCache);
break;
}
else if (element is List)
{
//
paragraph = new ListParagraph(element, StructuralCache);
break;
}
// Skip all elements, which are not valid list item children
if (((TextPointer)textPointer).IsFrozen)
{
// Need to clone TextPointer before moving it.
textPointer = textPointer.CreatePointer();
}
textPointer.MoveToPosition(element.ElementEnd);
}
else if (runType == TextPointerContext.ElementEnd)
{
// End of list, if the same as Owner of associated element
// Skip content otherwise
if (Element == ((TextPointer)textPointer).Parent)
{
break;
}
if (((TextPointer)textPointer).IsFrozen)
{
// Need to clone TextPointer before moving it.
textPointer = textPointer.CreatePointer();
}
textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
}
else
{
// Skip content
if (((TextPointer)textPointer).IsFrozen)
{
// Need to clone TextPointer before moving it.
textPointer = textPointer.CreatePointer();
}
textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
}
}
if (paragraph != null)
{
StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer;
}
return paragraph;
}
示例13: GetRawRectangleFromTextPosition
/// <summary>
/// Retrieves the height and offset, in pixels, of the edge of
/// the object/character represented by position.
/// </summary>
/// <param name="position">
/// Position of an object/character.
/// </param>
/// <param name="transform">
/// Transform to be applied to returned rect
/// </param>
/// <returns>
/// The height, in pixels, of the edge of the object/character
/// represented by position.
/// </returns>
/// <exception cref="System.InvalidOperationException">
/// Throws InvalidOperationException if IsValid is false.
/// If IsValid returns false, Validate method must be called before
/// calling this method.
/// </exception>
/// <remarks>
/// Rect.Width is always 0.
/// Output parameter Transform is always Identity. It is not expected that editing scenarios
/// will require speparate transform with raw rectangle for this case.
/// If the document is empty, then this method returns the expected
/// height of a character, if placed at the specified position.
/// </remarks>
internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
{
#if DEBUG
DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetRectFromTextPosition {0}, {1}", (FixedTextPointer)position, position.LogicalDirection));
#endif
FixedTextPointer ftp = Container.VerifyPosition(position);
FixedPosition fixedp;
// need a default caret size, otherwise infinite corners cause text editor and MultiPageTextView problems.
// Initialize transform to Identity. This function always returns Identity transform.
Rect designRect = new Rect(0, 0, 0, 10);
transform = Transform.Identity;
Debug.Assert(ftp != null);
if (ftp.FlowPosition.IsBoundary)
{
if (!_GetFirstFixedPosition(ftp, out fixedp))
{
return designRect;
}
}
else if (!_GetFixedPosition(ftp, out fixedp))
{
//
// This is the start/end element, we need to find out the next element and return the next element
// start offset/height.
//
if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None)
{
ITextPointer psNext = position.CreatePointer(1);
FixedTextPointer ftpNext = Container.VerifyPosition(psNext);
if (!_GetFixedPosition(ftpNext, out fixedp))
{
return designRect;
}
}
else
{
return designRect;
}
}
if (fixedp.Page != this.PageIndex)
{
return designRect;
}
DependencyObject element = this.FixedPage.GetElement(fixedp.Node);
if (element is Glyphs)
{
Glyphs g = (Glyphs)element;
designRect = _GetGlyphRunDesignRect(g, fixedp.Offset, fixedp.Offset);
// need to do transform
GeneralTransform tran = g.TransformToAncestor(this.FixedPage);
designRect = _GetTransformedCaretRect(tran, designRect.TopLeft, designRect.Height);
}
else if (element is Image)
{
Image image = (Image)element;
GeneralTransform tran = image.TransformToAncestor(this.FixedPage);
Point offset = new Point(0, 0);
if (fixedp.Offset > 0)
{
offset.X += image.ActualWidth;
}
designRect = _GetTransformedCaretRect(tran, offset, image.ActualHeight);
}
else if (element is Path)
{
Path path = (Path)element;
GeneralTransform tran = path.TransformToAncestor(this.FixedPage);
//.........这里部分代码省略.........
示例14: IsAdjacentToFormatElement
// Returns true if pointer preceeds an Inline start or end edge.
private bool IsAdjacentToFormatElement(ITextPointer pointer)
{
TextPointerContext context;
bool isAdjacentToFormatElement;
isAdjacentToFormatElement = false;
context = pointer.GetPointerContext(LogicalDirection.Forward);
if (context == TextPointerContext.ElementStart &&
TextSchema.IsFormattingType(pointer.GetElementType(LogicalDirection.Forward)))
{
isAdjacentToFormatElement = true;
}
else if (context == TextPointerContext.ElementEnd &&
TextSchema.IsFormattingType(pointer.ParentType))
{
isAdjacentToFormatElement = true;
}
return isAdjacentToFormatElement;
}
示例15: IsAfterLastParagraph
// Position at document end - after the last paragraph/list/table is
// considered as valid insertion point position.
// It has though a special behavior for caret positioning and text insertion
internal static bool IsAfterLastParagraph(ITextPointer thisPosition)
{
return thisPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.None &&
thisPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementEnd &&
!typeof(Inline).IsAssignableFrom(thisPosition.GetElementType(LogicalDirection.Backward));
}