diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2022-08-22 23:55:07 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-22 23:55:07 -0600 |
| commit | b23e24937eb0d75eabdf17d91a59e9acc871e4b7 (patch) | |
| tree | f051522e4a95cab735d37103094b16b8b5a3516d /lib | |
| parent | 0abb4a012c1750081330fda1395526246093f100 (diff) | |
share image info cache between primary and scratch documents to avoid decoding same image more than once (PR #2321)
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/asciidoctor/pdf/converter.rb | 2 | ||||
| -rw-r--r-- | lib/asciidoctor/pdf/ext/prawn/images.rb | 27 |
2 files changed, 29 insertions, 0 deletions
diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index 576c8682..f00441f0 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -432,6 +432,7 @@ module Asciidoctor else @optimize = nil end + image_info_cache # allocate_scratch_prototype calls create_scrate_prototype to set up the scratch prototype # scratch calls init_scratch on a copy of the prototype to instantiate a scratch document # push_scratch and pop_scratch make changes to the document catalog and attributes transactional @@ -5212,6 +5213,7 @@ module Asciidoctor # NOTE: prepare scratch document to use page margin from recto side (which has same width as verso side) set_page_margin page_margin_recto end + @image_info_cache = originator.instance_variable_get :@image_info_cache @scratch_prototype = originator.instance_variable_get :@scratch_prototype @tmp_files = originator.instance_variable_get :@tmp_files text_formatter.scratch = true diff --git a/lib/asciidoctor/pdf/ext/prawn/images.rb b/lib/asciidoctor/pdf/ext/prawn/images.rb index 7f85d431..414ae4e9 100644 --- a/lib/asciidoctor/pdf/ext/prawn/images.rb +++ b/lib/asciidoctor/pdf/ext/prawn/images.rb @@ -33,9 +33,36 @@ module Asciidoctor end end + # Override built-in method to cache info separately from obj. + def build_image_object file + if ::File === file + cache_key = ((::File.absolute_path? (file_path = file.path)) ? file_path : (File.absolute_path file_path)).to_sym + info = image_info_cache[cache_key] + end + unless info + image_content = verify_and_read_image file + if cache_key || !(info = image_info_cache[(cache_key = ::Digest::SHA1.hexdigest image_content)]) + # build the image object + info = (::Prawn.image_handler.find image_content).new image_content + renderer.min_version info.min_pdf_version if info.respond_to? :min_pdf_version + image_info_cache[cache_key] = info + end + end + # reuse image if it has already been embedded + unless (image_obj = image_registry[cache_key]) + # add the image to the PDF then register it in case we see it again + image_registry[cache_key] = image_obj = info.build_pdf_object self + end + [image_obj, info] + end + def recommend_prawn_gmagick? err, image_format ::Prawn::Errors::UnsupportedImageType === err && !(defined? ::GMagick::Image) && ((err.message.include? 'PNG') || (%w(jpg png).none? image_format)) end + + def image_info_cache + @image_info_cache ||= {} + end end ::Prawn::Document.extensions << Images |
