iTextSharp.text.pdf.BidiOrder.ProcessEmbeddings C# (CSharp) Метод

ProcessEmbeddings() приватный статический Метод

private static ProcessEmbeddings ( sbyte resultTypes, sbyte paragraphEmbeddingLevel ) : sbyte[]
resultTypes sbyte
paragraphEmbeddingLevel sbyte
Результат sbyte[]
        private static sbyte[] ProcessEmbeddings(sbyte[] resultTypes, sbyte paragraphEmbeddingLevel)
        {
            int EXPLICIT_LEVEL_LIMIT = 62;

            int textLength = resultTypes.Length;
            sbyte[] embeddings = new sbyte[textLength];

            // This stack will store the embedding levels and override status in a single sbyte
            // as described above.
            sbyte[] embeddingValueStack = new sbyte[EXPLICIT_LEVEL_LIMIT];
            int stackCounter = 0;

            // An LRE or LRO at level 60 is invalid, since the new level 62 is invalid.  But
            // an RLE at level 60 is valid, since the new level 61 is valid.  The current wording
            // of the rules requires that the RLE remain valid even if a previous LRE is invalid.
            // This keeps track of ignored LRE or LRO codes at level 60, so that the matching PDFs
            // will not try to pop the stack.
            int overflowAlmostCounter = 0;

            // This keeps track of ignored pushes at level 61 or higher, so that matching PDFs will
            // not try to pop the stack.
            int overflowCounter = 0;

            // Rule X1.

            // Keep the level separate from the value (level | override status flag) for ease of access.
            sbyte currentEmbeddingLevel = paragraphEmbeddingLevel;
            sbyte currentEmbeddingValue = paragraphEmbeddingLevel;

            // Loop through types, handling all remaining rules
            for (int i = 0; i < textLength; ++i) {

                embeddings[i] = currentEmbeddingValue;

                sbyte t = resultTypes[i];

                // Rules X2, X3, X4, X5
                switch (t) {
                    case RLE:
                    case LRE:
                    case RLO:
                    case LRO:
                        // Only need to compute new level if current level is valid
                        if (overflowCounter == 0) {
                            sbyte newLevel;
                            if (t == RLE || t == RLO) {
                                newLevel = (sbyte)((currentEmbeddingLevel + 1) | 1); // least greater odd
                            } else { // t == LRE || t == LRO
                                newLevel = (sbyte)((currentEmbeddingLevel + 2) & ~1); // least greater even
                            }

                            // If the new level is valid, push old embedding level and override status
                            // No check for valid stack counter, since the level check suffices.
                            if (newLevel < EXPLICIT_LEVEL_LIMIT) {
                                embeddingValueStack[stackCounter] = currentEmbeddingValue;
                                stackCounter++;

                                currentEmbeddingLevel = newLevel;
                                if (t == LRO || t == RLO) { // override
                                    currentEmbeddingValue = (sbyte)((byte)newLevel | 0x80);
                                } else {
                                    currentEmbeddingValue = newLevel;
                                }

                                // Adjust level of format mark (for expositional purposes only, this gets
                                // removed later).
                                embeddings[i] = currentEmbeddingValue;
                                break;
                            }

                            // Otherwise new level is invalid, but a valid level can still be achieved if this
                            // level is 60 and we encounter an RLE or RLO further on.  So record that we
                            // 'almost' overflowed.
                            if (currentEmbeddingLevel == 60) {
                                overflowAlmostCounter++;
                                break;
                            }
                        }

                        // Otherwise old or new level is invalid.
                        overflowCounter++;
                        break;

                    case PDF:
                        // The only case where this did not actually overflow but may have almost overflowed
                        // is when there was an RLE or RLO on level 60, which would result in level 61.  So we
                        // only test the almost overflow condition in that case.
                        //
                        // Also note that there may be a PDF without any pushes at all.

                        if (overflowCounter > 0) {
                            --overflowCounter;
                        } else if (overflowAlmostCounter > 0 && currentEmbeddingLevel != 61) {
                            --overflowAlmostCounter;
                        } else if (stackCounter > 0) {
                            --stackCounter;
                            currentEmbeddingValue = embeddingValueStack[stackCounter];
                            currentEmbeddingLevel = (sbyte)(currentEmbeddingValue & 0x7f);
                        }
                        break;

                    case B:
                        // Rule X8.

                        // These values are reset for clarity, in this implementation B can only
                        // occur as the last code in the array.
                        stackCounter = 0;
                        overflowCounter = 0;
                        overflowAlmostCounter = 0;
                        currentEmbeddingLevel = paragraphEmbeddingLevel;
                        currentEmbeddingValue = paragraphEmbeddingLevel;

                        embeddings[i] = paragraphEmbeddingLevel;
                        break;

                    default:
                        break;
                }
            }

            return embeddings;
        }