rmagick 4.2.6 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
-