Vous êtes sur la page 1sur 4

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
namespace Text_to_Speech
{
public static class WordBreaker
{
/// <summary>
/// Returns a TextRange covering a word containing or following this Tex
tPointer.
/// </summary>
/// <remarks>
/// If this TextPointer is within a word or at start of word, the contai
ning word range is returned.
/// If this TextPointer is between two words, the following word range i
s returned.
/// If this TextPointer is at trailing word boundary, the following word
range is returned.
/// </remarks>
public static TextRange GetWordRange(TextPointer position)
{
TextRange wordRange = null;
TextPointer wordStartPosition = null;
TextPointer wordEndPosition = null;

// Go forward first, to find word end position.


wordEndPosition = GetPositionAtWordBoundary(position, /*wordBreakDir
ection*/LogicalDirection.Forward);

if (wordEndPosition != null)
{
// Then travel backwards, to find word start position.
wordStartPosition = GetPositionAtWordBoundary(wordEndPosition, /
*wordBreakDirection*/LogicalDirection.Backward);
}

if (wordStartPosition != null && wordEndPosition != null)


{
wordRange = new TextRange(wordStartPosition, wordEndPosition);
}

return wordRange;
}

/// <summary>
/// 1. When wordBreakDirection = Forward, returns a position at the end
of the word,
///

i.e. a position with a wordBreak character (space) following it.

/// 2. When wordBreakDirection = Backward, returns a position at the st


art of the word,
///

i.e. a position with a wordBreak character (space) preceeding it

.
/// 3. Returns null when there is no workbreak in the requested directi
on.
/// </summary>
private static TextPointer GetPositionAtWordBoundary(TextPointer positio
n, LogicalDirection wordBreakDirection)
{
if (!position.IsAtInsertionPosition)
{
position = position.GetInsertionPosition(wordBreakDirection);
}

TextPointer navigator = position;


while (navigator != null && !IsPositionNextToWordBreak(navigator, wo
rdBreakDirection))
{
navigator = navigator.GetNextInsertionPosition(wordBreakDirectio
n);
}

return navigator;
}

// Helper for GetPositionAtWordBoundary.


// Returns true when passed TextPointer is next to a wordBreak in reques
ted direction.
private static bool IsPositionNextToWordBreak(TextPointer position, Logi
calDirection wordBreakDirection)
{
bool isAtWordBoundary = false;

// Skip over any formatting.


if (position.GetPointerContext(wordBreakDirection) != TextPointerCon
text.Text)
{
position = position.GetInsertionPosition(wordBreakDirection);
}

if (position.GetPointerContext(wordBreakDirection) == TextPointerCon
text.Text)
{
LogicalDirection oppositeDirection = (wordBreakDirection == Logi
calDirection.Forward) ?
LogicalDirection.Backward : LogicalDirection.Forward;

char[] runBuffer = new char[1];


char[] oppositeRunBuffer = new char[1];

position.GetTextInRun(wordBreakDirection, runBuffer, /*startInde


x*/0, /*count*/1);
position.GetTextInRun(oppositeDirection, oppositeRunBuffer, /*st
artIndex*/0, /*count*/1);

if (runBuffer[0] == ' ' && !(oppositeRunBuffer[0] == ' '))


{
isAtWordBoundary = true;

}
}
else
{
// If we're not adjacent to text then we always want to consider
this position a "word break".
// In practice, we're most likely next to an embedded object or
a block boundary.
isAtWordBoundary = true;
}

return isAtWordBoundary;
}
}
}

Vous aimerez peut-être aussi