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,135 @@
|
|
|
1
|
+
require "mcc2/printer/card_printer"
|
|
2
|
+
require "mcc2/printer/svg_drawer"
|
|
3
|
+
|
|
4
|
+
module Mcc2
|
|
5
|
+
module Printer
|
|
6
|
+
class FilePrinter < CardPrinter
|
|
7
|
+
include SvgDrawer
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super
|
|
11
|
+
@image_idx = 0
|
|
12
|
+
@context = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
|
|
16
|
+
def card_margin_left
|
|
17
|
+
0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def card_margin_right
|
|
21
|
+
0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def card_margin_top
|
|
25
|
+
0
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def card_margin_bottom
|
|
29
|
+
0
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
def print_card(layout_file, row)
|
|
35
|
+
chip = layout_file.build_chip_instance
|
|
36
|
+
@layout_file = layout_file
|
|
37
|
+
self.dpi = @layout_file.get_attr_value(S_FILEPRINTER_DPI).to_f
|
|
38
|
+
|
|
39
|
+
print_page(row, 0)
|
|
40
|
+
if layout_file.get_attr_value(S_DUPLEX) == S_TRUE
|
|
41
|
+
print_page(row, 1)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
chip&.pers_chip(row)
|
|
45
|
+
|
|
46
|
+
@image_idx += 1
|
|
47
|
+
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def print_page(row, page_nr)
|
|
52
|
+
page_width = @layout_file.get_attr_value(S_WIDTH).to_f
|
|
53
|
+
page_height = @layout_file.get_attr_value(S_HEIGHT).to_f
|
|
54
|
+
draw_pos_x = @layout_file.get_attr_value(S_X_OFFSET).to_f
|
|
55
|
+
draw_pos_y = @layout_file.get_attr_value(S_Y_OFFSET).to_f
|
|
56
|
+
image_width = mm(page_width).round
|
|
57
|
+
image_height = mm(page_height).round
|
|
58
|
+
|
|
59
|
+
row_idx = row["row_number"] if row
|
|
60
|
+
documentName = @layout_file.get_attr_value(S_FILEPRINTER_SAVE_AS).gsub("%i", @image_idx.to_s).gsub("%p", page_nr.to_s).gsub("%d", row_idx.to_s)
|
|
61
|
+
documentName = @layout_file.expand_path(documentName)
|
|
62
|
+
fileext = File.extname(documentName).downcase
|
|
63
|
+
|
|
64
|
+
change_context = @last_documentName != documentName
|
|
65
|
+
if @context
|
|
66
|
+
if change_context
|
|
67
|
+
@context.finish_print
|
|
68
|
+
@context = nil
|
|
69
|
+
else
|
|
70
|
+
@context.show_page
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if !@context
|
|
75
|
+
if %w[.pdf].include?(fileext)
|
|
76
|
+
surface = Cairo::PDFSurface.new(documentName, mm_to_pt(page_width), mm_to_pt(page_height))
|
|
77
|
+
surface.set_fallback_resolution(dpi, dpi)
|
|
78
|
+
surface.define_singleton_method(:finish_print){ finish }
|
|
79
|
+
elsif %w[.png].include?(fileext)
|
|
80
|
+
surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, image_width, image_height)
|
|
81
|
+
surface.define_singleton_method(:finish_print) do
|
|
82
|
+
write_to_png(documentName)
|
|
83
|
+
finish
|
|
84
|
+
end
|
|
85
|
+
elsif %w[.svg].include?(fileext)
|
|
86
|
+
surface = Cairo::SVGSurface.new(documentName, image_width, image_height)
|
|
87
|
+
surface.define_singleton_method(:finish_print){ finish }
|
|
88
|
+
else
|
|
89
|
+
require "rmagick"
|
|
90
|
+
|
|
91
|
+
surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, image_width, image_height)
|
|
92
|
+
dens = "#{dpi}x#{dpi}"
|
|
93
|
+
surface.define_singleton_method(:finish_print) do
|
|
94
|
+
# Convert to ImageMagick image
|
|
95
|
+
# "BGRA" matches the byte ordering of Cairo's FORMAT_ARGB32
|
|
96
|
+
image = Magick::Image.from_blob(surface.data) do |options|
|
|
97
|
+
options.format = 'BGRA'
|
|
98
|
+
options.size = "#{image_width}x#{image_height}"
|
|
99
|
+
options.depth = 8 # Bits per pixel channel
|
|
100
|
+
end.first
|
|
101
|
+
# Configure and save the image in the requested file format
|
|
102
|
+
image.write(documentName) do |img|
|
|
103
|
+
img.density = dens
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
finish
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
@context = Cairo::Context.new(surface)
|
|
110
|
+
@context.define_singleton_method(:finish_print) do
|
|
111
|
+
target.finish_print
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Create an SVG document with all the objects on it
|
|
116
|
+
if @context.target.is_a?(Cairo::PDFSurface)
|
|
117
|
+
# TODO where comes the factor 0.8 from?
|
|
118
|
+
svg_attrs = {width: "#{page_width*0.8}mm", height: "#{page_height*0.8}mm"}
|
|
119
|
+
end
|
|
120
|
+
svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}", **svg_attrs) do |svg|
|
|
121
|
+
tra = Transformation.new
|
|
122
|
+
draw(svg, tra.translate(mm(draw_pos_x).round, mm(draw_pos_y).round), layout_file, false, nil, row, page_nr)
|
|
123
|
+
end
|
|
124
|
+
svg_handle = RSVG::Handle.new_from_data(svg_data)
|
|
125
|
+
@context.render_rsvg_handle(svg_handle)
|
|
126
|
+
|
|
127
|
+
@last_documentName = documentName
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def close
|
|
131
|
+
@context&.finish_print
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
gem "win32api4ruby", ">= 0.2.1"
|
|
2
|
+
require "win32api4ruby"
|
|
3
|
+
require "mcc2/printer/card_printer"
|
|
4
|
+
require "mcc2/printer/svg_drawer"
|
|
5
|
+
require "mcc2_c_helper"
|
|
6
|
+
|
|
7
|
+
Win32api4ruby::Base.unicode = true
|
|
8
|
+
|
|
9
|
+
module Mcc2
|
|
10
|
+
module Printer
|
|
11
|
+
class GdiPrinter < CardPrinter
|
|
12
|
+
include SvgDrawer
|
|
13
|
+
|
|
14
|
+
attr_accessor :chip
|
|
15
|
+
|
|
16
|
+
def with_page(hPrinter, row, page_nr)
|
|
17
|
+
start_page(hPrinter, row, page_nr)
|
|
18
|
+
yield
|
|
19
|
+
ensure
|
|
20
|
+
end_page(hPrinter, row, page_nr)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def device_name
|
|
24
|
+
layout_file.get_attr_value(S_GDIPRINTER_NAME)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def device_initdata
|
|
28
|
+
layout_file.get_binary_attr(S_GDIPRINTER_INITDATA)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# startet das Drucken
|
|
32
|
+
# === Return
|
|
33
|
+
# -
|
|
34
|
+
# === Parameter
|
|
35
|
+
# +layout_file+::
|
|
36
|
+
# +row+:: ein Hash-Objekt
|
|
37
|
+
def print_card(layout_file, row)
|
|
38
|
+
@layout_file = layout_file
|
|
39
|
+
@chip = layout_file.build_chip_instance
|
|
40
|
+
|
|
41
|
+
devicename = device_name
|
|
42
|
+
|
|
43
|
+
duplex = layout_file.get_attr_value(S_DUPLEX) == S_TRUE
|
|
44
|
+
|
|
45
|
+
if initdata = device_initdata
|
|
46
|
+
initdata = Win32api4ruby::Winspool.create_DEVMOD(initdata)
|
|
47
|
+
else
|
|
48
|
+
raise Printer::Base::ResourceNotFoundError, I18n.t(:error_printer_not_setup, default: "Bitte richten Sie erst den ausgewählten Drucker ein !")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# einen DeviceContext für den Drucker erzeugen
|
|
52
|
+
hPrinter = Win32api4ruby::Gdi.create_dc(nil, devicename.to_s_win32, nil, initdata)
|
|
53
|
+
|
|
54
|
+
begin
|
|
55
|
+
start_doc(hPrinter, row)
|
|
56
|
+
|
|
57
|
+
page_nr = 0
|
|
58
|
+
print_page(hPrinter, initdata, row, page_nr)
|
|
59
|
+
|
|
60
|
+
if duplex
|
|
61
|
+
page_nr = 1
|
|
62
|
+
print_page(hPrinter, initdata, row, page_nr)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end_doc(hPrinter, row)
|
|
66
|
+
rescue
|
|
67
|
+
# wenn ein Fehler aufgetreten ist, wird der Druckjob abgebrochen und somit aus der Warteschlange entfernt
|
|
68
|
+
abort_doc(hPrinter, row)
|
|
69
|
+
raise
|
|
70
|
+
end
|
|
71
|
+
Win32api4ruby::Gdi.delete_dc(hPrinter)
|
|
72
|
+
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def print_page(hPrinter, initdata, row, page_nr)
|
|
77
|
+
page = prepare_gdi_page(hPrinter, initdata, row, page_nr)
|
|
78
|
+
page.draw
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def start_doc(hPrinter, row)
|
|
82
|
+
datasourcename = layout_file.get_attr_value(S_DATASOURCE)
|
|
83
|
+
# set document title
|
|
84
|
+
row_text = row["row_number"] if row
|
|
85
|
+
if !row_text && row
|
|
86
|
+
row_text = row.sort.map { |k, v| v }.select { |v| v && !v.empty? }.join(",")[0, 50] # take row-values
|
|
87
|
+
end
|
|
88
|
+
documentName = "MCC #{row_text} #{datasourcename}"
|
|
89
|
+
docinfo = Win32api4ruby::Gdi.create_DOCINFO
|
|
90
|
+
# Store the pointer instance in docinfo to avoid GC'ing
|
|
91
|
+
class << docinfo
|
|
92
|
+
attr_accessor :pDocumentName
|
|
93
|
+
end
|
|
94
|
+
docinfo[:lpszDocName] = docinfo.pDocumentName = documentName.to_s_win32
|
|
95
|
+
|
|
96
|
+
Win32api4ruby::Gdi.start_doc(hPrinter, docinfo)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def end_doc(hPrinter, row)
|
|
100
|
+
Win32api4ruby::Gdi.end_doc(hPrinter)
|
|
101
|
+
GC.start
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def abort_doc(hPrinter, row)
|
|
105
|
+
Win32api4ruby::Gdi.abort_doc(hPrinter)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class ReadyToSendPage
|
|
109
|
+
attr_reader :row
|
|
110
|
+
attr_reader :page_nr
|
|
111
|
+
|
|
112
|
+
# hPrinter, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse
|
|
113
|
+
def initialize(printer, set_dibits_to_device_args, row, page_nr)
|
|
114
|
+
@args = set_dibits_to_device_args
|
|
115
|
+
@row = row
|
|
116
|
+
@page_nr = page_nr
|
|
117
|
+
@printer = printer
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def draw
|
|
121
|
+
@printer.with_page(@args[0], row, page_nr) do
|
|
122
|
+
Win32api4ruby::Gdi.set_dibits_to_device(*@args)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def prepare_gdi_page(hPrinter, initdata, row, page_nr)
|
|
128
|
+
raise "unterschiedliche X- und Y-Auflösung wird beim Druck nicht unterstützt (#{initdata[:dmPrintQuality].inspect}x#{initdata[:dmYResolution].inspect})" if initdata[:dmYResolution] != initdata[:dmPrintQuality] && initdata[:dmYResolution] != 0 && initdata[:dmPrintQuality] != 0
|
|
129
|
+
self.dpi = [initdata[:dmYResolution], initdata[:dmPrintQuality]].max
|
|
130
|
+
|
|
131
|
+
page_width = @layout_file.get_attr_value(S_WIDTH).to_f + card_margin_left + card_margin_right
|
|
132
|
+
page_height = @layout_file.get_attr_value(S_HEIGHT).to_f + card_margin_top + card_margin_bottom
|
|
133
|
+
draw_pos_x = @layout_file.get_attr_value(S_X_OFFSET).to_f - card_margin_left
|
|
134
|
+
draw_pos_y = @layout_file.get_attr_value(S_Y_OFFSET).to_f - card_margin_top
|
|
135
|
+
|
|
136
|
+
# ein Bild als RVG (Vektorgraphik) erzeugen, auf dem alle Objekte plaziert sind
|
|
137
|
+
selected_object_id = nil # wird nur für Darstellung auf Bildschirm gebraucht
|
|
138
|
+
preview = false # wird nur für Darstellung auf Bildschirm gebraucht
|
|
139
|
+
|
|
140
|
+
image_width = mm(page_width).round
|
|
141
|
+
image_height = mm(page_height).round
|
|
142
|
+
|
|
143
|
+
svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}") do |svg|
|
|
144
|
+
svg.g(transform: "scale(1 -1) translate(0 -#{image_height})") do
|
|
145
|
+
tra = Transformation.new
|
|
146
|
+
draw(svg, tra, layout_file, preview, selected_object_id, row, page_nr)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
svg_handle = RSVG::Handle.new_from_data(svg_data)
|
|
151
|
+
surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, image_width, image_height)
|
|
152
|
+
context = Cairo::Context.new(surface)
|
|
153
|
+
context.set_source_rgb(1.0, 1.0, 1.0)
|
|
154
|
+
context.paint
|
|
155
|
+
context.render_rsvg_handle(svg_handle)
|
|
156
|
+
lpvBits = surface.data
|
|
157
|
+
# Convert BGRA data of librsvg to BGR of Win32 print API
|
|
158
|
+
# lpvBits = lpvBits.unpack("a3x"*(lpvBits.bytesize/4)).join
|
|
159
|
+
# The faster converter of BGRA to BGR image data
|
|
160
|
+
lpvBits = Mcc2CHelper.bgra_to_bgr(lpvBits)
|
|
161
|
+
|
|
162
|
+
block_size = 4 # each scanline has to be DWORD padded
|
|
163
|
+
# split the image in single rows
|
|
164
|
+
lpvBits = lpvBits.unpack("a#{image_width * 3}" * image_height).map do |imgrow|
|
|
165
|
+
# align each row to DWORD
|
|
166
|
+
imgrow << "\0" * (block_size - 1 - (imgrow.length - 1 & (block_size - 1)))
|
|
167
|
+
end.join
|
|
168
|
+
|
|
169
|
+
xDest, yDest, dwWidth, dwHeight, xSrc, ySrc = mm(draw_pos_x), mm(draw_pos_y), image_width, image_height, 0, 0
|
|
170
|
+
uStartScan, cScanLines = 0, dwHeight
|
|
171
|
+
fuColorUse = Win32api4ruby::Gdi::DIB_RGB_COLORS
|
|
172
|
+
|
|
173
|
+
lpbmi = Win32api4ruby::Gdi.create_BITMAPINFOHEADER
|
|
174
|
+
lpbmi[:biWidth] = dwWidth
|
|
175
|
+
lpbmi[:biHeight] = dwHeight
|
|
176
|
+
lpbmi[:biPlanes] = 1
|
|
177
|
+
lpbmi[:biBitCount] = 24
|
|
178
|
+
lpbmi[:biCompression] = Win32api4ruby::Gdi::BI_RGB
|
|
179
|
+
lpbmi[:biSizeImage] = lpvBits.length
|
|
180
|
+
lpbmi[:biXPelsPerMeter] = 0
|
|
181
|
+
lpbmi[:biYPelsPerMeter] = 0
|
|
182
|
+
lpbmi[:biClrUsed] = 0
|
|
183
|
+
lpbmi[:biClrImportant] = 0
|
|
184
|
+
|
|
185
|
+
ReadyToSendPage.new self, [hPrinter, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse], row, page_nr
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def start_page(hPrinter, row, page_nr)
|
|
189
|
+
Win32api4ruby::Gdi.start_page(hPrinter)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def end_page(hPrinter, row, page_nr)
|
|
193
|
+
Win32api4ruby::Gdi.end_page(hPrinter)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require "mcc2/printer/card_printer"
|
|
2
|
+
require "mcc2/printer/svg_drawer"
|
|
3
|
+
require "ffi-cups"
|
|
4
|
+
|
|
5
|
+
module Mcc2
|
|
6
|
+
module Printer
|
|
7
|
+
class LinuxCupsPrinter < CardPrinter
|
|
8
|
+
include SvgDrawer
|
|
9
|
+
|
|
10
|
+
# die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
|
|
11
|
+
def card_margin_left
|
|
12
|
+
0
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def card_margin_right
|
|
16
|
+
0
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def card_margin_top
|
|
20
|
+
0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def card_margin_bottom
|
|
24
|
+
0
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def printer_name
|
|
28
|
+
layout_file.get_attr_value(S_LINUX_CUPS_PRINTER)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def print_card(layout_file, row)
|
|
32
|
+
chip = layout_file.build_chip_instance
|
|
33
|
+
@layout_file = layout_file
|
|
34
|
+
self.dpi = layout_file.get_attr_value(S_LINUX_CUPS_DPI).to_f
|
|
35
|
+
|
|
36
|
+
page_width = @layout_file.get_attr_value(S_WIDTH).to_f
|
|
37
|
+
page_height = @layout_file.get_attr_value(S_HEIGHT).to_f
|
|
38
|
+
|
|
39
|
+
printer = Cups::Printer.get_destination(printer_name)
|
|
40
|
+
file_pdf = Tempfile.new(["mcc2", ".pdf"])
|
|
41
|
+
|
|
42
|
+
Cairo::PDFSurface.new(file_pdf.path, mm_to_pt(page_width), mm_to_pt(page_height)) do |surface|
|
|
43
|
+
surface.set_fallback_resolution(dpi, dpi)
|
|
44
|
+
Cairo::Context.new(surface) do |context|
|
|
45
|
+
print_page(context, row, 0)
|
|
46
|
+
duplex = layout_file.get_attr_value(S_DUPLEX) == S_TRUE
|
|
47
|
+
if duplex
|
|
48
|
+
context.show_page
|
|
49
|
+
print_page(context, row, 1)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
json_str = @layout_file.get_attr_value(S_LINUX_CUPS_OPTIONS)
|
|
55
|
+
options = JSON.parse(json_str)
|
|
56
|
+
options.transform_values! do |value|
|
|
57
|
+
(value =~ /=(.*)\z/) ? $1 : value # Wert bei "CONST=wert" herausselektieren
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# system("xdg-open", file_pdf.path)
|
|
61
|
+
printer.print_file(file_pdf.path, "MCC2 - #{layout_file.filename}", options)
|
|
62
|
+
|
|
63
|
+
chip&.pers_chip(row)
|
|
64
|
+
|
|
65
|
+
true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#--------------------------------------------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
def print_page(context, row, page_nr)
|
|
71
|
+
draw_pos_x = @layout_file.get_attr_value(S_X_OFFSET).to_f
|
|
72
|
+
draw_pos_y = @layout_file.get_attr_value(S_Y_OFFSET).to_f
|
|
73
|
+
page_width = @layout_file.get_attr_value(S_WIDTH).to_f
|
|
74
|
+
page_height = @layout_file.get_attr_value(S_HEIGHT).to_f
|
|
75
|
+
image_width = mm(page_width).round
|
|
76
|
+
image_height = mm(page_height).round
|
|
77
|
+
|
|
78
|
+
# ein Bild als RVG (Vektorgraphik) erzeugen, auf dem alle Objekte plaziert sind
|
|
79
|
+
selected_object_id = nil # wird nur für Darstellung auf Bildschirm gebraucht
|
|
80
|
+
preview = false # wird nur für Darstellung auf Bildschirm gebraucht
|
|
81
|
+
|
|
82
|
+
# TODO where comes the factor 0.8 from?
|
|
83
|
+
svg_data = svg_builder(width: "#{page_width*0.8}mm", height: "#{page_height*0.8}mm", viewBox: "0 0 #{image_width} #{image_height}") do |svg|
|
|
84
|
+
tra = Transformation.new
|
|
85
|
+
draw(svg, tra.translate(mm(draw_pos_x).round, mm(draw_pos_y).round), layout_file, preview, selected_object_id, row, page_nr)
|
|
86
|
+
end
|
|
87
|
+
svg_handle = RSVG::Handle.new_from_data(svg_data)
|
|
88
|
+
context.render_rsvg_handle(svg_handle)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|