compute_explicit_levels

in lib/twitter_cldr/shared/bidi.rb [133:243]


      def compute_explicit_levels
        current_embedding = @base_embedding

        
        
        directional_override = -1

        
        
        
        

        embedding_stack = []
        @formatter_indices ||= []
        sp = 0

        @length.times do |i|
          is_ltr = false
          is_special = true
          is_ltr = @types[i] == :LRE || @types[i] == :LRO

          case @types[i]
            when :RLE, :RLO, :LRE, :LRO
              new_embedding = if is_ltr
                
                ((current_embedding & ~1) + 2)
              else
                
                ((current_embedding + 1) | 1)
              end

              
              if new_embedding < MAX_DEPTH
                
                

                current_embedding |= -0x80 if (directional_override != -1)
                embedding_stack[sp] = current_embedding
                current_embedding = new_embedding
                sp += 1

                directional_override = if @types[i] == :LRO
                  :L
                elsif @types[i] == :RLO
                  :R
                else
                  -1
                end
              end

            when :PDF
              
              
              
              if sp > 0
                sp -= 1
                new_embedding = embedding_stack[sp]
                current_embedding = new_embedding & 0x7f

                directional_override = if new_embedding < 0
                  (new_embedding & 1) == 0 ? :L : :R
                else
                  -1
                end
              end

            else
              is_special = false
          end

          @levels[i] = current_embedding

          if is_special
            
            @formatter_indices << i
          elsif directional_override != -1
            @types[i] = directional_override
          end
        end

        
        
        
        
        
        

        output = 0
        input = 0
        size = @formatter_indices.size

        0.upto(size).each do |i|
          if i == size
            next_fmt = @length
          else
            next_fmt = @formatter_indices[i]
          end

          len = next_fmt - input

          
          arraycopy(@levels, input, @levels, output, len)
          arraycopy(@types, input, @types, output, len)

          output += len
          input = next_fmt + 1
        end

        @length -= @formatter_indices.size
      end