-
-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathprinter-dc.rkt
234 lines (196 loc) · 9.38 KB
/
printer-dc.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#lang racket/base
(require racket/class
racket/draw/private/local
racket/draw/private/dc
racket/draw/unsafe/cairo
racket/draw/private/bitmap
racket/draw/private/bitmap-dc
racket/draw/private/record-dc
racket/draw/private/ps-setup
ffi/unsafe
ffi/unsafe/alloc
"../common/queue.rkt"
"widget.rkt"
"utils.rkt"
"types.rkt")
(provide
(protect-out printer-dc%
show-print-setup))
(define GTK_UNIT_POINTS 1)
(define GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG 0)
(define GTK_PRINT_OPERATION_RESULT_ERROR 0)
(define GTK_PRINT_OPERATION_RESULT_APPLY 1)
(define GTK_PRINT_OPERATION_RESULT_CANCEL 2)
(define GTK_PRINT_OPERATION_RESULT_IN_PROGRESS 3)
(define GTK_PAGE_ORIENTATION_PORTRAIT 0)
(define GTK_PAGE_ORIENTATION_LANDSCAPE 1)
(define GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT 2)
(define GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE 3)
(define _GtkPageSetup (_cpointer/null 'GtkPageSetup))
(define _GtkPrintSettings (_cpointer/null 'GtkPrintSettings))
(define _GtkPrintOperation _GtkWidget) ; not really, but we connect signals...
(define _GtkPrintContext (_cpointer/null 'GtkPrintContext))
(define-gtk gtk_page_setup_new (_fun -> _GtkPageSetup)
#:wrap (allocator gobject-unref))
(define-gtk gtk_page_setup_copy (_fun _GtkPageSetup -> _GtkPageSetup)
#:wrap (allocator gobject-unref))
(define allocated-page-setup ((allocator gobject-unref) values))
(define-gtk gtk_print_settings_new (_fun -> _GtkPrintSettings)
#:wrap (allocator gobject-unref))
(define-gtk gtk_page_setup_get_paper_height (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_paper_width (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_left_margin (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_right_margin (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_top_margin (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_bottom_margin (_fun _GtkPageSetup _int -> _double))
(define-gtk gtk_page_setup_get_orientation (_fun _GtkPageSetup -> _int))
(define-gtk gtk_page_setup_set_orientation (_fun _GtkPageSetup _int -> _void))
(define-gtk gtk_print_operation_new (_fun -> _GtkPrintOperation)
#:wrap (allocator gobject-unref))
(define-gtk gtk_print_operation_set_default_page_setup (_fun _GtkPrintOperation _GtkPageSetup
-> _void))
(define-gtk gtk_print_operation_run (_fun _GtkPrintOperation
_int
(_or-null _GtkWindow)
(_ptr o _pointer)
-> _int))
(define-gtk gtk_print_operation_set_allow_async (_fun _GtkPrintOperation _gboolean -> _void))
(define-gtk gtk_print_operation_set_n_pages (_fun _GtkPrintOperation _int -> _void))
(define-gtk gtk_print_context_get_cairo_context (_fun _GtkPrintContext -> _cairo_t))
(define-gtk gtk_print_run_page_setup_dialog_async (_fun (_or-null _GtkWindow)
_GtkPageSetup
_GtkPrintSettings
_fpointer
_pointer
-> _void))
(define (print-setup-done page-setup cb)
((ptr-ref cb _racket) page-setup))
(define print_setup_done (function-ptr print-setup-done
(_fun _GtkPageSetup _pointer -> _void)))
(define (pss-install-page-setup pss page-setup)
(gtk_page_setup_set_orientation page-setup (if (eq? (send pss get-orientation) 'landscape)
GTK_PAGE_ORIENTATION_LANDSCAPE
GTK_PAGE_ORIENTATION_PORTRAIT)))
(define (show-print-setup parent)
(let* ([pss (current-ps-setup)]
[page-setup (or (send pss get-native)
(let ([ps (gtk_page_setup_new)])
(send pss set-native ps gtk_page_setup_copy)
ps))]
[print-settings (gtk_print_settings_new)]
[sema (make-semaphore)]
[done-page-setup #f]
[cell (malloc-immobile-cell (lambda (ps)
(set! done-page-setup (and ps
(allocated-page-setup ps)))
(semaphore-post sema)))])
(pss-install-page-setup pss page-setup)
(gtk_print_run_page_setup_dialog_async (and parent
(send parent get-gtk))
page-setup
print-settings
print_setup_done
cell)
(yield sema)
;; `ptr-set!'s are a hack to ensure that the objects are not GCed:
(ptr-set! cell _racket page-setup)
(ptr-set! cell _racket print-settings)
(free-immobile-cell cell)
(and done-page-setup
(begin
(send pss set-native done-page-setup gtk_page_setup_copy)
(send pss set-orientation (if (member
(gtk_page_setup_get_orientation done-page-setup)
(list GTK_PAGE_ORIENTATION_LANDSCAPE
GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE))
'landscape
'portrait))
#t))))
(define-signal-handler connect-begin-print "begin-print"
(_fun _GtkPrintOperation _GtkPrintContext -> _void)
(lambda (op-gtk ctx-gtk)
(void)))
(define-signal-handler connect-draw-page "draw-page"
(_fun _GtkPrintOperation _GtkPrintContext _int -> _void)
(lambda (op-gtk ctx-gtk page-no)
(let ([wx (gtk->wx op-gtk)])
(when wx
(send wx draw-page ctx-gtk page-no)))))
(define-signal-handler connect-done "done"
(_fun _GtkPrintOperation _int -> _void)
(lambda (op-gtk res)
(when (= res GTK_PRINT_OPERATION_RESULT_CANCEL)
(let ([wx (gtk->wx op-gtk)])
(when wx
(send wx done))))))
(define-signal-handler connect-end-print "end-print"
(_fun _GtkPrintOperation _GtkPrintContext -> _void)
(lambda (op-gtk ctx-gtk)
(let ([wx (gtk->wx op-gtk)])
(when wx
(send wx done)))))
(define printout%
(class widget%
(init-field op-gtk
pages
page-setup)
(super-new [gtk op-gtk])
(connect-begin-print op-gtk)
(connect-draw-page op-gtk)
(connect-done op-gtk)
(connect-end-print op-gtk)
(gtk_print_operation_set_n_pages op-gtk (length pages))
(gtk_print_operation_set_allow_async op-gtk #t)
(gtk_print_operation_set_default_page_setup op-gtk page-setup)
(define done-sema (make-semaphore))
(define/public (go)
(let ([res (gtk_print_operation_run op-gtk
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
#f)])
(yield done-sema)))
(define/public (draw-page ctx-gtk pageno)
(let ([cr (gtk_print_context_get_cairo_context ctx-gtk)])
((list-ref pages pageno)
(make-object
(class (dc-mixin default-dc-backend%)
(super-new)
(define orig-matrix (make-cairo_matrix_t 0.0 0.0 0.0 0.0 0.0 0.0))
(cairo_get_matrix cr orig-matrix)
(define/override (init-cr-matrix cr) (cairo_set_matrix cr orig-matrix))
(define/override (get-cr) cr))))))
(define/public (done)
(semaphore-post done-sema))))
(define printer-dc%
(class (record-dc-mixin (dc-mixin bitmap-dc-backend%))
(init [parent #f])
(super-make-object (make-object bitmap% 1 1))
(inherit get-recorded-command
reset-recording)
(define pages null)
(define/override (end-page)
(set! pages (cons (get-recorded-command) pages))
(reset-recording))
(define page-setup (or (let-values ([(ps copier)
(send (current-ps-setup)
get-native-copy)])
ps)
(gtk_page_setup_new)))
(pss-install-page-setup (current-ps-setup) page-setup)
(define page-width (- (gtk_page_setup_get_paper_width page-setup GTK_UNIT_POINTS)
(gtk_page_setup_get_left_margin page-setup GTK_UNIT_POINTS)
(gtk_page_setup_get_right_margin page-setup GTK_UNIT_POINTS)))
(define page-height (- (gtk_page_setup_get_paper_height page-setup GTK_UNIT_POINTS)
(gtk_page_setup_get_top_margin page-setup GTK_UNIT_POINTS)
(gtk_page_setup_get_bottom_margin page-setup GTK_UNIT_POINTS)))
(define page-scaling 1.0) ; scale from gtk_print_operation_run is too late
(define/override (get-size)
(values (/ page-width page-scaling) (/ page-height page-scaling)))
(define/override (get-device-scale)
(values page-scaling page-scaling))
(define/override (end-doc)
(send (new printout%
[op-gtk (gtk_print_operation_new)]
[pages (reverse pages)]
[page-setup page-setup])
go)
(void))))