// genereate a list of blocks describing the characters
        private List <CharacterDescriptor>[] generateCharacterDescriptorBlockList()
        {
            char currentCharacter, previousCharacter = '\0';
            List <List <CharacterDescriptor> > characterBlockList = new List <List <CharacterDescriptor> >();
            // initialize first block
            List <CharacterDescriptor> characterBlock = null;
            CodePageInfo cpi = new CodePageInfo(OutConfig.CodePage);

            // get the difference between two characters required to create a new group
            int differenceBetweenCharsForNewGroup = OutConfig.generateLookupBlocks ?
                                                    OutConfig.lookupBlocksNewAfterCharCount : int.MaxValue;

            // iterate over characters, saving previous character each time
            for (int charIndex = 0; charIndex < Characters.Length; ++charIndex)
            {
                // get character
                currentCharacter = Characters[charIndex].Character;

                // check if this character is too far from the previous character and it isn't the first char
                if (cpi.GetCharacterDifferance(previousCharacter, currentCharacter) < differenceBetweenCharsForNewGroup && previousCharacter != '\0')
                {
                    // it may not be far enough to generate a new group but it still may be non-sequential
                    // in this case we need to generate place holders
                    int previousCharacterOffset = cpi.GetOffsetFromCharacter(previousCharacter);
                    int currentCharacterOffset  = cpi.GetOffsetFromCharacter(currentCharacter);

                    for (int sequentialCharIndex = previousCharacterOffset + 1;
                         sequentialCharIndex < currentCharacterOffset;
                         ++sequentialCharIndex)
                    {
                        // add the character placeholder to the current char block
                        characterBlock.Add(new CharacterDescriptor(this));
                    }
                    // fall through and add to current block
                }
                else
                {
                    // done with current block, add to list (null is for first character which hasn't
                    // created a group yet)
                    if (characterBlock != null)
                    {
                        characterBlockList.Add(characterBlock);
                    }

                    // create new block
                    characterBlock = new List <CharacterDescriptor>();
                }

                // add to current block
                characterBlock.Add(Characters[charIndex]);

                // save previous char
                previousCharacter = currentCharacter;
            }

            // done; add current block to list
            characterBlockList.Add(characterBlock);

            return(characterBlockList.ToArray());
        }
        // get font info from string
        private void populateFontInfoFromCharacters()
        {
            // do nothing if no chars defined
            if (Characters.Length == 0)
            {
                return;
            }

            // total offset
            int charByteOffset = 0;

            // set start char
            FirstChar = CodePageInfo.GetLastValidCharacter();
            LastChar  = CodePageInfo.GetFirstValidCharacter();

            // the fixed absolute character height
            this.FixedAbsolutCharHeight = OutConfig.rotation.getAbsoluteCharacterDimensions(Characters[0].BitmapToGenerate.Size).Height;

            // iterate through letter string
            for (int charIdx = 0; charIdx < Characters.Length; ++charIdx)
            {
                // skip empty bitmaps
                if (Characters[charIdx].BitmapToGenerate == null)
                {
                    continue;
                }

                // get char
                char currentChar = Characters[charIdx].Character;

                // is this character smaller than start char?
                if (CodePageInfo.GetCharacterDifferance(currentChar, FirstChar) > 0)
                {
                    FirstChar = currentChar;
                }

                // is this character bigger than end char?
                if (CodePageInfo.GetCharacterDifferance(currentChar, LastChar) < 0)
                {
                    LastChar = currentChar;
                }

                // populate offset of character
                Characters[charIdx].OffsetInBytes = charByteOffset;

                // increment byte offset
                charByteOffset += Characters[charIdx].DataLength;
            }
        }