pdf_margins 0.1.1 → 0.2.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
  SHA1:
3
- metadata.gz: 6065ffaa732ecbbbe1d9addb6275715ea9613596
4
- data.tar.gz: 8a3e756c74ba210add152540fee7948255bd40ff
3
+ metadata.gz: d41e2247fb4dead96b77524b5c4524bfc3802692
4
+ data.tar.gz: 73d2bd7d01f22f3232716376e64ee52a63c81a20
5
5
  SHA512:
6
- metadata.gz: 5f89e8ca71ee8d320e7afc9cae7181a839429c23e306b6ce916a4294a6991bc9a4d99c407405d6f102648ab4bf489a0b5d73e97fff1fa68f4cd8eb8a4d569195
7
- data.tar.gz: bc12bde2c429fe3eb0ed5b79daa775b837717a773b9ad391209f11c7747b544c650c9c984aecbe6c3c793a6f1d1b6fad57ecf504ffad4b9d5ddc58c3f29747bf
6
+ metadata.gz: 2231c4e3028feddc1b17ce1413d938518b27b11e14e84913683e90a1187c21b2ec47c91c1927116f063d11096d04822301b0c86fda17d3559b83cc3d2430e3b9
7
+ data.tar.gz: 1fe63baac8954e2b26774d7aa644ffaab0754c936a64fffca2c1f0e7edd3158995cf98a0d77a118c61695eee1d1b770ff799d752332dcf99470ed4e7564c9627
data/README.md CHANGED
@@ -5,18 +5,31 @@ pdf/margins
5
5
  Status](https://travis-ci.org/newspaperclub/pdf_margins.png)](https://travis-ci.org/newspaperclub/pdf_margins)
6
6
 
7
7
  Simple Ruby library to check a PDF for clear margin areas, by rendering to
8
- a CMYK bitmap, ensuring that the pixel area defined by each margin is empty.
9
- It's pretty slow, but this is a lot easier than attempting to work out which
10
- object in a PDF is rendering into the margin area.
8
+ a bitmap, ensuring that the pixel area defined by each margin is empty.
11
9
 
12
- Depends on RMagick, and thus requires a Ruby interpreter that supports
13
- C extensions, such as MRI.
10
+ This is a bit of a clumsy technique, but it's faster than parsing and
11
+ understanding all the permutations of the PDF format that may result in an
12
+ object being visible in the margins.
14
13
 
15
- Written by [Tom Taylor](http://scraplab.net), [Newspaper Club](http://www.newspaperclub.com).
14
+ It shells out to `mudraw`, part of [mupdf] [1], for rastering the PDF to PNGs,
15
+ and then uses [Chunky PNG] [2] to examine each page's margins.
16
+
17
+ On Ubuntu, you may wish to install `mupdf` from the [PPA] [3].
18
+
19
+ Written by [Tom Taylor] [3], [Newspaper Club] [4].
20
+
21
+ [1]: http://www.mupdf.com
22
+ [2]: https://github.com/wvanbergen/chunky_png
23
+ [3]: https://launchpad.net/~mupdf/+archive/stable
24
+ [4]: http://scraplab.net
25
+ [5]: http://www.newspaperclub.com
16
26
 
17
27
  Example
18
28
  --
19
29
 
30
+ # accepts a `spreads` boolean which assumes margin dimensions refer to
31
+ # spreads, and so alternates which pages we check left and right margins on
32
+ spreads = true
20
33
  # measurements in mm, ordered top, right, bottom, left (same as CSS)
21
- checker = PDF::Margins::Checker.new('example.pdf', 10, 10, 10, 10)
34
+ checker = PDF::Margins::Checker.new('example.pdf', 10, 10, 10, 10, spreads)
22
35
  puts checker.issues.inspect
@@ -1,5 +1,7 @@
1
1
  require 'pdf/margins/issue'
2
- require 'RMagick'
2
+ require 'chunky_png'
3
+ require 'oily_png'
4
+ require 'tmpdir'
3
5
 
4
6
  module PDF
5
7
  module Margins
@@ -12,12 +14,12 @@ module PDF
12
14
  SCALE_MULTIPLIER = 1
13
15
  RESOLUTION = DEFAULT_RESOLUTION * SCALE_MULTIPLIER
14
16
 
15
- attr_reader :file, :top_margin, :right_margin, :bottom_margin, :left_margin, :spreads
17
+ attr_reader :file_path, :top_margin, :right_margin, :bottom_margin, :left_margin, :spreads
16
18
 
17
19
  # Dimensions are in mm, to be converted to PDF points later. Pass spreads
18
20
  # as true to check left and right margins of spreads, not pages.
19
- def initialize(file, top_margin, right_margin, bottom_margin, left_margin, spreads=false)
20
- @file = file
21
+ def initialize(file_path, top_margin, right_margin, bottom_margin, left_margin, spreads=false)
22
+ @file_path = file_path
21
23
  @top_margin = top_margin
22
24
  @right_margin = right_margin
23
25
  @bottom_margin = bottom_margin
@@ -26,36 +28,41 @@ module PDF
26
28
  end
27
29
 
28
30
  def issues
29
- image_list = Magick::Image.read(file) do
30
- # Force CMYK colorspace, because ImageMagick autodetects PDF colorspace
31
- # depending on the contents of the file. By forcing the colorspace we
32
- # ensure that the subsequent checks in the `dirty_pixels?` method work.
33
- self.colorspace = Magick::CMYKColorspace
34
- self.density = RESOLUTION
35
- self.antialias = false
36
- end
31
+ temp_dir_path = Dir.mktmpdir("pdf_margins")
32
+
33
+ begin
34
+ # This produces greyscale PNGs - we throw the colour away because we
35
+ # don't need it to check for margins.
36
+ system("mudraw -g -b 0 -r #{RESOLUTION} -o #{temp_dir_path}/%d.png #{file_path}") || raise
37
+
38
+ issues = []
37
39
 
38
- image_list.each_with_index.map do |image, index|
40
+ Dir.glob("#{temp_dir_path}/*.png").each_with_index do |png_path, index|
41
+ image = ChunkyPNG::Image.from_file(png_path)
42
+ page_number = index + 1
39
43
 
40
- page_number = index + 1
41
- [].tap do |page_issues|
42
- if dirty_pixels?(top_pixels(image, top_margin))
43
- page_issues << Issue.new(page_number, :top)
44
+ if dirty_top_margin?(image, top_margin)
45
+ issues << Issue.new(page_number, :top)
44
46
  end
45
47
 
46
- if dirty_pixels?(bottom_pixels(image, bottom_margin))
47
- page_issues << Issue.new(page_number, :bottom)
48
+ if dirty_bottom_margin?(image, bottom_margin)
49
+ issues << Issue.new(page_number, :bottom)
48
50
  end
49
51
 
50
- if (!spreads || page_number % 2 == 0) && dirty_pixels?(left_pixels(image, left_margin))
51
- page_issues << Issue.new(page_number, :left)
52
+ if (!spreads || page_number % 2 == 0) && dirty_left_margin?(image, left_margin)
53
+ issues << Issue.new(page_number, :left)
52
54
  end
53
55
 
54
- if (!spreads || page_number % 2 != 0) && dirty_pixels?(right_pixels(image, right_margin))
55
- page_issues << Issue.new(page_number, :right)
56
+ if (!spreads || page_number % 2 != 0) && dirty_right_margin?(image, right_margin)
57
+ issues << Issue.new(page_number, :right)
56
58
  end
57
59
  end
58
- end.flatten
60
+
61
+ ensure
62
+ FileUtils.remove_entry(temp_dir_path)
63
+ end
64
+
65
+ return issues
59
66
  end
60
67
 
61
68
  private
@@ -64,31 +71,38 @@ module PDF
64
71
  (mm * MM_TO_PTS * SCALE_MULTIPLIER).floor
65
72
  end
66
73
 
67
- def top_pixels(image, mm)
68
- width_px = mm_to_pixels(mm)
69
- image.get_pixels(0, 0, image.columns, width_px)
74
+ def dirty_top_margin?(image, mm)
75
+ px = mm_to_pixels(mm)
76
+ dirty_pixels?(image, 0, px-1, 0, image.width-1)
70
77
  end
71
78
 
72
- def left_pixels(image, mm)
73
- width_px = mm_to_pixels(mm)
74
- image.get_pixels(0, 0, width_px, image.rows)
79
+ def dirty_left_margin?(image, mm)
80
+ px = mm_to_pixels(mm)
81
+ dirty_pixels?(image, 0, image.height-1, 0, px-1)
75
82
  end
76
83
 
77
- def right_pixels(image, mm)
78
- width_px = mm_to_pixels(mm)
79
- x = image.columns - width_px
80
- image.get_pixels(x, 0, width_px, image.rows)
84
+ def dirty_right_margin?(image, mm)
85
+ px = mm_to_pixels(mm)
86
+ offset = image.width - px - 1
87
+ dirty_pixels?(image, 0, image.height-1, offset, image.width-1)
81
88
  end
82
89
 
83
- def bottom_pixels(image, mm)
84
- width_px = mm_to_pixels(mm)
85
- y = image.rows - width_px
86
- image.get_pixels(0, y, image.columns, width_px)
90
+ def dirty_bottom_margin?(image, mm)
91
+ px = mm_to_pixels(mm)
92
+ offset = image.height - px - 1
93
+ dirty_pixels?(image, offset, image.height-1, 0, image.width-1)
87
94
  end
88
95
 
89
- def dirty_pixels?(pixels)
90
- pixels.any? do |p|
91
- (p.cyan | p.magenta | p.yellow | p.black) > 0
96
+ def dirty_pixels?(image, row_start, row_end, column_start, column_end)
97
+ rows = (row_start..row_end).to_a
98
+ columns = (column_start..column_end).to_a
99
+
100
+ white = ChunkyPNG::Color::WHITE
101
+
102
+ rows.any? do |row|
103
+ columns.any? do |column|
104
+ image[column, row] != white
105
+ end
92
106
  end
93
107
  end
94
108
 
@@ -1,5 +1,5 @@
1
1
  module PDF
2
2
  module Margins
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdf_margins
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-11 00:00:00.000000000 Z
11
+ date: 2013-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rmagick
14
+ name: chunky_png
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 2.13.2
19
+ version: 1.2.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 2.13.2
26
+ version: 1.2.8
27
+ - !ruby/object:Gem::Dependency
28
+ name: oily_png
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
108
  version: '0'
95
109
  requirements: []
96
110
  rubyforge_project:
97
- rubygems_version: 2.0.2
111
+ rubygems_version: 2.0.3
98
112
  signing_key:
99
113
  specification_version: 4
100
114
  summary: Simple library to checks whether the margins are clear in a PDF