Beispiel #1
0
 private static void SetWidthFromArgumentsIfPresent(Type2BuildCharContext context, decimal nomimalWidthX, int expectedArgumentLength)
 {
     if (context.Stack.Length > expectedArgumentLength)
     {
         context.Width = nomimalWidthX + context.Stack.PopBottom();
     }
 }
Beispiel #2
0
        private static Type2Glyph Run(CommandSequence sequence)
        {
            var context = new Type2BuildCharContext();

            var hasRunStackClearingCommand = false;

            foreach (var command in sequence.Commands)
            {
                command.Match(x => context.Stack.Push(x),
                              x =>
                {
                    if (!hasRunStackClearingCommand)
                    {
                        /*
                         * The first stack-clearing operator, which must be one of hstem, hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
                         * rmoveto, or endchar, takes an additional argument — the width (as described earlier), which may be expressed as zero or one numeric argument.
                         */
                        hasRunStackClearingCommand = true;
                        switch (x.Name)
                        {
                        case "hstem":
                        case "hstemhm":
                        case "vstemhm":
                        case "vstem":
                            {
                                var oddArgCount = context.Stack.Length % 2 != 0;
                                if (oddArgCount)
                                {
                                    context.Width = context.Stack.PopBottom();
                                }
                                break;
                            }

                        case "hmoveto":
                        case "vmoveto":
                            SetWidthFromArgumentsIfPresent(context, 1);
                            break;

                        case "rmoveto":
                            SetWidthFromArgumentsIfPresent(context, 2);
                            break;

                        case "cntrmask":
                        case "hintmask":
                        case "endchar:":
                            SetWidthFromArgumentsIfPresent(context, 0);
                            break;

                        default:
                            hasRunStackClearingCommand = false;
                            break;
                        }
                    }
                    x.Run(context);
                });
            }

            return(new Type2Glyph(context.Path, context.Width));
        }
Beispiel #3
0
        public void Run([NotNull] Type2BuildCharContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            runCommand(context);
        }
Beispiel #4
0
        private static Type2Glyph Run(CommandSequence sequence, double defaultWidthX, double nominalWidthX)
        {
            var context = new Type2BuildCharContext();

            var hasRunStackClearingCommand = false;

            for (var i = -1; i < sequence.Values.Count; i++)
            {
                if (i >= 0)
                {
                    var value = sequence.Values[i];
                    context.Stack.Push(value);
                }

                foreach (var commandIdentifier in sequence.GetCommandsAt(i + 1))
                {
                    var command = Type2CharStringParser.GetCommand(commandIdentifier);

                    var isOnlyCommand = sequence.Values.Count + sequence.CommandIdentifiers.Count == 1;

                    if (!hasRunStackClearingCommand)
                    {
                        /*
                         * The first stack-clearing operator, which must be one of hstem, hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
                         * rmoveto, or endchar, takes an additional argument — the width (as described earlier), which may be expressed as zero or one numeric argument.
                         */
                        hasRunStackClearingCommand = true;
                        switch (command.Name)
                        {
                        case "hstem":
                        case "hstemhm":
                        case "vstemhm":
                        case "vstem":
                        {
                            var oddArgCount = context.Stack.Length % 2 != 0;
                            if (oddArgCount)
                            {
                                context.Width = nominalWidthX + context.Stack.PopBottom();
                            }

                            break;
                        }

                        case "hmoveto":
                        case "vmoveto":
                            SetWidthFromArgumentsIfPresent(context, nominalWidthX, 1);
                            break;

                        case "rmoveto":
                            SetWidthFromArgumentsIfPresent(context, nominalWidthX, 2);
                            break;

                        case "cntrmask":
                        case "hintmask":
                            SetWidthFromArgumentsIfPresent(context, nominalWidthX, 0);
                            break;

                        case "endchar":
                            if (isOnlyCommand)
                            {
                                context.Width = defaultWidthX;
                            }
                            else
                            {
                                SetWidthFromArgumentsIfPresent(context, nominalWidthX, 0);
                            }
                            break;

                        default:
                            hasRunStackClearingCommand = false;
                            break;
                        }
                    }

                    command.Run(context);
                }
            }

            return(new Type2Glyph(context.Path, context.Width));
        }