New Upstream Release - ruby-rbpdf

Ready changes

Summary

Merged new upstream version: 1.21.0+ds (was: 1.20.1).

Resulting package

Built on 2023-04-08T20:31 (took 8m23s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases ruby-rbpdf-fontapt install -t fresh-releases ruby-rbpdf

Lintian Result

Diff

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..6d77f6b
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,72 @@
+
+name: test
+
+on: [push, pull_request]
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        ruby: ['jruby', '2.3', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2']
+        gemfile: ['Gemfile.rails5', 'Gemfile.rails5_rmagick', 'Gemfile.rails5_mini_magick',
+                  'Gemfile.rails6', 'Gemfile.rails6_rmagick', 'Gemfile.rails6_mini_magick',
+                  'Gemfile.rails7', 'Gemfile.rails7_rmagick', 'Gemfile.rails7_mini_magick',
+                  'Gemfile.rbpdf-font']
+        exclude:
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails5' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails5_rmagick' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails5_mini_magick' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails6_rmagick' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails6_mini_magick' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails7_rmagick' }
+          - { ruby: 'jruby', gemfile: 'Gemfile.rails7_mini_magick' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails6' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails6_rmagick' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails6_mini_magick' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails7' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails7_rmagick' }
+          - { ruby: '2.3', gemfile: 'Gemfile.rails7_mini_magick' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails6' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails6_rmagick' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails6_mini_magick' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails7' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails7_rmagick' }
+          - { ruby: '2.4', gemfile: 'Gemfile.rails7_mini_magick' }
+          - { ruby: '2.5', gemfile: 'Gemfile.rails7' }
+          - { ruby: '2.5', gemfile: 'Gemfile.rails7_rmagick' }
+          - { ruby: '2.5', gemfile: 'Gemfile.rails7_mini_magick' }
+          - { ruby: '2.6', gemfile: 'Gemfile.rails7' }
+          - { ruby: '2.6', gemfile: 'Gemfile.rails7_rmagick' }
+          - { ruby: '2.6', gemfile: 'Gemfile.rails7_mini_magick' }
+          - { ruby: '3.0', gemfile: 'Gemfile.rails5' }
+          - { ruby: '3.0', gemfile: 'Gemfile.rails5_rmagick' }
+          - { ruby: '3.0', gemfile: 'Gemfile.rails5_mini_magick' }
+          - { ruby: '3.1', gemfile: 'Gemfile.rails5' }
+          - { ruby: '3.1', gemfile: 'Gemfile.rails5_rmagick' }
+          - { ruby: '3.1', gemfile: 'Gemfile.rails5_mini_magick' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails5' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails5_rmagick' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails5_mini_magick' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails6' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails6_rmagick' }
+          - { ruby: '3.2', gemfile: 'Gemfile.rails6_mini_magick' }
+    env:
+      BUNDLE_GEMFILE: ${{ matrix.gemfile }}
+    name: Ruby ${{ matrix.ruby }}, ${{ matrix.gemfile }}
+    steps:
+      - uses: actions/checkout@v3
+      - name: Set up Ruby
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          bundler-cache: true
+      - name: rbpdf-font tests
+        id: rbpdf-font
+        if: contains(matrix.gemfile, 'rbpdf-font')
+        run:  bundle install && cd rbpdf-font && rake test
+      - name: rbpdf tests
+        id: rbpdf
+        if: steps.rbpdf-font.conclusion == 'skipped'
+        run:  bundle exec rake test
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 0f3291e..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-language: ruby
-dist: xenial
-rvm:
-  - 2.0
-  - 2.1
-  - 2.2.2
-  - 2.3.0
-  - 2.4.1
-  - 2.5.1
-  - 2.6
-  - jruby
-matrix:
-  include:
-    - rvm: 1.8.7
-      dist: trusty
-      gemfile: Gemfile.rails3
-    - rvm: 1.8.7
-      dist: trusty
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: 1.8.7
-      dist: trusty
-      gemfile: Gemfile.rbpdf-font
-    - rvm: 1.9.2
-      dist: trusty
-      gemfile: Gemfile.rails3
-    - rvm: 1.9.2
-      dist: trusty
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: 1.9.2
-      dist: trusty
-      gemfile: Gemfile.rbpdf-font
-    - rvm: 1.9.3
-      dist: trusty
-      gemfile: Gemfile.rails3
-    - rvm: 1.9.3
-      dist: trusty
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: 1.9.3
-      dist: trusty
-      gemfile: Gemfile.rails4
-    - rvm: 1.9.3
-      dist: trusty
-      gemfile: Gemfile.rails4_rmagick
-    - rvm: 1.9.3
-      dist: trusty
-      gemfile: Gemfile.rbpdf-font
-  exclude:
-    - rvm: 2.0
-      gemfile: Gemfile.rails5
-    - rvm: 2.0
-      gemfile: Gemfile.rails5_rmagick
-    - rvm: 2.0
-      gemfile: Gemfile.rails5_mini_magick
-    - rvm: 2.1
-      gemfile: Gemfile.rails5
-    - rvm: 2.1
-      gemfile: Gemfile.rails5_rmagick
-    - rvm: 2.1
-      gemfile: Gemfile.rails5_mini_magick
-    - rvm: 2.5.1
-      gemfile: Gemfile.rails3
-    - rvm: 2.5.1
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: 2.5.1
-      gemfile: Gemfile.rails4
-    - rvm: 2.5.1
-      gemfile: Gemfile.rails4_rmagick
-    - rvm: 2.6
-      gemfile: Gemfile.rails3
-    - rvm: 2.6
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: 2.6
-      gemfile: Gemfile.rails4
-    - rvm: 2.6
-      gemfile: Gemfile.rails4_rmagick
-    - rvm: jruby
-      gemfile: Gemfile.rails3_rmagick
-    - rvm: jruby
-      gemfile: Gemfile.rails4_rmagick
-    - rvm: jruby
-      gemfile: Gemfile.rails5_rmagick
-    - rvm: jruby
-      gemfile: Gemfile.rails5_mini_magick
-before_install:
-  - gem update bundler
-install:
-  - bundle install
-script:
-  - if [[ "$BUNDLE_GEMFILE" =~ rbpdf-font$ ]]; then cd rbpdf-font && bundle exec rake test ; else bundle exec rake test ; fi
-gemfile:
-  - Gemfile.rails3
-  - Gemfile.rails3_rmagick
-  - Gemfile.rails4
-  - Gemfile.rails4_rmagick
-  - Gemfile.rails5
-  - Gemfile.rails5_rmagick
-  - Gemfile.rails5_mini_magick
-  - Gemfile.rbpdf-font
-notifications:
-  email: false
diff --git a/CHANGELOG b/CHANGELOG
index 105fb88..6692a2d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,17 @@
+1.21.0 2023-02-13
+       - Support for Ruby 3.0.0, 3.1.0, 3.2.0. (Drop support for Ruby 2.2 and earlier.) #66
+       - Support Rails 6 and Rails 7. (Drop support for Rails 3.x, 4.x) #66, #72
+       - Fix RMagick 5.0 compatible. #66
+       - Infinite loop has been resolved. #68, #74
+       - Fixed a bug that caused the x position to shift when an <img> tag was behind a <li> tag in HTML. #74
+       - fix: Incorrect characters when copying out of a generated PDF with Unicode fonts. #71
+       - Suppresses output for Circle(), Ellipse(), PieSector(), and PieSectorXY() when the radius is 0. #67
+       - Don't change an object while iterating over it #59 (by thegcat)
+       - fix : bidi bug #56 (by ahorek)
+       - Avoid rdoc stack level too deep (SystemStackError) in gem install. #76
+       - PDF example output option OUTPUT=true added #70
+       - Make the image file path acquisition process extensible #58 (by yui-har)
+
 1.20.1 2019-08-21
        - fix license warning. (by pavel)
        - Removed test resource from distribution target in gemspec.
diff --git a/Gemfile.rails4 b/Gemfile.rails4
deleted file mode 100644
index 53f86c8..0000000
--- a/Gemfile.rails4
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (c) 2011-2017 NAITOH Jun
-# Released under the MIT license
-# http://www.opensource.org/licenses/MIT
-
-source 'https://rubygems.org'
-
-# Specify your gem's dependencies in rbpdf.gemspec
-gemspec
-
-gem "actionpack", "~> 4.2.4"
-if RUBY_VERSION <'2.1' # Ruby 1.9.3 or 2.0
-  gem "nokogiri", "< 1.7.0"
-end
diff --git a/Gemfile.rails4_rmagick b/Gemfile.rails4_rmagick
deleted file mode 100644
index 66e315a..0000000
--- a/Gemfile.rails4_rmagick
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (c) 2011-2017 NAITOH Jun
-# Released under the MIT license
-# http://www.opensource.org/licenses/MIT
-
-source 'https://rubygems.org'
-
-# Specify your gem's dependencies in rbpdf.gemspec
-gemspec
-
-gem "actionpack", "~> 4.2.4"
-if RUBY_VERSION <'2.1' # Ruby 1.9.3 or 2.0
-  gem "nokogiri", "< 1.7.0"
-end
-gem "rmagick"
diff --git a/Gemfile.rails5 b/Gemfile.rails6
similarity index 70%
rename from Gemfile.rails5
rename to Gemfile.rails6
index defc0f5..d2ac350 100644
--- a/Gemfile.rails5
+++ b/Gemfile.rails6
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2017 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -7,4 +7,4 @@ source 'https://rubygems.org'
 # Specify your gem's dependencies in rbpdf.gemspec
 gemspec
 
-gem "actionpack", "~> 5.2.2"
+gem "actionpack", "~> 6.1.7.2"
diff --git a/Gemfile.rails5_mini_magick b/Gemfile.rails6_mini_magick
similarity index 73%
rename from Gemfile.rails5_mini_magick
rename to Gemfile.rails6_mini_magick
index e8d0287..b76ee4c 100644
--- a/Gemfile.rails5_mini_magick
+++ b/Gemfile.rails6_mini_magick
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2019 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -7,5 +7,5 @@ source 'https://rubygems.org'
 # Specify your gem's dependencies in rbpdf.gemspec
 gemspec
 
-gem "actionpack", "~> 5.2.2"
+gem "actionpack", "~> 6.1.7.2"
 gem "mini_magick"
diff --git a/Gemfile.rails5_rmagick b/Gemfile.rails6_rmagick
similarity index 72%
rename from Gemfile.rails5_rmagick
rename to Gemfile.rails6_rmagick
index d8ce8da..71ff400 100644
--- a/Gemfile.rails5_rmagick
+++ b/Gemfile.rails6_rmagick
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2017 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -7,5 +7,5 @@ source 'https://rubygems.org'
 # Specify your gem's dependencies in rbpdf.gemspec
 gemspec
 
-gem "actionpack", "~> 5.2.2"
+gem "actionpack", "~> 6.1.7.2"
 gem "rmagick"
diff --git a/Gemfile.rails3 b/Gemfile.rails7
similarity index 58%
rename from Gemfile.rails3
rename to Gemfile.rails7
index 45c1899..a3ef725 100644
--- a/Gemfile.rails3
+++ b/Gemfile.rails7
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2017 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -7,6 +7,4 @@ source 'https://rubygems.org'
 # Specify your gem's dependencies in rbpdf.gemspec
 gemspec
 
-gem "actionpack", "~> 3.2.22"
-gem "i18n", "~> 0.6.11"
-gem "rack-cache", "~> 1.2.0"
+gem "actionpack", "~> 7.0.4.2"
diff --git a/Gemfile.rails7_mini_magick b/Gemfile.rails7_mini_magick
new file mode 100644
index 0000000..bfe5891
--- /dev/null
+++ b/Gemfile.rails7_mini_magick
@@ -0,0 +1,11 @@
+# Copyright (c) 2011-2023 NAITOH Jun
+# Released under the MIT license
+# http://www.opensource.org/licenses/MIT
+
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in rbpdf.gemspec
+gemspec
+
+gem "actionpack", "~> 7.0.4.2"
+gem "mini_magick"
diff --git a/Gemfile.rails3_rmagick b/Gemfile.rails7_rmagick
similarity index 60%
rename from Gemfile.rails3_rmagick
rename to Gemfile.rails7_rmagick
index 847ce48..6f63eed 100644
--- a/Gemfile.rails3_rmagick
+++ b/Gemfile.rails7_rmagick
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2017 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -7,7 +7,5 @@ source 'https://rubygems.org'
 # Specify your gem's dependencies in rbpdf.gemspec
 gemspec
 
-gem "actionpack", "~> 3.2.22"
-gem "i18n", "~> 0.6.11"
-gem "rack-cache", "~> 1.2.0"
+gem "actionpack", "~> 7.0.4.2"
 gem "rmagick"
diff --git a/README.md b/README.md
index f1c2dd1..7dc6a2d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/naitoh/rbpdf.svg?branch=master)](https://travis-ci.org/naitoh/rbpdf)
+[![Build Status](https://github.com/naitoh/rbpdf/workflows/test/badge.svg)](https://github.com/naitoh/rbpdf/actions)
 
 # RBPDF Template Plugin
 
@@ -59,6 +59,16 @@ RBPDF Japanese Example of simple use in .html.erb:
 %><%==@pdf.output()%>
 ```
 
+PDF example output
+```
+$ OUTPUT=true bundle exec rake test TEST=test/rbpdf_examples_test.rb
+$ ls -1 *.pdf
+example001.pdf
+example002.pdf
+example003.pdf
+:
+```
+
 See the following files for sample of useage:
 
 test_unicode.rbpdf
diff --git a/debian/changelog b/debian/changelog
index 5ce2e52..4b31419 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,9 @@
-ruby-rbpdf (1.20.1-3) UNRELEASED; urgency=medium
+ruby-rbpdf (1.21.0+ds-1) UNRELEASED; urgency=medium
 
   * Update standards version to 4.6.2, no changes needed.
+  * New upstream release.
 
- -- Debian Janitor <janitor@jelmer.uk>  Thu, 05 Jan 2023 04:45:45 -0000
+ -- Debian Janitor <janitor@jelmer.uk>  Sat, 08 Apr 2023 20:23:36 -0000
 
 ruby-rbpdf (1.20.1-2) unstable; urgency=medium
 
diff --git a/debian/patches/0001-rbpdf-font-test-test-font-path-contents-not-exact-lo.patch b/debian/patches/0001-rbpdf-font-test-test-font-path-contents-not-exact-lo.patch
index e8e4333..cb43682 100644
--- a/debian/patches/0001-rbpdf-font-test-test-font-path-contents-not-exact-lo.patch
+++ b/debian/patches/0001-rbpdf-font-test-test-font-path-contents-not-exact-lo.patch
@@ -6,11 +6,11 @@ Subject: rbpdf-font/test: test font path contents, not exact location
  rbpdf-font/test/rbpdf_font_file_test.rb | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)
 
-diff --git a/rbpdf-font/test/rbpdf_font_file_test.rb b/rbpdf-font/test/rbpdf_font_file_test.rb
-index 9593c5a..17a2f10 100644
---- a/rbpdf-font/test/rbpdf_font_file_test.rb
-+++ b/rbpdf-font/test/rbpdf_font_file_test.rb
-@@ -3,9 +3,7 @@ require 'test_helper'
+Index: ruby-rbpdf.git/rbpdf-font/test/rbpdf_font_file_test.rb
+===================================================================
+--- ruby-rbpdf.git.orig/rbpdf-font/test/rbpdf_font_file_test.rb
++++ ruby-rbpdf.git/rbpdf-font/test/rbpdf_font_file_test.rb
+@@ -7,9 +7,7 @@ require 'test_helper'
  class RbpdfFontFileTest < Test::Unit::TestCase
    test "Font path test" do
      font_path = RBPDFFontDescriptor.getfontpath
diff --git a/lib/rbpdf.rb b/lib/rbpdf.rb
index ac78e3b..ff9d776 100755
--- a/lib/rbpdf.rb
+++ b/lib/rbpdf.rb
@@ -49,7 +49,7 @@
 require "rbpdf/version"
 
 require 'htmlentities'
-require 'rbpdf-font' 
+require 'rbpdf-font'
 require 'erb'
 
 begin
@@ -5030,7 +5030,7 @@ class RBPDF
           tmpname = Tempfile.new(File::basename(file), @@k_path_cache)
           tmpname.binmode
           jpeg_quality = @jpeg_quality
-          tmpname.print img.to_blob { self.quality = jpeg_quality }
+          tmpname.print img.to_blob { |image| image.quality = jpeg_quality }
         else
           return false
         end
@@ -6796,9 +6796,12 @@ protected
     # sort glyphs by key
     #ksort(subsetglyphs)
     # add composite glyps to subsetglyphs and remove missing glyphs
+    subsetglyphs_tmp = []
     subsetglyphs.each_with_index {|val, key|
       next if val.nil?
+
       if indexToLoc[key]
+        subsetglyphs_tmp[key] = val
         offset = table['glyf']['offset'] + indexToLoc[key]
         numberOfContours = getSHORT(font, offset); offset += 2
         if numberOfContours < 0  # composite glyph
@@ -6808,7 +6811,7 @@ protected
             glyphIndex = getUSHORT(font, offset); offset += 2
             if subsetglyphs[glyphIndex].nil? and indexToLoc[glyphIndex]
               # add missing glyphs
-              subsetglyphs[glyphIndex] = true
+              subsetglyphs_tmp[glyphIndex] = true
             end
             # skip some bytes by case
             if (flags & 1) != 0
@@ -6827,10 +6830,10 @@ protected
             break if (flags & 32) == 0
           }
         end
-      else
-        subsetglyphs.delete_at(key)
       end
     }
+    subsetglyphs = subsetglyphs_tmp
+
     # build new glyf table with only used glyphs
     glyf = ''
     glyfSize = 0
@@ -7241,11 +7244,19 @@ protected
     out << ' /BaseFont /' + fontname + ''
     out << ' /Name /F' + font['i'].to_s
     out << ' /Encoding /' + font['enc']
-    out << ' /DescendantFonts [' + (@n + 1).to_s + ' 0 R]'
+    out << " /ToUnicode #{@n + 1} 0 R"
+    out << " /DescendantFonts [#{@n + 2} 0 R]"
     out << ' >>'
     out << ' endobj'
     out(out)
 
+    # ToUnicode Object
+    newobj()
+    filter = @compress ? '/Filter /FlateDecode ' : ''
+    stream = @compress ? Zlib::Deflate.deflate(@@cmap_identity_h) : @@cmap_identity_h
+    stream = getrawstream(stream)
+    out("<<#{filter}/Length #{stream.length}>> stream\n#{stream}\nendstream\nendobj")
+
     # CIDFontType2
     # A CIDFont whose glyph descriptions are based on TrueType font technology
     newobj();
@@ -8076,18 +8087,27 @@ protected
   end
 
   #
-  # Format output stream
+  # get raw output stream.
   # @param string :s string to output.
   # @param int :n object reference for encryption mode
   # @access protected
   #
-  def getstream(s, n=0)
+  def getrawstream(s, n=0)
     if n <= 0
       # default to current object
       n = @n
     end
-    s = encrypt_data(n, s)
-    return "stream\n" + s + "\nendstream"
+    encrypt_data(n, s)
+  end
+
+  #
+  # Format output stream
+  # @param string :s string to output.
+  # @param int :n object reference for encryption mode
+  # @access protected
+  #
+  def getstream(s, n=0)
+    "stream\n" + getrawstream(s, n=0) + "\nendstream"
   end
 
   #
@@ -8855,7 +8875,7 @@ public
       dash = style['dash']
       dash_string = ''
       if dash != 0 and dash != ''
-        if dash =~ /^.+,/
+        if dash.is_a?(String) && dash =~ /^.+,/
           tab = dash.split(',')
         else
           tab = [dash]
@@ -9131,6 +9151,8 @@ public
   # [@since 4.9.019 (2010-04-26)]
   #
   def outellipticalarc(xc, yc, rx, ry, xang=0, angs=0, angf=360, pie=false, nc=2)
+    return if rx == 0 && ry == 0
+
     k = @k
     if nc < 2
       nc = 2
@@ -9768,7 +9790,7 @@ public
         end
       when @@k_pdf
         # X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override.
-        if remember.length
+        unless remember.empty?
           last = remember.length - 1
           case remember[last][:num]
           when @@k_rle, @@k_lre, @@k_rlo, @@k_lro
@@ -10176,12 +10198,7 @@ public
         end
       end
       # remove marked characters
-      chardata2.each_with_index do |value, key|
-        if value[:char] == false
-          chardata2.delete_at(key)
-        end
-      end
-      chardata = chardata2
+      chardata = chardata2.reject {|value| value[:char] == false }
       numchars = chardata.size
       chardata2 = nil
       arabicarr = nil
@@ -11024,16 +11041,20 @@ protected
       cssblocks[key] = block.split('{')
     }
     # split groups of selectors (comma-separated list of selectors)
+    cssblocks_tmp = []
     cssblocks.each_with_index { |block, key|
       # index 0 contains the CSS selector, index 1 contains CSS properties
       if block[0].index(',')
         selectors = block[0].split(',')
         selectors.each {|sel|
-          cssblocks.push [sel.strip, block[1]]
+          cssblocks_tmp.push [sel.strip, block[1]]
         }
-        cssblocks.delete_at(key)
+      else
+        cssblocks_tmp.push [block[0], block[1]]
       end
     }
+    cssblocks = cssblocks_tmp
+
     # covert array to selector => properties
     cssdata = {}
     cssblocks.each { |block|
@@ -11312,11 +11333,11 @@ protected
       while html_b =~ /<xre([^\>]*)>(.*?)\n(.*?)<\/pre>/mi
         # preserve newlines on <pre> tag
         html_b = html_b.gsub(/<xre([^\>]*)>(.*?)\n(.*?)<\/pre>/mi) do
-          if ($2 != '') and ($3 != '') 
+          if ($2 != '') and ($3 != '')
             "<xre#{$1}>#{$2}<br />#{$3}</pre>"
-          elsif ($2 == '') and ($3 != '') 
+          elsif ($2 == '') and ($3 != '')
             "<xre#{$1}>#{$3}</pre>"
-          elsif ($2 != '') and ($3 == '') 
+          elsif ($2 != '') and ($3 == '')
             "<xre#{$1}>#{$2}</pre>"
           else
             "<xre#{$1}></pre>"
@@ -12879,7 +12900,7 @@ public
             startlinepage = @page
           end
         end
-      elsif dom[key]['value'].strip.length > 0
+      elsif dom[key]['value'].length > 0
         # print list-item
         if !empty_string(@lispacer)
           SetFont(pfontname, pfontstyle, pfontsize)
@@ -12898,7 +12919,7 @@ public
           end
         end
         # text
-        @htmlvspace = 0
+        @htmlvspace = 0 unless dom[key]['value'].strip.length == 0
         if !@premode and isRTLTextDir()
           # reverse spaces order
           len1 = dom[key]['value'].length
@@ -13331,27 +13352,10 @@ public
         SetLeftMargin(@l_margin + @c_margin)
         SetRightMargin(@r_margin + @c_margin)
 
-        begin
-          if tag['attribute']['src'] =~ /^http/
-            tmpFile = get_image_file(tag['attribute']['src'])
-            img_file = tmpFile.path
-          else
-            img_file = tag['attribute']['src']
-          end
-#        if (type == 'eps') or (type == 'ai')
-#          ImageEps(img_file, xpos, @y, iw, ih, imglink, true, align, '', border, true)
-#        elsif type == 'svg'
-#          ImageSVG(img_file, xpos, @y, iw, ih, imglink, align, '', border, true)
-#        else
-          result_img = Image(img_file, xpos, @y, iw, ih, '', imglink, align, false, 300, '', false, false, border, false, false, true)
-#        end
-        rescue => err
-          logger.error "pdf: Image: error: #{err.message}"
-          result_img = false
-        ensure
-          # remove temp files
-          tmpFile.close(true) unless tmpFile.nil?
-        end
+        result_img =
+          proc_image_file(tag['attribute']['src']) do |img_file|
+            Image(img_file, xpos, @y, iw, ih, '', imglink, align, false, 300, '', false, false, border, false, false, true)
+          end
 
         if result_img or ih != 0
           case align
@@ -13487,6 +13491,25 @@ public
   end
   protected :openHTMLTagHandler
 
+  def proc_image_file(src, &block)
+    tmpFile = nil
+    img_file =
+      if src =~ /^http/
+        tmpFile = get_image_file(src)
+        tmpFile.path
+      else
+        src
+      end
+    yield img_file
+  rescue => err
+    logger.error "pdf: Image: error: #{err.message}"
+    false
+  ensure
+    # remove temp files
+    tmpFile.close(true) if tmpFile
+  end
+  private :proc_image_file
+
   #
   # Process closing tags.
   # [@param array :dom] html dom array
diff --git a/lib/rbpdf/version.rb b/lib/rbpdf/version.rb
index a08d16e..5817078 100644
--- a/lib/rbpdf/version.rb
+++ b/lib/rbpdf/version.rb
@@ -1,7 +1,7 @@
-# Copyright (c) 2011-2019 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
 module Rbpdf
-  VERSION = "1.20.1"
+  VERSION = "1.21.0"
 end
diff --git a/lib/unicode_data.rb b/lib/unicode_data.rb
index bdfa961..4b6c03d 100644
--- a/lib/unicode_data.rb
+++ b/lib/unicode_data.rb
@@ -18326,6 +18326,35 @@ module Unicode_data
 382=>158   # zcaron2
 }
 
+#
+# ToUnicode map for Identity-H
+#   CMapType : 1 = Convert to CID, 2 = Convert to Unicode
+#
+@@cmap_identity_h = <<-CMap
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CMapName /Adobe-Identity-UCS def
+/CMapType 2 def
+/CIDSystemInfo <<
+  /Registry (Adobe)
+  /Ordering (UCS)
+  /Supplement 0
+>> def
+/WMode 0 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+
+1 beginbfrange
+<0000> <ffff> <0000>
+endbfrange
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+CMap
+
 end
 
 #============================================================+
diff --git a/rbpdf.gemspec b/rbpdf.gemspec
index 3d8ed0d..45a5f9b 100644
--- a/rbpdf.gemspec
+++ b/rbpdf.gemspec
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (c) 2011-2019 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
                        ["Rakefile", "rbpdf.gemspec", "Gemfile",
                         "CHANGELOG", "test_unicode.rbpdf", "README.md", "LICENSE.TXT", "MIT-LICENSE",
                         "utf8test.txt", "logo_example.png" ]
-  spec.rdoc_options  += [ '--exclude', 'lib/fonts/',
+  spec.rdoc_options  += [ '--exclude', 'lib/core/mini_magick.rb',
                           '--exclude', 'lib/htmlcolors.rb',
                           '--exclude', 'lib/unicode_data.rb' ]
 
@@ -31,23 +31,12 @@ Gem::Specification.new do |spec|
   spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
   spec.require_paths = ["lib"]
 
-  if RUBY_VERSION == "1.8.7"
-    spec.add_runtime_dependency "htmlentities", "= 4.3.1"
-  else
-    spec.add_runtime_dependency "htmlentities"
-  end
+  spec.add_runtime_dependency "htmlentities"
   spec.add_runtime_dependency "rbpdf-font", "~> 1.19.0"
-  spec.required_ruby_version = '>= 1.8.7'
+  spec.required_ruby_version = '>= 2.3.0'
 
   spec.add_development_dependency "bundler"
-  if RUBY_VERSION <'1.9.3' # Ruby 1.8.7 or 1.9.2
-    spec.add_development_dependency "rake", "<= 10.5"
-  else
-    spec.add_development_dependency "rake"
-  end
-  if RUBY_VERSION <'1.9' # Ruby 1.8.7
-    spec.add_development_dependency "test-unit", "<= 3.1.5"
-  else
-    spec.add_development_dependency "test-unit", "~> 3.2"
-  end
+  spec.add_development_dependency "rake"
+  spec.add_development_dependency "test-unit"
+  spec.add_development_dependency "webrick"
 end
diff --git a/test/rbpdf_annotation_test.rb b/test/rbpdf_annotation_test.rb
new file mode 100644
index 0000000..8c5f75f
--- /dev/null
+++ b/test/rbpdf_annotation_test.rb
@@ -0,0 +1,66 @@
+# Copyright (c) 2011-2023 NAITOH Jun
+# Released under the MIT license
+# http://www.opensource.org/licenses/MIT
+
+require 'test_helper'
+
+class RbpdfTest < Test::Unit::TestCase
+  test "Annotation Basic Test" do
+    pdf = RBPDF.new
+
+    x = pdf.get_x
+    y = pdf.get_y
+    w = 30, h = 40
+    txt = "Text annotation \ntest"
+    opt = {'Subtype'=>'Text', 'Name' => 'Comment', 'T' => 'title example', 'Subj' => 'example', 'C' => [255, 255, 0]}
+    annot_obj_id_org = pdf.instance_variable_get('@annot_obj_id')
+    pdf.annotation('', '', w, h, txt, opt)
+    page_annots = pdf.instance_variable_get('@page_annots')
+
+    assert_equal 2,   page_annots.length
+    assert_equal nil, page_annots[0]
+    assert_equal 1,   page_annots[1].length
+    assert_equal 0,   page_annots[1][0]['numspaces']
+    assert_equal x,   page_annots[1][0]['x']
+    assert_equal y,   page_annots[1][0]['y']
+    assert_equal w,   page_annots[1][0]['w']
+    assert_equal h,   page_annots[1][0]['h']
+    assert_equal opt, page_annots[1][0]['opt']
+    assert_equal txt, page_annots[1][0]['txt']
+
+    annot_obj_id = pdf.instance_variable_get('@annot_obj_id')
+    assert_equal annot_obj_id_org + 1, annot_obj_id
+  end
+
+  test "Annotation FileAttachment Test" do
+    pdf = RBPDF.new
+
+    TEST_FILE_NAME = 'utf8test.txt'
+    TEST_FILE_NAME_PATH = 'example/rails/public/' + TEST_FILE_NAME
+
+    x = 80, y = 25, w = 20, h = 30
+    txt = 'text file'
+    opt = {'Subtype'=>'FileAttachment', 'Name' => 'PushPin', 'FS' => TEST_FILE_NAME_PATH}
+    annot_obj_id_org = pdf.instance_variable_get('@annot_obj_id')
+    embedded_start_obj_id = pdf.instance_variable_get('@embedded_start_obj_id')
+
+    pdf.annotation(x, y, w, h, txt, opt)
+    page_annots = pdf.instance_variable_get('@page_annots')
+
+    assert_equal 2,   page_annots.length
+    assert_equal nil, page_annots[0]
+    assert_equal 1,   page_annots[1].length
+    assert_equal 0,   page_annots[1][0]['numspaces']
+    assert_equal x,   page_annots[1][0]['x']
+    assert_equal y,   page_annots[1][0]['y']
+    assert_equal w,   page_annots[1][0]['w']
+    assert_equal h,   page_annots[1][0]['h']
+    assert_equal opt, page_annots[1][0]['opt']
+    assert_equal txt, page_annots[1][0]['txt']
+
+    annot_obj_id = pdf.instance_variable_get('@annot_obj_id')
+    assert_equal annot_obj_id_org + 1, annot_obj_id
+    embeddedfiles = pdf.instance_variable_get('@embeddedfiles')
+    assert_equal({TEST_FILE_NAME=>{"file"=>TEST_FILE_NAME_PATH, "n"=>embedded_start_obj_id}}, embeddedfiles)
+  end
+end
diff --git a/test/rbpdf_bidi_test.rb b/test/rbpdf_bidi_test.rb
index e6c6c4d..5ef1be1 100644
--- a/test/rbpdf_bidi_test.rb
+++ b/test/rbpdf_bidi_test.rb
@@ -152,6 +152,10 @@ class RbpdfTest < Test::Unit::TestCase
     assert_equal [0x61, 0x62, 0x63, 0x5ea, 0x5d9, 0x5e8, 0x5d1, 0x5e2], ary_str
     ary_str = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_str_2 + ascii_str), utf8_str_2 + ascii_str, 'R')
     assert_equal [0x61, 0x62, 0x63, 0x5ea, 0x5d9, 0x5e8, 0x5d1, 0x5e2], ary_str
+
+    utf8_str_3 = "(425,1\xE2\x80\xAC hours)"
+    ary_str = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_str_3), utf8_str_3, 'L')
+    assert_equal [0x28, 0x34, 0x32, 0x35, 0x2C, 0x31, 0x20, 0x68, 0x6F, 0x75, 0x72, 0x73, 0x29], ary_str
   end
 
   test "Bidi ascii space test" do
diff --git a/test/rbpdf_content_test.rb b/test/rbpdf_content_test.rb
index 83cea12..57129eb 100644
--- a/test/rbpdf_content_test.rb
+++ b/test/rbpdf_content_test.rb
@@ -118,6 +118,21 @@ class RbpdfPageTest < Test::Unit::TestCase
     assert_equal 'S'                                          , content[14]
   end
 
+  test "circle content radius=0 (no circle output)" do
+    pdf = MYPDF.new
+
+    pdf.set_print_header(false)
+    pdf.add_page
+    pdf.circle(100, 200, 0)
+
+    content = []
+    contents = pdf.getPageBuffer(1)
+    contents.each_line {|line| content.push line.chomp }
+
+    assert_equal 5, content.length
+    assert_equal 'S'                                          , content[4]
+  end
+
   test "write content test" do
     pdf = MYPDF.new
     pdf.add_page()
diff --git a/test/rbpdf_examples_test.rb b/test/rbpdf_examples_test.rb
index 4048587..db55317 100644
--- a/test/rbpdf_examples_test.rb
+++ b/test/rbpdf_examples_test.rb
@@ -79,5 +79,7 @@ class RbpdfTest < Test::Unit::TestCase
 
     assert_not_equal 0, content.length
     assert_equal '%PDF-1.7', content[0]
+
+    File.open("example#{data}.pdf", mode = "w"){|f| f.write(contents) } if ENV['OUTPUT']
   end
 end
diff --git a/test/rbpdf_html_test.rb b/test/rbpdf_html_test.rb
index ef9f157..2d3e094 100644
--- a/test/rbpdf_html_test.rb
+++ b/test/rbpdf_html_test.rb
@@ -582,6 +582,29 @@ class RbpdfHtmlTest < Test::Unit::TestCase
     assert_equal 'a\\\\bc', pdf_text
   end
 
+  test "write_html <ol><li> tag test" do
+    pdf = MYPDF.new
+    pdf.set_print_header(false)
+    pdf.add_page()
+
+    htmlcontent = '<ol><li>text A</li><li>text B</li></ol>'
+    pdf.write_html(htmlcontent, true, 0, true, 0)
+    pdf_text = pdf.get_html_text(1)
+    assert_equal '1.text A2.text B', pdf_text
+  end
+
+  test "write_html <ol><li> tag with image tag test" do
+    pdf = MYPDF.new
+    pdf.set_print_header(false)
+    pdf.add_page()
+
+    img_file = File.join(File.dirname(__FILE__), 'logo_rbpdf_8bit.png')
+    htmlcontent = "<ol><img src='#{img_file}' width='30' height='30' border='0' /><li>text A</li><li>text B</li></ol>"
+    pdf.write_html(htmlcontent, true, 0, true, 0)
+    pdf_text = pdf.get_html_text(1)
+    assert_equal ' 1.text A2.text B', pdf_text # A space is placed before the img tag.
+  end
+
   test "write_html Character Entities test" do
     pdf = MYPDF.new
     pdf.set_print_header(false)
diff --git a/test/rbpdf_htmlcell_test.rb b/test/rbpdf_htmlcell_test.rb
index 38a6ddd..a8c4221 100644
--- a/test/rbpdf_htmlcell_test.rb
+++ b/test/rbpdf_htmlcell_test.rb
@@ -12,7 +12,11 @@ class RbpdfTest < Test::Unit::TestCase
                                     :border => 0,      :pno => 2, :no => 2},
     'Page Break border'         => {:html => '<p>foo</p>', :margin => 30,
                                     :border => 'LRBT', :pno => 2, :no => 2},
-    'pre tag y position'        => {:html => "<p>test 0</p>\n <pre>test 1\ntest 2\ntest 3</pre>\n <p>test 10</p>", :line => 7,
+    'Y position when there is no space between pre and p tags' =>
+                                   {:html => "<p>test 0</p>\n <pre>test 1\ntest 2\ntest 3</pre><p>test 10</p>", :line => 7,
+                                    :border => 0,      :pno => 1, :no => 1},
+    'Y position when there is a space between pre and p tags' =>
+                                   {:html => "<p>test 0</p>\n <pre>test 1\ntest 2\ntest 3</pre>\n <p>test 10</p>", :line => 7,
                                     :border => 0,      :pno => 1, :no => 1},
   }
 
diff --git a/test/rbpdf_image_rmagick_test.rb b/test/rbpdf_image_rmagick_test.rb
index 32f6956..a26d091 100644
--- a/test/rbpdf_image_rmagick_test.rb
+++ b/test/rbpdf_image_rmagick_test.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2017 NAITOH Jun
+# Copyright (c) 2011-2023 NAITOH Jun
 # Released under the MIT license
 # http://www.opensource.org/licenses/MIT
 
@@ -17,9 +17,7 @@ class RbpdfTest < Test::Unit::TestCase
 
   data(images)
   test "image getimagesize test" do |data|
-    if data[:use_magick] and (!Object.const_defined?(:Magick) and !Object.const_defined?(:MiniMagick))
-      return
-    end
+    return if data[:use_magick] and !Object.const_defined?(:Magick) and !Object.const_defined?(:MiniMagick)
 
     pdf = RBPDF.new
     pdf.add_page
@@ -43,7 +41,8 @@ class RbpdfTest < Test::Unit::TestCase
 
   data(images)
   test "imageToPNG delete test" do |data|
-    return unless Object.const_defined?(:Magick)
+    return unless Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
+
     pdf = RBPDF.new
     pdf.add_page
     img_file = File.join(File.dirname(__FILE__), data[:file])
@@ -60,6 +59,7 @@ class RbpdfTest < Test::Unit::TestCase
 
   test "Magick::ImageList delete GIF alpha channel test" do
     return unless Object.const_defined?(:Magick)
+
     pdf = RBPDF.new
     pdf.add_page
     img_file = File.join(File.dirname(__FILE__), 'logo_rbpdf_8bit_alpha.gif')
@@ -73,7 +73,7 @@ class RbpdfTest < Test::Unit::TestCase
   end
 
   test "image_alpha_mask DeviceGray test" do
-    return unless Object.const_defined?(:Magick)
+    return unless Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
 
     pdf = RBPDF.new
     pdf.add_page
@@ -100,7 +100,7 @@ class RbpdfTest < Test::Unit::TestCase
 
   data(images)
   test "ImagePngAlpha test" do |data|
-    return unless Object.const_defined?(:Magick)
+    return unless Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
 
     pdf = RBPDF.new
     pdf.add_page
@@ -121,9 +121,7 @@ class RbpdfTest < Test::Unit::TestCase
 
   data(images)
   test "Image test" do |data|
-    if data[:use_magick] and !Object.const_defined?(:Magick)
-      return
-    end
+    return if data[:use_magick] and !Object.const_defined?(:Magick) and !Object.const_defined?(:MiniMagick)
 
     pdf = RBPDF.new
     pdf.add_page
@@ -134,7 +132,7 @@ class RbpdfTest < Test::Unit::TestCase
   end
 
   test "HTML Image test" do
-    return unless Object.const_defined?(:Magick)
+    return unless Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
 
     images = {
       'png_test_alpha.png'        => 40.11,
diff --git a/test/rbpdf_image_test.rb b/test/rbpdf_image_test.rb
index 5f3dd9d..89754c0 100644
--- a/test/rbpdf_image_test.rb
+++ b/test/rbpdf_image_test.rb
@@ -138,8 +138,22 @@ class RbpdfTest < Test::Unit::TestCase
     assert_equal 1, result_img
   end
 
-  test "HTML Image test without RMagick" do
-    return if Object.const_defined?(:Magick)
+  test "Image proc_image_file test" do
+    pdf = RBPDF.new
+    pdf.add_page
+    img_file = File.join(File.dirname(__FILE__), '..', 'logo_example.png')
+
+    result_img = pdf.send(:proc_image_file, img_file) do |f|
+      pdf.image(f, 50, 0, 0, '', '', '', '', false, 300, '', true)
+    end
+
+    no = pdf.get_num_pages
+    assert_equal 1, no
+    assert_equal 1, result_img
+  end
+
+  test "HTML Image test without RMagick or MiniMagick" do
+    return if Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
 
     # no use
     # utf8_japanese_aiueo_str  = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a"
@@ -155,8 +169,8 @@ class RbpdfTest < Test::Unit::TestCase
       'ng.png'                    => 9.42
     }
 
-    pdf = RBPDF.new
     images.each {|image, h|
+      pdf = RBPDF.new
       pdf.add_page
       img_file = File.join(File.dirname(__FILE__), image)
       htmlcontent = '<img src="'+ img_file + '"/>'
@@ -171,4 +185,74 @@ class RbpdfTest < Test::Unit::TestCase
       assert_equal '[' + image + ']:' + (y_org + h).round(2).to_s, '[' + image + ']:' + y.round(2).to_s
     }
   end
+
+  test "HTML Image vertically align image in line test without RMagick or MiniMagick" do
+    return if Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
+
+    image_sizes = [
+      # writeHTML() : not !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case
+      {'width' => 10,  'height' => 20, 'cell' => false},
+      {'width' => 100, 'height' => 100, 'cell' => false},
+      {'width' => 100, 'height' => 100, 'cell' => true},
+      {'width' => 500, 'height' => 100, 'cell' => false},
+      # writeHTML() : !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case
+      {'width' => 600, 'height' => 10, 'cell' => false},
+      {'width' => 600, 'height' => 10, 'cell' => true},
+      {'width' => 600, 'height' => 13, 'cell' => false},
+    ]
+
+    img_file = File.join(File.dirname(__FILE__), 'logo_rbpdf_8bit.png')
+    image_sizes.each {|size|
+      pdf = RBPDF.new
+      pdf.add_page
+      htmlcontent = "<body><img src='#{img_file}' width='#{size['width']}' height='#{size['height']}'/></body>"
+
+      x_org = pdf.get_x
+      y_org = pdf.get_y
+
+      imgw = pdf.getHTMLUnitToUnits(size['width'])
+      imgh = pdf.getHTMLUnitToUnits(size['height'])
+      pdf.write_html(htmlcontent, true, 0, true, size['cell'])
+      x = pdf.get_x
+      y = pdf.get_y
+      w = pdf.get_page_width
+      r_margin = pdf.instance_variable_get("@r_margin")
+      lasth = pdf.get_font_size * pdf.get_cell_height_ratio
+      if x + imgw > w - r_margin
+        result = lasth * 2
+      else
+        result = lasth + imgh - pdf.get_font_size_pt / pdf.get_scale_factor
+      end
+
+      test_name = "[ width: #{size['width']} height: #{size['height']} cell: #{size['cell']}]:"
+      assert_equal test_name + x_org.to_s, test_name + x.to_s
+      assert_equal test_name + (y_org + result).round(2).to_s, test_name + y.round(2).to_s
+    }
+  end
+
+  test "HTML Image vertically align image in line and shift the annotations and links test without RMagick or MiniMagick" do
+    return if Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick)
+
+    img_file = File.join(File.dirname(__FILE__), 'logo_rbpdf_8bit.png')
+    width = 300
+    height = 600
+    pdf = RBPDF.new
+    pdf.add_page
+    htmlcontent = "<body><img src='#{img_file}' width='#{width}' height='#{height}'/><img src='#{img_file}' width='#{width}' height='#{height}'/></body>"
+    x_org = pdf.get_x
+    y_org = pdf.get_y
+    imgh = pdf.getHTMLUnitToUnits(height)
+
+    opt = {'Subtype'=>'Text', 'Name' => 'Comment', 'T' => 'title example', 'Subj' => 'example', 'C' => [255, 255, 0]}
+    pdf.annotation('', '', 20, 30, 'Text annotation', opt)
+
+    pdf.write_html(htmlcontent, true, 0, true, false)
+    x = pdf.get_x
+    y = pdf.get_y
+    lasth = pdf.get_font_size * pdf.get_cell_height_ratio
+    result = lasth + imgh - pdf.get_font_size_pt / pdf.get_scale_factor
+
+    assert_equal x_org.to_s, x.to_s
+    assert_equal (y_org + result).round(2), y.round(2)
+  end
 end

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/core/mini_magick.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/core/rmagick.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/htmlcolors.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/rbpdf.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/rbpdf/version.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.21.0/lib/unicode_data.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/specifications/rbpdf-1.21.0.gemspec

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/core/mini_magick.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/core/rmagick.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/htmlcolors.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/rbpdf.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/rbpdf/version.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rbpdf-1.20.1/lib/unicode_data.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/specifications/rbpdf-1.20.1.gemspec

No differences were encountered between the control files of package ruby-rbpdf

No differences were encountered between the control files of package ruby-rbpdf-font

More details

Full run details