/// <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();
            }
        }
Exemplo n.º 2
0
        /// <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);
 }
Exemplo n.º 4
0
 /// <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);
 }