hexapdf-extras 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c7f4718bb802b0d1dd228a9fa22fb44ed10dd95402d72c664d937dc8368c5c2
4
- data.tar.gz: 7a8111bdb4d323ae5ca910bb215c6aacdbb0799ea05a264a5d4d459a7b21c67c
3
+ metadata.gz: 33a96708a4a5370678eefced16946538c63b6a078631d0f5c6b431a997874ff1
4
+ data.tar.gz: 82dadc4117398db36f731c1aeb0fe2a360f299a1d4cc19ae039297ec39129efa
5
5
  SHA512:
6
- metadata.gz: bdf857f06fc000adb0a716bcb4d039b314a0acd3f424a2e39f370bf61851741467f4b3e6319b02d7d0f86d95179ab399ad88cdf0ba95f2202efbae9e422c3ef1
7
- data.tar.gz: a9ba5813153564d05eff9c10e538a1793c3c6f469025969d50e17ffeb2755e64c7b2c57d88f4a0acb18ef1dfdc853f22d8238fb559e665261134bae5c44ff850
6
+ metadata.gz: 7182df01f81a1712c18e8145ca27f0a2b33fc05b7c1dedc6f725be302029938afb76d35d2d3c08d15145bdf240963b20dcf1e4e641aed450327d704a3f765e45
7
+ data.tar.gz: 6473c0cbf68559279f377fdfc2862050d7ebb2ab0521d97c8fe1660321a7636a1a9aed992bc669afac25c8d15f5fbaa9b4b7092a4fff9369afde4bf2ab0fe2aa
data/README.rdoc CHANGED
@@ -38,6 +38,29 @@ Note: There was a {bug in poppler}[https://gitlab.freedesktop.org/poppler/popple
38
38
  (already fixed) which leads to invalid rendering in Okular (as of 2022-08-06).
39
39
 
40
40
 
41
+ === Barcode Generator
42
+
43
+ This extensions provides access to generating nearly any kind of barcode. It taps into the graphic
44
+ objects and boxes system of HexaPDF to easily allow creating barcodes:
45
+
46
+ require 'hexapdf'
47
+ require 'hexapdf-extras'
48
+
49
+ doc = HexaPDF::Document.new
50
+ canvas = doc.pages.add.canvas
51
+ canvas.draw(:barcode, at: [100, 100], width: 300, symbology: :code128, value: "Hello HexaPDF!")
52
+ doc.write('zint.pdf')
53
+
54
+ Underneath the +ruby-zint+ library is used which relies on the libzint library via FFI. This means
55
+ that you need to install the +ruby-zint+ library for this extension to work.
56
+
57
+ See
58
+ {HexaPDF::Extras::GraphicObject::Zint}[https://hexapdf-extras.gettalong.org/api/HexaPDF/Extras/GraphicObject/Zint.html]
59
+ and
60
+ {HexaPDF::Extras::Layout::ZintBox}[https://hexapdf-extras.gettalong.org/api/HexaPDF/Extras/Layout/ZintBox.html]
61
+ for details.
62
+
63
+
41
64
  === Swiss QR-bill generator
42
65
 
43
66
  This extension provides a box class for the document layouting facilities of HexaPDF to easily
@@ -0,0 +1,228 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zint'
4
+
5
+ module HexaPDF
6
+ module Extras
7
+ module GraphicObject
8
+
9
+ # Generates a barcode using the {ruby-zint}[https://github.com/eliasfroehner/ruby-zint]
10
+ # library that uses the libzint barcode generation library.
11
+ #
12
+ # It implements the {HexaPDF graphic object
13
+ # interface}[https://hexapdf.gettalong.org/documentation/api/HexaPDF/Content/GraphicObject/index.html]
14
+ # and can therefore easily be used via the +:barcode+ name:
15
+ #
16
+ # canvas.draw(:barcode, width: 50, at: [10, 40], value: 'Hello!', symbology: :code128)
17
+ #
18
+ # Except for a few keyword arguments all are passed through to ruby-zint, so everything that
19
+ # is supported by Zint::Barcode can be used. To make specifying symbologies easier, it is
20
+ # possible to use symbolic names instead of the constants, see #configure.
21
+ #
22
+ # == Examples
23
+ #
24
+ # * Linear barcode
25
+ #
26
+ # #>pdf-canvas100
27
+ # canvas.draw(:barcode, width: 60, at: [20, 45], value: '1123456', symbology: :upce)
28
+ # canvas.draw(:barcode, width: 60, at: [20, 5], value: 'Hello!', symbology: :code128)
29
+ #
30
+ # * Stacked barcode
31
+ #
32
+ # #>pdf-canvas100
33
+ # canvas.draw(:barcode, width: 80, at: [10, 40], symbology: :codablockf,
34
+ # value: 'Hello HexaPDF!', option_1: 3)
35
+ #
36
+ # * Composite barcode
37
+ #
38
+ # #>pdf-canvas100
39
+ # canvas.draw(:barcode, width: 80, at: [10, 20], symbology: :gs1_128_cc,
40
+ # value: '[99]1234-abcd', primary: "[01]03312345678903", option_1: 3)
41
+ #
42
+ # * 2D barcode
43
+ #
44
+ # #>pdf-canvas100
45
+ # canvas.draw(:barcode, width: 80, at: [10, 10], symbology: :datamatrix,
46
+ # value: 'Hello HexaPDF!', option_3: 100, output_options: 0x0100)
47
+ class Zint
48
+
49
+ # Creates and configures a new Zint drawing support object.
50
+ #
51
+ # See #configure for the allowed keyword arguments.
52
+ def self.configure(**kwargs)
53
+ new.configure(**kwargs)
54
+ end
55
+
56
+ # The position of the bottom-left corner of the barcode.
57
+ #
58
+ # Default: [0, 0].
59
+ #
60
+ # Examples:
61
+ #
62
+ # #>pdf-canvas100
63
+ # canvas.draw(:barcode, height: 50, value: 'test', symbology: :code128)
64
+ # canvas.draw(:barcode, height: 50, value: 'test', symbology: :code128, at: [20, 50])
65
+ attr_accessor :at
66
+
67
+ # The width of resulting barcode.
68
+ #
69
+ # The resulting size of the barcode depends on whether width and #height are set:
70
+ #
71
+ # * If neither width nor height are set, the barcode uses the size returned by ruby-zint.
72
+ #
73
+ # * If both are set, the barcode is fit exactly into the given rectangle.
74
+ #
75
+ # * If either width or height is set, the other dimension is based on the set dimension so
76
+ # that the original aspect ratio is maintained.
77
+ #
78
+ # Default: nil.
79
+ #
80
+ # Examples:
81
+ #
82
+ # * No dimension set
83
+ #
84
+ # #>pdf-canvas100
85
+ # canvas.draw(:barcode, value: 'test', symbology: :code128)
86
+ #
87
+ # * One dimension set
88
+ #
89
+ # #>pdf-canvas100
90
+ # canvas.draw(:barcode, width: 60, value: 'test', symbology: :code128)
91
+ # canvas.draw(:barcode, height: 50, value: 'test', symbology: :code128, at: [0, 50])
92
+ #
93
+ # * Both dimensions set
94
+ #
95
+ # #>pdf-canvas100
96
+ # canvas.draw(:barcode, width: 60, height: 60, value: 'test', symbology: :code128)
97
+ attr_accessor :width
98
+
99
+ # The height of the barcode.
100
+ #
101
+ # For details and examples see #width.
102
+ #
103
+ # Default: nil.
104
+ attr_accessor :height
105
+
106
+ # The font used when outputting strings.
107
+ #
108
+ # Any font that is supported by the HexaPDF::Document::Layout module is supported.
109
+ #
110
+ # Default: 'Helvetica'.
111
+ #
112
+ # Examples:
113
+ #
114
+ # #>pdf-canvas100
115
+ # canvas.draw(:barcode, height: 50, font: 'Courier', value: 'test', symbology: :code128)
116
+ attr_accessor :font
117
+
118
+ # The keyword arguments that are passed on to Zint::Barcode.new.
119
+ #
120
+ # Default: {}.
121
+ attr_accessor :zint_kws
122
+
123
+ # Creates a Zint graphic object.
124
+ def initialize
125
+ @at = [0, 0]
126
+ @width = nil
127
+ @height = nil
128
+ @font = 'Helvetica'
129
+ @zint_kws = {}
130
+ end
131
+
132
+ # Configures the Zint graphic object and returns self.
133
+ #
134
+ # The following arguments are allowed:
135
+ #
136
+ # :at::
137
+ # The position of the bottom-left corner (see #at).
138
+ #
139
+ # :width::
140
+ # The width of the barcode (see #width).
141
+ #
142
+ # :height::
143
+ # The height of the barcode (see #height).
144
+ #
145
+ # :font::
146
+ # The font to use when outputting strings (see #font).
147
+ #
148
+ # :symbology::
149
+ # The type of barcode. Supports using symbols instead of constants, e.g. +:code128+
150
+ # instead of Zint::BARCODE_CODE128.
151
+ #
152
+ # :zint_kws::
153
+ # Keyword arguments that are passed on to ruby-zint.
154
+ #
155
+ # Any arguments not specified are not modified and retain their old value, see the attribute
156
+ # methods for the inital default values.
157
+ def configure(at: nil, width: nil, height: nil, font: nil, symbology: nil, **zint_kws)
158
+ @at = at if at
159
+ @width = width if width
160
+ @height = height if height
161
+ @font = font if font
162
+ @zint_kws = zint_kws unless zint_kws.empty?
163
+ @zint_kws[:symbology] = if symbology && symbology.kind_of?(Symbol)
164
+ ::Zint.const_get("BARCODE_#{symbology.upcase}")
165
+ elsif symbology
166
+ symbology
167
+ end
168
+ self
169
+ end
170
+
171
+ # Maps the Zint color codes to HexaPDF color names.
172
+ COLOR_CODES = {
173
+ 1 => "cyan",
174
+ 2 => "blue",
175
+ 3 => "magenta",
176
+ 4 => "red",
177
+ 5 => "yellow",
178
+ 6 => "green",
179
+ 7 => "black",
180
+ 8 => "white",
181
+ }
182
+
183
+ # Draws the Zint::Barcode object onto the given canvas, with the bottom-left corner at the
184
+ # position specified by #at and the size specified by #width and #height.
185
+ def draw(canvas)
186
+ form = form_xobject(canvas.context.document)
187
+ canvas.xobject(form, at: @at, width: @width, height: @height)
188
+ end
189
+
190
+ # Creates a Form XObject for the given HexaPDF::Document that contains the visual
191
+ # representation of the barcode.
192
+ def form_xobject(document)
193
+ barcode = ::Zint::Barcode.new(**@zint_kws)
194
+ vector = barcode.to_vector
195
+
196
+ height = vector.height
197
+ form = document.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, vector.width, height]})
198
+ canvas = form.canvas
199
+
200
+ canvas.fill_color(barcode.bgcolour).rectangle(0, 0, vector.width, height).fill
201
+ vector.each_rectangle.group_by {|rect| rect.colour }.each do |color, rects|
202
+ canvas.fill_color(COLOR_CODES.fetch(color, barcode.fgcolour))
203
+ rects.each {|rect| canvas.rectangle(rect.x, height - rect.y, rect.width, -rect.height) }
204
+ canvas.fill
205
+ end
206
+ vector.each_circle.group_by {|circle| circle.colour }.each do |color, circles|
207
+ canvas.fill_color(COLOR_CODES.fetch(color, barcode.fgcolour))
208
+ circles.each {|circle| canvas.circle(circle.x, height - circle.y, circle.diameter / 2.0) }
209
+ canvas.fill
210
+ end
211
+ layout = canvas.context.document.layout
212
+ vector.each_string do |string|
213
+ fragment = layout.text_fragments(string.text, font: @font, font_size: string.fsize)[0]
214
+ x = string.x + case string.halign
215
+ when 0 then -fragment.width / 2.0
216
+ when 1 then 0
217
+ when 2 then -fragment.width
218
+ end
219
+ fragment.draw(canvas, x, height - string.y)
220
+ end
221
+
222
+ form
223
+ end
224
+ end
225
+
226
+ end
227
+ end
228
+ end
@@ -4,6 +4,7 @@ module HexaPDF
4
4
  module Extras
5
5
  module GraphicObject
6
6
  autoload(:QRCode, 'hexapdf/extras/graphic_object/qr_code')
7
+ autoload(:Zint, 'hexapdf/extras/graphic_object/zint')
7
8
  end
8
9
  end
9
10
  end
@@ -4,15 +4,7 @@ require 'hexapdf/error'
4
4
  require 'hexapdf/layout/box'
5
5
  require 'hexapdf/extras/layout'
6
6
 
7
- module HexaPDF::Extras::Layout::NumericMeasurementHelper #:nodoc:
8
- refine Numeric do
9
- def mm
10
- self * 72 / 25.4
11
- end
12
- end
13
- end
14
-
15
- using HexaPDF::Extras::Layout::NumericMeasurementHelper
7
+ using HexaPDF::Utils
16
8
 
17
9
  module HexaPDF
18
10
  module Extras
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hexapdf/layout/box'
4
+ require 'hexapdf/extras/graphic_object/zint'
5
+
6
+ module HexaPDF
7
+ module Extras
8
+ module Layout
9
+
10
+ # A ZintBox object is used for displaying a barcode.
11
+ #
12
+ # Internally, GraphicObject::Zint is used, so any option except +at+, +width+ and +height+
13
+ # supported there can be used here.
14
+ #
15
+ # The size of the barcode is determined by the width and height of the box. For details on how
16
+ # this works see GraphicObject::Zint#width.
17
+ #
18
+ # Example:
19
+ #
20
+ # #>pdf-composer100
21
+ # composer.box(:barcode, height: 30, style: {position: :float},
22
+ # data: {value: 'Test', symbology: :qrcode})
23
+ # composer.box(:barcode, width: 60, style: {position: :float},
24
+ # data: {value: 'Test', symbology: :code128, bgcolour: 'ff0000',
25
+ # fgcolour: '00ffff'})
26
+ # composer.box(:barcode, width: 30, height: 50, style: {position: :float},
27
+ # data: {value: 'Test', symbology: :code128})
28
+ # composer.box(:barcode, data: {value: 'Test', symbology: :code128})
29
+ class ZintBox < HexaPDF::Layout::ImageBox
30
+
31
+ # The HexaPDF::Extras::GraphicObject::Zint object that will be drawn.
32
+ attr_reader :barcode
33
+
34
+ # Creates a new ZintBox object with the given arguments.
35
+ #
36
+ # The argument +data+ needs to contain a hash with the arguments that are passed on to
37
+ # GraphicObject::Zint.
38
+ #
39
+ # Note: Although this box derives from ImageBox, the #image method will only return the
40
+ # correct object after #fit was called.
41
+ def initialize(data:, **kwargs)
42
+ super(image: nil, **kwargs)
43
+ @barcode = GraphicObject::Zint.configure(**data)
44
+ end
45
+
46
+ # Fits the barcode into the given area.
47
+ def fit(available_width, available_height, frame)
48
+ @image ||= @barcode.form_xobject(frame.document)
49
+ super
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -5,6 +5,7 @@ module HexaPDF
5
5
  module Layout
6
6
  autoload(:QRCodeBox, 'hexapdf/extras/layout/qr_code_box')
7
7
  autoload(:SwissQRBill, 'hexapdf/extras/layout/swiss_qr_bill')
8
+ autoload(:ZintBox, 'hexapdf/extras/layout/zint_box')
8
9
  end
9
10
  end
10
11
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module HexaPDF
4
4
  module Extras
5
- VERSION = '1.1.2'
5
+ VERSION = '1.2.0'
6
6
  end
7
7
  end
@@ -11,10 +11,13 @@ end
11
11
 
12
12
  HexaPDF::DefaultDocumentConfiguration['graphic_object.map'][:qrcode] =
13
13
  'HexaPDF::Extras::GraphicObject::QRCode'
14
+ HexaPDF::DefaultDocumentConfiguration['graphic_object.map'][:barcode] =
15
+ 'HexaPDF::Extras::GraphicObject::Zint'
14
16
 
15
17
  HexaPDF::DefaultDocumentConfiguration['layout.boxes.map'][:qrcode] =
16
18
  'HexaPDF::Extras::Layout::QRCodeBox'
17
-
19
+ HexaPDF::DefaultDocumentConfiguration['layout.boxes.map'][:barcode] =
20
+ 'HexaPDF::Extras::Layout::ZintBox'
18
21
  HexaPDF::DefaultDocumentConfiguration['layout.boxes.map'][:swiss_qr_bill] =
19
22
  'HexaPDF::Extras::Layout::SwissQRBill'
20
23
 
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+ require 'hexapdf'
3
+ require 'hexapdf/extras/graphic_object/zint'
4
+
5
+ describe HexaPDF::Extras::GraphicObject::Zint do
6
+ before do
7
+ @obj = HexaPDF::Extras::GraphicObject::Zint.new
8
+ end
9
+
10
+ it "allows creation via the ::configure method" do
11
+ obj = HexaPDF::Extras::GraphicObject::Zint.configure(value: 'test')
12
+ assert_equal('test', obj.zint_kws[:value])
13
+ end
14
+
15
+ it "creates a default drawing support object" do
16
+ assert_equal([0, 0], @obj.at)
17
+ assert_nil(@obj.width)
18
+ assert_nil(@obj.height)
19
+ assert_equal('Helvetica', @obj.font)
20
+ assert_equal({}, @obj.zint_kws)
21
+ end
22
+
23
+ it "allows configuration of the object" do
24
+ assert_same(@obj, @obj.configure(value: 'test', width: 30, symbology: :code128))
25
+ assert_equal('test', @obj.zint_kws[:value])
26
+ assert_equal(::Zint::BARCODE_CODE128, @obj.zint_kws[:symbology])
27
+ assert_equal(30, @obj.width)
28
+ @obj.configure(symbology: ::Zint::BARCODE_DATAMATRIX)
29
+ assert_equal(::Zint::BARCODE_DATAMATRIX, @obj.zint_kws[:symbology])
30
+ end
31
+
32
+ describe "draw" do
33
+ before do
34
+ doc = HexaPDF::Document.new
35
+ @canvas = doc.pages.add.canvas
36
+ end
37
+
38
+ it "draws a barcode onto the canvas" do
39
+ @obj.configure(value: 'test', width: 50, symbology: :code128)
40
+ @obj.draw(@canvas)
41
+ assert_operators(@canvas.contents,
42
+ [[:save_graphics_state],
43
+ [:concatenate_matrix, [0.316456, 0, 0, 0.316456, 0, 0]],
44
+ [:paint_xobject, [:XO1]],
45
+ [:restore_graphics_state]])
46
+ assert_operators(@canvas.context.resources.xobject(:XO1).contents,
47
+ [[:set_device_rgb_non_stroking_color, [1.0, 1.0, 1.0]],
48
+ [:append_rectangle, [0, 0, 158.0, 118.900002]],
49
+ [:fill_path_non_zero],
50
+ [:set_device_rgb_non_stroking_color, [0.0, 0.0, 0.0]],
51
+ [:append_rectangle, [0.0, 118.900002, 4.0, -100.0]],
52
+ [:append_rectangle, [6.0, 118.900002, 2.0, -100.0]],
53
+ [:append_rectangle, [12.0, 118.900002, 2.0, -100.0]],
54
+ [:append_rectangle, [22.0, 118.900002, 2.0, -100.0]],
55
+ [:append_rectangle, [28.0, 118.900002, 8.0, -100.0]],
56
+ [:append_rectangle, [38.0, 118.900002, 2.0, -100.0]],
57
+ [:append_rectangle, [44.0, 118.900002, 2.0, -100.0]],
58
+ [:append_rectangle, [48.0, 118.900002, 4.0, -100.0]],
59
+ [:append_rectangle, [56.0, 118.900002, 2.0, -100.0]],
60
+ [:append_rectangle, [66.0, 118.900002, 2.0, -100.0]],
61
+ [:append_rectangle, [70.0, 118.900002, 8.0, -100.0]],
62
+ [:append_rectangle, [82.0, 118.900002, 2.0, -100.0]],
63
+ [:append_rectangle, [88.0, 118.900002, 2.0, -100.0]],
64
+ [:append_rectangle, [94.0, 118.900002, 8.0, -100.0]],
65
+ [:append_rectangle, [104.0, 118.900002, 2.0, -100.0]],
66
+ [:append_rectangle, [110.0, 118.900002, 8.0, -100.0]],
67
+ [:append_rectangle, [122.0, 118.900002, 2.0, -100.0]],
68
+ [:append_rectangle, [126.0, 118.900002, 2.0, -100.0]],
69
+ [:append_rectangle, [132.0, 118.900002, 4.0, -100.0]],
70
+ [:append_rectangle, [142.0, 118.900002, 6.0, -100.0]],
71
+ [:append_rectangle, [150.0, 118.900002, 2.0, -100.0]],
72
+ [:append_rectangle, [154.0, 118.900002, 4.0, -100.0]],
73
+ [:fill_path_non_zero],
74
+ [:set_font_and_size, [:F1, 14.0]],
75
+ [:set_device_gray_non_stroking_color, [0.0]],
76
+ [:begin_text],
77
+ [:set_text_matrix, [1, 0, 0, 1, 67.716, 3.5]],
78
+ [:show_text, ["test"]],
79
+ [:end_text]])
80
+ end
81
+
82
+ it "supports all string alignments" do
83
+ @obj.configure(value: '1123456', width: 50, symbology: :upce)
84
+ @obj.draw(@canvas)
85
+ assert_operators(@canvas.context.resources.xobject(:XO1).contents,
86
+ [[:set_device_rgb_non_stroking_color, [1.0, 1.0, 1.0]],
87
+ [:append_rectangle, [0, 0, 134.0, 116.400002]],
88
+ [:fill_path_non_zero],
89
+ [:set_device_rgb_non_stroking_color, [0.0, 0.0, 0.0]],
90
+ [:append_rectangle, [18.0, 116.400002, 2.0, -110.0]],
91
+ [:append_rectangle, [22.0, 116.400002, 2.0, -110.0]],
92
+ [:append_rectangle, [28.0, 116.400002, 4.0, -100.0]],
93
+ [:append_rectangle, [36.0, 116.400002, 2.0, -100.0]],
94
+ [:append_rectangle, [42.0, 116.400002, 2.0, -100.0]],
95
+ [:append_rectangle, [48.0, 116.400002, 4.0, -100.0]],
96
+ [:append_rectangle, [54.0, 116.400002, 2.0, -100.0]],
97
+ [:append_rectangle, [64.0, 116.400002, 2.0, -100.0]],
98
+ [:append_rectangle, [70.0, 116.400002, 6.0, -100.0]],
99
+ [:append_rectangle, [78.0, 116.400002, 2.0, -100.0]],
100
+ [:append_rectangle, [82.0, 116.400002, 4.0, -100.0]],
101
+ [:append_rectangle, [92.0, 116.400002, 2.0, -100.0]],
102
+ [:append_rectangle, [102.0, 116.400002, 2.0, -100.0]],
103
+ [:append_rectangle, [106.0, 116.400002, 2.0, -100.0]],
104
+ [:append_rectangle, [110.0, 116.400002, 2.0, -110.0]],
105
+ [:append_rectangle, [114.0, 116.400002, 2.0, -110.0]],
106
+ [:append_rectangle, [118.0, 116.400002, 2.0, -110.0]],
107
+ [:fill_path_non_zero],
108
+ [:set_font_and_size, [:F1, 14.0]],
109
+ [:set_device_gray_non_stroking_color, [0.0]],
110
+ [:begin_text],
111
+ [:set_text_matrix, [1, 0, 0, 1, 0.216, 0.400002]],
112
+ [:show_text, ["1"]],
113
+ [:set_font_and_size, [:F1, 20.0]],
114
+ [:move_text, [32.424, 0]],
115
+ [:show_text, ["123456"]],
116
+ [:set_font_and_size, [:F1, 14.0]],
117
+ [:move_text, [93.36, 0]],
118
+ [:show_text, ["2"]],
119
+ [:end_text]])
120
+ end
121
+
122
+ it "supports dotty mode" do
123
+ @obj.configure(value: 't', width: 50, symbology: :datamatrix, output_options: 0x0100)
124
+ @obj.draw(@canvas)
125
+ form_contents = @canvas.context.resources.xobject(:XO1).contents
126
+ assert_operators(form_contents,
127
+ [[:set_device_rgb_non_stroking_color, [1.0, 1.0, 1.0]],
128
+ [:append_rectangle, [0, 0, 20, 20]],
129
+ [:fill_path_non_zero],
130
+ [:set_device_rgb_non_stroking_color, [0.0, 0.0, 0.0]],
131
+ [:move_to, [1.8, 19.0]],
132
+ [:curve_to, [1.8, 19.285458, 1.647214, 19.550091, 1.4, 19.69282]],
133
+ [:curve_to, [1.152786, 19.835549, 0.847214, 19.835549, 0.6, 19.69282]],
134
+ [:curve_to, [0.352786, 19.550091, 0.2, 19.285458, 0.2, 19.0]],
135
+ [:curve_to, [0.2, 18.714542, 0.352786, 18.449909, 0.6, 18.30718]],
136
+ [:curve_to, [0.847214, 18.164451, 1.152786, 18.164451, 1.4, 18.30718]],
137
+ [:curve_to, [1.647214, 18.449909, 1.8, 18.714542, 1.8, 19.0]],
138
+ [:close_subpath],
139
+ [:move_to, [5.8, 19]]], range: 0..12)
140
+ assert_operators(form_contents,
141
+ [[:move_to, [19.8, 1.0]],
142
+ [:curve_to, [19.8, 1.285458, 19.647214, 1.550091, 19.4, 1.69282]],
143
+ [:curve_to, [19.152786, 1.835549, 18.847214, 1.835549, 18.6, 1.69282]],
144
+ [:curve_to, [18.352786, 1.550091, 18.2, 1.285458, 18.2, 1.0]],
145
+ [:curve_to, [18.2, 0.714542, 18.352786, 0.449909, 18.6, 0.30718]],
146
+ [:curve_to, [18.847214, 0.164451, 19.152786, 0.164451, 19.4, 0.30718]],
147
+ [:curve_to, [19.647214, 0.449909, 19.8, 0.714542, 19.8, 1.0]],
148
+ [:close_subpath],
149
+ [:fill_path_non_zero]], range: -9..-1)
150
+ end
151
+ end
152
+ end
@@ -3,7 +3,7 @@ require 'hexapdf'
3
3
  require 'hexapdf/extras'
4
4
  require 'hexapdf/extras/layout/swiss_qr_bill'
5
5
 
6
- using HexaPDF::Extras::Layout::NumericMeasurementHelper
6
+ using HexaPDF::Utils
7
7
 
8
8
  describe HexaPDF::Extras::Layout::SwissQRBill do
9
9
  def create_box(data, **kwargs)
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'hexapdf'
3
+ require 'hexapdf/extras/layout/zint_box'
4
+
5
+ describe HexaPDF::Extras::Layout::ZintBox do
6
+ def create_box(**kwargs)
7
+ HexaPDF::Extras::Layout::ZintBox.new(**kwargs)
8
+ end
9
+
10
+ describe "initialize" do
11
+ it "takes the common box arguments" do
12
+ box = create_box(width: 10, height: 15, data: {})
13
+ assert_equal(10, box.width)
14
+ assert_equal(15, box.height)
15
+ end
16
+
17
+ it "creates the zint barcode graphic object" do
18
+ box = create_box(data: {value: 'test', symbology: :code128})
19
+ assert_equal({value: 'test', symbology: 20}, box.barcode.zint_kws)
20
+ end
21
+ end
22
+
23
+ describe "fit" do
24
+ it "creates the form xobject and uses that as image for its superclass" do
25
+ doc = HexaPDF::Document.new
26
+ frame = HexaPDF::Layout::Frame.new(0, 0, 100, 100, context: doc.pages.add)
27
+
28
+ box = create_box(data: {value: 'test', symbology: :code128})
29
+ assert_nil(box.image)
30
+ box.fit(100, 100, frame)
31
+ assert_equal(:Form, box.image[:Subtype])
32
+ end
33
+ end
34
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-20 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hexapdf
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.36'
19
+ version: '0.42'
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: '0.36'
26
+ version: '0.42'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rqrcode_core
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-zint
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
41
55
  description:
42
56
  email: t_leitner@gmx.at
43
57
  executables: []
@@ -51,13 +65,17 @@ files:
51
65
  - lib/hexapdf/extras.rb
52
66
  - lib/hexapdf/extras/graphic_object.rb
53
67
  - lib/hexapdf/extras/graphic_object/qr_code.rb
68
+ - lib/hexapdf/extras/graphic_object/zint.rb
54
69
  - lib/hexapdf/extras/layout.rb
55
70
  - lib/hexapdf/extras/layout/qr_code_box.rb
56
71
  - lib/hexapdf/extras/layout/swiss_qr_bill.rb
72
+ - lib/hexapdf/extras/layout/zint_box.rb
57
73
  - lib/hexapdf/extras/version.rb
58
74
  - test/hexapdf/extras/graphic_object/test_qr_code.rb
75
+ - test/hexapdf/extras/graphic_object/test_zint.rb
59
76
  - test/hexapdf/extras/layout/test_qr_code_box.rb
60
77
  - test/hexapdf/extras/layout/test_swiss_qr_bill.rb
78
+ - test/hexapdf/extras/layout/test_zint_box.rb
61
79
  - test/test_helper.rb
62
80
  homepage: https://hexapdf-extras.gettalong.org
63
81
  licenses:
@@ -71,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
89
  requirements:
72
90
  - - ">="
73
91
  - !ruby/object:Gem::Version
74
- version: '2.5'
92
+ version: '2.7'
75
93
  required_rubygems_version: !ruby/object:Gem::Requirement
76
94
  requirements:
77
95
  - - ">="