mcc2 1.5.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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.autotest +23 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +3 -0
- data/Gemfile +13 -0
- data/History.txt +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +51 -0
- data/Rakefile +12 -0
- data/config/i18n-tasks.yml +193 -0
- data/exe/mcc2 +18 -0
- data/exe/mcc2-generate-preview +17 -0
- data/exe/mcc2print +6 -0
- data/lib/libguib16.rb +1620 -0
- data/lib/mcc2/advanced_data_edit_dlg.rb +139 -0
- data/lib/mcc2/cc_dialogbox.rb +52 -0
- data/lib/mcc2/constants.rb +154 -0
- data/lib/mcc2/dataman/base.rb +61 -0
- data/lib/mcc2/dataman/csv.rb +49 -0
- data/lib/mcc2/dataman/database.rb +8 -0
- data/lib/mcc2/dataman/dbf.rb +45 -0
- data/lib/mcc2/dataman/none.rb +25 -0
- data/lib/mcc2/dataview.rb +348 -0
- data/lib/mcc2/dataview_dlg.rb +232 -0
- data/lib/mcc2/debug_tools.rb +20 -0
- data/lib/mcc2/fx_colored_item.rb +101 -0
- data/lib/mcc2/generate_preview.rb +68 -0
- data/lib/mcc2/gui/advanced_data_edit_dlg.rbin +0 -0
- data/lib/mcc2/gui/dataview_dlg.pp +522 -0
- data/lib/mcc2/gui/layoutview_dlg.pp +5115 -0
- data/lib/mcc2/gui/mcc2_mainwin.pp +838 -0
- data/lib/mcc2/gui/picture_data_edit_dlg.rbin +0 -0
- data/lib/mcc2/gui/printerview_dlg.pp +3311 -0
- data/lib/mcc2/images/Image-Arrow-Left.gif +0 -0
- data/lib/mcc2/images/Image-Arrow-Right.gif +0 -0
- data/lib/mcc2/images/Image-FastArrowLeft.gif +0 -0
- data/lib/mcc2/images/Image-FastArrowRight.bmp +0 -0
- data/lib/mcc2/images/Image-FastArrowRight.gif +0 -0
- data/lib/mcc2/images/application-exit.png +0 -0
- data/lib/mcc2/images/copy.png +0 -0
- data/lib/mcc2/images/country_de.png +0 -0
- data/lib/mcc2/images/country_gb.png +0 -0
- data/lib/mcc2/images/country_rs.png +0 -0
- data/lib/mcc2/images/cut.png +0 -0
- data/lib/mcc2/images/distribute-horizontal-baseline.png +0 -0
- data/lib/mcc2/images/distribute-vertical-baseline.png +0 -0
- data/lib/mcc2/images/document-close.png +0 -0
- data/lib/mcc2/images/document-edit.png +0 -0
- data/lib/mcc2/images/document-new.png +0 -0
- data/lib/mcc2/images/document-open.png +0 -0
- data/lib/mcc2/images/document-print-frame.png +0 -0
- data/lib/mcc2/images/document-print.png +0 -0
- data/lib/mcc2/images/document-save-as.png +0 -0
- data/lib/mcc2/images/document-save.png +0 -0
- data/lib/mcc2/images/documentation.png +0 -0
- data/lib/mcc2/images/draw-rectangle.png +0 -0
- data/lib/mcc2/images/dummy.gif +0 -0
- data/lib/mcc2/images/exchange-positions.png +0 -0
- data/lib/mcc2/images/insert-image.png +0 -0
- data/lib/mcc2/images/insert-text.png +0 -0
- data/lib/mcc2/images/libreoffice-oasis-master-document.png +0 -0
- data/lib/mcc2/images/measure.png +0 -0
- data/lib/mcc2/images/messagebox_warning.png +0 -0
- data/lib/mcc2/images/paste.png +0 -0
- data/lib/mcc2/images/process-stop.png +0 -0
- data/lib/mcc2/images/zoom-in.png +0 -0
- data/lib/mcc2/layout.rb +323 -0
- data/lib/mcc2/layout_file.rb +794 -0
- data/lib/mcc2/layout_object/barcode.rb +33 -0
- data/lib/mcc2/layout_object/box.rb +18 -0
- data/lib/mcc2/layout_object/chip.rb +54 -0
- data/lib/mcc2/layout_object/embed.rb +16 -0
- data/lib/mcc2/layout_object/go_attribut.rb +16 -0
- data/lib/mcc2/layout_object/graphic.rb +59 -0
- data/lib/mcc2/layout_object/magstripe.rb +13 -0
- data/lib/mcc2/layout_object/picture.rb +22 -0
- data/lib/mcc2/layout_object/text.rb +29 -0
- data/lib/mcc2/layout_win.rb +2052 -0
- data/lib/mcc2/layoutview.rb +845 -0
- data/lib/mcc2/layoutview_dlg.rb +2058 -0
- data/lib/mcc2/locales.rb +27 -0
- data/lib/mcc2/mcc2_mainwin.rb +453 -0
- data/lib/mcc2/mcc2gui.rb +295 -0
- data/lib/mcc2/mcc2print.rb +54 -0
- data/lib/mcc2/picture_data_edit_dlg.rb +139 -0
- data/lib/mcc2/print_dlg.rb +520 -0
- data/lib/mcc2/printer/base.rb +148 -0
- data/lib/mcc2/printer/card_printer.rb +45 -0
- data/lib/mcc2/printer/file_printer.rb +135 -0
- data/lib/mcc2/printer/gdi_card_printer.rb +14 -0
- data/lib/mcc2/printer/gdi_printer.rb +197 -0
- data/lib/mcc2/printer/linux_cups_printer.rb +92 -0
- data/lib/mcc2/printer/preview.rb +277 -0
- data/lib/mcc2/printer/printer_cab.rb +118 -0
- data/lib/mcc2/printer/printer_cx320_direct.rb +286 -0
- data/lib/mcc2/printer/printer_epl.rb +118 -0
- data/lib/mcc2/printer/printer_ttp34x.rb +124 -0
- data/lib/mcc2/printer/printer_zebra.rb +324 -0
- data/lib/mcc2/printer/svg_drawer.rb +689 -0
- data/lib/mcc2/printerview.rb +604 -0
- data/lib/mcc2/printerview_dlg.rb +1248 -0
- data/lib/mcc2/version.rb +3 -0
- data/lib/mcc2.rb +11 -0
- data/locales/de.yml +6 -0
- data/locales/en.yml +502 -0
- data/locales/rs.yml +502 -0
- data/mcc2.gemspec +41 -0
- data/test/dummy.rb +19 -0
- data/test/layouts/bart_simpson.png +0 -0
- data/test/layouts/color_test.xml +151 -0
- data/test/layouts/ms.xml +67 -0
- data/test/ruby_print.rb +380 -0
- data/test/test.csv +4 -0
- data/test/test.dbf +0 -0
- data/test/test.str +4 -0
- data/test/test_mcc2.rb +8 -0
- data.tar.gz.sig +6 -0
- metadata +421 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require "mcc2/printer/card_printer"
|
|
2
|
+
require "mcc2/printer/svg_drawer"
|
|
3
|
+
require "socket"
|
|
4
|
+
require "rmagick"
|
|
5
|
+
|
|
6
|
+
module Mcc2
|
|
7
|
+
module Printer
|
|
8
|
+
class PrinterEpl < CardPrinter
|
|
9
|
+
include SvgDrawer
|
|
10
|
+
|
|
11
|
+
# die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
|
|
12
|
+
def card_margin_left
|
|
13
|
+
0
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def card_margin_right
|
|
17
|
+
0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def card_margin_top
|
|
21
|
+
0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def card_margin_bottom
|
|
25
|
+
0
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
def print_card(layout_file, row)
|
|
31
|
+
self.dpi = layout_file.get_attr_value(S_EPLPRINTER_DPI).to_f
|
|
32
|
+
|
|
33
|
+
page_commands = layout_file.get_attr_value(S_EPLPRINTER_PAGE_COMMANDS)
|
|
34
|
+
page_width = layout_file.get_attr_value(S_WIDTH).to_f
|
|
35
|
+
page_height = layout_file.get_attr_value(S_HEIGHT).to_f
|
|
36
|
+
draw_pos_x = layout_file.get_attr_value(S_X_OFFSET).to_f
|
|
37
|
+
draw_pos_y = layout_file.get_attr_value(S_Y_OFFSET).to_f
|
|
38
|
+
image_width = mm(page_width - draw_pos_x).round
|
|
39
|
+
image_height = mm(page_height - draw_pos_y).round
|
|
40
|
+
|
|
41
|
+
surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, image_width, image_height)
|
|
42
|
+
surface.set_fallback_resolution(dpi, dpi)
|
|
43
|
+
Cairo::Context.new(surface) do |context|
|
|
44
|
+
context.set_source_rgb(1.0, 1.0, 1.0) # make white background
|
|
45
|
+
context.paint
|
|
46
|
+
|
|
47
|
+
svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}") do |svg|
|
|
48
|
+
tra = Transformation.new
|
|
49
|
+
draw(svg, tra, layout_file, false, nil, row, 0)
|
|
50
|
+
end
|
|
51
|
+
svg_handle = RSVG::Handle.new_from_data(svg_data)
|
|
52
|
+
context.render_rsvg_handle(svg_handle)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Convert to ImageMagick image
|
|
56
|
+
# "BGRA" matches the byte ordering of Cairo's FORMAT_ARGB32
|
|
57
|
+
pic = Magick::Image.from_blob(surface.data) do |options|
|
|
58
|
+
options.format = 'BGRA'
|
|
59
|
+
options.size = "#{image_width}x#{image_height}"
|
|
60
|
+
options.depth = 8 # Bits per pixel channel
|
|
61
|
+
end.first
|
|
62
|
+
|
|
63
|
+
page_commands.gsub!("\\e", "\e")
|
|
64
|
+
page_commands.gsub!("\n", "\r\n")
|
|
65
|
+
page_commands.gsub!("%PAGE_WIDTH_MM%", page_width.to_s)
|
|
66
|
+
page_commands.gsub!("%PAGE_HEIGHT_MM%", page_height.to_s)
|
|
67
|
+
page_commands.gsub!("%PAGE_OFFSET_X_MM%", draw_pos_x.to_s)
|
|
68
|
+
page_commands.gsub!("%PAGE_OFFSET_Y_MM%", draw_pos_y.to_s)
|
|
69
|
+
page_commands.gsub!("%PAGE_WIDTH_PX%", mm(page_width).to_i.to_s)
|
|
70
|
+
page_commands.gsub!("%PAGE_HEIGHT_PX%", mm(page_height).to_i.to_s)
|
|
71
|
+
page_commands.gsub!("%PAGE_OFFSET_X_PX%", mm(draw_pos_x).to_i.to_s)
|
|
72
|
+
page_commands.gsub!("%PAGE_OFFSET_Y_PX%", mm(draw_pos_y).to_i.to_s)
|
|
73
|
+
|
|
74
|
+
page_commands.gsub!("%IMAGE_LEN_DATA_PCX%") do
|
|
75
|
+
pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
|
|
76
|
+
pic = pic.quantize(2, Magick::RGBColorspace, false)
|
|
77
|
+
pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
|
|
78
|
+
pic.class_type = Magick::PseudoClass
|
|
79
|
+
pic.image_type = Magick::BilevelType
|
|
80
|
+
data = pic.to_blob do |image|
|
|
81
|
+
image.format = "pcx"
|
|
82
|
+
end
|
|
83
|
+
# File.write("test.pcx", data)
|
|
84
|
+
"#{data.bytesize}\r\n#{data}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
open_socket(layout_file) do |sock|
|
|
88
|
+
sock.write page_commands
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
def open_socket(layout_file)
|
|
97
|
+
dev = layout_file.get_attr_value(S_EPLPRINTER_DEVICE)
|
|
98
|
+
sock = File.open(dev, "wb")
|
|
99
|
+
if block_given?
|
|
100
|
+
begin
|
|
101
|
+
return yield(sock)
|
|
102
|
+
ensure
|
|
103
|
+
sock.close
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
sock
|
|
107
|
+
end
|
|
108
|
+
private :open_socket
|
|
109
|
+
|
|
110
|
+
def send_command(layout_file, data, &block)
|
|
111
|
+
open_socket(layout_file) do |sock|
|
|
112
|
+
sock.write data
|
|
113
|
+
yield sock if block
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require "mcc2/printer/card_printer"
|
|
2
|
+
require "mcc2/printer/svg_drawer"
|
|
3
|
+
require "socket"
|
|
4
|
+
require "rmagick"
|
|
5
|
+
|
|
6
|
+
module Mcc2
|
|
7
|
+
module Printer
|
|
8
|
+
class PrinterTTP34x < CardPrinter
|
|
9
|
+
include SvgDrawer
|
|
10
|
+
|
|
11
|
+
# die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
|
|
12
|
+
def card_margin_left
|
|
13
|
+
0
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def card_margin_right
|
|
17
|
+
0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def card_margin_top
|
|
21
|
+
0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def card_margin_bottom
|
|
25
|
+
0
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
def print_card(layout_file, row)
|
|
31
|
+
self.dpi = layout_file.get_attr_value(S_TTP34XPRINTER_DPI).to_f
|
|
32
|
+
|
|
33
|
+
page_commands = layout_file.get_attr_value(S_TTP34XPRINTER_PAGE_COMMANDS)
|
|
34
|
+
page_width = layout_file.get_attr_value(S_WIDTH).to_f
|
|
35
|
+
page_height = layout_file.get_attr_value(S_HEIGHT).to_f
|
|
36
|
+
draw_pos_x = layout_file.get_attr_value(S_X_OFFSET).to_f
|
|
37
|
+
draw_pos_y = layout_file.get_attr_value(S_Y_OFFSET).to_f
|
|
38
|
+
image_width = mm(page_width - draw_pos_x).round
|
|
39
|
+
image_height = mm(page_height - draw_pos_y).round
|
|
40
|
+
|
|
41
|
+
surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, image_width, image_height)
|
|
42
|
+
surface.set_fallback_resolution(dpi, dpi)
|
|
43
|
+
Cairo::Context.new(surface) do |context|
|
|
44
|
+
context.set_source_rgb(1.0, 1.0, 1.0) # make white background
|
|
45
|
+
context.paint
|
|
46
|
+
|
|
47
|
+
svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}") do |svg|
|
|
48
|
+
tra = Transformation.new
|
|
49
|
+
draw(svg, tra, layout_file, false, nil, row, 0)
|
|
50
|
+
end
|
|
51
|
+
svg_handle = RSVG::Handle.new_from_data(svg_data)
|
|
52
|
+
context.render_rsvg_handle(svg_handle)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Convert to ImageMagick image
|
|
56
|
+
# "BGRA" matches the byte ordering of Cairo's FORMAT_ARGB32
|
|
57
|
+
pic = Magick::Image.from_blob(surface.data) do |options|
|
|
58
|
+
options.format = 'BGRA'
|
|
59
|
+
options.size = "#{image_width}x#{image_height}"
|
|
60
|
+
options.depth = 8 # Bits per pixel channel
|
|
61
|
+
end.first
|
|
62
|
+
|
|
63
|
+
page_commands.gsub!("\\e", "\e")
|
|
64
|
+
page_commands.gsub!("\n", "\r\n")
|
|
65
|
+
page_commands.gsub!("%PAGE_WIDTH_MM%", page_width.to_s)
|
|
66
|
+
page_commands.gsub!("%PAGE_HEIGHT_MM%", page_height.to_s)
|
|
67
|
+
page_commands.gsub!("%PAGE_WIDTH_PX%", mm(page_width).to_i.to_s)
|
|
68
|
+
page_commands.gsub!("%PAGE_HEIGHT_PX%", mm(page_height).to_i.to_s)
|
|
69
|
+
page_commands.gsub!("%PAGE_OFFSET_X_MM%", draw_pos_x.to_s)
|
|
70
|
+
page_commands.gsub!("%PAGE_OFFSET_Y_MM%", draw_pos_y.to_s)
|
|
71
|
+
page_commands.gsub!("%PAGE_OFFSET_X_PX%", mm(draw_pos_x).to_i.to_s)
|
|
72
|
+
page_commands.gsub!("%PAGE_OFFSET_Y_PX%", mm(draw_pos_y).to_i.to_s)
|
|
73
|
+
|
|
74
|
+
page_commands.gsub!("%IMAGE_LEN_DATA_PCX%") do
|
|
75
|
+
pic = pic.quantize(2, Magick::RGBColorspace, false)
|
|
76
|
+
pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
|
|
77
|
+
pic = pic.quantize(2, Magick::RGBColorspace, false)
|
|
78
|
+
pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
|
|
79
|
+
pic.class_type = Magick::PseudoClass
|
|
80
|
+
pic.image_type = Magick::BilevelType
|
|
81
|
+
# wir müssen die Farben invertieren, da TTP anscheinend das Negativ druckt !!!
|
|
82
|
+
pic_negate = pic.negate
|
|
83
|
+
data = pic_negate.to_blob do |image|
|
|
84
|
+
image.format = "pcx"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# pic_negate.display # bitte NUR unter LINUX aktivieren
|
|
88
|
+
# File.write("TSC-TTP346M.pcx", data)
|
|
89
|
+
|
|
90
|
+
"#{data.bytesize},#{data}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
open_socket(layout_file) do |sock|
|
|
94
|
+
sock.write page_commands
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
true
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
def open_socket(layout_file)
|
|
103
|
+
dev = layout_file.get_attr_value(S_TTP34XPRINTER_DEVICE)
|
|
104
|
+
sock = File.open(dev, "wb")
|
|
105
|
+
if block_given?
|
|
106
|
+
begin
|
|
107
|
+
return yield(sock)
|
|
108
|
+
ensure
|
|
109
|
+
sock.close
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
sock
|
|
113
|
+
end
|
|
114
|
+
private :open_socket
|
|
115
|
+
|
|
116
|
+
def send_command(layout_file, data, &block)
|
|
117
|
+
open_socket(layout_file) do |sock|
|
|
118
|
+
sock.write data
|
|
119
|
+
yield sock if block
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
require "win32api4ruby"
|
|
2
|
+
require "zebra_dll"
|
|
3
|
+
require "mcc2/printer/gdi_card_printer" # die Basisklasse für alle CardPrinter
|
|
4
|
+
|
|
5
|
+
module Mcc2
|
|
6
|
+
module Printer
|
|
7
|
+
# Diese Klasse definiert einen Zebra-Drucker.
|
|
8
|
+
class PrinterZebra < GdiCardPrinter
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def device_name
|
|
16
|
+
layout_file.get_attr_value(S_ZEBRAPRINTER_NAME)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def device_initdata
|
|
20
|
+
layout_file.get_binary_attr(S_ZEBRAPRINTER_INITDATA)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def move_to_reject_box
|
|
24
|
+
if @type &&
|
|
25
|
+
@type == 420 ||
|
|
26
|
+
@type == 430 ||
|
|
27
|
+
@type == 520 ||
|
|
28
|
+
@type == 720
|
|
29
|
+
# Bei Druckern mit Ausschuss-Fach, Karte in Ausschuss-Fach
|
|
30
|
+
# TODO geht noch nicht richtig, es werden 2 Karten in das Ausschuss-Fach transportiert
|
|
31
|
+
send_command("MRB", "Karte in Ausschuss-Fach")
|
|
32
|
+
else
|
|
33
|
+
# Bei Druckern ohne Ausschuss-Fach, Karte einfach auswerfen
|
|
34
|
+
send_command("MO", "Karte auswerfen (Ausschuss)")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def print_card(layout_file, row)
|
|
39
|
+
# Wird für Chip-Perso benötigt
|
|
40
|
+
@layout_file = layout_file
|
|
41
|
+
@chip = layout_file.build_chip_instance
|
|
42
|
+
|
|
43
|
+
# Warte, bis Durck der vorherigen Karte beendet ist.
|
|
44
|
+
st = Time.now
|
|
45
|
+
begin
|
|
46
|
+
puts "Zebra-Drucker: #{send_command_ex("V", "Firmware-Version ermitteln")}"
|
|
47
|
+
rescue ZebraException => e
|
|
48
|
+
raise if Time.now - st > 30
|
|
49
|
+
sleep 1
|
|
50
|
+
retry
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if chip
|
|
54
|
+
send_command("MCL", "Karte zum Kontaktlos-Leser fahren")
|
|
55
|
+
begin
|
|
56
|
+
# Kartenpersonalisierung
|
|
57
|
+
chip.pers_chip(row)
|
|
58
|
+
rescue => e
|
|
59
|
+
puts "Fehler bei Chip-Personalisierung: #{e} #{e.class} #{e.backtrace.join("\n")}"
|
|
60
|
+
begin
|
|
61
|
+
move_to_reject_box
|
|
62
|
+
rescue => e1
|
|
63
|
+
raise("Fehler bei Chip-Personalisierung, Karte ausgeschleust: #{e}\nFehler beim Ausschleusen: #{e1}")
|
|
64
|
+
end
|
|
65
|
+
raise("Fehler bei Chip-Personalisierung, Karte ausgeschleust: #{e}")
|
|
66
|
+
end
|
|
67
|
+
send_command("MIB", "Karte vom Leser zum Drucken weiter schicken")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Jetzt erst den eigentlichen Druck beginnen
|
|
71
|
+
super
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Sendet ein Kommando an den Drucker
|
|
75
|
+
def send_command(command, msg = nil)
|
|
76
|
+
puts("Zebra: Send command '#{command}' #{msg}")
|
|
77
|
+
open_handle
|
|
78
|
+
begin
|
|
79
|
+
send_cmd(command, msg)
|
|
80
|
+
ensure
|
|
81
|
+
close_handle
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Sendet ein Kommando an den Drucker
|
|
86
|
+
def send_command_ex(command, msg = nil)
|
|
87
|
+
puts("Zebra: Send command ex '#{command}' #{msg}")
|
|
88
|
+
ret = ""
|
|
89
|
+
open_handle
|
|
90
|
+
begin
|
|
91
|
+
ret = send_cmd_ex(command, msg)
|
|
92
|
+
ensure
|
|
93
|
+
close_handle
|
|
94
|
+
end
|
|
95
|
+
ret
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def open_handle(name = nil)
|
|
99
|
+
h_printer = DL.malloc(4)
|
|
100
|
+
h_printer.struct!("L", :handle)
|
|
101
|
+
|
|
102
|
+
devicename = name || device_name
|
|
103
|
+
|
|
104
|
+
printer_type = DL.malloc(4)
|
|
105
|
+
printer_type.struct!("L", :type)
|
|
106
|
+
|
|
107
|
+
err = DL.malloc(4)
|
|
108
|
+
err.struct!("L", :err)
|
|
109
|
+
|
|
110
|
+
# puts("---\nGet handle '#{devicename}'")
|
|
111
|
+
Time.now
|
|
112
|
+
result = ZebraDll.get_handle(h_printer, devicename, printer_type, err)
|
|
113
|
+
|
|
114
|
+
@handle = h_printer[:handle]
|
|
115
|
+
@type = printer_type[:type]
|
|
116
|
+
error = err[:err]
|
|
117
|
+
|
|
118
|
+
# puts("result = #{result}, error = #{error}")
|
|
119
|
+
# puts("type = #{@type}")
|
|
120
|
+
# puts("needed: #{Time.now - start}")
|
|
121
|
+
|
|
122
|
+
if result == 0
|
|
123
|
+
raise ZebraException.new(error, "Fehler bei Get Handle")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def send_cmd(command, msg = nil)
|
|
128
|
+
if !@handle
|
|
129
|
+
raise StandardError.new("Es muss erst ein Drucker-Handle geöffnet werden!")
|
|
130
|
+
end
|
|
131
|
+
err = DL.malloc(4)
|
|
132
|
+
err.struct!("L", :err)
|
|
133
|
+
# puts("---\nSend command #{command}")
|
|
134
|
+
Time.now
|
|
135
|
+
result = ZebraDll.send_cmd(@handle, @type, "#{command}\r", err)
|
|
136
|
+
error = err[:err]
|
|
137
|
+
|
|
138
|
+
# puts("result = #{result}, error = #{error}")
|
|
139
|
+
# puts("needed: #{Time.now - start}")
|
|
140
|
+
|
|
141
|
+
if result == 0
|
|
142
|
+
raise ZebraException.new(error, "Fehler bei Druckerkommando #{command} #{msg}")
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def send_cmd_ex(command, msg = nil)
|
|
147
|
+
response = DL.malloc(1024)
|
|
148
|
+
# response.struct!('S', :response)
|
|
149
|
+
|
|
150
|
+
resp_size = DL.malloc(4)
|
|
151
|
+
resp_size.struct!("L", :size)
|
|
152
|
+
|
|
153
|
+
err = DL.malloc(4)
|
|
154
|
+
err.struct!("L", :err)
|
|
155
|
+
|
|
156
|
+
# puts("---\nSend Command Ex: #{command}")
|
|
157
|
+
# result = ZebraDll.send_cmdex(@handle, @type, "#{command.to_s_win32}\r", response, resp_size, err)
|
|
158
|
+
result = ZebraDll.send_cmdex(@handle, @type, "#{command}\r", response, resp_size, err)
|
|
159
|
+
|
|
160
|
+
resp_size[:size]
|
|
161
|
+
error = err[:err]
|
|
162
|
+
|
|
163
|
+
# puts("result = #{result}")
|
|
164
|
+
# puts("response size = #{size}")
|
|
165
|
+
# puts("response = #{response} (#{response[0, size].inspect})")
|
|
166
|
+
# puts("result = #{result}")
|
|
167
|
+
# puts("error = #{error}")
|
|
168
|
+
# puts("needed: #{Time.now - start}")
|
|
169
|
+
|
|
170
|
+
if result == 0
|
|
171
|
+
raise ZebraException.new(error, "Fehler bei Druckerkommando #{command} #{msg}")
|
|
172
|
+
end
|
|
173
|
+
response
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def close_handle
|
|
177
|
+
if @handle
|
|
178
|
+
err = DL.malloc(4)
|
|
179
|
+
err.struct!("L", :err)
|
|
180
|
+
# puts("---\nClose handle")
|
|
181
|
+
Time.now
|
|
182
|
+
result = ZebraDll.close_handle(@handle, err)
|
|
183
|
+
error = err[:err]
|
|
184
|
+
|
|
185
|
+
# puts("result = #{result}, error = #{error}")
|
|
186
|
+
# puts("needed: #{Time.now - start}")
|
|
187
|
+
|
|
188
|
+
if result == 0
|
|
189
|
+
raise ZebraException.new(error, "Fehler bei Close Handle")
|
|
190
|
+
end
|
|
191
|
+
@handle = nil
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class ZebraException < RuntimeError
|
|
197
|
+
ERRORS = {
|
|
198
|
+
-1 => "ZBR_ERROR_PRINTER_MECHANICAL_ERROR - Mechanical error",
|
|
199
|
+
1 => "ZBR_ERROR_BROKEN_RIBBON - Indicates a broken ribbon",
|
|
200
|
+
2 => "ZBR_ERROR_TEMPERATURE - Print head temperature is too high",
|
|
201
|
+
3 => "ZBR_ERROR_MECHANICAL_ERROR Mechanical error",
|
|
202
|
+
4 => "ZBR_ERROR_OUT_OF_CARD Printer is out of cards, or unable to feed the card",
|
|
203
|
+
5 => "ZBR_ERROR_CARD_IN_ENCODER Unable to encode magnetic or smart card encoder",
|
|
204
|
+
6 => "ZBR_ERROR_CARD_NOT_IN_ENCODER Unable to encode the card because it is not in the encoder",
|
|
205
|
+
7 => "ZBR_ERROR_PRINT_HEAD_OPEN Print head is up",
|
|
206
|
+
8 => "ZBR_ERROR_OUT_OF_RIBBON Out of ribbon",
|
|
207
|
+
9 => "ZBR_ERROR_REMOVE_RIBBON Ribbon needs to be removed",
|
|
208
|
+
10 => "ZBR_ERROR_PARAMETERS_ERROR Wrong number of parameters or a value is incorrect",
|
|
209
|
+
11 => "ZBR_ERROR_INVALID_COORDINATES Invalid coordinates while trying to draw a barcode or graphics",
|
|
210
|
+
12 => "ZBR_ERROR_UNKNOWN_BARCODE Undefined barcode type",
|
|
211
|
+
13 => "ZBR_ERROR_UNKNOWN_TEXT Text for magnetic encoding or bar code drawing is invalid",
|
|
212
|
+
14 => "ZBR_ERROR_COMMAND_ERROR Invalid command",
|
|
213
|
+
20 => "ZBR_ERROR_BARCODE_DATA_SYNTAX Syntax error in the barcode command or parameters",
|
|
214
|
+
21 => "ZBR_ERROR_TEXT_DATA_SYNTAX General text data error",
|
|
215
|
+
22 => "ZBR_ERROR_GRAPHIC_DATA_SYNTAX Syntax error in the graphic command data",
|
|
216
|
+
30 => "ZBR_ERROR_GRAPHIC_IMAGE_INITIALIZATION Unable to initialize the graphics buffer",
|
|
217
|
+
31 => "ZBR_ERROR_GRAPHIC_IMAGE_MAXIMUM_WIDTH_EXCEEDED Graphic object to be drawn exceeds the X range",
|
|
218
|
+
32 => "ZBR_ERROR_GRAPHIC_IMAGE_MAXIMUM_HEIGHT_EXCEEDED Graphic object to be drawn exceeds the Y range",
|
|
219
|
+
33 => "ZBR_ERROR_GRAPHIC_IMAGE_DATA_CHECKSUM_ERROR Graphic data checksum error",
|
|
220
|
+
34 => "ZBR_ERROR_DATA_TRANSFER_TIME_OUT Data time-out error, usually happens when the USB cable is taken out while printing",
|
|
221
|
+
35 => "ZBR_ERROR_CHECK_RIBBON Incorrect ribbon installed",
|
|
222
|
+
40 => "ZBR_ERROR_INVALID_MAGNETIC_DATA Invalid magnetic encoding data",
|
|
223
|
+
41 => "ZBR_ERROR_MAG_ENCODER_WRITE Error while encoding a magnetic stripe",
|
|
224
|
+
42 => "ZBR_ERROR_READING_ERROR Error while reading a magnetic stripe",
|
|
225
|
+
43 => "ZBR_ERROR_MAG_ENCODER_MECHANICAL Magnetic encoder mechanical error",
|
|
226
|
+
44 => "ZBR_ERROR_MAG_ENCODER_NOT_RESPONDING Magnetic encoder not responding",
|
|
227
|
+
45 => "ZBR_ERROR_MAG_ENCODER_MISSING_OR_CARD_JAM Magnetic encoder is missing or the card is jammed before reaching the encoder",
|
|
228
|
+
47 => "ZBR_ERROR_ROTATION_ERROR Error while trying to flip the card",
|
|
229
|
+
48 => "ZBR_ERROR_COVER_OPEN Feeder Cover Lid is open (P110 and P120 only)",
|
|
230
|
+
49 => "ZBR_ERROR_ENCODING_ERROR Error while trying to encode on a magnetic stripe",
|
|
231
|
+
50 => "ZBR_ERROR_MAGNETIC_ERROR Magnetic encoder error",
|
|
232
|
+
51 => "ZBR_ERROR_BLANK_TRACK One or more of the tracks of the magnetic stripe are blank",
|
|
233
|
+
52 => "ZBR_ERROR_FLASH_ERROR Flash memory error",
|
|
234
|
+
53 => "ZBR_ERROR_NO_ACCESS Cannot access the printer",
|
|
235
|
+
54 => "ZBR_ERROR_SEQUENCE_ERROR Reception timeout, protocol errors",
|
|
236
|
+
55 => "ZBR_ERROR_PROX_ERROR Reception timeout, protocol errors",
|
|
237
|
+
56 => "ZBR_ERROR_CONTACT_DATA_ERROR Parameter error",
|
|
238
|
+
57 => "ZBR_ERROR_PROX_DATA_ERROR Parameter error",
|
|
239
|
+
60 => "ZBR_SDK_ERROR_PRINTER_NOT_SUPPORTED Printer not supported",
|
|
240
|
+
61 => "ZBR_SDK_ERROR_CANNOT_GET_PRINTER_HANDLE Unable to open handle to Zebra printer driver\nIst der Drucker korrekt installiert und eingeschaltet? Falls ja, bitte den Drucker ein- und ausschalten.",
|
|
241
|
+
62 => "ZBR_SDK_ERROR_CANNOT_GET_PRINTER_DRIVER Cannot open printer driver",
|
|
242
|
+
63 => "ZBR_SDK_ERROR_INVALID_PARAMETER One of the arguments is invalid",
|
|
243
|
+
64 => "ZBR_SDK_ERROR_PRINTER_BUSY Printer is in use",
|
|
244
|
+
65 => "ZBR_SDK_ERROR_INVALID_PRINTER_HANDLE Invalid printer handle",
|
|
245
|
+
66 => "ZBR_SDK_ERROR_CLOSE_HANDLE_ERROR Error closing printer driver handle",
|
|
246
|
+
67 => "ZBR_SDK_ERROR_COMMUNICATION_ERROR Command failed due to communication error",
|
|
247
|
+
68 => "ZBR_SDK_ERROR_BUFFER_OVERFLOW Response too large for buffer",
|
|
248
|
+
69 => "ZBR_SDK_ERROR_READ_DATA_ERROR Error reading data",
|
|
249
|
+
70 => "ZBR_SDK_ERROR_WRITE_DATA_ERROR Error writing data",
|
|
250
|
+
71 => "ZBR_SDK_ERROR_LOAD_LIBRARY_ERROR Error loading SDK",
|
|
251
|
+
72 => "ZBR_SDK_ERROR_INVALID_STRUCT_ALIGNMENT Invalid structure alignment",
|
|
252
|
+
73 => "ZBR_SDK_ERROR_GETTING_DEVICE_CONTEXT Unable to create the device context for the driver",
|
|
253
|
+
74 => "ZBR_SDK_ERROR_SPOOLER_ERROR Print spooler error",
|
|
254
|
+
75 => "ZBR_SDK_ERROR_OUT_OF_MEMORY Operating system is out of memory",
|
|
255
|
+
76 => "ZBR_SDK_ERROR_OUT_OF_DISK_SPACE Operating system is out of disk space",
|
|
256
|
+
77 => "ZBR_SDK_ERROR_USER_ABORT Print job aborted by the user",
|
|
257
|
+
78 => "ZBR_SDK_ERROR_APPLICATION_ABORT Application aborted",
|
|
258
|
+
79 => "ZBR_SDK_ERROR_CREATE_FILE_ERROR Error creating file",
|
|
259
|
+
80 => "ZBR_SDK_ERROR_WRITE_FILE_ERROR Error writing file",
|
|
260
|
+
81 => "ZBR_SDK_ERROR_READ_FILE_ERROR Error reading file",
|
|
261
|
+
82 => "ZBR_SDK_ERROR_INVALID_MEDIA Invalid media",
|
|
262
|
+
8001 => "ZBR_GDI_ERROR_GENERIC_ERROR Window API error, call GetLastError() function from Win32 API for error information",
|
|
263
|
+
8002 => "ZBR_GDI_ERROR_INVALID_PARAMETER One of the arguments is invalid",
|
|
264
|
+
8003 => "ZBR_GDI_ERROR_OUT_OF_MEMORY Operating system is out of memory",
|
|
265
|
+
8004 => "ZBR_GDI_ERROR_OBJECT_BUSY One of the objects specified in the API call is in use",
|
|
266
|
+
8005 => "ZBR_GDI_ERROR_INSUFFICIENT_BUFFER A buffer specified as an argument in the API call is not large enough",
|
|
267
|
+
8006 => "ZBR_GDI_ERROR_NOT_IMPLEMENTED Method is not implemented ",
|
|
268
|
+
8007 => "ZBR_GDI_ERROR_WIN32_ERROR Method generated a Win32 error, call GetLastError() function from Win32 API for error information",
|
|
269
|
+
8008 => "ZBR_GDI_ERROR_WRONG_STATE Object called by the API is in an invalid state",
|
|
270
|
+
8009 => "ZBR_GDI_ERROR_ABORTED Method aborted",
|
|
271
|
+
8010 => "ZBR_GDI_ERROR_FILE_NOT_FOUND File not found",
|
|
272
|
+
8011 => "ZBR_GDI_ERROR_VALUE_OVERFLOW Arithmetic operation in the method caused a numeric overflow",
|
|
273
|
+
8012 => "ZBR_GDI_ERROR_ACCESS_DENIED Access denied to the specified file ",
|
|
274
|
+
8013 => "ZBR_GDI_ERROR_UNKNOWN_IMAGE_FORMAT Specified image file format is unknown",
|
|
275
|
+
8014 => "ZBR_GDI_ERROR_FONT_FAMILY_NOT_FOUND Specified font is not installed",
|
|
276
|
+
8015 => "ZBR_GDI_ERROR_FONT_STYLE_NOT_FOUND Invalid font style",
|
|
277
|
+
8016 => "ZBR_GDI_ERROR_NOT_TRUE_TYPE_FONT Specified font is not a True Type font and cannot be used with GDI+",
|
|
278
|
+
8017 => "ZBR_GDI_ERROR_UNSUPPORTED_GDIPLUS_VERSION Installed GDI+ version",
|
|
279
|
+
8018 => "ZBR_GDI_ERROR_GDIPLUS_NOT_INITIALIZED The GDI+ API is not initialized",
|
|
280
|
+
8019 => "ZBR_GDI_ERROR_PROPERTY_NOT_FOUND Specified property does not exist in the image",
|
|
281
|
+
8020 => "ZBR_GDI_ERROR_PROPERTY_NOT_SUPPORTED Specified property is not supported by the image format",
|
|
282
|
+
8021 => "ZBR_GDI_ERROR_GRAPHICS_ALREADY_INITIALIZED Graphic buffer has already been initialized",
|
|
283
|
+
8022 => "ZBR_GDI_ERROR_NO_GRAPHIC_DATA No data in the graphic buffer to print",
|
|
284
|
+
8023 => "ZBR_GDI_ERROR_GRAPHICS_NOT_INITIALIZED Graphics buffer has not been initialized",
|
|
285
|
+
8024 => "ZBR_GDI_ERROR_GETTING_DEVICE_CONTEXT Unable to create the device context for the driver",
|
|
286
|
+
8025 => "ZBR_DLG_ERROR_DLG_CANCELED User closed or canceled the DLG window",
|
|
287
|
+
8026 => "ZBR_DLG_ERROR_SETUP_FAILURE PrintDlg function failed to load the required resources",
|
|
288
|
+
8027 => "ZBR_DLG_ERROR_PARSE_FAILURE PrintDlg function failed to parse the strings in the [devices] section of the WIN.INI file",
|
|
289
|
+
8028 => "ZBR_DLG_ERROR_RET_DEFAULT_FAILUREPD_RETURNDEFAULT flag was specified in the Flags member of the PRINTDLG structure, but the hDevMode or hDevNames member was not NULL",
|
|
290
|
+
8029 => "ZBR_DLG_ERROR_LOAD_DRV_FAILURE PrintDlg function failed to load the device driver for the specified printer",
|
|
291
|
+
8030 => "ZBR_DLG_ERROR_GET_DEVMODE_FAIL Printer driver failed to initialize a DEVMODE structure",
|
|
292
|
+
8031 => "ZBR_DLG_ERROR_INIT_FAILURE PrintDlg function failed during initialization, and there is no more specific extended error code to describe the failure",
|
|
293
|
+
8032 => "ZBR_DLG_ERROR_NO_DEVICES No printer drivers were found",
|
|
294
|
+
8033 => "ZBR_DLG_ERROR_NO_DEFAULT_PRINTER A default printer does not exist",
|
|
295
|
+
8034 => "ZBR_DLG_ERROR_DN_DM_MISMATCH Data in the DEVMODE and DEVNAMES structures describes two different printers",
|
|
296
|
+
8035 => "ZBR_DLG_ERROR_CREATE_IC_FAILURE PrintDlg function failed when it attempted to create an information context",
|
|
297
|
+
8036 => "ZBR_DLG_ERROR_PRINTER_NOT_FOUND The [devices] section of the WIN.INI file did not contain an entry for the requested printer",
|
|
298
|
+
8037 => "ZBR_DLG_ERROR_DEFAULT_DIFFERENT Error occurs when you store the DEVNAMES structure, and the user changes the default printer by using the Control Panel"
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
def initialize(error_code, message)
|
|
302
|
+
error_message = ZebraException.get_message(error_code)
|
|
303
|
+
super("#{message} (#{error_code} - #{error_message})")
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def self.get_message(error_code)
|
|
307
|
+
ERRORS[error_code]
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
if __FILE__ == $0
|
|
312
|
+
printer = PrinterZebra.new
|
|
313
|
+
printer.open_handle("Zebra P430i Card Printer USB")
|
|
314
|
+
printer.send_cmd("MCL")
|
|
315
|
+
printer.close_handle
|
|
316
|
+
|
|
317
|
+
sleep(5)
|
|
318
|
+
|
|
319
|
+
printer.open_handle("Zebra P430i Card Printer USB")
|
|
320
|
+
printer.send_cmd("MRB")
|
|
321
|
+
printer.close_handle
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|