File: images_spec.rb

package info (click to toggle)
ruby-prawn 2.2.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,320 kB
  • sloc: ruby: 15,654; sh: 43; makefile: 20
file content (172 lines) | stat: -rw-r--r-- 5,410 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
require 'spec_helper'
require 'set'
require 'pathname'

describe Prawn::Images do
  let(:pdf) { create_pdf }
  let(:filename) { "#{Prawn::DATADIR}/images/pigs.jpg" }

  it "onlies embed an image once, even if it's added multiple times" do
    pdf.image filename, at: [100, 100]
    pdf.image filename, at: [300, 300]

    output = pdf.render
    images = PDF::Inspector::XObject.analyze(output)
    # there should be 2 images in the page resources
    expect(images.page_xobjects.first.size).to eq(2)
    # but only 1 image xobject
    expect(output.scan(%r{/Type /XObject}).size).to eq(1)
  end

  it 'returns the image info object' do
    info = pdf.image(filename)

    expect(info).to be_a_kind_of(Prawn::Images::JPG)

    expect(info.height).to eq(453)
  end

  it 'accepts IO objects' do
    file = File.open(filename, 'rb')
    info = pdf.image(file)

    expect(info.height).to eq(453)
  end

  it 'rewinds IO objects to be able to embed them multiply' do
    file = File.open(filename, 'rb')

    pdf.image(file)
    info = pdf.image(file)
    expect(info.height).to eq(453)
  end

  it 'accepts Pathname objects' do
    info = pdf.image(Pathname.new(filename))
    expect(info.height).to eq(453)
  end

  context 'setting the length of the bytestream' do
    it 'correctlies work with images from Pathname objects' do
      pdf.image(Pathname.new(filename))
      expect(pdf).to have_parseable_xobjects
    end

    it 'correctlies work with images from IO objects' do
      pdf.image(File.open(filename, 'rb'))
      expect(pdf).to have_parseable_xobjects
    end

    it 'correctlies work with images from IO objects not set to mode rb' do
      pdf.image(File.open(filename, 'r'))
      expect(pdf).to have_parseable_xobjects
    end
  end

  it 'raise_errors an UnsupportedImageType if passed a BMP' do
    pending "spec disabled since tru256.bmp removed from source package (Debian patch)
    filename = "#{Prawn::DATADIR}/images/tru256.bmp"
    expect { pdf.image filename, at: [100, 100] }
      .to raise_error(Prawn::Errors::UnsupportedImageType)
  end

  it 'raise_errors an UnsupportedImageType if passed an interlaced PNG' do
    pending "spec disabled since dice_interlaced.png removed from source package (Debian patch)"
    filename = "#{Prawn::DATADIR}/images/dice_interlaced.png"
    expect { pdf.image filename, at: [100, 100] }
      .to raise_error(Prawn::Errors::UnsupportedImageType)
  end

  xit 'bumps PDF version to 1.5 or greater on embedding 16-bit PNGs' do
    pdf.image "#{Prawn::DATADIR}/images/16bit.png"
    expect(pdf.state.version).to be >= 1.5
  end

  xit 'embeds 16-bit alpha channels for 16-bit PNGs' do
    pdf.image "#{Prawn::DATADIR}/images/16bit.png"

    output = pdf.render
    expect(output).to match(%r{/BitsPerComponent 16})
    expect(output).to_not match(%r{/BitsPerComponent 8})
  end

  it 'flows an image to a new page if it will not fit on a page' do
    pdf.image filename, fit: [600, 600]
    pdf.image filename, fit: [600, 600]
    output = StringIO.new(pdf.render, 'r+')
    hash = PDF::Reader::ObjectHash.new(output)
    pages = hash.values.find do |obj|
      obj.is_a?(Hash) && obj[:Type] == :Pages
    end[:Kids]
    expect(pages.size).to eq(2)
    expect(hash[pages[0]][:Resources][:XObject].keys).to eq([:I1])
    expect(hash[pages[1]][:Resources][:XObject].keys).to eq([:I2])
  end

  it 'does not flow an image to a new page if it will fit on one page' do
    pdf.image filename, fit: [400, 400]
    pdf.image filename, fit: [400, 400]
    output = StringIO.new(pdf.render, 'r+')
    hash = PDF::Reader::ObjectHash.new(output)
    pages = hash.values.find do |obj|
      obj.is_a?(Hash) && obj[:Type] == :Pages
    end[:Kids]
    expect(pages.size).to eq(1)
    expect(Set.new(hash[pages[0]][:Resources][:XObject].keys)).to eq(
      Set.new([:I1, :I2])
    )
  end

  it 'does not start a new page just for a stretchy bounding box' do
    allow(pdf).to receive(:start_new_page)
    pdf.bounding_box([0, pdf.cursor], width: pdf.bounds.width) do
      pdf.image filename
    end
    expect(pdf).to_not have_received(:start_new_page)
  end

  describe ':fit option' do
    it 'fits inside the defined constraints' do
      info = pdf.image filename, fit: [100, 400]
      expect(info.scaled_width).to be <= 100
      expect(info.scaled_height).to be <= 400

      info = pdf.image filename, fit: [400, 100]
      expect(info.scaled_width).to be <= 400
      expect(info.scaled_height).to be <= 100

      info = pdf.image filename, fit: [604, 453]
      expect(info.scaled_width).to eq(604)
      expect(info.scaled_height).to eq(453)
    end
    it 'moves text position' do
      y = pdf.y
      pdf.image filename, fit: [100, 400]
      expect(pdf.y).to be < y
    end
  end

  describe ':at option' do
    it 'does not move text position' do
      y = pdf.y
      pdf.image filename, at: [100, 400]
      expect(pdf.y).to eq(y)
    end
  end

  describe ':width option without :height option' do
    it 'scales the width and height' do
      info = pdf.image filename, width: 225
      expect(info.scaled_height).to eq(168.75)
      expect(info.scaled_width).to eq(225.0)
    end
  end

  describe ':height option without :width option' do
    it 'scales the width and height' do
      info = pdf.image filename, height: 225
      expect(info.scaled_height).to eq(225.0)
      expect(info.scaled_width).to eq(300.0)
    end
  end
end