pdf-reader 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG +3 -0
- data/Rakefile +2 -1
- data/lib/pdf/reader/buffer.rb +14 -6
- data/lib/pdf/reader/cmap.rb +0 -2
- data/lib/pdf/reader/encoding.rb +16 -13
- data/lib/pdf/reader/font.rb +17 -11
- data/lib/pdf/reader/glyph_hash.rb +4 -4
- data/lib/pdf/reader/pages_strategy.rb +6 -6
- data/lib/pdf/reader/register_receiver.rb +16 -30
- data/lib/pdf/reader/width_calculator/built_in.rb +49 -9
- metadata +34 -51
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: ea0ed09942ae54e900f0387fd9e46213a6db401b
         | 
| 4 | 
            +
              data.tar.gz: baa54a8a557c8ad86bf3760c0e361f84c16728ef
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: f276cce73b972af13426088bc33217efd576d4e7d7f9dc866aee27950d8cad0f8e8831308314599608a6161cf1aacd4efa1b228c39a6dbff4f78fbc606802c49
         | 
| 7 | 
            +
              data.tar.gz: a9a9d46c2f2eebe93dd15d92fc22d6fb69577fba113bf8f123f7f3efb06d1dcaebe2238c07cc6e0dadcd54f96ed47a4cc57eb043f59d769d397fb36b38a1cc88
         | 
    
        data/CHANGELOG
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | @@ -2,6 +2,7 @@ require "rubygems" | |
| 2 2 | 
             
            require "bundler"
         | 
| 3 3 | 
             
            Bundler.setup
         | 
| 4 4 |  | 
| 5 | 
            +
            require 'yaml'
         | 
| 5 6 | 
             
            require 'rake'
         | 
| 6 7 | 
             
            require 'rdoc/task'
         | 
| 7 8 | 
             
            require 'rspec/core/rake_task'
         | 
| @@ -19,7 +20,7 @@ if RUBY_VERSION >= "1.9" && RUBY_ENGINE == "ruby" | |
| 19 20 | 
             
              Cane::RakeTask.new(:quality) do |cane|
         | 
| 20 21 | 
             
                cane.abc_max = 20
         | 
| 21 22 | 
             
                cane.style_measure = 100
         | 
| 22 | 
            -
                cane.max_violations =  | 
| 23 | 
            +
                cane.max_violations = 93
         | 
| 23 24 |  | 
| 24 25 | 
             
                cane.use Morecane::EncodingCheck, :encoding_glob => "{app,lib,spec}/**/*.rb"
         | 
| 25 26 | 
             
              end
         | 
    
        data/lib/pdf/reader/buffer.rb
    CHANGED
    
    | @@ -38,6 +38,14 @@ class PDF::Reader | |
| 38 38 | 
             
              class Buffer
         | 
| 39 39 | 
             
                TOKEN_WHITESPACE=[0x00, 0x09, 0x0A, 0x0C, 0x0D, 0x20]
         | 
| 40 40 |  | 
| 41 | 
            +
                # some strings for comparissons. Declaring them here avoids creating new
         | 
| 42 | 
            +
                # strings that need GC over and over
         | 
| 43 | 
            +
                LEFT_PAREN = "("
         | 
| 44 | 
            +
                LESS_THAN = "<"
         | 
| 45 | 
            +
                STREAM = "stream"
         | 
| 46 | 
            +
                ID = "ID"
         | 
| 47 | 
            +
                FWD_SLASH = "/"
         | 
| 48 | 
            +
             | 
| 41 49 | 
             
                attr_reader :pos
         | 
| 42 50 |  | 
| 43 51 | 
             
                # Creates a new buffer.
         | 
| @@ -121,7 +129,7 @@ class PDF::Reader | |
| 121 129 |  | 
| 122 130 | 
             
                  # the PDF 1.7 spec (section #3.4) says that EOL markers can be either \r, \n, or both.
         | 
| 123 131 | 
             
                  lines = data.split(/[\n\r]+/).reverse
         | 
| 124 | 
            -
                  eof_index = lines.index { |l| l.strip | 
| 132 | 
            +
                  eof_index = lines.index { |l| l.strip[/^%%EOF/] }
         | 
| 125 133 |  | 
| 126 134 | 
             
                  raise MalformedPDFError, "PDF does not contain EOF marker" if eof_index.nil?
         | 
| 127 135 | 
             
                  raise MalformedPDFError, "PDF EOF marker does not follow offset" if eof_index >= lines.size-1
         | 
| @@ -176,11 +184,11 @@ class PDF::Reader | |
| 176 184 | 
             
                #
         | 
| 177 185 | 
             
                def state
         | 
| 178 186 | 
             
                  case @tokens.last
         | 
| 179 | 
            -
                  when  | 
| 180 | 
            -
                  when  | 
| 181 | 
            -
                  when  | 
| 182 | 
            -
                  when  | 
| 183 | 
            -
                    if in_content_stream?  && @tokens[-2] !=  | 
| 187 | 
            +
                  when LEFT_PAREN then :literal_string
         | 
| 188 | 
            +
                  when LESS_THAN then :hex_string
         | 
| 189 | 
            +
                  when STREAM then :stream
         | 
| 190 | 
            +
                  when ID
         | 
| 191 | 
            +
                    if in_content_stream?  && @tokens[-2] != FWD_SLASH
         | 
| 184 192 | 
             
                      :inline
         | 
| 185 193 | 
             
                    else
         | 
| 186 194 | 
             
                      :regular
         | 
    
        data/lib/pdf/reader/cmap.rb
    CHANGED
    
    | @@ -142,8 +142,6 @@ class PDF::Reader | |
| 142 142 | 
             
                  # add all values in the range to our mapping
         | 
| 143 143 | 
             
                  (start_code..end_code).each_with_index do |val, idx|
         | 
| 144 144 | 
             
                    @map[val] = dst.length == 1 ? [dst[0] + idx] : [dst[0], dst[1] + 1]
         | 
| 145 | 
            -
                    # ensure a single range does not exceed 255 chars
         | 
| 146 | 
            -
                    raise PDF::Reader::MalformedPDFError, "a CMap bfrange cann't exceed 255 chars" if idx > 255
         | 
| 147 145 | 
             
                  end
         | 
| 148 146 | 
             
                end
         | 
| 149 147 |  | 
    
        data/lib/pdf/reader/encoding.rb
    CHANGED
    
    | @@ -36,8 +36,7 @@ class PDF::Reader | |
| 36 36 | 
             
                attr_reader :unpack
         | 
| 37 37 |  | 
| 38 38 | 
             
                def initialize(enc)
         | 
| 39 | 
            -
                  @mapping  =  | 
| 40 | 
            -
                                 # also maps control and invalid chars to UNKNOWN_CHAR
         | 
| 39 | 
            +
                  @mapping  = default_mapping # maps from character codes to Unicode codepoints
         | 
| 41 40 | 
             
                  @string_cache  = {} # maps from character codes to UTF-8 strings.
         | 
| 42 41 |  | 
| 43 42 | 
             
                  if enc.kind_of?(Hash)
         | 
| @@ -54,7 +53,6 @@ class PDF::Reader | |
| 54 53 | 
             
                  @map_file = get_mapping_file(enc)
         | 
| 55 54 |  | 
| 56 55 | 
             
                  load_mapping(@map_file) if @map_file
         | 
| 57 | 
            -
                  add_control_chars_to_mapping
         | 
| 58 56 | 
             
                end
         | 
| 59 57 |  | 
| 60 58 | 
             
                # set the differences table for this encoding. should be an array in the following format:
         | 
| @@ -130,6 +128,21 @@ class PDF::Reader | |
| 130 128 |  | 
| 131 129 | 
             
                private
         | 
| 132 130 |  | 
| 131 | 
            +
                # returns a hash that:
         | 
| 132 | 
            +
                # - maps control chars and nil to the unicode "unknown character"
         | 
| 133 | 
            +
                # - leaves all other bytes <= 255 unchaged
         | 
| 134 | 
            +
                #
         | 
| 135 | 
            +
                # Each specific encoding will change this default as required for their glyphs
         | 
| 136 | 
            +
                def default_mapping
         | 
| 137 | 
            +
                  all_bytes = (0..255).to_a
         | 
| 138 | 
            +
                  tuples = all_bytes.map {|i|
         | 
| 139 | 
            +
                    CONTROL_CHARS.include?(i) ? [i, UNKNOWN_CHAR] : [i,i]
         | 
| 140 | 
            +
                  }
         | 
| 141 | 
            +
                  mapping = Hash[tuples]
         | 
| 142 | 
            +
                  mapping[nil] = UNKNOWN_CHAR
         | 
| 143 | 
            +
                  mapping
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 133 146 | 
             
                def internal_int_to_utf8_string(glyph_code)
         | 
| 134 147 | 
             
                  ret = [
         | 
| 135 148 | 
             
                    @mapping[glyph_code.to_i] || glyph_code.to_i
         | 
| @@ -194,8 +207,6 @@ class PDF::Reader | |
| 194 207 | 
             
                end
         | 
| 195 208 |  | 
| 196 209 | 
             
                def load_mapping(file)
         | 
| 197 | 
            -
                  return if has_mapping?
         | 
| 198 | 
            -
             | 
| 199 210 | 
             
                  RUBY_VERSION >= "1.9" ? mode = "r:BINARY" : mode = "r"
         | 
| 200 211 | 
             
                  File.open(file, mode) do |f|
         | 
| 201 212 | 
             
                    f.each do |l|
         | 
| @@ -205,13 +216,5 @@ class PDF::Reader | |
| 205 216 | 
             
                  end
         | 
| 206 217 | 
             
                end
         | 
| 207 218 |  | 
| 208 | 
            -
                def add_control_chars_to_mapping
         | 
| 209 | 
            -
                  PDF::Reader::Encoding::CONTROL_CHARS.each do |byte|
         | 
| 210 | 
            -
                    unless @mapping[byte]
         | 
| 211 | 
            -
                      @mapping[byte] = PDF::Reader::Encoding::UNKNOWN_CHAR
         | 
| 212 | 
            -
                    end
         | 
| 213 | 
            -
                  end
         | 
| 214 | 
            -
                  @mapping[nil] = PDF::Reader::Encoding::UNKNOWN_CHAR
         | 
| 215 | 
            -
                end
         | 
| 216 219 | 
             
              end
         | 
| 217 220 | 
             
            end
         | 
    
        data/lib/pdf/reader/font.rb
    CHANGED
    
    | @@ -53,16 +53,7 @@ class PDF::Reader | |
| 53 53 | 
             
                end
         | 
| 54 54 |  | 
| 55 55 | 
             
                def basefont=(font)
         | 
| 56 | 
            -
                   | 
| 57 | 
            -
                  # with encoding= if required
         | 
| 58 | 
            -
                  case font
         | 
| 59 | 
            -
                  when "Symbol" then
         | 
| 60 | 
            -
                    @encoding = PDF::Reader::Encoding.new("SymbolEncoding")
         | 
| 61 | 
            -
                  when "ZapfDingbats" then
         | 
| 62 | 
            -
                    @encoding = PDF::Reader::Encoding.new("ZapfDingbatsEncoding")
         | 
| 63 | 
            -
                  else
         | 
| 64 | 
            -
                    @encoding = nil
         | 
| 65 | 
            -
                  end
         | 
| 56 | 
            +
                  @encoding ||= default_encoding(font)
         | 
| 66 57 | 
             
                  @basefont = font
         | 
| 67 58 | 
             
                end
         | 
| 68 59 |  | 
| @@ -91,6 +82,17 @@ class PDF::Reader | |
| 91 82 |  | 
| 92 83 | 
             
                private
         | 
| 93 84 |  | 
| 85 | 
            +
                def default_encoding(font_name)
         | 
| 86 | 
            +
                  case font_name.to_s
         | 
| 87 | 
            +
                  when "Symbol" then
         | 
| 88 | 
            +
                    PDF::Reader::Encoding.new(:SymbolEncoding)
         | 
| 89 | 
            +
                  when "ZapfDingbats" then
         | 
| 90 | 
            +
                    PDF::Reader::Encoding.new(:ZapfDingbatsEncoding)
         | 
| 91 | 
            +
                  else
         | 
| 92 | 
            +
                    PDF::Reader::Encoding.new(:StandardEncoding)
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 94 96 | 
             
                def build_width_calculator
         | 
| 95 97 | 
             
                  if @subtype == :Type0
         | 
| 96 98 | 
             
                    PDF::Reader::WidthCalculator::TypeZero.new(self)
         | 
| @@ -114,7 +116,11 @@ class PDF::Reader | |
| 114 116 | 
             
                def extract_base_info(obj)
         | 
| 115 117 | 
             
                  @subtype  = @ohash.object(obj[:Subtype])
         | 
| 116 118 | 
             
                  @basefont = @ohash.object(obj[:BaseFont])
         | 
| 117 | 
            -
                   | 
| 119 | 
            +
                  if @ohash.object(obj[:Encoding])
         | 
| 120 | 
            +
                    @encoding = PDF::Reader::Encoding.new(@ohash.object(obj[:Encoding]))
         | 
| 121 | 
            +
                  else
         | 
| 122 | 
            +
                    @encoding = default_encoding(@basefont)
         | 
| 123 | 
            +
                  end
         | 
| 118 124 | 
             
                  @widths   = @ohash.object(obj[:Widths]) || []
         | 
| 119 125 | 
             
                  @first_char = @ohash.object(obj[:FirstChar])
         | 
| 120 126 | 
             
                  @last_char = @ohash.object(obj[:LastChar])
         | 
| @@ -66,10 +66,10 @@ class PDF::Reader | |
| 66 66 | 
             
                    "0x#{str[3,4]}".hex
         | 
| 67 67 | 
             
                  elsif str.match(/\Au[A-F\d]{4,6}\Z/)
         | 
| 68 68 | 
             
                    "0x#{str[1,6]}".hex
         | 
| 69 | 
            -
                  elsif str.match(/\A[A-Za-z]\d{1, | 
| 70 | 
            -
                    str[1, | 
| 71 | 
            -
                  elsif str.match(/\A[A-Za-z]{2}\d{2, | 
| 72 | 
            -
                    str[2, | 
| 69 | 
            +
                  elsif str.match(/\A[A-Za-z]\d{1,5}\Z/)
         | 
| 70 | 
            +
                    str[1,5].to_i
         | 
| 71 | 
            +
                  elsif str.match(/\A[A-Za-z]{2}\d{2,5}\Z/)
         | 
| 72 | 
            +
                    str[2,5].to_i
         | 
| 73 73 | 
             
                  else
         | 
| 74 74 | 
             
                    nil
         | 
| 75 75 | 
             
                  end
         | 
| @@ -30,9 +30,9 @@ class PDF::Reader | |
| 30 30 | 
             
              # Walks the pages of the PDF file and calls the appropriate callback methods when
         | 
| 31 31 | 
             
              # something of interest is found.
         | 
| 32 32 | 
             
              #
         | 
| 33 | 
            -
              # The callback methods should exist on the receiver object passed into the constructor. | 
| 34 | 
            -
              # some content is found that will trigger a callback, the receiver is checked | 
| 35 | 
            -
              # is defined.
         | 
| 33 | 
            +
              # The callback methods should exist on the receiver object passed into the constructor.
         | 
| 34 | 
            +
              # Whenever some content is found that will trigger a callback, the receiver is checked
         | 
| 35 | 
            +
              # to see if the callback is defined.
         | 
| 36 36 | 
             
              #
         | 
| 37 37 | 
             
              # If it is defined it will be called. If not, processing will continue.
         | 
| 38 38 | 
             
              #
         | 
| @@ -40,9 +40,9 @@ class PDF::Reader | |
| 40 40 | 
             
              # The following callbacks are available and should be methods defined on your receiver class. Only
         | 
| 41 41 | 
             
              # implement the ones you need - the rest will be ignored.
         | 
| 42 42 | 
             
              #
         | 
| 43 | 
            -
              # Some callbacks will include parameters which will be passed in as an array. For callbacks | 
| 44 | 
            -
              # paramters, or where you don't need them, the *params argument can be left off. | 
| 45 | 
            -
              # method definitions are:
         | 
| 43 | 
            +
              # Some callbacks will include parameters which will be passed in as an array. For callbacks
         | 
| 44 | 
            +
              # that supply no paramters, or where you don't need them, the *params argument can be left off.
         | 
| 45 | 
            +
              # Some example callback method definitions are:
         | 
| 46 46 | 
             
              #
         | 
| 47 47 | 
             
              #   def begin_document
         | 
| 48 48 | 
             
              #   def end_page
         | 
| @@ -11,10 +11,12 @@ class PDF::Reader | |
| 11 11 | 
             
              #
         | 
| 12 12 | 
             
              # Usage:
         | 
| 13 13 | 
             
              #
         | 
| 14 | 
            -
              # | 
| 15 | 
            -
              # | 
| 16 | 
            -
              # | 
| 17 | 
            -
              # | 
| 14 | 
            +
              #     PDF::Reader.open("somefile.pdf") do |reader|
         | 
| 15 | 
            +
              #       receiver = PDF::Reader::RegisterReceiver.new
         | 
| 16 | 
            +
              #       reader.page(1).walk(receiver)
         | 
| 17 | 
            +
              #       callback = receiver.first_occurance_of(:show_text)
         | 
| 18 | 
            +
              #       callback[:args].first.should == "Hellow World"
         | 
| 19 | 
            +
              #     end
         | 
| 18 20 | 
             
              #
         | 
| 19 21 | 
             
              class RegisterReceiver
         | 
| 20 22 |  | 
| @@ -34,18 +36,12 @@ class PDF::Reader | |
| 34 36 |  | 
| 35 37 | 
             
                # count the number of times a callback fired
         | 
| 36 38 | 
             
                def count(methodname)
         | 
| 37 | 
            -
                   | 
| 38 | 
            -
                  callbacks.each { |cb| counter += 1 if cb[:name] == methodname}
         | 
| 39 | 
            -
                  return counter
         | 
| 39 | 
            +
                  callbacks.count { |cb| cb[:name] == methodname}
         | 
| 40 40 | 
             
                end
         | 
| 41 41 |  | 
| 42 42 | 
             
                # return the details for every time the specified callback was fired
         | 
| 43 43 | 
             
                def all(methodname)
         | 
| 44 | 
            -
                   | 
| 45 | 
            -
                  callbacks.each do |cb|
         | 
| 46 | 
            -
                    ret << cb if cb[:name] == methodname
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
                  return ret
         | 
| 44 | 
            +
                  callbacks.select { |cb| cb[:name] == methodname }
         | 
| 49 45 | 
             
                end
         | 
| 50 46 |  | 
| 51 47 | 
             
                def all_args(methodname)
         | 
| @@ -54,42 +50,32 @@ class PDF::Reader | |
| 54 50 |  | 
| 55 51 | 
             
                # return the details for the first time the specified callback was fired
         | 
| 56 52 | 
             
                def first_occurance_of(methodname)
         | 
| 57 | 
            -
                  callbacks. | 
| 58 | 
            -
                    return cb if cb[:name] == methodname
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
                  return nil
         | 
| 53 | 
            +
                  callbacks.find { |cb| cb[:name] == methodname }
         | 
| 61 54 | 
             
                end
         | 
| 62 55 |  | 
| 63 56 | 
             
                # return the details for the final time the specified callback was fired
         | 
| 64 57 | 
             
                def final_occurance_of(methodname)
         | 
| 65 | 
            -
                   | 
| 66 | 
            -
                  callbacks.each do |cb|
         | 
| 67 | 
            -
                    returnme = cb if cb[:name] == methodname
         | 
| 68 | 
            -
                  end
         | 
| 69 | 
            -
                  return returnme
         | 
| 58 | 
            +
                  all(methodname).last
         | 
| 70 59 | 
             
                end
         | 
| 71 60 |  | 
| 72 61 | 
             
                # return the first occurance of a particular series of callbacks
         | 
| 73 62 | 
             
                def series(*methods)
         | 
| 74 63 | 
             
                  return nil if methods.empty?
         | 
| 75 64 |  | 
| 76 | 
            -
                  indexes = (0..(callbacks.size-1 | 
| 65 | 
            +
                  indexes = (0..(callbacks.size-1))
         | 
| 77 66 | 
             
                  method_indexes = (0..(methods.size-1))
         | 
| 78 67 | 
             
                  match = nil
         | 
| 79 68 |  | 
| 80 69 | 
             
                  indexes.each do |idx|
         | 
| 81 70 | 
             
                    count = methods.size
         | 
| 82 71 | 
             
                    method_indexes.each do |midx|
         | 
| 83 | 
            -
                      count -= 1 if callbacks[idx+midx][:name] == methods[midx]
         | 
| 72 | 
            +
                      count -= 1 if callbacks[idx+midx] && callbacks[idx+midx][:name] == methods[midx]
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                    if count == 0
         | 
| 75 | 
            +
                      return callbacks[idx, methods.size]
         | 
| 84 76 | 
             
                    end
         | 
| 85 | 
            -
                    match = idx and break if count == 0
         | 
| 86 | 
            -
                  end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  if match
         | 
| 89 | 
            -
                    return callbacks[match, methods.size]
         | 
| 90 | 
            -
                  else
         | 
| 91 | 
            -
                    return nil
         | 
| 92 77 | 
             
                  end
         | 
| 78 | 
            +
                  nil
         | 
| 93 79 | 
             
                end
         | 
| 94 80 | 
             
              end
         | 
| 95 81 | 
             
            end
         | 
| @@ -3,12 +3,52 @@ | |
| 3 3 | 
             
            require 'afm'
         | 
| 4 4 | 
             
            require 'pdf/reader/synchronized_cache'
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 6 | 
            +
            # monkey patch the afm gem to give us access to the metrics by glyph code. I've
         | 
| 7 | 
            +
            # got a pull request to upstream so hopefully this can be removed soon. See
         | 
| 8 | 
            +
            # https://github.com/halfbyte/afm/pull/3
         | 
| 9 | 
            +
            class AFM::Font
         | 
| 10 | 
            +
              attr_reader :char_metrics_by_code
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              # Loading a Font Metrics file by absolute path (no automatic font path resolution)
         | 
| 13 | 
            +
              def initialize(filename)
         | 
| 14 | 
            +
                @metadata = {}
         | 
| 15 | 
            +
                @char_metrics = {}
         | 
| 16 | 
            +
                @char_metrics_by_code = {}
         | 
| 17 | 
            +
                @kern_pairs = []
         | 
| 18 | 
            +
                File.open(filename) do |file|
         | 
| 19 | 
            +
                  mode = :meta
         | 
| 20 | 
            +
                  file.each_line do |line|
         | 
| 21 | 
            +
                    case(line)
         | 
| 22 | 
            +
                    when /^StartFontMetrics/ ; mode = :meta
         | 
| 23 | 
            +
                    when /^StartCharMetrics/ ; mode = :char_metrics
         | 
| 24 | 
            +
                    when /^EndCharMetrics/ ; mode = :meta
         | 
| 25 | 
            +
                    when /^StartKernData/ ; mode = :kern_data
         | 
| 26 | 
            +
                    when /^StartKernPairs/ ; mode = :kern_pairs
         | 
| 27 | 
            +
                    when /^EndKernPairs/ ; mode = :kern_data
         | 
| 28 | 
            +
                    when /^EndKernData/ ; mode = :meta
         | 
| 29 | 
            +
                    else
         | 
| 30 | 
            +
                      case(mode)
         | 
| 31 | 
            +
                      when :meta
         | 
| 32 | 
            +
                        if match = line.match(/^([\w]+) (.*)$/)
         | 
| 33 | 
            +
                          @metadata[match[1]] = match[2]
         | 
| 34 | 
            +
                        end
         | 
| 35 | 
            +
                      when :char_metrics
         | 
| 36 | 
            +
                        metrics = {}
         | 
| 37 | 
            +
                        metrics[:charcode] = match[1].to_i if match = line.match(/C (-?\d+) *?;/)
         | 
| 38 | 
            +
                        metrics[:wx] = match[1].to_i if match = line.match(/WX (-?\d+) *?;/)
         | 
| 39 | 
            +
                        metrics[:name] = match[1] if match = line.match(/N ([.\w]+) *?;/)
         | 
| 40 | 
            +
                        if match = line.match(/B (-?\d+) (-?\d+) (-?\d+) (-?\d+) *?;/)
         | 
| 41 | 
            +
                          metrics[:boundingbox] = [match[1].to_i, match[2].to_i, match[3].to_i, match[4].to_i]
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
                        @char_metrics[metrics[:name]] = metrics if metrics[:name]
         | 
| 44 | 
            +
                        @char_metrics_by_code[metrics[:charcode]] = metrics if metrics[:charcode] && metrics[:charcode] > 0
         | 
| 45 | 
            +
                      when :kern_pairs
         | 
| 46 | 
            +
                        if match = line.match(/^KPX ([.\w]+) ([.\w]+) (-?\d+)$/)
         | 
| 47 | 
            +
                          @kern_pairs << [match[1], match[2], match[3].to_i]
         | 
| 48 | 
            +
                        end
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                  end
         | 
| 12 52 | 
             
                end
         | 
| 13 53 | 
             
              end
         | 
| 14 54 | 
             
            end
         | 
| @@ -37,11 +77,11 @@ class PDF::Reader | |
| 37 77 | 
             
                  def glyph_width(code_point)
         | 
| 38 78 | 
             
                    return 0 if code_point.nil? || code_point < 0
         | 
| 39 79 |  | 
| 40 | 
            -
                    m = @metrics. | 
| 80 | 
            +
                    m = @metrics.char_metrics_by_code[code_point]
         | 
| 41 81 | 
             
                    if m.nil?
         | 
| 42 82 | 
             
                      names = @font.encoding.int_to_name(code_point)
         | 
| 43 83 | 
             
                      m = names.map { |name|
         | 
| 44 | 
            -
                        @metrics. | 
| 84 | 
            +
                        @metrics.char_metrics[name.to_s]
         | 
| 45 85 | 
             
                      }.compact.first
         | 
| 46 86 | 
             
                    end
         | 
| 47 87 |  | 
| @@ -50,7 +90,7 @@ class PDF::Reader | |
| 50 90 | 
             
                    elsif @font.widths[code_point - 1]
         | 
| 51 91 | 
             
                      @font.widths[code_point - 1]
         | 
| 52 92 | 
             
                    else
         | 
| 53 | 
            -
                      raise ArgumentError, "Unknown glyph width for #{code_point}"
         | 
| 93 | 
            +
                      raise ArgumentError, "Unknown glyph width for #{code_point} #{@font.basefont}"
         | 
| 54 94 | 
             
                    end
         | 
| 55 95 | 
             
                  end
         | 
| 56 96 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,36 +1,32 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: pdf-reader
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.3. | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              version: 1.3.3
         | 
| 6 5 | 
             
            platform: ruby
         | 
| 7 6 | 
             
            authors:
         | 
| 8 7 | 
             
            - James Healy
         | 
| 9 8 | 
             
            autorequire: 
         | 
| 10 9 | 
             
            bindir: bin
         | 
| 11 10 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013- | 
| 11 | 
            +
            date: 2013-04-07 00:00:00.000000000 Z
         | 
| 13 12 | 
             
            dependencies:
         | 
| 14 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 14 | 
             
              name: rake
         | 
| 16 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            -
                none: false
         | 
| 18 16 | 
             
                requirements:
         | 
| 19 | 
            -
                - -  | 
| 17 | 
            +
                - - '>='
         | 
| 20 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 21 19 | 
             
                    version: '0'
         | 
| 22 20 | 
             
              type: :development
         | 
| 23 21 | 
             
              prerelease: false
         | 
| 24 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            -
                none: false
         | 
| 26 23 | 
             
                requirements:
         | 
| 27 | 
            -
                - -  | 
| 24 | 
            +
                - - '>='
         | 
| 28 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 29 26 | 
             
                    version: '0'
         | 
| 30 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 28 | 
             
              name: rspec
         | 
| 32 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 | 
            -
                none: false
         | 
| 34 30 | 
             
                requirements:
         | 
| 35 31 | 
             
                - - ~>
         | 
| 36 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -38,7 +34,6 @@ dependencies: | |
| 38 34 | 
             
              type: :development
         | 
| 39 35 | 
             
              prerelease: false
         | 
| 40 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 41 | 
            -
                none: false
         | 
| 42 37 | 
             
                requirements:
         | 
| 43 38 | 
             
                - - ~>
         | 
| 44 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -46,7 +41,6 @@ dependencies: | |
| 46 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 47 42 | 
             
              name: ZenTest
         | 
| 48 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 | 
            -
                none: false
         | 
| 50 44 | 
             
                requirements:
         | 
| 51 45 | 
             
                - - ~>
         | 
| 52 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -54,7 +48,6 @@ dependencies: | |
| 54 48 | 
             
              type: :development
         | 
| 55 49 | 
             
              prerelease: false
         | 
| 56 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 | 
            -
                none: false
         | 
| 58 51 | 
             
                requirements:
         | 
| 59 52 | 
             
                - - ~>
         | 
| 60 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -62,7 +55,6 @@ dependencies: | |
| 62 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 63 56 | 
             
              name: cane
         | 
| 64 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 65 | 
            -
                none: false
         | 
| 66 58 | 
             
                requirements:
         | 
| 67 59 | 
             
                - - ~>
         | 
| 68 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -70,7 +62,6 @@ dependencies: | |
| 70 62 | 
             
              type: :development
         | 
| 71 63 | 
             
              prerelease: false
         | 
| 72 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 73 | 
            -
                none: false
         | 
| 74 65 | 
             
                requirements:
         | 
| 75 66 | 
             
                - - ~>
         | 
| 76 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -78,55 +69,48 @@ dependencies: | |
| 78 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 79 70 | 
             
              name: morecane
         | 
| 80 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 81 | 
            -
                none: false
         | 
| 82 72 | 
             
                requirements:
         | 
| 83 | 
            -
                - -  | 
| 73 | 
            +
                - - '>='
         | 
| 84 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 85 75 | 
             
                    version: '0'
         | 
| 86 76 | 
             
              type: :development
         | 
| 87 77 | 
             
              prerelease: false
         | 
| 88 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 89 | 
            -
                none: false
         | 
| 90 79 | 
             
                requirements:
         | 
| 91 | 
            -
                - -  | 
| 80 | 
            +
                - - '>='
         | 
| 92 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 93 82 | 
             
                    version: '0'
         | 
| 94 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 95 84 | 
             
              name: ir_b
         | 
| 96 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 97 | 
            -
                none: false
         | 
| 98 86 | 
             
                requirements:
         | 
| 99 | 
            -
                - -  | 
| 87 | 
            +
                - - '>='
         | 
| 100 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 101 89 | 
             
                    version: '0'
         | 
| 102 90 | 
             
              type: :development
         | 
| 103 91 | 
             
              prerelease: false
         | 
| 104 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 105 | 
            -
                none: false
         | 
| 106 93 | 
             
                requirements:
         | 
| 107 | 
            -
                - -  | 
| 94 | 
            +
                - - '>='
         | 
| 108 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 109 96 | 
             
                    version: '0'
         | 
| 110 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 111 98 | 
             
              name: rdoc
         | 
| 112 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 113 | 
            -
                none: false
         | 
| 114 100 | 
             
                requirements:
         | 
| 115 | 
            -
                - -  | 
| 101 | 
            +
                - - '>='
         | 
| 116 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 117 103 | 
             
                    version: '0'
         | 
| 118 104 | 
             
              type: :development
         | 
| 119 105 | 
             
              prerelease: false
         | 
| 120 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            -
                none: false
         | 
| 122 107 | 
             
                requirements:
         | 
| 123 | 
            -
                - -  | 
| 108 | 
            +
                - - '>='
         | 
| 124 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 125 110 | 
             
                    version: '0'
         | 
| 126 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 127 112 | 
             
              name: Ascii85
         | 
| 128 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 129 | 
            -
                none: false
         | 
| 130 114 | 
             
                requirements:
         | 
| 131 115 | 
             
                - - ~>
         | 
| 132 116 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -134,7 +118,6 @@ dependencies: | |
| 134 118 | 
             
              type: :runtime
         | 
| 135 119 | 
             
              prerelease: false
         | 
| 136 120 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 137 | 
            -
                none: false
         | 
| 138 121 | 
             
                requirements:
         | 
| 139 122 | 
             
                - - ~>
         | 
| 140 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -142,23 +125,20 @@ dependencies: | |
| 142 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 143 126 | 
             
              name: ruby-rc4
         | 
| 144 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 145 | 
            -
                none: false
         | 
| 146 128 | 
             
                requirements:
         | 
| 147 | 
            -
                - -  | 
| 129 | 
            +
                - - '>='
         | 
| 148 130 | 
             
                  - !ruby/object:Gem::Version
         | 
| 149 131 | 
             
                    version: '0'
         | 
| 150 132 | 
             
              type: :runtime
         | 
| 151 133 | 
             
              prerelease: false
         | 
| 152 134 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 153 | 
            -
                none: false
         | 
| 154 135 | 
             
                requirements:
         | 
| 155 | 
            -
                - -  | 
| 136 | 
            +
                - - '>='
         | 
| 156 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 157 138 | 
             
                    version: '0'
         | 
| 158 139 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 159 140 | 
             
              name: hashery
         | 
| 160 141 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 161 | 
            -
                none: false
         | 
| 162 142 | 
             
                requirements:
         | 
| 163 143 | 
             
                - - ~>
         | 
| 164 144 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -166,7 +146,6 @@ dependencies: | |
| 166 146 | 
             
              type: :runtime
         | 
| 167 147 | 
             
              prerelease: false
         | 
| 168 148 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 169 | 
            -
                none: false
         | 
| 170 149 | 
             
                requirements:
         | 
| 171 150 | 
             
                - - ~>
         | 
| 172 151 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -174,23 +153,20 @@ dependencies: | |
| 174 153 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 175 154 | 
             
              name: ttfunk
         | 
| 176 155 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 177 | 
            -
                none: false
         | 
| 178 156 | 
             
                requirements:
         | 
| 179 | 
            -
                - -  | 
| 157 | 
            +
                - - '>='
         | 
| 180 158 | 
             
                  - !ruby/object:Gem::Version
         | 
| 181 159 | 
             
                    version: '0'
         | 
| 182 160 | 
             
              type: :runtime
         | 
| 183 161 | 
             
              prerelease: false
         | 
| 184 162 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 185 | 
            -
                none: false
         | 
| 186 163 | 
             
                requirements:
         | 
| 187 | 
            -
                - -  | 
| 164 | 
            +
                - - '>='
         | 
| 188 165 | 
             
                  - !ruby/object:Gem::Version
         | 
| 189 166 | 
             
                    version: '0'
         | 
| 190 167 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 191 168 | 
             
              name: afm
         | 
| 192 169 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 193 | 
            -
                none: false
         | 
| 194 170 | 
             
                requirements:
         | 
| 195 171 | 
             
                - - ~>
         | 
| 196 172 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -198,7 +174,6 @@ dependencies: | |
| 198 174 | 
             
              type: :runtime
         | 
| 199 175 | 
             
              prerelease: false
         | 
| 200 176 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 201 | 
            -
                none: false
         | 
| 202 177 | 
             
                requirements:
         | 
| 203 178 | 
             
                - - ~>
         | 
| 204 179 | 
             
                  - !ruby/object:Gem::Version
         | 
| @@ -312,12 +287,22 @@ files: | |
| 312 287 | 
             
            - bin/pdf_callbacks
         | 
| 313 288 | 
             
            homepage: http://github.com/yob/pdf-reader
         | 
| 314 289 | 
             
            licenses: []
         | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 317 | 
            -
             | 
| 318 | 
            -
             | 
| 319 | 
            -
             | 
| 320 | 
            -
             | 
| 290 | 
            +
            metadata: {}
         | 
| 291 | 
            +
            post_install_message: |2+
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                ********************************************
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                v1.0.0 of PDF::Reader introduced a new page-based API. There are extensive
         | 
| 296 | 
            +
                examples showing how to use it in the README and examples directory.
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                For detailed documentation, check the rdocs for the PDF::Reader,
         | 
| 299 | 
            +
                PDF::Reader::Page and PDF::Reader::ObjectHash classes.
         | 
| 300 | 
            +
             | 
| 301 | 
            +
                The old API is marked as deprecated but will continue to work with no
         | 
| 302 | 
            +
                visible warnings for now.
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                ********************************************
         | 
| 305 | 
            +
             | 
| 321 306 | 
             
            rdoc_options:
         | 
| 322 307 | 
             
            - --title
         | 
| 323 308 | 
             
            - PDF::Reader Documentation
         | 
| @@ -327,21 +312,19 @@ rdoc_options: | |
| 327 312 | 
             
            require_paths:
         | 
| 328 313 | 
             
            - lib
         | 
| 329 314 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 330 | 
            -
              none: false
         | 
| 331 315 | 
             
              requirements:
         | 
| 332 | 
            -
              - -  | 
| 316 | 
            +
              - - '>='
         | 
| 333 317 | 
             
                - !ruby/object:Gem::Version
         | 
| 334 318 | 
             
                  version: 1.8.7
         | 
| 335 319 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 336 | 
            -
              none: false
         | 
| 337 320 | 
             
              requirements:
         | 
| 338 | 
            -
              - -  | 
| 321 | 
            +
              - - '>='
         | 
| 339 322 | 
             
                - !ruby/object:Gem::Version
         | 
| 340 323 | 
             
                  version: '0'
         | 
| 341 324 | 
             
            requirements: []
         | 
| 342 325 | 
             
            rubyforge_project: 
         | 
| 343 | 
            -
            rubygems_version:  | 
| 326 | 
            +
            rubygems_version: 2.0.0
         | 
| 344 327 | 
             
            signing_key: 
         | 
| 345 | 
            -
            specification_version:  | 
| 328 | 
            +
            specification_version: 4
         | 
| 346 329 | 
             
            summary: A library for accessing the content of PDF files
         | 
| 347 330 | 
             
            test_files: []
         |