hexapdf-extras 1.1.2 → 1.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
  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
  - - ">="