prawn-svg 0.36.1 → 0.37.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28ccc4cc947f9d497484516d673f66098fd4624e11aba0035afc4d4373ec27cc
4
- data.tar.gz: 19344cb3568acff4b85de31d199024070dacaa10eeaf4305d9d35265a547dbda
3
+ metadata.gz: d5c28b2e706923d04785979a68f0e457f14df7c71b519d16db6e0bb45e3458bc
4
+ data.tar.gz: 3ade59453c7005f624b4dcd36d9930f27285291c410b00fe57b3d3d278673e4c
5
5
  SHA512:
6
- metadata.gz: 535e9463f1577596e42889fec04c0d0a41cfb30ee6cd0c293c4a028987bde0bf607c482767d1d916445ad7042d14c653a696e2da9c096ff8e40dc6ccc3a69ae6
7
- data.tar.gz: 929c06b75e31fd7314b5ade1ad86f00a6b4d8b98fceff0f66672cf7f1a0b1b70cf75fc28461042c8f91915d43bc5778ea27e49d6aa00aa280037835f9683db8c
6
+ metadata.gz: 250c187430ff8042898b9ee55a595162824613e13a9760a8e32dd21e5a026dfabe012a80f3c19442b3a97635ab020aa1eb113cd70dcc86ffef888f6bc2d39fa1
7
+ data.tar.gz: 1d79258d401547d57dd694878e08d9a50d0166cce4fefd9351cfda0ef6a7c3096910a88a29650993f0eeadd44d7f2fba21d25f438e31660750cc4b847cacc760
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prawn-svg (0.36.1)
4
+ prawn-svg (0.37.0)
5
5
  css_parser (~> 1.6)
6
6
  matrix (~> 0.4.2)
7
7
  prawn (>= 0.11.1, < 3)
data/README.md CHANGED
@@ -114,9 +114,9 @@ prawn-svg supports CSS, both in `<style>` blocks and `style` attributes.
114
114
  In CSS selectors you can use element names, IDs, classes, attributes (existence, `=`, `^=`, `$=`, `*=`, `~=`, `|=`)
115
115
  and all combinators (` `, `>`, `+`, `~`).
116
116
  The pseudo-classes `:first-child`, `:last-child` and `:nth-child(n)` (where n is a number) also work.
117
+ `!important` is supported.
117
118
 
118
- Pseudo-elements and the other pseudo-classes are not supported. Specificity ordering is
119
- implemented, but `!important` is not.
119
+ Pseudo-elements and the other pseudo-classes are not supported.
120
120
 
121
121
  ## Not supported
122
122
 
@@ -1,7 +1,5 @@
1
1
  module Prawn::SVG::CSS
2
2
  class Stylesheets
3
- USER_AGENT_STYLESHEET = 'svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }'.freeze
4
-
5
3
  attr_reader :css_parser, :root, :media
6
4
 
7
5
  def initialize(css_parser, root, media = :all)
@@ -11,7 +9,6 @@ module Prawn::SVG::CSS
11
9
  end
12
10
 
13
11
  def load
14
- load_user_agent_stylesheet
15
12
  load_style_elements
16
13
  xpath_styles = gather_xpath_styles
17
14
  associate_xpath_styles_with_elements(xpath_styles)
@@ -19,10 +16,6 @@ module Prawn::SVG::CSS
19
16
 
20
17
  private
21
18
 
22
- def load_user_agent_stylesheet
23
- css_parser.add_block!(USER_AGENT_STYLESHEET)
24
- end
25
-
26
19
  def load_style_elements
27
20
  REXML::XPath.match(root, '//style').each do |source|
28
21
  data = source.texts.map(&:value).join
@@ -142,7 +142,7 @@ class Prawn::SVG::Elements::Base
142
142
  source.elements.select do |elem|
143
143
  # To be strict, we shouldn't treat namespace-less elements as SVG, but for
144
144
  # backwards compatibility, and because it doesn't hurt, we will.
145
- elem.namespace == SVG_NAMESPACE || elem.namespace == ''
145
+ [SVG_NAMESPACE, ''].include?(elem.namespace)
146
146
  end
147
147
  end
148
148
 
@@ -203,20 +203,27 @@ class Prawn::SVG::Elements::Base
203
203
  end
204
204
 
205
205
  def extract_attributes_and_properties
206
- if (styles = document.element_styles[source])
207
- # TODO : implement !important, at the moment it's just ignored
208
- styles.each do |name, value, _important|
209
- @properties.set(name, value)
210
- end
206
+ # Apply user agent stylesheet
207
+ if %w[svg symbol image marker pattern foreignObject].include?(source.name)
208
+ @properties.set('overflow', 'hidden')
211
209
  end
212
210
 
213
- @properties.load_hash(parse_css_declarations(source.attributes['style'] || ''))
214
-
211
+ # Apply presentation attributes, and set attributes that aren't presentation attributes
215
212
  source.attributes.each do |name, value|
216
213
  # Properties#set returns nil if it's not a recognised property name
217
214
  @properties.set(name, value) or @attributes[name] = value
218
215
  end
219
216
 
217
+ # Apply stylesheet styles
218
+ if (styles = document.element_styles[source])
219
+ styles.each do |name, value, important|
220
+ @properties.set(name, value, important: important)
221
+ end
222
+ end
223
+
224
+ # Apply inline styles
225
+ @properties.load_hash(parse_css_declarations(source.attributes['style'] || ''))
226
+
220
227
  state.computed_properties.compute_properties(@properties)
221
228
  end
222
229
 
@@ -262,6 +269,14 @@ class Prawn::SVG::Elements::Base
262
269
  ['hidden', 'scroll'].include?(computed_properties.overflow)
263
270
  end
264
271
 
272
+ def stroke_width
273
+ if computed_properties.stroke.none?
274
+ 0
275
+ else
276
+ pixels(properties.stroke_width) || 1.0
277
+ end
278
+ end
279
+
265
280
  def clone_element_source(source)
266
281
  new_source = source.dup
267
282
  document.element_styles[new_source] = document.element_styles[source]
@@ -28,6 +28,9 @@ class Prawn::SVG::Elements::Gradient < Prawn::SVG::Elements::Base
28
28
  def gradient_arguments(element)
29
29
  bbox = element.bounding_box
30
30
 
31
+ stroke_width = element.stroke_width
32
+ bbox_with_stroke = bbox&.zip([-stroke_width, stroke_width, stroke_width, -stroke_width])&.map(&:sum)
33
+
31
34
  if type == :radial
32
35
  {
33
36
  from: [fx, fy],
@@ -35,18 +38,18 @@ class Prawn::SVG::Elements::Gradient < Prawn::SVG::Elements::Base
35
38
  to: [cx, cy],
36
39
  r2: r,
37
40
  stops: stops,
38
- matrix: matrix_for_bounding_box(*bbox),
41
+ matrix: matrix_for_bounding_box(bbox),
39
42
  wrap: wrap,
40
- bounding_box: bbox
43
+ bounding_box: bbox_with_stroke
41
44
  }
42
45
  else
43
46
  {
44
47
  from: [x1, y1],
45
48
  to: [x2, y2],
46
49
  stops: stops,
47
- matrix: matrix_for_bounding_box(*bbox),
50
+ matrix: matrix_for_bounding_box(bbox),
48
51
  wrap: wrap,
49
- bounding_box: bbox
52
+ bounding_box: bbox_with_stroke
50
53
  }
51
54
  end
52
55
  end
@@ -57,8 +60,10 @@ class Prawn::SVG::Elements::Gradient < Prawn::SVG::Elements::Base
57
60
 
58
61
  private
59
62
 
60
- def matrix_for_bounding_box(bounding_x1, bounding_y1, bounding_x2, bounding_y2)
61
- if units == :bounding_box
63
+ def matrix_for_bounding_box(bbox)
64
+ if bbox && units == :bounding_box
65
+ bounding_x1, bounding_y1, bounding_x2, bounding_y2 = *bbox
66
+
62
67
  width = bounding_x2 - bounding_x1
63
68
  height = bounding_y1 - bounding_y2
64
69
 
@@ -79,10 +79,21 @@ class Prawn::SVG::GradientRenderer
79
79
 
80
80
  repeat_count, repeat_offset, transform = compute_wrapping(wrap, from, to, current_pdf_translation)
81
81
 
82
+ x0, y0, x1, y1 = bounding_box || prawn_bounding_box
83
+
84
+ offset_x, offset_y = prawn.bounds.anchor
85
+ x0 += offset_x
86
+ y0 += offset_y
87
+ x1 += offset_x
88
+ y1 += offset_y
89
+
90
+ width = x1 - x0
91
+ height = y0 - y1
92
+
82
93
  transparency_group = prawn.ref!(
83
94
  Type: :XObject,
84
95
  Subtype: :Form,
85
- BBox: prawn.state.page.dimensions,
96
+ BBox: [x0, y1, x1, y0],
86
97
  Group: {
87
98
  Type: :Group,
88
99
  S: :Transparency,
@@ -108,7 +119,7 @@ class Prawn::SVG::GradientRenderer
108
119
  )
109
120
 
110
121
  transparency_group.stream << begin
111
- box = PDF::Core.real_params(prawn.state.page.dimensions)
122
+ box = PDF::Core.real_params([x0, y1, width, height])
112
123
 
113
124
  <<~CMDS.strip
114
125
  /Pattern cs
@@ -1,6 +1,6 @@
1
1
  module Prawn::SVG
2
2
  class Properties
3
- Config = Struct.new(:default, :inheritable?, :valid_values, :attr, :ivar)
3
+ Config = Struct.new(:default, :inheritable?, :valid_values, :attr, :ivar, :id)
4
4
 
5
5
  EM = 16
6
6
  FONT_SIZES = {
@@ -49,6 +49,7 @@ module Prawn::SVG
49
49
 
50
50
  PROPERTIES.each do |name, value|
51
51
  value.attr = name.gsub('-', '_')
52
+ value.id = value.attr.to_sym
52
53
  value.ivar = "@#{value.attr}"
53
54
  end
54
55
 
@@ -57,9 +58,11 @@ module Prawn::SVG
57
58
  ATTR_NAMES = PROPERTIES.keys.map { |name| name.gsub('-', '_') }
58
59
 
59
60
  attr_accessor(*ATTR_NAMES)
61
+ attr_reader :important_ids
60
62
 
61
63
  def initialize
62
64
  @numeric_font_size = EM
65
+ @important_ids = []
63
66
  end
64
67
 
65
68
  def load_default_stylesheet
@@ -70,10 +73,11 @@ module Prawn::SVG
70
73
  self
71
74
  end
72
75
 
73
- def set(name, value)
76
+ def set(name, value, important: false)
74
77
  name = name.to_s.downcase
75
78
  if (config = PROPERTIES[name])
76
- if (value = parse_value(config, value.strip))
79
+ if (value = parse_value(config, value.strip)) && (important || !@important_ids.include?(config.id))
80
+ @important_ids << config.id if important
77
81
  instance_variable_set(config.ivar, value)
78
82
  end
79
83
  elsif name == 'font'
@@ -99,7 +103,7 @@ module Prawn::SVG
99
103
  PROPERTY_CONFIGS.each do |config|
100
104
  value = other.send(config.attr)
101
105
 
102
- if value && value != 'inherit'
106
+ if value && value != 'inherit' && (!@important_ids.include?(config.id) || other.important_ids.include?(config.id))
103
107
  instance_variable_set(config.ivar, value)
104
108
 
105
109
  elsif value.nil? && !config.inheritable?
@@ -107,6 +111,7 @@ module Prawn::SVG
107
111
  end
108
112
  end
109
113
 
114
+ @important_ids += other.important_ids
110
115
  @numeric_font_size = calculate_numeric_font_size
111
116
  nil
112
117
  end
@@ -1,5 +1,5 @@
1
1
  module Prawn
2
2
  module SVG
3
- VERSION = '0.36.1'.freeze
3
+ VERSION = '0.37.0'.freeze
4
4
  end
5
5
  end
data/lib/prawn-svg.rb CHANGED
@@ -10,7 +10,7 @@ require 'prawn/svg/calculators/arc_to_bezier_curve'
10
10
  require 'prawn/svg/calculators/aspect_ratio'
11
11
  require 'prawn/svg/calculators/document_sizing'
12
12
  require 'prawn/svg/calculators/pixels'
13
- require 'prawn/svg/transform_utils'
13
+ require 'prawn/svg/pdfmatrix'
14
14
  require 'prawn/svg/transform_parser'
15
15
  require 'prawn/svg/url_loader'
16
16
  require 'prawn/svg/loaders/data'
@@ -62,7 +62,6 @@ RSpec.describe Prawn::SVG::CSS::Stylesheets do
62
62
  width_and_styles = result.map { |k, v| [k.attributes['width'].to_i, v] }.sort_by(&:first)
63
63
 
64
64
  expected = [
65
- [0, [['overflow', 'hidden', false]]],
66
65
  [1, [['fill', '#ff0000', false]]],
67
66
  [2,
68
67
  [['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#440000', false],
@@ -121,7 +120,6 @@ RSpec.describe Prawn::SVG::CSS::Stylesheets do
121
120
  it 'scans the document for style tags and adds the style information to the css parser' do
122
121
  css_parser = instance_double(CssParser::Parser)
123
122
 
124
- expect(css_parser).to receive(:add_block!).with('svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }')
125
123
  expect(css_parser).to receive(:add_block!).with("a\n before>\n x y\n inside <>&gt;\n k j\n after\nz")
126
124
  expect(css_parser).to receive(:add_block!).with('hello')
127
125
  allow(css_parser).to receive(:each_rule_set)
@@ -175,8 +175,8 @@ describe Prawn::SVG::Elements::Base do
175
175
  </style>
176
176
  <rect width="100" height="100"></rect>
177
177
  <g class="special">
178
- <rect width="100" height="100"></rect>
179
- <rect width="100" height="100" style="fill: yellow;"></rect>
178
+ <rect width="100" fill="blue" height="100"></rect>
179
+ <rect width="100" height="100" fill="blue" style="fill: yellow;"></rect>
180
180
  </g>
181
181
  </svg>
182
182
  SVG
@@ -24,8 +24,26 @@ describe Prawn::SVG::Elements::Gradient do
24
24
  expect(document.gradients['flag']).to eq element
25
25
  end
26
26
 
27
+ it 'returns correct gradient arguments for an element with no bounding box' do
28
+ arguments = element.gradient_arguments(double(bounding_box: nil, stroke_width: 0))
29
+ expect(arguments).to eq(
30
+ from: [0.0, 0.0],
31
+ to: [0.2, 1.0],
32
+ wrap: :pad,
33
+ matrix: Matrix[[1.0, 0.0, 0.0], [0.0, -1.0, 600.0], [0.0, 0.0, 1.0]],
34
+ bounding_box: nil,
35
+ stops: [
36
+ { offset: 0, color: 'ff0000', opacity: 1.0 },
37
+ { offset: 0.25, color: 'ff0000', opacity: 1.0 },
38
+ { offset: 0.5, color: 'ffffff', opacity: 1.0 },
39
+ { offset: 0.75, color: '0000ff', opacity: 1.0 },
40
+ { offset: 1, color: '0000ff', opacity: 1.0 }
41
+ ]
42
+ )
43
+ end
44
+
27
45
  it 'returns correct gradient arguments for an element' do
28
- arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
46
+ arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
29
47
  expect(arguments).to eq(
30
48
  from: [0.0, 0.0],
31
49
  to: [0.2, 1.0],
@@ -59,7 +77,7 @@ describe Prawn::SVG::Elements::Gradient do
59
77
  end
60
78
 
61
79
  it 'returns correct gradient arguments for an element' do
62
- arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
80
+ arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
63
81
  expect(arguments).to eq(
64
82
  from: [0.5, 0.2],
65
83
  to: [0.0, 0.2],
@@ -90,7 +108,7 @@ describe Prawn::SVG::Elements::Gradient do
90
108
  end
91
109
 
92
110
  it 'returns correct gradient arguments for an element' do
93
- arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
111
+ arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
94
112
  expect(arguments).to eq(
95
113
  from: [100.0, 500.0],
96
114
  to: [200.0, 600.0],
@@ -113,7 +131,7 @@ describe Prawn::SVG::Elements::Gradient do
113
131
  end
114
132
 
115
133
  it 'returns correct gradient arguments for an element' do
116
- arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
134
+ arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
117
135
  expect(arguments).to eq(
118
136
  from: [100.0, 500.0],
119
137
  to: [200.0, 600.0],
@@ -138,7 +156,7 @@ describe Prawn::SVG::Elements::Gradient do
138
156
  end
139
157
 
140
158
  it 'passes in the transform via the apply_transformations option' do
141
- arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
159
+ arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
142
160
 
143
161
  expect(arguments).to eq(
144
162
  from: [0.0, 0.0],
@@ -168,7 +186,7 @@ describe Prawn::SVG::Elements::Gradient do
168
186
  end
169
187
 
170
188
  it 'correctly inherits the attributes from the parent element' do
171
- arguments = document.gradients['flag-2'].gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
189
+ arguments = document.gradients['flag-2'].gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
172
190
  expect(arguments).to eq(
173
191
  from: [150.0, 500.0],
174
192
  to: [220.0, 600.0],
@@ -178,7 +196,7 @@ describe Prawn::SVG::Elements::Gradient do
178
196
  bounding_box: [100, 100, 200, 0]
179
197
  )
180
198
 
181
- arguments = document.gradients['flag-3'].gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
199
+ arguments = document.gradients['flag-3'].gradient_arguments(double(bounding_box: [100, 100, 200, 0], stroke_width: 0))
182
200
  expect(arguments).to eq(
183
201
  from: [170.0, 500.0],
184
202
  to: [220.0, 600.0],
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Illustration" viewBox="0 0 1275 850" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <defs>
4
+ <style>.cls-3{fill:url(#linear-gradient);}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:url(#linear-gradient-2);}</style>
5
+ <linearGradient gradientTransform="translate(3610.94 -4546.2)" gradientUnits="userSpaceOnUse" id="linear-gradient" x1="-3428.66" x2="-2829.15" y1="4803.57" y2="4803.57">
6
+ <stop offset="0" stop-color="orange" stop-opacity="0"/>
7
+ <stop offset=".04" stop-color="orange" stop-opacity=".04"/>
8
+ <stop offset=".12" stop-color="orange" stop-opacity=".16"/>
9
+ <stop offset=".21" stop-color="orange" stop-opacity=".34"/>
10
+ <stop offset=".32" stop-color="orange" stop-opacity=".6"/>
11
+ <stop offset=".44" stop-color="orange" stop-opacity=".92"/>
12
+ <stop offset=".47" stop-color="orange"/>
13
+ <stop offset=".58" stop-color="darksalmon"/>
14
+ <stop offset=".8" stop-color="darksalmon"/>
15
+ <stop offset=".9" stop-color="red"/>
16
+ </linearGradient>
17
+ <linearGradient gradientTransform="translate(5391.8 -3148.45)" gradientUnits="userSpaceOnUse" id="linear-gradient-2" x1="-4854.3" x2="-4254.78" y1="3443.47" y2="3443.47">
18
+ <stop offset=".06" stop-color="orange" stop-opacity="0"/>
19
+ <stop offset=".11" stop-color="orange" stop-opacity=".07"/>
20
+ <stop offset=".19" stop-color="orange" stop-opacity=".26"/>
21
+ <stop offset=".31" stop-color="orange" stop-opacity=".56"/>
22
+ <stop offset=".46" stop-color="orange" stop-opacity=".97"/>
23
+ <stop offset=".47" stop-color="orange"/>
24
+ <stop offset="1" stop-color="red"/>
25
+ </linearGradient>
26
+ <linearGradient gradientTransform="translate(-1037.04 -401.09)" id="linear-gradient-3" x1="1460.82" x2="2060.34" xlink:href="#linear-gradient-2" y1="1006.26" y2="1006.26"/>
27
+ <linearGradient gradientTransform="translate(-295.18 -2362.64)" gradientUnits="userSpaceOnUse" id="linear-gradient-4" x1="610.99" x2="1210.5" y1="2682.84" y2="2682.84">
28
+ <stop offset=".09" stop-color="orange" stop-opacity="0"/>
29
+ <stop offset=".13" stop-color="orange" stop-opacity=".05"/>
30
+ <stop offset=".21" stop-color="orange" stop-opacity=".19"/>
31
+ <stop offset=".31" stop-color="orange" stop-opacity=".41"/>
32
+ <stop offset=".42" stop-color="orange" stop-opacity=".72"/>
33
+ <stop offset=".52" stop-color="orange"/>
34
+ <stop offset=".92" stop-color="red"/>
35
+ </linearGradient>
36
+ <linearGradient gradientTransform="translate(520.38 -911.81)" gradientUnits="userSpaceOnUse" id="linear-gradient-5" x1="-366.91" x2="258.33" y1="1381.44" y2="1381.44">
37
+ <stop offset="0" stop-color="#fff" stop-opacity="0"/>
38
+ <stop offset="1" stop-color="#fff"/>
39
+ </linearGradient>
40
+ </defs>
41
+ <rect class="cls-3" height="138.93" rx="69.47" ry="69.47" transform="translate(1004.69 98.45) rotate(135)" width="599.51" x="182.2" y="187.85"/>
42
+ <rect class="cls-7" height="138.93" rx="69.47" ry="69.47" transform="translate(1637.84 -88.45) rotate(135)" width="599.51" x="537.48" y="225.52"/>
43
+ <rect class="cls-5" height="138.93" rx="69.47" ry="69.47" transform="translate(-216.02 688.88) rotate(-45)" width="599.51" x="423.77" y="535.72"/>
44
+ <rect class="cls-6" height="138.93" rx="69.47" ry="69.47" transform="translate(-46.13 529.06) rotate(-45)" width="599.51" x="315.78" y="250.74"/>
45
+ </svg>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="320" height="320">
3
+ <rect x="10" y="10" width="100" height="100" class="green" id="id" />
4
+ <text x="10" y="130" fill="green">The square above should be green</text>
5
+
6
+ <rect x="10" y="170" width="100" height="100" class="green" style="fill: blue;" />
7
+ <text x="10" y="290" fill="green">The square above should be also be green</text>
8
+
9
+ <style>
10
+ .green { fill: green !important; }
11
+ rect.green { fill: red; }
12
+ #id { fill: orange; }
13
+ </style>
14
+ </svg>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="320" height="320">
3
+ <rect x="10" y="10" width="100" height="100" fill="red" />
4
+ <text x="10" y="130" fill="green">The square above should be green</text>
5
+
6
+ <rect x="10" y="170" width="100" height="100" fill="red" style="fill: blue;" />
7
+ <text x="10" y="290" fill="blue">The square above should be blue</text>
8
+
9
+ <style>
10
+ rect { fill: green; }
11
+ </style>
12
+ </svg>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn-svg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.36.1
4
+ version: 0.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mog Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-26 00:00:00.000000000 Z
11
+ date: 2025-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -150,12 +150,12 @@ files:
150
150
  - lib/prawn/svg/loaders/web.rb
151
151
  - lib/prawn/svg/paint.rb
152
152
  - lib/prawn/svg/pathable.rb
153
+ - lib/prawn/svg/pdfmatrix.rb
153
154
  - lib/prawn/svg/percentage.rb
154
155
  - lib/prawn/svg/properties.rb
155
156
  - lib/prawn/svg/renderer.rb
156
157
  - lib/prawn/svg/state.rb
157
158
  - lib/prawn/svg/transform_parser.rb
158
- - lib/prawn/svg/transform_utils.rb
159
159
  - lib/prawn/svg/ttf.rb
160
160
  - lib/prawn/svg/url_loader.rb
161
161
  - lib/prawn/svg/version.rb
@@ -216,6 +216,7 @@ files:
216
216
  - spec/sample_svg/ellipse01.svg
217
217
  - spec/sample_svg/gistfile1.svg
218
218
  - spec/sample_svg/google_charts.svg
219
+ - spec/sample_svg/gradient_offset_transparency.svg
219
220
  - spec/sample_svg/gradient_stress_test.svg
220
221
  - spec/sample_svg/gradient_transform.svg
221
222
  - spec/sample_svg/gradients-cmyk.svg
@@ -226,6 +227,7 @@ files:
226
227
  - spec/sample_svg/image02_base64.svg
227
228
  - spec/sample_svg/image03.svg
228
229
  - spec/sample_svg/image_svg.svg
230
+ - spec/sample_svg/important.svg
229
231
  - spec/sample_svg/line01.svg
230
232
  - spec/sample_svg/links.svg
231
233
  - spec/sample_svg/marker.svg
@@ -243,6 +245,7 @@ files:
243
245
  - spec/sample_svg/pie_piece.svg
244
246
  - spec/sample_svg/polygon01.svg
245
247
  - spec/sample_svg/polyline01.svg
248
+ - spec/sample_svg/presentation_attribute_precedence.svg
246
249
  - spec/sample_svg/preserve-space.svg
247
250
  - spec/sample_svg/quad01.svg
248
251
  - spec/sample_svg/radgrad01-bounding.svg
File without changes