rmagick 4.2.6 → 5.5.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/ImageMagick6/devcontainer.json +1 -1
  3. data/.devcontainer/{ImageMagick7/devcontainer.json → devcontainer.json} +2 -2
  4. data/.devcontainer/setup-user.sh +1 -1
  5. data/.editorconfig +1 -1
  6. data/.github/workflows/ci.yml +87 -9
  7. data/.gitignore +4 -0
  8. data/.rubocop_todo.yml +16 -9
  9. data/.yardopts +1 -1
  10. data/CHANGELOG.md +130 -0
  11. data/Gemfile +20 -0
  12. data/README.md +10 -17
  13. data/Rakefile +63 -80
  14. data/before_install_linux.sh +3 -3
  15. data/before_install_osx.sh +6 -5
  16. data/ext/RMagick/extconf.rb +112 -52
  17. data/ext/RMagick/{rmagick.c → rmagick.cpp} +19 -22
  18. data/ext/RMagick/rmagick.h +88 -59
  19. data/ext/RMagick/rmagick_gvl.h +224 -0
  20. data/ext/RMagick/{rmdraw.c → rmdraw.cpp} +170 -159
  21. data/ext/RMagick/{rmenum.c → rmenum.cpp} +69 -50
  22. data/ext/RMagick/{rmfill.c → rmfill.cpp} +85 -24
  23. data/ext/RMagick/{rmilist.c → rmilist.cpp} +191 -93
  24. data/ext/RMagick/{rmimage.c → rmimage.cpp} +1543 -989
  25. data/ext/RMagick/{rminfo.c → rminfo.cpp} +140 -152
  26. data/ext/RMagick/{rmkinfo.c → rmkinfo.cpp} +46 -34
  27. data/ext/RMagick/rmmain.cpp +1923 -0
  28. data/ext/RMagick/{rmmontage.c → rmmontage.cpp} +50 -29
  29. data/ext/RMagick/{rmpixel.c → rmpixel.cpp} +108 -83
  30. data/ext/RMagick/{rmstruct.c → rmstruct.cpp} +6 -6
  31. data/ext/RMagick/{rmutil.c → rmutil.cpp} +62 -161
  32. data/lib/rmagick/version.rb +3 -1
  33. data/lib/rmagick.rb +2 -0
  34. data/lib/rmagick_internal.rb +76 -110
  35. data/lib/rvg/embellishable.rb +6 -2
  36. data/lib/rvg/misc.rb +7 -7
  37. data/lib/rvg/rvg.rb +2 -0
  38. data/lib/rvg/stretchable.rb +2 -2
  39. data/lib/rvg/transformable.rb +1 -1
  40. data/rmagick.gemspec +4 -13
  41. data/sig/rmagick/_draw_common_methods.rbs +64 -0
  42. data/sig/rmagick/_image_common_methods.rbs +389 -0
  43. data/sig/rmagick/draw.rbs +38 -0
  44. data/sig/rmagick/draw_attribute.rbs +28 -0
  45. data/sig/rmagick/enum.rbs +814 -0
  46. data/sig/rmagick/error.rbs +11 -0
  47. data/sig/rmagick/fill.rbs +21 -0
  48. data/sig/rmagick/geometry.rbs +14 -0
  49. data/sig/rmagick/image.rbs +194 -0
  50. data/sig/rmagick/image_list.rbs +181 -0
  51. data/sig/rmagick/iptc.rbs +101 -0
  52. data/sig/rmagick/kernel_info.rbs +12 -0
  53. data/sig/rmagick/optional_method_arguments.rbs +10 -0
  54. data/sig/rmagick/pixel.rbs +46 -0
  55. data/sig/rmagick/struct.rbs +90 -0
  56. data/sig/rmagick.rbs +43 -0
  57. data/sig/rvg/clippath.rbs +34 -0
  58. data/sig/rvg/container.rbs +78 -0
  59. data/sig/rvg/deep_equal.rbs +48 -0
  60. data/sig/rvg/describable.rbs +30 -0
  61. data/sig/rvg/embellishable.rbs +226 -0
  62. data/sig/rvg/misc.rbs +145 -0
  63. data/sig/rvg/paint.rbs +55 -0
  64. data/sig/rvg/pathdata.rbs +77 -0
  65. data/sig/rvg/rvg.rbs +125 -0
  66. data/sig/rvg/stretchable.rbs +56 -0
  67. data/sig/rvg/stylable.rbs +66 -0
  68. data/sig/rvg/text.rbs +118 -0
  69. data/sig/rvg/transformable.rbs +59 -0
  70. data/sig/rvg/units.rbs +33 -0
  71. metadata +59 -129
  72. data/.codeclimate.yml +0 -63
  73. data/deprecated/RMagick.rb +0 -6
  74. data/ext/RMagick/rmmain.c +0 -1951
data/Rakefile CHANGED
@@ -63,26 +63,13 @@ end
63
63
  desc 'Release'
64
64
  task release: %i[assert_clean_repo push_and_tag]
65
65
 
66
- desc 'Release and build the legacy way'
67
- task legacy_release: ['legacy:README.html', 'legacy:extconf', 'legacy:doc', 'legacy:manifest', 'release']
66
+ namespace :website do
67
+ PATH_TO_LOCAL_WEBSITE_REPOSITORY = File.expand_path('../rmagick.github.io')
68
68
 
69
- namespace :legacy do
70
- require 'find'
71
-
72
- task :redcloth do
73
- require 'redcloth'
74
- end
75
-
76
- README = 'README.html'
77
- MANIFEST = 'ext/RMagick/MANIFEST'
78
-
79
- # Change the version number placeholders in a file.
80
- # Returns an array of lines from the file.
81
- def reversion(name)
69
+ def replace_reversion(lines)
82
70
  now = Time.new
83
71
  now = now.strftime('%m/%d/%y')
84
72
 
85
- lines = File.readlines name
86
73
  lines.each do |line|
87
74
  line.gsub!(/0\.0\.0/, Magick::VERSION)
88
75
  line.gsub!(%r{YY/MM/DD}, now)
@@ -90,87 +77,83 @@ namespace :legacy do
90
77
  lines
91
78
  end
92
79
 
93
- # Rewrite a file containing embedded version number placeholders.
94
- def reversion_file(name)
95
- lines = reversion(name)
96
- tmp_name = name + '_tmp'
97
- mv name, tmp_name
98
- begin
99
- File.open(name, 'w') { |f| lines.each { |line| f.write line } }
100
- rescue StandardError
101
- mv tmp_name, name
102
- ensure
103
- rm tmp_name
104
- end
105
- end
106
-
107
- desc 'Update version in extconf'
108
- task :extconf do
109
- reversion_file 'ext/RMagick/extconf.rb'
80
+ def update_html(input_dir, output_dir, file_name)
81
+ lines = File.readlines(File.join(input_dir, file_name))
82
+ lines = replace_reversion(lines)
83
+ File.open(File.join(output_dir, file_name), 'w') { |f| lines.each { |line| f.write line } }
110
84
  end
111
85
 
112
- desc 'Build README.txt from README.textile using RedCloth'
113
- task 'README.txt' => [:redcloth] do
114
- reversion_file 'README.textile'
115
- body = File.readlines 'README.textile'
116
- body = RedCloth.new(body.join).to_html + "\n"
117
- File.open('README.txt', 'w') { |f| f.write body }
118
- end
119
-
120
- desc 'Build README.html from README.txt'
121
- task README => 'README.txt' do
122
- puts "writing #{README}"
123
- File.open(README, 'w') do |html|
124
- html.write <<~END_HTML_HEAD
125
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
126
- <html>
86
+ ENTITY = {
87
+ '&' => '&amp;',
88
+ '>' => '&gt;',
89
+ '<' => '&lt;'
90
+ }.freeze
91
+
92
+ def file_to_html(input_dir, input_file_name, output_dir, output_file_name)
93
+ File.open(File.join(input_dir, input_file_name)) do |src|
94
+ File.open(File.join(output_dir, output_file_name), 'w') do |dest|
95
+ dest.puts <<~END_EXHTMLHEAD
96
+ <!DOCTYPE public PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
97
+ <html xmlns="http://www.w3.org/1999/xhtml">
127
98
  <head>
128
- <title>RMagick #{Magick::VERSION} README</title>
129
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
130
- <meta name="GENERATOR" content="RedCloth">
99
+ <meta name="generator" content="ex2html.rb" />
100
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
101
+ <link rel="stylesheet" type="text/css" href="css/popup.css" />
102
+ <title>RMagick example: #{input_file_name}</title>
131
103
  </head>
132
104
  <body>
133
- END_HTML_HEAD
134
- html.write File.readlines('README.txt')
135
- html.write <<~END_HTML_TAIL
105
+ <h1>#{input_file_name}</h1>
106
+ <div class="bodybox">
107
+ <div class="bodyfloat">
108
+ <pre>
109
+ END_EXHTMLHEAD
110
+
111
+ src.each do |line|
112
+ line.gsub!(/[&><]/) { |s| ENTITY[s] }
113
+ dest.puts(line)
114
+ end
115
+
116
+ dest.puts <<~END_EXHTMLTAIL
117
+ </pre>
118
+ </div>
119
+ </div>
120
+ <div id="close"><a href="javascript:window.close();">Close window</a></div>
136
121
  </body>
137
- </html>
138
- END_HTML_TAIL
122
+ </html>
123
+ END_EXHTMLTAIL
124
+ end
139
125
  end
140
126
  end
141
127
 
142
- desc 'Update versions in html files'
143
- task :doc do
144
- Dir.chdir('doc') do
145
- FileList['*.html'].each { |d| reversion_file(d) }
128
+ desc 'Update RMagick website'
129
+ task :update do
130
+ unless File.exist?(PATH_TO_LOCAL_WEBSITE_REPOSITORY)
131
+ puts "Please clone the rmagick.github.io repository to #{PATH_TO_LOCAL_WEBSITE_REPOSITORY}"
132
+ exit 1
146
133
  end
147
- end
148
-
149
- # Remove files we don't want in the tarball.
150
- # Ensure files are not executable. (ref: bug #10080)
151
- desc "Remove files we don't want in the .gem; ensure files are not executable"
152
- task :fix_files do
153
- rm 'README.txt', verbose: true
154
- chmod 0o644, FileList['doc/*.html', 'doc/ex/*.rb', 'doc/ex/images/*', 'examples/*.rb']
155
- end
156
134
 
157
- desc 'Build manifest'
158
- task :manifest do
159
- now = Time.new
160
- now = now.strftime('%H:%M:%S %m/%d/%y')
161
- puts "generating #{MANIFEST}"
135
+ Dir.glob('doc/*.html') do |file|
136
+ update_html('doc', PATH_TO_LOCAL_WEBSITE_REPOSITORY, File.basename(file))
137
+ end
162
138
 
163
- File.open(MANIFEST, 'w') do |f|
164
- f.puts "MANIFEST for #{Magick::VERSION} - #{now}\n\n"
165
- Find.find('.') do |name|
166
- next if File.directory? name
139
+ Dir.glob('doc/ex/*.rb') do |file|
140
+ file_name = File.basename(file)
141
+ file_to_html('doc/ex', file_name, PATH_TO_LOCAL_WEBSITE_REPOSITORY, "#{file_name}.html")
142
+ end
143
+ end
144
+ end
167
145
 
168
- f.puts name[2..-1] # remove leading "./"
169
- end
146
+ namespace :rbs do
147
+ desc 'Validate RBS definitions'
148
+ task :validate do
149
+ all_sigs = Dir.glob('sig').map { |dir| "-I #{dir}" }.join(' ')
150
+ sh("bundle exec rbs #{all_sigs} validate") do |ok, _|
151
+ abort('one or more rbs validate failed') unless ok
170
152
  end
171
153
  end
172
154
  end
173
155
 
156
+ require 'bundler/gem_tasks'
174
157
  require 'rake/extensiontask'
175
158
  require 'rspec/core/rake_task'
176
159
  RSpec::Core::RakeTask.new(:spec)
@@ -2,7 +2,7 @@
2
2
 
3
3
  set -euox pipefail
4
4
 
5
- gem install bundler
5
+ gem install bundler -v 2.3.26 # Bundler 2.4.x has dropped support for Ruby 2.3
6
6
 
7
7
  if [ -v STYLE_CHECKS ]; then
8
8
  set +ux
@@ -24,7 +24,7 @@ sudo apt-get autoremove -y imagemagick* libmagick* --purge
24
24
  # install build tools, ImageMagick delegates
25
25
  sudo apt-get install -y build-essential libx11-dev libxext-dev zlib1g-dev \
26
26
  liblcms2-dev libpng-dev libjpeg-dev libfreetype6-dev libxml2-dev \
27
- libtiff5-dev libwebp-dev liblqr-1-0-dev vim gsfonts ghostscript ccache
27
+ libtiff5-dev libwebp-dev liblqr-1-0-dev vim gsfonts ghostscript
28
28
 
29
29
  if [ ! -d /usr/include/freetype ]; then
30
30
  # If `/usr/include/freetype` is not existed, ImageMagick 6.7 configuration fails about Freetype.
@@ -52,7 +52,7 @@ build_imagemagick() {
52
52
  fi
53
53
 
54
54
  cd "${build_dir}"
55
- CC="ccache cc" CXX="ccache c++" ./configure --prefix=/usr "${options}"
55
+ ./configure --prefix=/usr "${options}"
56
56
  make -j
57
57
  }
58
58
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  set -euox pipefail
4
4
 
5
- gem install bundler
5
+ gem install bundler -v 2.3.26 # Bundler 2.4.x has dropped support for Ruby 2.3
6
6
 
7
7
  if [ -v STYLE_CHECKS ]; then
8
8
  set +ux
@@ -16,10 +16,11 @@ if [ ! -v IMAGEMAGICK_VERSION ]; then
16
16
  fi
17
17
 
18
18
  export HOMEBREW_NO_AUTO_UPDATE=true
19
- brew install wget pkg-config ghostscript freetype jpeg little-cms2 libomp libpng libtiff liblqr libtool libxml2 zlib webp
19
+ brew uninstall --force imagemagick imagemagick@6
20
+ brew install wget ghostscript freetype jpeg little-cms2 openexr libomp libpng libtiff liblqr libtool zlib webp
20
21
 
21
- export LDFLAGS="-L/usr/local/opt/libxml2/lib -L/usr/local/opt/zlib/lib"
22
- export CPPFLAGS="-I/usr/local/opt/libxml2/include -I/usr/local/opt/zlib/include"
22
+ export LDFLAGS="-L$(brew --prefix libxml2)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix glib)/lib -L$(brew --prefix openexr)/lib"
23
+ export CPPFLAGS="-I$(brew --prefix libxml2)/include -I$(brew --prefix zlib)/include -I$(brew --prefix glib)/include/glib-2.0 -I$(brew --prefix glib)/lib/glib-2.0/include -I$(brew --prefix openexr)/include/OpenEXR"
23
24
 
24
25
  project_dir=$(pwd)
25
26
  build_dir="${project_dir}/build-ImageMagick/ImageMagick-${IMAGEMAGICK_VERSION}"
@@ -42,7 +43,7 @@ build_imagemagick() {
42
43
  fi
43
44
 
44
45
  cd "${build_dir}"
45
- ./configure --prefix=/usr/local "${options}"
46
+ ./configure --prefix=/usr/local "${options}" --without-raw --without-jxl --without-openjp2
46
47
  make -j
47
48
  }
48
49
 
@@ -2,6 +2,13 @@ lib_dir = File.expand_path('../../lib', File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
3
3
  require 'rubygems'
4
4
  require 'mkmf'
5
+ require 'pkg-config'
6
+
7
+ module MakeMakefile
8
+ # Use the C++ compiler to retrieve the information needed to create a Makefile for mswin environment.
9
+ remove_const(:CONFTEST_C)
10
+ CONFTEST_C = "#{CONFTEST}.cpp"
11
+ end
5
12
 
6
13
  module RMagick
7
14
  class Extconf
@@ -9,6 +16,33 @@ module RMagick
9
16
  RMAGICK_VERS = ::Magick::VERSION
10
17
  MIN_RUBY_VERS = ::Magick::MIN_RUBY_VERSION
11
18
 
19
+ # ImageMagick 6.7 package
20
+ IM6_7_PACKAGES = ['ImageMagick'].freeze
21
+
22
+ # ImageMagick 6.8+ packages
23
+ IM6_PACKAGES = %w[
24
+ ImageMagick-6.Q64HDRI
25
+ ImageMagick-6.Q32HDRI
26
+ ImageMagick-6.Q16HDRI
27
+ ImageMagick-6.Q8HDRI
28
+ ImageMagick-6.Q64
29
+ ImageMagick-6.Q32
30
+ ImageMagick-6.Q16
31
+ ImageMagick-6.Q8
32
+ ].freeze
33
+
34
+ # ImageMagick 7 packages
35
+ IM7_PACKAGES = %w[
36
+ ImageMagick-7.Q64HDRI
37
+ ImageMagick-7.Q32HDRI
38
+ ImageMagick-7.Q16HDRI
39
+ ImageMagick-7.Q8HDRI
40
+ ImageMagick-7.Q64
41
+ ImageMagick-7.Q32
42
+ ImageMagick-7.Q16
43
+ ImageMagick-7.Q8
44
+ ].freeze
45
+
12
46
  attr_reader :headers
13
47
 
14
48
  def initialize
@@ -24,16 +58,17 @@ module RMagick
24
58
  return if RUBY_PLATFORM =~ /mswin|mingw/
25
59
 
26
60
  if find_executable('brew')
27
- pkg_config_path = "#{`brew --prefix imagemagick@6`.strip}/lib/pkgconfig"
61
+ append_pkg_config_path("#{`brew --prefix imagemagick`.strip}/lib/pkgconfig")
62
+ append_pkg_config_path("#{`brew --prefix imagemagick@6`.strip}/lib/pkgconfig")
28
63
  elsif find_executable('pacman')
29
- pkg_config_path = '/usr/lib/imagemagick6/pkgconfig'
30
- else
31
- return
64
+ append_pkg_config_path('/usr/lib/imagemagick6/pkgconfig')
32
65
  end
66
+ end
33
67
 
68
+ def append_pkg_config_path(path)
34
69
  pkg_config_paths = ENV['PKG_CONFIG_PATH'].to_s.split(':')
35
- if File.exist?(pkg_config_path) && !pkg_config_paths.include?(pkg_config_path)
36
- ENV['PKG_CONFIG_PATH'] = [ENV['PKG_CONFIG_PATH'], pkg_config_path].compact.join(':')
70
+ if File.exist?(path) && !pkg_config_paths.include?(path)
71
+ ENV['PKG_CONFIG_PATH'] = [ENV['PKG_CONFIG_PATH'], path].compact.join(':')
37
72
  end
38
73
  end
39
74
 
@@ -49,7 +84,7 @@ module RMagick
49
84
  end
50
85
 
51
86
  def configure_headers
52
- @headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h]
87
+ @headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h ruby.h ruby/io.h]
53
88
 
54
89
  if have_header('MagickCore/MagickCore.h')
55
90
  headers << 'MagickCore/MagickCore.h'
@@ -67,18 +102,21 @@ module RMagick
67
102
  check_multiple_imagemagick_versions
68
103
  check_partial_imagemagick_versions
69
104
 
70
- libdir = `pkg-config --libs-only-L #{$magick_package}`.chomp.sub('-L', '')
71
- ldflags = "#{ENV['LDFLAGS']} " + `pkg-config --libs #{$magick_package}`.chomp
105
+ original_ldflags = $LDFLAGS.dup
106
+
107
+ libdir = PKGConfig.libs_only_L($magick_package).chomp.sub('-L', '')
108
+ ldflags = "#{ENV['LDFLAGS']} " + PKGConfig.libs($magick_package).chomp
72
109
  rpath = libdir.empty? ? '' : "-Wl,-rpath,#{libdir}"
73
110
 
74
111
  # Save flags
75
- $CPPFLAGS = "#{ENV['CPPFLAGS']} " + `pkg-config --cflags #{$magick_package}`.chomp
76
- $LOCAL_LIBS = "#{ENV['LIBS']} " + `pkg-config --libs #{$magick_package}`.chomp
77
- $LDFLAGS = "#{ldflags} #{rpath}"
112
+ $CPPFLAGS += " #{ENV['CPPFLAGS']} " + PKGConfig.cflags($magick_package).chomp
113
+ $CPPFLAGS += ' -x c++ -std=c++11 -Wno-register'
114
+ $LOCAL_LIBS += " #{ENV['LIBS']} " + PKGConfig.libs($magick_package).chomp
115
+ $LDFLAGS += " #{ldflags} #{rpath}"
78
116
 
79
117
  unless try_link("int main() { }")
80
118
  # if linker does not recognizes '-Wl,-rpath,somewhere' option, it revert to original option
81
- $LDFLAGS = ldflags
119
+ $LDFLAGS = "#{original_ldflags} #{ldflags}"
82
120
  end
83
121
 
84
122
  configure_archflags_for_osx($magick_package) if RUBY_PLATFORM =~ /darwin/ # osx
@@ -86,8 +124,9 @@ module RMagick
86
124
  elsif RUBY_PLATFORM =~ /mingw/ # mingw
87
125
 
88
126
  dir_paths = search_paths_for_library_for_windows
89
- $CPPFLAGS = %(-I"#{dir_paths[:include]}")
90
- $LDFLAGS = %(-L"#{dir_paths[:lib]}")
127
+ $CPPFLAGS += %( -I"#{dir_paths[:include]}")
128
+ $CPPFLAGS += ' -x c++ -std=c++11 -Wno-register'
129
+ $LDFLAGS += %( -L"#{dir_paths[:lib]}")
91
130
  $LDFLAGS << ' -lucrt' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
92
131
 
93
132
  have_library(im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_' : 'CORE_RL_magick_')
@@ -99,11 +138,13 @@ module RMagick
99
138
  $LDFLAGS << %( -libpath:"#{dir_paths[:lib]}")
100
139
  $LDFLAGS << ' -libpath:ucrt' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
101
140
 
102
- $LOCAL_LIBS = im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_.lib' : 'CORE_RL_magick_.lib'
141
+ $LOCAL_LIBS += ' ' + (im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_.lib' : 'CORE_RL_magick_.lib')
103
142
 
143
+ $CPPFLAGS += ' /std:c++11'
104
144
  end
105
-
106
- $CPPFLAGS << (have_macro('__GNUC__') ? ' -std=gnu99' : ' -std=c99')
145
+ ruby_version = RUBY_VERSION.split('.')
146
+ $CPPFLAGS += " -DRUBY_VERSION_MAJOR=#{ruby_version[0]} -DRUBY_VERSION_MINOR=#{ruby_version[1]}"
147
+ $CPPFLAGS += ' $(optflags) $(debugflags)'
107
148
  end
108
149
 
109
150
  def exit_failure(msg)
@@ -123,31 +164,40 @@ module RMagick
123
164
  exit(1)
124
165
  end
125
166
 
167
+ def detect_imagemagick_packages(packages)
168
+ packages.select do |package|
169
+ PKGConfig.exist?(package)
170
+ end
171
+ end
172
+
173
+ def installed_im6_packages
174
+ @installed_im6_packages ||= detect_imagemagick_packages(IM6_PACKAGES)
175
+ end
176
+
177
+ def installed_im7_packages
178
+ @installed_im7_packages ||= detect_imagemagick_packages(IM7_PACKAGES)
179
+ end
180
+
126
181
  def determine_imagemagick_package
127
- packages = `pkg-config --list-all`.scan(/(ImageMagick\-[\.A-Z0-9]+) .*/).flatten
182
+ packages = [installed_im7_packages, installed_im6_packages].flatten
128
183
 
129
- # For ancient version of ImageMagick 6 we need a different regex
130
184
  if packages.empty?
131
- packages = `pkg-config --list-all`.scan(/(ImageMagick) .*/).flatten
185
+ # ImageMagick 6.7 does not have package file like ImageMagick-6.Q16.pc
186
+ packages = detect_imagemagick_packages(IM6_7_PACKAGES)
132
187
  end
133
188
 
134
189
  if packages.empty?
135
190
  exit_failure "Can't install RMagick #{RMAGICK_VERS}. Can't find ImageMagick with pkg-config\n"
136
191
  end
137
192
 
138
- if packages.length > 1
139
-
140
- im7_packages = packages.grep(/\AImageMagick-7/)
141
-
142
- if im7_packages.any?
143
- checking_for('forced use of ImageMagick 6') do
144
- if ENV['USE_IMAGEMAGICK_6']
145
- packages -= im7_packages
146
- true
147
- else
148
- packages = im7_packages
149
- false
150
- end
193
+ if installed_im6_packages.any? && installed_im7_packages.any?
194
+ checking_for('forced use of ImageMagick 6') do
195
+ if ENV['USE_IMAGEMAGICK_6']
196
+ packages = installed_im6_packages
197
+ true
198
+ else
199
+ packages = installed_im7_packages
200
+ false
151
201
  end
152
202
  end
153
203
  end
@@ -219,7 +269,7 @@ module RMagick
219
269
  # issue #169
220
270
  # set ARCHFLAGS appropriately for OSX
221
271
  def configure_archflags_for_osx(magick_package)
222
- return unless `pkg-config #{magick_package} --libs-only-L`.match(%r{-L(.+)/lib})
272
+ return unless PKGConfig.libs_only_L(magick_package).match(%r{-L(.+)/lib})
223
273
 
224
274
  imagemagick_dir = Regexp.last_match(1)
225
275
  command = Dir.glob(File.join(imagemagick_dir, "bin/*")).select { |file| File.executable? file }.first
@@ -262,10 +312,8 @@ module RMagick
262
312
  exit_failure <<~END_MINGW
263
313
  Can't install RMagick #{RMAGICK_VERS}.
264
314
  Can't find the ImageMagick library.
265
- Retry with '--with-opt-dir' option.
266
- Usage: gem install rmagick -- '--with-opt-dir=\"[path to ImageMagick]\"'
267
- e.g.
268
- gem install rmagick -- '--with-opt-dir=\"C:\\Program Files\\ImageMagick-6.9.1-Q16\"'
315
+
316
+ Please check PATH environment variable for ImageMagick installation path.
269
317
  END_MINGW
270
318
  end
271
319
 
@@ -273,9 +321,9 @@ module RMagick
273
321
  assert_minimum_ruby_version!
274
322
  assert_has_dev_libs!
275
323
 
276
- # Check for compiler. Extract first word so ENV['CC'] can be a program name with arguments.
277
- cc = (ENV['CC'] || RbConfig::CONFIG['CC'] || 'gcc').split(' ').first
278
- exit_failure "No C compiler found in ${ENV['PATH']}. See mkmf.log for details." unless find_executable(cc)
324
+ # Check for compiler. Extract first word so ENV['CXX'] can be a program name with arguments.
325
+ cxx = (ENV['CXX'] || RbConfig::CONFIG['CXX'] || 'g++').split(' ').first
326
+ exit_failure "No C++ compiler found in ${ENV['PATH']}. See mkmf.log for details." unless find_executable(cxx)
279
327
  end
280
328
 
281
329
  def assert_minimum_ruby_version!
@@ -294,16 +342,12 @@ module RMagick
294
342
  END_FAILURE
295
343
 
296
344
  if RUBY_PLATFORM !~ /mswin|mingw/
297
- unless find_executable('pkg-config')
298
- exit_failure "Can't install RMagick #{RMAGICK_VERS}. Can't find pkg-config in #{ENV['PATH']}\n"
299
- end
300
-
301
- unless `pkg-config --libs MagickCore`[/\bl\s*(MagickCore|Magick)6?\b/]
345
+ unless PKGConfig.libs('MagickCore')[/\bl\s*(MagickCore|Magick)6?\b/]
302
346
  exit_failure failure_message
303
347
  end
304
348
 
305
349
  $magick_package = determine_imagemagick_package
306
- $magick_version = `pkg-config #{$magick_package} --modversion`[/^(\d+\.\d+\.\d+)/]
350
+ $magick_version = PKGConfig.modversion($magick_package)[/^(\d+\.\d+\.\d+)/]
307
351
  else
308
352
  `#{magick_command} -version` =~ /Version: ImageMagick (\d+\.\d+\.\d+)-+\d+ /
309
353
  $magick_version = Regexp.last_match(1)
@@ -321,7 +365,9 @@ module RMagick
321
365
 
322
366
  def create_header_file
323
367
  ruby_api = [
324
- 'rb_gc_adjust_memory_usage' # Ruby 2.4.0
368
+ 'rb_gc_adjust_memory_usage', # Ruby 2.4.0
369
+ 'rb_gc_mark_movable', # Ruby 2.7.0
370
+ 'rb_io_path' # Ruby 3.2.0
325
371
  ]
326
372
  memory_api = %w[
327
373
  posix_memalign
@@ -360,9 +406,6 @@ module RMagick
360
406
 
361
407
  def create_makefile_file
362
408
  create_header_file
363
- # Prior to 1.8.5 mkmf duplicated the symbols on the command line and in the
364
- # extconf.h header. Suppress that behavior by removing the symbol array.
365
- $defs = []
366
409
 
367
410
  # Force re-compilation if the generated Makefile changed.
368
411
  $config_h = 'Makefile'
@@ -371,6 +414,22 @@ module RMagick
371
414
  print_summary
372
415
  end
373
416
 
417
+ def create_compile_flags_txt
418
+ cppflags = $CPPFLAGS.split(' ')
419
+ include_flags = cppflags.select { |flag| flag.start_with?('-I') }
420
+ define_flags = cppflags.select { |flag| flag.start_with?('-D') } + $defs
421
+
422
+ File.open('compile_flags.txt', 'w') do |f|
423
+ include_flags.each { |flag| f.puts(flag) }
424
+ f.puts "-I#{Dir.pwd}"
425
+ f.puts "-I#{RbConfig::CONFIG['rubyhdrdir']}"
426
+ f.puts "-I#{RbConfig::CONFIG['rubyhdrdir']}/ruby/backward"
427
+ f.puts "-I#{RbConfig::CONFIG['rubyarchhdrdir']}"
428
+ f.puts "-std=c++11"
429
+ define_flags.each { |flag| f.puts(flag) }
430
+ end
431
+ end
432
+
374
433
  def magick_command
375
434
  @magick_command ||= if find_executable('magick')
376
435
  'magick'
@@ -409,3 +468,4 @@ at_exit do
409
468
  message msg + "\n"
410
469
  end
411
470
  extconf.create_makefile_file
471
+ extconf.create_compile_flags_txt
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * Changes since Nov. 2009 copyright &copy; by Benjamin Thomas and Omer Bar-or
7
7
  *
8
- * @file rmagick.c
9
- * @version $Id: rmagick.c,v 1.4 2009/12/20 02:33:32 baror Exp $
8
+ * @file rmagick.cpp
9
+ * @version $Id: rmagick.cpp,v 1.4 2009/12/20 02:33:32 baror Exp $
10
10
  * @author Tim Hunter
11
11
  ******************************************************************************/
12
12
 
@@ -14,8 +14,6 @@
14
14
 
15
15
 
16
16
 
17
- static VALUE rm_yield_handle_exception(VALUE, VALUE) ATTRIBUTE_NORETURN;
18
-
19
17
  static VALUE
20
18
  rm_yield_body(VALUE object)
21
19
  {
@@ -42,7 +40,7 @@ rm_yield_handle_exception(VALUE allocated_area, VALUE exc)
42
40
  *
43
41
  */
44
42
  VALUE
45
- Magick_colors(VALUE class)
43
+ Magick_colors(VALUE klass)
46
44
  {
47
45
  const ColorInfo **color_info_list;
48
46
  size_t number_colors, x;
@@ -60,10 +58,10 @@ Magick_colors(VALUE class)
60
58
  {
61
59
  for (x = 0; x < number_colors; x++)
62
60
  {
63
- rb_rescue(rm_yield_body, Import_ColorInfo(color_info_list[x]), rm_yield_handle_exception, (VALUE)color_info_list);
61
+ rb_rescue(RESCUE_FUNC(rm_yield_body), Import_ColorInfo(color_info_list[x]), RESCUE_EXCEPTION_HANDLER_FUNC(rm_yield_handle_exception), (VALUE)color_info_list);
64
62
  }
65
63
  magick_free((void *)color_info_list);
66
- return class;
64
+ return klass;
67
65
  }
68
66
  else
69
67
  {
@@ -93,7 +91,7 @@ Magick_colors(VALUE class)
93
91
  *
94
92
  */
95
93
  VALUE
96
- Magick_fonts(VALUE class)
94
+ Magick_fonts(VALUE klass)
97
95
  {
98
96
  const TypeInfo **type_info;
99
97
  size_t number_types, x;
@@ -109,10 +107,10 @@ Magick_fonts(VALUE class)
109
107
  {
110
108
  for (x = 0; x < number_types; x++)
111
109
  {
112
- rb_rescue(rm_yield_body, Import_TypeInfo((const TypeInfo *)type_info[x]), rm_yield_handle_exception, (VALUE)type_info);
110
+ rb_rescue(RESCUE_FUNC(rm_yield_body), Import_TypeInfo((const TypeInfo *)type_info[x]), RESCUE_EXCEPTION_HANDLER_FUNC(rm_yield_handle_exception), (VALUE)type_info);
113
111
  }
114
112
  magick_free((void *)type_info);
115
- return class;
113
+ return klass;
116
114
  }
117
115
  else
118
116
  {
@@ -170,7 +168,7 @@ MagickInfo_to_format(const MagickInfo *magick_info)
170
168
  * @return [Hash] the formats hash.
171
169
  */
172
170
  VALUE
173
- Magick_init_formats(VALUE class ATTRIBUTE_UNUSED)
171
+ Magick_init_formats(VALUE klass ATTRIBUTE_UNUSED)
174
172
  {
175
173
  const MagickInfo **magick_info;
176
174
  size_t number_formats, x;
@@ -210,11 +208,11 @@ Magick_init_formats(VALUE class ATTRIBUTE_UNUSED)
210
208
  * Set resource limits.
211
209
  * @param resource [String, Symbol] the type of resource
212
210
  * @param limit [Numeric] the new limit number
213
- *
211
+ *
214
212
  * @return [Numeric] the old limit.
215
213
  */
216
214
  VALUE
217
- Magick_limit_resource(int argc, VALUE *argv, VALUE class)
215
+ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
218
216
  {
219
217
  VALUE resource, limit;
220
218
  ResourceType res = UndefinedResource;
@@ -227,7 +225,7 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE class)
227
225
  switch (TYPE(resource))
228
226
  {
229
227
  case T_NIL:
230
- return class;
228
+ return klass;
231
229
 
232
230
  case T_SYMBOL:
233
231
  id = (ID)SYM2ID(resource);
@@ -265,7 +263,7 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE class)
265
263
  str = StringValueCStr(resource);
266
264
  if (*str == '\0')
267
265
  {
268
- return class;
266
+ return klass;
269
267
  }
270
268
  else if (rm_strcasecmp("area", str) == 0)
271
269
  {
@@ -321,12 +319,12 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE class)
321
319
  * @param threshold [Numeric] the number of megabytes to set.
322
320
  */
323
321
  VALUE
324
- Magick_set_cache_threshold(VALUE class, VALUE threshold)
322
+ Magick_set_cache_threshold(VALUE klass, VALUE threshold)
325
323
  {
326
324
  unsigned long thrshld = NUM2ULONG(threshold);
327
325
  SetMagickResourceLimit(MemoryResource, (MagickSizeType)thrshld);
328
326
  SetMagickResourceLimit(MapResource, (MagickSizeType)(2*thrshld));
329
- return class;
327
+ return klass;
330
328
  }
331
329
 
332
330
 
@@ -354,7 +352,7 @@ Magick_set_cache_threshold(VALUE class, VALUE threshold)
354
352
  * @param args [String] the mask of log event.
355
353
  */
356
354
  VALUE
357
- Magick_set_log_event_mask(int argc, VALUE *argv, VALUE class)
355
+ Magick_set_log_event_mask(int argc, VALUE *argv, VALUE klass)
358
356
  {
359
357
  int x;
360
358
 
@@ -366,7 +364,7 @@ Magick_set_log_event_mask(int argc, VALUE *argv, VALUE class)
366
364
  {
367
365
  SetLogEventMask(StringValueCStr(argv[x]));
368
366
  }
369
- return class;
367
+ return klass;
370
368
  }
371
369
 
372
370
  /**
@@ -388,9 +386,8 @@ Magick_set_log_event_mask(int argc, VALUE *argv, VALUE class)
388
386
  * @param format [String] the format to set.
389
387
  */
390
388
  VALUE
391
- Magick_set_log_format(VALUE class, VALUE format)
389
+ Magick_set_log_format(VALUE klass, VALUE format)
392
390
  {
393
391
  SetLogFormat(StringValueCStr(format));
394
- return class;
392
+ return klass;
395
393
  }
396
-