public void EnumSubSegments(EnumTextSegmentsCallback segmentCallback, object data) { bool result = true; for (int i = 0; result && (i < SubSegments.Count); i++) { result = segmentCallback(SubSegments[i], data); } }
/// <summary> /// foreach(sentence in text.sentences) /// foreach(segment in sentence) /// continueIteration = segmentCallback(segment, data) /// endfor /// /// if (sentenceCallback != null) /// continueIteration = sentenceCallback(sentence, data) /// endif /// /// if (!continueIteration) /// break /// endif /// endfor /// </summary> /// <param name="text"></param> /// <param name="count"></param> /// <param name="sentenceCallback"></param> /// <param name="segmentCallback"></param> /// <param name="data"></param> /// <returns></returns> internal override int EnumTextSegments(char[] text, int count, EnumSentencesCallback sentenceCallback, EnumTextSegmentsCallback segmentCallback, object data) { if (_isDisposed) { return 0; } var wordBreaker = CurrentWordBreaker ?? DefaultCultureWordBreaker; var spellChecker = CurrentSpellChecker; bool spellCheckerNeeded = _mode.HasFlag(SpellerMode.SpellingErrors) || _mode.HasFlag(SpellerMode.Suggestions); if ((wordBreaker == null) || (spellCheckerNeeded && spellChecker == null)) return 0; int segmentCount = 0; bool continueIteration = true; // WinRT WordsSegmenter doesn't have the ability to break down text into segments (sentences). // Treat the whole text as a single segment for now. foreach(string strSentence in new string[]{string.Join(string.Empty, text)}) { SpellerSentence sentence = new SpellerSentence(strSentence, wordBreaker, CurrentSpellChecker, this); segmentCount += sentence.Segments.Count; if (segmentCallback != null) { for (int i = 0; continueIteration && (i < sentence.Segments.Count); i++) { continueIteration = segmentCallback(sentence.Segments[i], data); } } if (sentenceCallback != null) { continueIteration = sentenceCallback(sentence, data); } if (!continueIteration) break; } return segmentCount; }
internal static void EnumSubsegments(object textSegmentHandle, EnumTextSegmentsCallback segmentCallback, object data) { ITextSegment textSegment = (ITextSegment)textSegmentHandle; int subSegmentCount; bool result = true; textSegment.get_Count(out subSegmentCount); // Walk the subsegments, the error's in there somewhere. for (int i = 0; result && i < subSegmentCount; i++) { ITextSegment subSegment; textSegment.get_Item(i, out subSegment); try { result = segmentCallback(subSegment, data); } finally { Marshal.ReleaseComObject(subSegment); } } }
// Helper for methods that need to iterate over segments within a text run. // Returns the total number of segments encountered. internal abstract int EnumTextSegments(char[] text, int count, EnumSentencesCallback sentenceCallback, EnumTextSegmentsCallback segmentCallback, object data);
internal int EnumTextSegments(char[] text, int count, EnumSentencesCallback sentenceCallback, EnumTextSegmentsCallback segmentCallback, object data) { int segmentCount = 0; // Unintuively, the speller engine will grab and store the pointer // we pass into ITextChunk.SetInputArray. So it's not safe to merely // pinvoke text directly. We need to allocate a chunk of memory // and keep it fixed for the duration of this method call. IntPtr inputArray = Marshal.AllocHGlobal(count * 2); try { // Give the TextChunk its next block of text. Marshal.Copy(text, 0, inputArray, count); _textChunk.SetInputArray(inputArray, count); // // Iterate over sentences. // UnsafeNativeMethods.IEnumVariant sentenceEnumerator; // Note because we're in the engine's ReuseObjects mode, we may // not use ITextChunk.get_Sentences. We must use the enumerator. _textChunk.GetEnumerator(out sentenceEnumerator); try { NativeMethods.VARIANT variant = new NativeMethods.VARIANT(); int[] fetched = new int[1]; bool continueIteration = true; sentenceEnumerator.Reset(); do { int result; variant.Clear(); result = EnumVariantNext(sentenceEnumerator, variant, fetched); if (result != NativeMethods.S_OK) break; if (fetched[0] == 0) break; SpellerInterop.ISentence sentence = (SpellerInterop.ISentence)variant.ToObject(); try { int sentenceSegmentCount; sentence.get_Count(out sentenceSegmentCount); segmentCount += sentenceSegmentCount; if (segmentCallback != null) { // // Iterate over segments. // for (int i = 0; continueIteration && i < sentenceSegmentCount; i++) { SpellerInterop.ITextSegment textSegment; // Do a callback for this ITextSegment. sentence.get_Item(i, out textSegment); try { if (!segmentCallback(textSegment, data)) { continueIteration = false; } } finally { Marshal.ReleaseComObject(textSegment); } } } // Make another callback when we're done with the entire sentence. if (sentenceCallback != null) { continueIteration = sentenceCallback(sentence, data); } } finally { Marshal.ReleaseComObject(sentence); } } while (continueIteration); variant.Clear(); } finally { Marshal.ReleaseComObject(sentenceEnumerator); } } finally { Marshal.FreeHGlobal(inputArray); } return segmentCount; }