prawnpdf / prawn

Fast, Nimble PDF Writer for Ruby
https://prawnpdf.org
Other
4.66k stars 688 forks source link

support arbitrary fill patterns #1202

Open artbot1 opened 3 years ago

artbot1 commented 3 years ago
module Prawn
  module Graphics
    module Patterns

can generate shading patterns

PatternType: 2

but there is no support for fill patterns yet

PatternType: 1

here an example from the PDF doc

15 0 obj
<< /Type /Pattern
/PatternType 1          % Tiling pattern
/PaintType 1
/TilingType 2
/BBox [ 0 0 100 100 ]
/XStep 100
/YStep 100
/Resources 16 0 R
/Matrix [ 0.4 0.0 0.0 0.4 0.0 0.0 ]
/Length 183
>>

it would be great if prawn would support this. think of (monochrome) bar charts with patterns etc.

artbot1 commented 3 years ago

here some (very) quick an dirty sample code for this (just to see what's possible):

require 'prawn.rb'

module Prawn
  module Graphics
    module Patterns
      def create_art_pattern
        patterns = page.resources[:Pattern] ||= {}

        art_pat= ref!(
          #Type: '/Pattern',
          PatternType: 1,
          PaintType: 1,
          TilingType: 2,
          BBox: [ 0,0,20,20 ],
          XStep: 20,
          YStep: 20,
          Matrix: [ 1.0,0.0,0.0,1.0,0.0,0.0 ]
        )

        stream= PDF::Core::Stream.new
        stream << "5.0 5.0 10.0 10.0 re"
        stream << "\nf"

        art_pat.stream = stream

        registry_key= "dummytest123"
        patterns["SP#{registry_key}"] = art_pat

        type= :fill

        operator =
          case type
          when :fill
            'scn'
          when :stroke
            'SCN'
          else
            raise ArgumentError, "unknown type '#{type}'"
          end

        set_color_space type, :Pattern
        renderer.add_content "/SP#{registry_key} #{operator}"
      end

    end
  end
end

pdf= Prawn::Document.new(page_layout: :portrait, page_size: 'A4', margin: 0.0) do
  #stroke_axis(:step_length => 1.cm.to_i) #only shows up with margin > 0
  pdf= self
  #fill_gradient [50, 300], [150, 200], 'ff0000', '0000ff'

  create_art_pattern
  fill_rectangle [50, 300], 100, 100

  #fill_rectangle [155, 300], 100, 100

  render_file('/tmp/gradient.pdf')
end
gettalong commented 2 years ago

Thanks - this sounds useful to have in Prawn but will probably be need to be implemented by the community. So pull requests for this feature are welcome!