From 55e342d08e829e3a98f9aed47aba2fa2d1ee6754 Mon Sep 17 00:00:00 2001 From: Thomas Leitner Date: Thu, 8 Dec 2016 11:04:44 +0100 Subject: [PATCH] Fix dash implementation to conform to spec The PDF 1.7 specification says that the dash array can contain zeros but that not all numbers must be zero. Additionally, a single dash length or any number in a dash array may not be negative. --- lib/prawn/graphics/dash.rb | 13 ++++++++++--- spec/graphics_spec.rb | 6 +++++- spec/stroke_styles_spec.rb | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/prawn/graphics/dash.rb b/lib/prawn/graphics/dash.rb index ffe1778c0..abf4ee33d 100644 --- a/lib/prawn/graphics/dash.rb +++ b/lib/prawn/graphics/dash.rb @@ -28,8 +28,9 @@ module Dash # 3 on, 2 off, 3 on, 2 off, ... # # * If the parameter +length+ is an array, it specifies the - # lengths of alternating dashes and gaps. The :space option is - # ignored in this case. + # lengths of alternating dashes and gaps. The numbers must be + # non-negative and not all zero. The :space option is ignored + # in this case. # # Examples: # @@ -37,6 +38,8 @@ module Dash # 2 on, 1 off, 2 on, 1 off, ... # length = [3, 1, 2, 3] # 3 on, 1 off, 2 on, 3 off, 3 on, 1 off, ... + # length = [3, 0, 1] + # 3 on, 0 off, 1 on, 3 off, 0 on, 1 off, ... # # Options may contain the keys :space and :phase # @@ -55,9 +58,13 @@ module Dash def dash(length = nil, options = {}) return current_dash_state if length.nil? - if length == 0 || length.kind_of?(Array) && length.any? { |e| e == 0 } + if length == 0 || length.kind_of?(Array) && length.all? { |e| e == 0 } fail ArgumentError, "Zero length dashes are invalid. Call #undash to disable dashes." + elsif length.kind_of?(Integer) && length < 0 || + length.kind_of?(Array) && length.any? { |e| e < 0 } + fail ArgumentError, + "Negative numbers are not allowed for dash lengths." end self.current_dash_state = { :dash => length, diff --git a/spec/graphics_spec.rb b/spec/graphics_spec.rb index a12562c89..69a64e44f 100644 --- a/spec/graphics_spec.rb +++ b/spec/graphics_spec.rb @@ -500,7 +500,11 @@ expect { @pdf.dash(0) }.to raise_error(ArgumentError) expect { @pdf.dash([0]) }.to raise_error(ArgumentError) expect { @pdf.dash([0, 0]) }.to raise_error(ArgumentError) - expect { @pdf.dash([0, 0, 0, 1]) }.to raise_error(ArgumentError) + end + + it "should raise an error when dash is called w. negative lengths" do + expect { @pdf.dash(-1) }.to raise_error(ArgumentError) + expect { @pdf.dash([1, -3]) }.to raise_error(ArgumentError) end it "the current graphic state should keep track of previous unchanged settings" do diff --git a/spec/stroke_styles_spec.rb b/spec/stroke_styles_spec.rb index c2c54ed98..1ed4182f2 100644 --- a/spec/stroke_styles_spec.rb +++ b/spec/stroke_styles_spec.rb @@ -149,6 +149,11 @@ dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render) expect(dashes.stroke_dash).to eq([[1, 2, 3, 4], 0]) end + it "at least one number in the array must not be zero" do + @pdf.dash([1, 0]) + dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render) + expect(dashes.stroke_dash).to eq([[1, 0], 0]) + end it "space options has to be ignored" do @pdf.dash([1, 2, 3, 4], :space => 3) dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)