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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # $Id: RMagick.rb,v 1.84 2009/09/15 22:08:41 rmagick Exp $
2
4
  #==============================================================================
3
5
  # Copyright (C) 2009 by Timothy P. Hunter
@@ -12,7 +14,7 @@ if RUBY_PLATFORM =~ /mingw/i
12
14
  begin
13
15
  require 'ruby_installer'
14
16
  ENV['PATH'].split(File::PATH_SEPARATOR).grep(/ImageMagick/i).each do |path|
15
- RubyInstaller::Runtime.add_dll_directory(path)
17
+ RubyInstaller::Runtime.add_dll_directory(path) if File.exist?(File.join(path, 'CORE_RL_magick_.dll')) || File.exist?(File.join(path, 'CORE_RL_MagickCore_.dll'))
16
18
  end
17
19
  rescue LoadError
18
20
  end
@@ -23,9 +25,6 @@ require 'observer'
23
25
  require 'RMagick2.so'
24
26
 
25
27
  module Magick
26
- @formats = nil
27
- @trace_proc = nil
28
- @exit_block_set_up = nil
29
28
  IMAGEMAGICK_VERSION = Magick::Magick_version.split[1].split('-').first
30
29
 
31
30
  class << self
@@ -53,43 +52,14 @@ module Magick
53
52
  # => {"3FR"=>" r-+", "3G2"=>" r-+", "3GP"=>" r-+", "A"=>"*rw+",
54
53
  # ...
55
54
  def formats
56
- @formats ||= init_formats
55
+ formats = init_formats
57
56
 
58
57
  if block_given?
59
- @formats.each { |k, v| yield k, v }
58
+ formats.each { |k, v| yield k, v }
60
59
  self
61
60
  else
62
- @formats
63
- end
64
- end
65
-
66
- # If the Magick module attribute +trace_proc+ is set to a Proc object,
67
- # RMagick calls the proc whenever an image is created or destroyed.
68
- #
69
- # You can use this proc to keep track of which images your program has created
70
- # and which have been destroyed.
71
- #
72
- # @param p [Proc] The proc object.
73
- # The following value will be passed into the proc object.
74
- # - +which+ - A symbol that indicates which operation the proc is being called for.
75
- # If the proc is called for an image creation, the value is +:c+.
76
- # If called for an image destruction, the value is +:d+.
77
- # - +description+ - A string describing the image. This is the same string that
78
- # would be returned by calling the image's inspect method.
79
- # - +id+ - A unique identifier for the image. This identifier is not the same as the object's +object_id+.
80
- # - +method+ - The name of the method responsible for creating or destroying the image.
81
- #
82
- # @example
83
- # Magick.trace_proc = proc do |which, description, id, method|
84
- # ...
85
- # end
86
- def trace_proc=(p)
87
- if @trace_proc.nil? && !p.nil? && !@exit_block_set_up
88
- at_exit { @trace_proc = nil }
89
- @exit_block_set_up = true
61
+ formats
90
62
  end
91
-
92
- @trace_proc = p
93
63
  end
94
64
  end
95
65
 
@@ -106,7 +76,7 @@ module Magick
106
76
  MinimumGeometry = GeometryValue.new(:MinimumGeometry, 6).freeze
107
77
 
108
78
  class Geometry
109
- FLAGS = ['', '%', '!', '<', '>', '@', '^']
79
+ FLAGS = ['', '%', '!', '<', '>', '@', '^'].freeze
110
80
  RFLAGS = {
111
81
  '%' => PercentGeometry,
112
82
  '!' => AspectGeometry,
@@ -114,7 +84,7 @@ module Magick
114
84
  '>' => GreaterGeometry,
115
85
  '@' => AreaGeometry,
116
86
  '^' => MinimumGeometry
117
- }
87
+ }.freeze
118
88
 
119
89
  attr_accessor :width, :height, :x, :y, :flag
120
90
 
@@ -170,7 +140,7 @@ module Magick
170
140
 
171
141
  # Convert object to a geometry string
172
142
  def to_s
173
- str = ''
143
+ str = String.new
174
144
  if @width > 0
175
145
  fmt = @width.truncate == @width ? '%d' : '%.2f'
176
146
  str << sprintf(fmt, @width)
@@ -256,6 +226,7 @@ module Magick
256
226
  private
257
227
 
258
228
  def enquote(str)
229
+ str = to_string(str)
259
230
  if str.length > 2 && /\A(?:\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})\z/.match(str)
260
231
  str
261
232
  else
@@ -263,11 +234,21 @@ module Magick
263
234
  end
264
235
  end
265
236
 
266
- def check_opacity(opacity)
267
- return if opacity.is_a?(String) && opacity['%']
237
+ def to_opacity(opacity)
238
+ return opacity if opacity.is_a?(String) && opacity.end_with?('%')
268
239
 
269
240
  value = Float(opacity)
270
241
  Kernel.raise ArgumentError, 'opacity must be >= 0 and <= 1.0' if value < 0 || value > 1.0
242
+
243
+ value
244
+ end
245
+
246
+ def to_string(obj)
247
+ return obj if obj.is_a?(String)
248
+ return obj.to_s if obj.is_a?(Symbol)
249
+ return obj.to_str if obj.respond_to?(:to_str)
250
+
251
+ Kernel.raise TypeError, "no implicit conversion of #{obj.class} into String"
271
252
  end
272
253
 
273
254
  public
@@ -311,17 +292,19 @@ module Magick
311
292
 
312
293
  # Invoke a clip-path defined by def_clip_path.
313
294
  def clip_path(name)
314
- primitive "clip-path #{name}"
295
+ primitive "clip-path #{to_string(name)}"
315
296
  end
316
297
 
317
298
  # Define the clipping rule.
318
299
  def clip_rule(rule)
300
+ rule = to_string(rule)
319
301
  Kernel.raise ArgumentError, "Unknown clipping rule #{rule}" unless %w[evenodd nonzero].include?(rule.downcase)
320
302
  primitive "clip-rule #{rule}"
321
303
  end
322
304
 
323
305
  # Define the clip units
324
306
  def clip_units(unit)
307
+ unit = to_string(unit)
325
308
  Kernel.raise ArgumentError, "Unknown clip unit #{unit}" unless %w[userspace userspaceonuse objectboundingbox].include?(unit.downcase)
326
309
  primitive "clip-units #{unit}"
327
310
  end
@@ -350,7 +333,7 @@ module Magick
350
333
  # (pop) graphic-context".
351
334
  def define_clip_path(name)
352
335
  push('defs')
353
- push("clip-path \"#{name}\"")
336
+ push("clip-path #{enquote(name)}")
354
337
  push('graphic-context')
355
338
  yield
356
339
  ensure
@@ -370,7 +353,7 @@ module Magick
370
353
  # Let anything through, but the only defined argument
371
354
  # is "UTF-8". All others are apparently ignored.
372
355
  def encoding(encoding)
373
- primitive "encoding #{encoding}"
356
+ primitive "encoding #{to_string(encoding)}"
374
357
  end
375
358
 
376
359
  # Specify object fill, a color name or pattern name
@@ -382,22 +365,23 @@ module Magick
382
365
 
383
366
  # Specify fill opacity (use "xx%" to indicate percentage)
384
367
  def fill_opacity(opacity)
385
- check_opacity(opacity)
368
+ opacity = to_opacity(opacity)
386
369
  primitive "fill-opacity #{opacity}"
387
370
  end
388
371
 
389
372
  def fill_rule(rule)
373
+ rule = to_string(rule)
390
374
  Kernel.raise ArgumentError, "Unknown fill rule #{rule}" unless %w[evenodd nonzero].include?(rule.downcase)
391
375
  primitive "fill-rule #{rule}"
392
376
  end
393
377
 
394
378
  # Specify text drawing font
395
379
  def font(name)
396
- primitive "font \'#{name}\'"
380
+ primitive "font #{enquote(name)}"
397
381
  end
398
382
 
399
383
  def font_family(name)
400
- primitive "font-family \'#{name}\'"
384
+ primitive "font-family #{enquote(name)}"
401
385
  end
402
386
 
403
387
  def font_stretch(stretch)
@@ -435,38 +419,17 @@ module Magick
435
419
 
436
420
  # IM 6.5.5-8 and later
437
421
  def interline_spacing(space)
438
- begin
439
- Float(space)
440
- rescue ArgumentError
441
- Kernel.raise ArgumentError, 'invalid value for interline_spacing'
442
- rescue TypeError
443
- Kernel.raise TypeError, "can't convert #{space.class} into Float"
444
- end
445
- primitive "interline-spacing #{space}"
422
+ primitive "interline-spacing #{Float(space)}"
446
423
  end
447
424
 
448
425
  # IM 6.4.8-3 and later
449
426
  def interword_spacing(space)
450
- begin
451
- Float(space)
452
- rescue ArgumentError
453
- Kernel.raise ArgumentError, 'invalid value for interword_spacing'
454
- rescue TypeError
455
- Kernel.raise TypeError, "can't convert #{space.class} into Float"
456
- end
457
- primitive "interword-spacing #{space}"
427
+ primitive "interword-spacing #{Float(space)}"
458
428
  end
459
429
 
460
430
  # IM 6.4.8-3 and later
461
431
  def kerning(space)
462
- begin
463
- Float(space)
464
- rescue ArgumentError
465
- Kernel.raise ArgumentError, 'invalid value for kerning'
466
- rescue TypeError
467
- Kernel.raise TypeError, "can't convert #{space.class} into Float"
468
- end
469
- primitive "kerning #{space}"
432
+ primitive "kerning #{Float(space)}"
470
433
  end
471
434
 
472
435
  # Draw a line
@@ -477,7 +440,7 @@ module Magick
477
440
  # Specify drawing fill and stroke opacities. If the value is a string
478
441
  # ending with a %, the number will be multiplied by 0.01.
479
442
  def opacity(opacity)
480
- check_opacity(opacity)
443
+ opacity = to_opacity(opacity)
481
444
  primitive "opacity #{opacity}"
482
445
  end
483
446
 
@@ -485,7 +448,7 @@ module Magick
485
448
  # primitive requires that the commands be surrounded by quotes or
486
449
  # apostrophes. Here we simply use apostrophes.
487
450
  def path(cmds)
488
- primitive "path '" + cmds + "'"
451
+ primitive "path #{enquote(cmds)}"
489
452
  end
490
453
 
491
454
  # Define a pattern. In the block, call primitive methods to
@@ -493,7 +456,7 @@ module Magick
493
456
  # as the argument to the 'fill' or 'stroke' methods
494
457
  def pattern(name, x, y, width, height)
495
458
  push('defs')
496
- push("pattern #{name} " + sprintf('%g %g %g %g', x, y, width, height))
459
+ push("pattern #{to_string(name)} " + sprintf('%g %g %g %g', x, y, width, height))
497
460
  push('graphic-context')
498
461
  yield
499
462
  ensure
@@ -544,8 +507,7 @@ module Magick
544
507
  if what.length.zero?
545
508
  primitive 'pop graphic-context'
546
509
  else
547
- # to_s allows a Symbol to be used instead of a String
548
- primitive 'pop ' + what.map(&:to_s).join(' ')
510
+ primitive 'pop ' + what.map { |x| to_string(x) }.join(' ')
549
511
  end
550
512
  end
551
513
 
@@ -558,8 +520,7 @@ module Magick
558
520
  if what.length.zero?
559
521
  primitive 'push graphic-context'
560
522
  else
561
- # to_s allows a Symbol to be used instead of a String
562
- primitive 'push ' + what.map(&:to_s).join(' ')
523
+ primitive 'push ' + what.map { |x| to_string(x) }.join(' ')
563
524
  end
564
525
  end
565
526
 
@@ -615,7 +576,7 @@ module Magick
615
576
  if list.length.zero?
616
577
  primitive 'stroke-dasharray none'
617
578
  else
618
- list.each do |x|
579
+ list.map! { |x| Float(x) }.each do |x|
619
580
  Kernel.raise ArgumentError, "dash array elements must be > 0 (#{x} given)" if x <= 0
620
581
  end
621
582
  primitive "stroke-dasharray #{list.join(',')}"
@@ -628,16 +589,19 @@ module Magick
628
589
  end
629
590
 
630
591
  def stroke_linecap(value)
592
+ value = to_string(value)
631
593
  Kernel.raise ArgumentError, "Unknown linecap type: #{value}" unless %w[butt round square].include?(value.downcase)
632
594
  primitive "stroke-linecap #{value}"
633
595
  end
634
596
 
635
597
  def stroke_linejoin(value)
598
+ value = to_string(value)
636
599
  Kernel.raise ArgumentError, "Unknown linejoin type: #{value}" unless %w[round miter bevel].include?(value.downcase)
637
600
  primitive "stroke-linejoin #{value}"
638
601
  end
639
602
 
640
603
  def stroke_miterlimit(value)
604
+ value = Float(value)
641
605
  Kernel.raise ArgumentError, 'miterlimit must be >= 1' if value < 1
642
606
  primitive "stroke-miterlimit #{value}"
643
607
  end
@@ -645,7 +609,7 @@ module Magick
645
609
  # Specify opacity of stroke drawing color
646
610
  # (use "xx%" to indicate percentage)
647
611
  def stroke_opacity(opacity)
648
- check_opacity(opacity)
612
+ opacity = to_opacity(opacity)
649
613
  primitive "stroke-opacity #{opacity}"
650
614
  end
651
615
 
@@ -656,7 +620,8 @@ module Magick
656
620
 
657
621
  # Draw text at position x,y. Add quotes to text that is not already quoted.
658
622
  def text(x, y, text)
659
- Kernel.raise ArgumentError, 'missing text argument' if text.to_s.empty?
623
+ text = to_string(text)
624
+ Kernel.raise ArgumentError, 'missing text argument' if text.empty?
660
625
  if text.length > 2 && /\A(?:\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})\z/.match(text)
661
626
  # text already quoted
662
627
  elsif !text['\'']
@@ -801,12 +766,6 @@ module Magick
801
766
  module Post_ObjectData_Descriptor
802
767
  Confirmed_ObjectData_Size = '9:10'
803
768
  end
804
-
805
- # Make all constants above immutable
806
- constants.each do |record|
807
- rec = const_get(record)
808
- rec.constants.each { |ds| rec.const_get(ds).freeze }
809
- end
810
769
  end # module Magick::IPTC
811
770
 
812
771
  # Ruby-level Magick::Image methods
@@ -1116,13 +1075,13 @@ module Magick
1116
1075
  %i[red green blue opacity].each do |c|
1117
1076
  module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
1118
1077
  def #{c}
1119
- return collect { |p| p.#{c} }
1078
+ return collect { |p| p.#{c} }
1120
1079
  end
1121
1080
  def #{c}=(v)
1122
- each { |p| p.#{c} = v }
1123
- changed
1124
- notify_observers(self)
1125
- nil
1081
+ each { |p| p.#{c} = v }
1082
+ changed
1083
+ notify_observers(self)
1084
+ v
1126
1085
  end
1127
1086
  END_EVAL
1128
1087
  end
@@ -1346,17 +1305,11 @@ module Magick
1346
1305
  %w[& + - |].each do |op|
1347
1306
  module_eval <<-END_BINOPS, __FILE__, __LINE__ + 1
1348
1307
  def #{op}(other)
1308
+ assert_image_array(other)
1349
1309
  ilist = self.class.new
1350
- begin
1351
- a = other #{op} @images
1352
- rescue TypeError
1353
- Kernel.raise ArgumentError, "Magick::ImageList expected, got " + other.class.to_s
1354
- end
1310
+ a = other #{op} @images
1355
1311
  current = get_current()
1356
- a.each do |image|
1357
- assert_image image
1358
- ilist << image
1359
- end
1312
+ a.each { |image| ilist << image }
1360
1313
  ilist.set_current current
1361
1314
  return ilist
1362
1315
  end
@@ -1385,16 +1338,18 @@ module Magick
1385
1338
  # return if A.scene != B.scene
1386
1339
  # return A.length <=> B.length
1387
1340
  def <=>(other)
1388
- Kernel.raise TypeError, "#{self.class} required (#{other.class} given)" unless other.is_a? self.class
1341
+ return unless other.is_a? self.class
1342
+
1389
1343
  size = [length, other.length].min
1390
1344
  size.times do |x|
1391
1345
  r = self[x] <=> other[x]
1392
1346
  return r unless r.zero?
1393
1347
  end
1348
+
1394
1349
  return 0 if @scene.nil? && other.scene.nil?
1350
+ return if @scene.nil? && !other.scene.nil?
1351
+ return if !@scene.nil? && other.scene.nil?
1395
1352
 
1396
- Kernel.raise TypeError, "cannot convert nil into #{other.scene.class}" if @scene.nil? && !other.scene.nil?
1397
- Kernel.raise TypeError, "cannot convert nil into #{scene.class}" if !@scene.nil? && other.scene.nil?
1398
1353
  r = scene <=> other.scene
1399
1354
  return r unless r.zero?
1400
1355
 
@@ -1426,7 +1381,7 @@ module Magick
1426
1381
 
1427
1382
  %i[
1428
1383
  at each each_index empty? fetch
1429
- first hash include? index length rindex sort!
1384
+ first hash include? index length rindex
1430
1385
  ].each do |mth|
1431
1386
  module_eval <<-END_SIMPLE_DELEGATES, __FILE__, __LINE__ + 1
1432
1387
  def #{mth}(*args, &block)
@@ -1436,6 +1391,11 @@ module Magick
1436
1391
  end
1437
1392
  alias size length
1438
1393
 
1394
+ def sort!(*args, &block)
1395
+ @images.sort!(*args, &block)
1396
+ self
1397
+ end
1398
+
1439
1399
  def clear
1440
1400
  @scene = nil
1441
1401
  @images.clear
@@ -1483,7 +1443,7 @@ module Magick
1483
1443
  alias map! collect!
1484
1444
  alias __map__! collect!
1485
1445
 
1486
- # ImageMagic used affinity in 6.4.3, switch to remap in 6.4.4.
1446
+ # ImageMagick used affinity in 6.4.3, switch to remap in 6.4.4.
1487
1447
  alias affinity remap
1488
1448
 
1489
1449
  def compact
@@ -1546,7 +1506,12 @@ module Magick
1546
1506
  end
1547
1507
 
1548
1508
  def eql?(other)
1549
- assert_image_array other
1509
+ begin
1510
+ assert_image_array other
1511
+ rescue ArgumentError
1512
+ return false
1513
+ end
1514
+
1550
1515
  eql = other.eql?(@images)
1551
1516
  begin # "other" is another ImageList
1552
1517
  eql &&= @scene == other.scene
@@ -1650,7 +1615,9 @@ module Magick
1650
1615
  # it up the line. Catch a NameError and emit a useful message.
1651
1616
  def method_missing(meth_id, *args, &block)
1652
1617
  if @scene
1653
- @images[@scene].send(meth_id, *args, &block)
1618
+ img = @images[@scene]
1619
+ new_img = img.send(meth_id, *args, &block)
1620
+ img.object_id == new_img.object_id ? self : new_img
1654
1621
  else
1655
1622
  super
1656
1623
  end
@@ -1837,7 +1804,6 @@ module Magick
1837
1804
  end
1838
1805
 
1839
1806
  def values_at(*args)
1840
- a = @images.values_at(*args)
1841
1807
  a = self.class.new
1842
1808
  @images.values_at(*args).each { |image| a << image }
1843
1809
  a.scene = a.length - 1
@@ -1888,7 +1854,7 @@ module Magick
1888
1854
  class HatchFill
1889
1855
  def initialize(bgcolor, hatchcolor = 'white', dist = 10)
1890
1856
  @bgcolor = bgcolor
1891
- @hatchpixel = Pixel.from_color(hatchcolor)
1857
+ @hatchpixel = hatchcolor.is_a?(Pixel) ? hatchcolor : Pixel.from_color(hatchcolor)
1892
1858
  @dist = dist
1893
1859
  end
1894
1860
 
@@ -162,6 +162,8 @@ module Magick
162
162
  (@width - @image.columns * scale) / 2.0
163
163
  when /\AxMax/
164
164
  @width - @image.columns * scale
165
+ else
166
+ 0
165
167
  end
166
168
 
167
169
  ty = case @align
@@ -171,6 +173,8 @@ module Magick
171
173
  (@height - @image.rows * scale) / 2.0
172
174
  when /YMax\z/
173
175
  @height - @image.rows * scale
176
+ else
177
+ 0
174
178
  end
175
179
  [tx, ty]
176
180
  end
@@ -182,7 +186,7 @@ module Magick
182
186
  width = @width
183
187
  height = @height
184
188
  elsif @meet_or_slice == 'meet'
185
- scale = [@width / @image.columns, @height / @image.rows].min
189
+ scale = [@width / @image.columns, @height / @image.rows].min || 1.0
186
190
  width = @image.columns
187
191
  height = @image.rows
188
192
  else
@@ -193,7 +197,7 @@ module Magick
193
197
  end
194
198
 
195
199
  gc.clip_path(name)
196
- scale = [@width / @image.columns, @height / @image.rows].max
200
+ scale = [@width / @image.columns, @height / @image.rows].max || 1.0
197
201
  width = @image.columns
198
202
  height = @image.rows
199
203
  end
data/lib/rvg/misc.rb CHANGED
@@ -452,10 +452,10 @@ module Magick
452
452
  }
453
453
 
454
454
  FONT_WEIGHT = {
455
- 'normal' => Magick::NormalWeight,
456
- 'bold' => Magick::BoldWeight,
457
- 'bolder' => Magick::BolderWeight,
458
- 'lighter' => Magick::LighterWeight
455
+ normal: Magick::NormalWeight,
456
+ bold: Magick::BoldWeight,
457
+ bolder: Magick::BolderWeight,
458
+ lighter: Magick::LighterWeight
459
459
  }
460
460
 
461
461
  TEXT_ANCHOR = {
@@ -579,7 +579,7 @@ module Magick
579
579
 
580
580
  def font_weight(weight)
581
581
  # If the arg is not in the hash use it directly. Handles numeric values.
582
- weight = FONT_WEIGHT.fetch(weight) { |key| key }
582
+ weight = weight.is_a?(Numeric) ? weight : FONT_WEIGHT.fetch(weight.to_sym, Magick::NormalWeight)
583
583
  @gc.font_weight(weight)
584
584
  @shadow[-1].font_weight = weight
585
585
  nil
@@ -646,7 +646,7 @@ module Magick
646
646
 
647
647
  def skewX(degrees)
648
648
  degrees = Magick::RVG.convert_one_to_float(degrees)
649
- @gc.skewX(degrees)
649
+ @gc.skewx(degrees)
650
650
  @ry = Math.tan(GraphicContext.degrees_to_radians(degrees))
651
651
  concat_matrix
652
652
  nil
@@ -654,7 +654,7 @@ module Magick
654
654
 
655
655
  def skewY(degrees)
656
656
  degrees = Magick::RVG.convert_one_to_float(degrees)
657
- @gc.skewY(degrees)
657
+ @gc.skewy(degrees)
658
658
  @rx = Math.tan(GraphicContext.degrees_to_radians(degrees))
659
659
  concat_matrix
660
660
  nil
data/lib/rvg/rvg.rb CHANGED
@@ -90,6 +90,8 @@ module Magick
90
90
  end
91
91
  bg_image
92
92
  end
93
+ else
94
+ @background_image.copy
93
95
  end
94
96
  else
95
97
  @background_image.copy
@@ -137,8 +137,8 @@ module Magick
137
137
  rescue ArgumentError
138
138
  raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})"
139
139
  end
140
- raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0
141
- raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0
140
+ raise(ArgumentError, "viewbox width must be > 0 (#{@vbx_width} given)") unless @vbx_width >= 0
141
+ raise(ArgumentError, "viewbox height must be > 0 (#{@vbx_height} given)") unless @vbx_height >= 0
142
142
 
143
143
  # return the user-coordinate space attributes if defined
144
144
  class << self
@@ -89,7 +89,7 @@ module Magick
89
89
  cx = Float(args[0])
90
90
  cy = Float(args[1])
91
91
  @transforms << [:translate, [cx, cy]]
92
- @transforms << [:rotate, [angle]]
92
+ @transforms << [:rotate, [Float(angle)]]
93
93
  @transforms << [:translate, [-cx, -cy]]
94
94
  else
95
95
  raise ArgumentError, "wrong number of arguments (#{args.length} for 1 or 3)"
data/rmagick.gemspec CHANGED
@@ -14,25 +14,16 @@ Gem::Specification.new do |s|
14
14
  s.license = 'MIT'
15
15
 
16
16
  tracked_files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
17
- file_exclusion_regex = %r{\A(doc|benchmarks|examples|spec|lib/rvg/to_c.rb)}
17
+ file_exclusion_regex = /\A(doc|benchmarks|examples|spec|Steepfile)/
18
18
  files = tracked_files.reject { |file| file[file_exclusion_regex] }
19
19
 
20
20
  s.files = files
21
- s.require_paths << 'ext' << 'deprecated'
21
+ s.require_paths << 'ext'
22
22
 
23
23
  s.extensions = %w[ext/RMagick/extconf.rb]
24
24
  s.required_ruby_version = ">= #{Magick::MIN_RUBY_VERSION}"
25
25
  s.requirements << "ImageMagick #{Magick::MIN_IM_VERSION} or later"
26
26
 
27
- s.add_development_dependency 'pry', '~> 0.14'
28
- s.add_development_dependency 'rake-compiler', '~> 1.0'
29
- s.add_development_dependency 'rspec', '~> 3.8'
30
- s.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
31
- if RUBY_PLATFORM !~ /mswin|mingw/
32
- s.add_development_dependency 'rubocop', '~> 0.81.0'
33
- s.add_development_dependency 'rubocop-rspec', '~> 1.38.1'
34
- s.add_development_dependency 'rubocop-performance', '~> 1.5.2'
35
- end
36
- s.add_development_dependency 'simplecov', '~> 0.16.1'
37
- s.add_development_dependency 'yard', '~> 0.9.24'
27
+ s.add_runtime_dependency 'pkg-config', '~> 1.4'
28
+ s.add_runtime_dependency 'observer', '~> 0.1'
38
29
  end
@@ -0,0 +1,64 @@
1
+ module Magick
2
+ interface _DrawCommonMethods
3
+ def affine: (magick_real sx, magick_real rx, magick_real ry, magick_real sy, magick_real tx, magick_real ty) -> self
4
+ def alpha: (magick_real x, magick_real y, PaintMethod method) -> self
5
+ def arc: (magick_real start_x, magick_real start_y, magick_real end_x, magick_real end_y, magick_real start_degrees, magick_real end_degrees) -> self
6
+ def bezier: (*magick_real points) -> self
7
+ def circle: (magick_real origin_x, magick_real origin_y, magick_real perim_x, magick_real perim_y) -> self
8
+ def clip_path: (interned name) -> self
9
+ def clip_rule: (interned rule) -> self
10
+ def clip_units: (interned unit) -> self
11
+ def color: (magick_real x, magick_real y, PaintMethod method) -> self
12
+ def decorate: (DecorationType decoration) -> self
13
+ def define_clip_path: (interned name) { () -> void } -> void
14
+ def ellipse: (magick_real origin_x, magick_real origin_y, magick_real width, magick_real height, magick_real arc_start, magick_real arc_end) -> self
15
+ def encoding: (interned encoding) -> self
16
+ def fill: (interned colorspec) -> self
17
+ alias fill_color fill
18
+ alias fill_pattern fill
19
+ def fill_opacity: (magick_percentage opacity) -> self
20
+ def fill_rule: (interned rule) -> self
21
+ def gravity: (GravityType grav) -> self
22
+ def image: (CompositeOperator composite, magick_real x, magick_real y, magick_real width, magick_real height, String image_file_path) -> self
23
+ def interline_spacing: (magick_real space) -> self
24
+ def interword_spacing: (magick_real space) -> self
25
+ def kerning: (magick_real space) -> self
26
+ def line: (magick_real start_x, magick_real start_y, magick_real end_x, magick_real end_y) -> self
27
+ def opacity: (magick_percentage opacity) -> self
28
+ def path: (interned cmds) -> self
29
+ def pattern: (interned name, magick_real x, magick_real y, magick_real width, magick_real height) { () -> void } -> void
30
+ def point: (magick_real x, magick_real y) -> self
31
+ def pointsize: (magick_real points) -> self
32
+ def polygon: (*magick_real points) -> self
33
+ def polyline: (*magick_real points) -> self
34
+ def rectangle: (magick_real upper_left_x, magick_real upper_left_y, magick_real lower_right_x, magick_real lower_right_y) -> self
35
+ def roundrectangle: (magick_real center_x, magick_real center_y, magick_real width, magick_real height, magick_real corner_width, magick_real corner_height) -> self
36
+ def skewx: (magick_real angle) -> self
37
+ def skewy: (magick_real angle) -> self
38
+ def stroke: (interned colorspec) -> self
39
+ alias stroke_color stroke
40
+ alias stroke_pattern stroke
41
+ def stroke_antialias: (bool `bool`) -> self
42
+ def stroke_dasharray: (*magick_real list) -> self
43
+ def stroke_dashoffset: (?magick_real value) -> self
44
+ def stroke_linecap: (interned value) -> self
45
+ def stroke_linejoin: (interned value) -> self
46
+ def stroke_miterlimit: (magick_real value) -> self
47
+ def stroke_opacity: (magick_percentage opacity) -> self
48
+ def text_align: (AlignType alignment) -> self
49
+ def text_antialias: (bool boolean) -> self
50
+ def text_undercolor: (String color) -> self
51
+
52
+ def annotate: (magick_image image_arg, int width_arg, int height_arg, int x_arg, int y_arg, string text) -> self
53
+ | (magick_image image_arg, int width_arg, int height_arg, int x_arg, int y_arg, string text) { (self) -> void } -> self
54
+ def composite: (magick_real x, magick_real y, magick_real width, magick_real height, magick_image image, ?CompositeOperator composite_op) -> self
55
+ def draw: (magick_image image_arg) -> self
56
+ def get_type_metrics: (magick_image image, string text) -> TypeMetric
57
+ | (string text) -> TypeMetric
58
+ def get_multiline_type_metrics: (magick_image image, string text) -> TypeMetric
59
+ | (string text) -> TypeMetric
60
+ def marshal_dump: () -> Hash[Symbol, untyped]
61
+ def marshal_load: (Hash[Symbol, untyped] ddraw) -> self
62
+ def primitive: (string primitive) -> self
63
+ end
64
+ end