protected T ReadDictionary(T dictionary, CompactFontFormatData data, string[] stringIndex)
        {
            while (data.CanRead())
            {
                operands.Clear();
                var infiniteLoopProtection = 0;

                while (true)
                {
                    infiniteLoopProtection++;
                    // Avoid the library getting caught in an infinite loop, probably not possible.
                    // "An operator may be preceded by up to a maximum of 48 operands."
                    if (infiniteLoopProtection > 256)
                    {
                        throw new InvalidOperationException("Got caught in an infinite loop trying to read a CFF dictionary.");
                    }

                    var byte0 = data.ReadByte();

                    // Operands and operators are distinguished by the first byte, 0 - 21 specify operators
                    if (byte0 <= 21)
                    {
                        var key = byte0 == 12 ? new OperandKey(byte0, data.ReadByte()) : new OperandKey(byte0);

                        ApplyOperation(dictionary, operands, key, stringIndex);
                        break;
                    }

                    /*
                     * b0 value     value range         calculation
                     *  32 - 246      -107 - +107       b0 - 139
                     * 247 - 250      +108 - +1131      (b0 - 247)*256 + b1 + 108
                     * 251 - 254     -1131 - -108       -(b0 - 251)*256 - b1 - 108
                     *  28          -32768 - +32767     b1 << 8 | b2
                     *  29          -(2^31)-+(2^31-1)   b1 << 24 | b2 << 16 | b3 << 8 | b4
                     *
                     * A byte value of 30 defines a real number operand
                     */
                    if (byte0 == 28)
                    {
                        var value = data.ReadByte() << 8 | data.ReadByte();
                        operands.Add(new Operand(value));
                    }
                    else if (byte0 == 29)
                    {
                        var value = data.ReadByte() << 24 | data.ReadByte() << 16 |
                                    data.ReadByte() << 8 | data.ReadByte();
                        operands.Add(new Operand(value));
                    }
                    else if (byte0 == 30)
                    {
                        var realNumber = ReadRealNumber(data);
                        operands.Add(new Operand(realNumber));
                    }
                    else if (byte0 >= 32 && byte0 <= 246)
                    {
                        var value = byte0 - 139;
                        operands.Add(new Operand(value));
                    }
                    else if (byte0 >= 247 && byte0 <= 250)
                    {
                        var value = (byte0 - 247) * 256 + data.ReadByte() + 108;
                        operands.Add(new Operand(value));
                    }
                    else if (byte0 >= 251 && byte0 <= 254)
                    {
                        var value = -(byte0 - 251) * 256 - data.ReadByte() - 108;
                        operands.Add(new Operand(value));
                    }
                    else
                    {
                        throw new InvalidOperationException($"The first dictionary byte was not in the range 29 - 254. Got {byte0}.");
                    }
                }
            }

            return(dictionary);
        }