/// <summary> /// Searches for custom commands in the specified range of glyphs and allows them to be evaluated /// with the specified evaluator function. /// </summary> /// <param name="startGlyph">The index of the first glyph to consider.</param> /// <param name="glyphCount">The number of glyphs to consider.</param> /// <param name="state">A state object to pass to the evaluator.</param> /// <param name="evaluator">The function with which to evaluate custom commands.</param> /// <remarks> /// This method will return custom commands which fall immediately after the last glyph in the /// specified range, but not commands which fall immediately before that range, unless the range /// starts at the beginning of the text. /// </remarks> public void GetCustomCommands(Int32 startGlyph, Int32 glyphCount, Object state, TextLayoutCommandEvaluator evaluator) { Contract.EnsureRange(startGlyph >= 0, nameof(startGlyph)); Contract.Require(evaluator, nameof(evaluator)); var glyphsSeen = 0; var glyphsMax = (glyphCount == Int32.MaxValue) ? Int32.MaxValue : startGlyph + glyphCount; var acquiredPointers = !HasAcquiredPointers; if (acquiredPointers) { AcquirePointers(); } Seek(0); while (StreamPositionInObjects < Count) { var cmdType = *(TextLayoutCommandType *)Data; switch (cmdType) { case TextLayoutCommandType.Text: { var cmd = (TextLayoutTextCommand *)Data; glyphsSeen += cmd->TextLength; } break; case TextLayoutCommandType.Icon: { glyphsSeen++; } break; case TextLayoutCommandType.LineBreak: { var cmd = (TextLayoutLineBreakCommand *)Data; if (cmd->Length > 0) { glyphsSeen += cmd->Length; } } break; case TextLayoutCommandType.Custom: { if (glyphsSeen > startGlyph || startGlyph == 0) { var cmd = (TextLayoutCustomCommand *)Data; evaluator(state, glyphsSeen, *cmd); } } break; } if (glyphsSeen > glyphsMax) { break; } SeekNextCommand(); } if (acquiredPointers) { ReleasePointers(); } }
/// <summary> /// Searches for custom commands in the specified range of glyphs and allows them to be evaluated /// with the specified evaluator function. /// </summary> /// <param name="startGlyph">The index of the first glyph to consider.</param> /// <param name="glyphCount">The number of glyphs to consider.</param> /// <param name="state">A state object to pass to the evaluator.</param> /// <param name="evaluator">The function with which to evaluate custom commands.</param> /// <remarks> /// This method will return custom commands which fall immediately after the last glyph in the /// specified range, but not commands which fall immediately before that range, unless the range /// starts at the beginning of the text. /// </remarks> public void GetCustomCommands(Int32 startGlyph, Int32 glyphCount, Object state, TextLayoutCommandEvaluator evaluator) { Contract.EnsureRange(startGlyph >= 0, nameof(startGlyph)); Contract.Require(evaluator, nameof(evaluator)); var terminateOnNextNonCommandToken = false; var glyphsSeen = 0; var glyphsMax = (glyphCount == Int32.MaxValue) ? Int32.MaxValue : startGlyph + glyphCount; var acquiredPointers = !HasAcquiredPointers; if (acquiredPointers) AcquirePointers(); Seek(0); while (StreamPositionInObjects < Count) { var cmdType = *(TextLayoutCommandType*)Data; if (cmdType != TextLayoutCommandType.Custom && terminateOnNextNonCommandToken) break; switch (cmdType) { case TextLayoutCommandType.Text: { var cmd = (TextLayoutTextCommand*)Data; glyphsSeen += cmd->TextLength; } break; case TextLayoutCommandType.Icon: { glyphsSeen++; } break; case TextLayoutCommandType.LineBreak: { var cmd = (TextLayoutLineBreakCommand*)Data; if (cmd->Length > 0) { glyphsSeen += cmd->Length; } } break; case TextLayoutCommandType.Custom: { if (glyphsSeen > startGlyph || startGlyph == 0) { var cmd = (TextLayoutCustomCommand*)Data; if (!evaluator(state, glyphsSeen, *cmd)) terminateOnNextNonCommandToken = true; } } break; } if (glyphsSeen > glyphsMax) break; SeekNextCommand(); } if (acquiredPointers) ReleasePointers(); }
/// <summary> /// Searches for custom commands in stream and allows them to be evaluated /// with the specified evaluator function. /// </summary> /// <param name="state">A state object to pass to the evaluator.</param> /// <param name="evaluator">The function with which to evaluate custom commands.</param> public void GetCustomCommands(Object state, TextLayoutCommandEvaluator evaluator) { GetCustomCommands(0, Int32.MaxValue, state, evaluator); }
/// <summary> /// Searches for custom commands in stream and allows them to be evaluated /// with the specified evaluator function. /// </summary> /// <param name="state">A state object to pass to the evaluator.</param> /// <param name="evaluator">The function with which to evaluate custom commands.</param> public void GetCustomCommands(Object state, TextLayoutCommandEvaluator evaluator) { GetCustomCommands(0, Int32.MaxValue, state, evaluator); }