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 +4 -4
- data/README.rdoc +23 -0
- data/lib/hexapdf/extras/graphic_object/zint.rb +228 -0
- data/lib/hexapdf/extras/graphic_object.rb +1 -0
- data/lib/hexapdf/extras/layout/swiss_qr_bill.rb +1 -9
- data/lib/hexapdf/extras/layout/zint_box.rb +56 -0
- data/lib/hexapdf/extras/layout.rb +1 -0
- data/lib/hexapdf/extras/version.rb +1 -1
- data/lib/hexapdf/extras.rb +4 -1
- data/test/hexapdf/extras/graphic_object/test_zint.rb +152 -0
- data/test/hexapdf/extras/layout/test_swiss_qr_bill.rb +1 -1
- data/test/hexapdf/extras/layout/test_zint_box.rb +34 -0
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33a96708a4a5370678eefced16946538c63b6a078631d0f5c6b431a997874ff1
|
4
|
+
data.tar.gz: 82dadc4117398db36f731c1aeb0fe2a360f299a1d4cc19ae039297ec39129efa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,15 +4,7 @@ require 'hexapdf/error'
|
|
4
4
|
require 'hexapdf/layout/box'
|
5
5
|
require 'hexapdf/extras/layout'
|
6
6
|
|
7
|
-
|
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
|
data/lib/hexapdf/extras.rb
CHANGED
@@ -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
|
@@ -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.
|
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-
|
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.
|
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.
|
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.
|
92
|
+
version: '2.7'
|
75
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
94
|
requirements:
|
77
95
|
- - ">="
|