diff --git a/lib/prawn/fonts/ttf.rb b/lib/prawn/fonts/ttf.rb index 5e55220f9..779234de8 100644 --- a/lib/prawn/fonts/ttf.rb +++ b/lib/prawn/fonts/ttf.rb @@ -393,18 +393,18 @@ def embed_simple_font(reference, font, unicode_mapping) XHeight: x_height ) - first_char = font.cmap.tables.first.code_map.index { |gid| !gid.zero? } - last_char = font.cmap.tables.first.code_map.rindex { |gid| !gid.zero? } + first_char, last_char = unicode_mapping.keys.minmax hmtx = font.horizontal_metrics widths = - font.cmap.tables.first.code_map[first_char..last_char].map do |gid| - if gid.zero? + (first_char..last_char).map do |code| + if unicode_mapping.key?(code) + gid = font.cmap.tables.first.code_map[code] + Integer(hmtx.widths[gid] * scale_factor) + else # These characters are not in the document so we don't ever use # these values but we need to encode them so let's use as little # sapce as possible. 0 - else - Integer(hmtx.widths[gid] * scale_factor) end end diff --git a/spec/prawn/font_spec.rb b/spec/prawn/font_spec.rb index a890c907e..ac9da98f4 100644 --- a/spec/prawn/font_spec.rb +++ b/spec/prawn/font_spec.rb @@ -670,4 +670,43 @@ def page_should_not_include_font(font) font_name = text.font_settings.first[:name].to_s.sub(/\w+\+/, 'subset+') expect(font_name).to eq 'subset+DustismoRoman' end + + it 'does not change width of unknown glyph' do + text_with_string_widths = + Class.new(PDF::Inspector::Text) do + attr_reader :string_widths + + def initialize(*) + super + @string_widths = [] + end + + def show_text(text, kerned = false) + super + @string_widths << ((@state.current_font.unpack text).reduce(0) do |width, code| + width + (@state.current_font.glyph_width code) * @font_settings[-1][:size] / 1000.0 + end) + end + end + + pdf = + Prawn::Document.new do + font_families.update( + 'DejaVu Sans' => { + normal: "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf", + bold: "#{Prawn::DATADIR}/fonts/DejaVuSans-Bold.ttf" + } + ) + + # changing option to subset: false fixes issue (albeit using different behavior) + font 'DejaVu Sans', subset: true do + text '日本語end', inline_format: true + end + end + + rendered_pdf = pdf.render + analyzed_pdf = text_with_string_widths.analyze(rendered_pdf) + expect(analyzed_pdf.string_widths.length).to be 2 + expect(analyzed_pdf.string_widths[0]).to be > 0.0 + end end diff --git a/spec/prawn_manual_spec.rb b/spec/prawn_manual_spec.rb index b92c55441..105016409 100644 --- a/spec/prawn_manual_spec.rb +++ b/spec/prawn_manual_spec.rb @@ -6,9 +6,9 @@ MANUAL_HASH = case RUBY_ENGINE when 'ruby' - '8ace5f35f945e5994647cefc2cf7bc369d131e0646d91eb8aeb94e58f72de18d8e7bf82f58fc45406110c4adad239dcbe834059580d29fec2b2a039db67db04c' + '7991e4f72e944140840e1c26f0fff331029846eaab148de8483d06491c7808bc4963e8e7376a514e855037f1f1b4197877a31f2df44f511f4f7f5e0ce5df3170' when 'jruby' - 'b77a740d3290192360c4c083018ca61ccc88d42e7c6a152c7bc394d751f5f08d85aec613549f6660713644b00518561cc0f9c947701f01e8c25632c9db81201a' + '29b8f8cb00910426805ce226fb47c59d6409683f35f0d2c056a6cf837ba086ca5c763ff89266cfc8e11b1d92af60c9974822b12ad761cdbdf520adb005a98750' end RSpec.describe Prawn do