blob: 49d25a785524ff39a88e6b6322e9a79085f7737c [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
2// "$Id: Fl_GDI_Printer.cxx 8467 2011-02-23 14:36:18Z manolo $"
3//
4// Support for WIN32 printing for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 2010 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25// http://www.fltk.org/str.php
26//
27
28#ifdef WIN32
29#include <FL/Fl_Printer.H>
30
31
32#include <FL/fl_ask.H>
33#include <FL/math.h>
34
35extern HWND fl_window;
36
37Fl_System_Printer::Fl_System_Printer(void) : Fl_Paged_Device() {
38 hPr = NULL;
39 driver(Fl_Display_Device::display_device()->driver());
40}
41
42Fl_System_Printer::~Fl_System_Printer(void) {
43 if (hPr) end_job();
44}
45
46static void WIN_SetupPrinterDeviceContext(HDC prHDC)
47{
48 if ( !prHDC ) return;
49
50 fl_window = 0;
51 fl_gc = prHDC;
52 SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations
53 SetMapMode(prHDC, MM_ANISOTROPIC);
54 SetTextAlign(prHDC, TA_BASELINE|TA_LEFT);
55 SetBkMode(prHDC, TRANSPARENT);
56 // this matches 720 logical units to the number of device units in 10 inches of paper
57 // thus the logical unit is the point (= 1/72 inch)
58 SetWindowExtEx(prHDC, 720, 720, NULL);
59 SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL);
60}
61
62
63int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
64// returns 0 iff OK
65{
66 DWORD commdlgerr;
67 DOCINFO di;
68 char docName [256];
69 int err = 0;
70
71 abortPrint = FALSE;
72 memset (&pd, 0, sizeof (PRINTDLG));
73 pd.lStructSize = sizeof (PRINTDLG);
74 pd.hwndOwner = GetForegroundWindow();
75 pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION;
76 pd.nMinPage = 1;
77 pd.nMaxPage = pagecount;
78 if (PrintDlg (&pd) != 0) {
79 hPr = pd.hDC;
80 if (hPr != NULL) {
81 strcpy (docName, "FLTK");
82 memset(&di, 0, sizeof(DOCINFO));
83 di.cbSize = sizeof (DOCINFO);
84 di.lpszDocName = (LPCSTR) docName;
85 prerr = StartDoc (hPr, &di);
86 if (prerr < 1) {
87 abortPrint = TRUE;
88 //fl_alert ("StartDoc error %d", prerr);
89 err = 1;
90 }
91 } else {
92 commdlgerr = CommDlgExtendedError ();
93 fl_alert ("Unable to create print context, error %lu",
94 (unsigned long) commdlgerr);
95 err = 1;
96 }
97 } else {
98 err = 1;
99 }
100 if(!err) {
101 if((pd.Flags & PD_PAGENUMS) != 0 ) {
102 if (frompage) *frompage = pd.nFromPage;
103 if (topage) *topage = pd.nToPage;
104 }
105 else {
106 if (frompage) *frompage = 1;
107 if (topage) *topage = pagecount;
108 }
109 x_offset = 0;
110 y_offset = 0;
111 WIN_SetupPrinterDeviceContext (hPr);
112 gc = (void *)fl_gc;
113 this->set_current();
114 }
115 return err;
116}
117
118void Fl_System_Printer::end_job (void)
119{
120 Fl_Display_Device::display_device()->set_current();
121 if (hPr != NULL) {
122 if (! abortPrint) {
123 prerr = EndDoc (hPr);
124 if (prerr < 0) {
125 fl_alert ("EndDoc error %d", prerr);
126 }
127 }
128 DeleteDC (hPr);
129 if (pd.hDevMode != NULL) {
130 GlobalFree (pd.hDevMode);
131 }
132 if (pd.hDevNames != NULL) {
133 GlobalFree (pd.hDevNames);
134 }
135 }
136 hPr = NULL;
137}
138
139void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h)
140{
141 POINT physPageSize;
142 POINT pixelsPerInch;
143
144 if (hPr == NULL) return;
145 SetWindowOrgEx(fl_gc, 0, 0, NULL);
146
147 physPageSize.x = GetDeviceCaps(hPr, HORZRES);
148 physPageSize.y = GetDeviceCaps(hPr, VERTRES);
149 DPtoLP(hPr, &physPageSize, 1);
150 *w = physPageSize.x + 1;
151 *h = physPageSize.y + 1;
152 pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX);
153 pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY);
154 DPtoLP(hPr, &pixelsPerInch, 1);
155 left_margin = (pixelsPerInch.x / 4);
156 *w -= (pixelsPerInch.x / 2);
157 top_margin = (pixelsPerInch.y / 4);
158 *h -= (pixelsPerInch.y / 2);
159
160 *x = left_margin;
161 *y = top_margin;
162 origin(x_offset, y_offset);
163}
164
165void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom)
166{
167 int x, y, w, h;
168 absolute_printable_rect(&x, &y, &w, &h);
169 if (left) *left = x;
170 if (top) *top = y;
171 if (right) *right = x;
172 if (bottom) *bottom = y;
173}
174
175int Fl_System_Printer::printable_rect(int *w, int *h)
176{
177 int x, y;
178 absolute_printable_rect(&x, &y, w, h);
179 return 0;
180}
181
182int Fl_System_Printer::start_page (void)
183{
184 int rsult, w, h;
185
186 rsult = 0;
187 if (hPr != NULL) {
188 WIN_SetupPrinterDeviceContext (hPr);
189 prerr = StartPage (hPr);
190 if (prerr < 0) {
191 fl_alert ("StartPage error %d", prerr);
192 rsult = 1;
193 }
194 printable_rect(&w, &h);
195 origin(0, 0);
196 fl_clip_region(0);
197 gc = (void *)fl_gc;
198 }
199 return rsult;
200}
201
202void Fl_System_Printer::origin (int deltax, int deltay)
203{
204 SetWindowOrgEx(fl_gc, - left_margin - deltax, - top_margin - deltay, NULL);
205 x_offset = deltax;
206 y_offset = deltay;
207}
208
209void Fl_System_Printer::scale (float scalex, float scaley)
210{
211 if (scaley == 0.) scaley = scalex;
212 int w, h;
213 SetWindowExtEx(fl_gc, (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL);
214 printable_rect(&w, &h);
215 origin(0, 0);
216}
217
218void Fl_System_Printer::rotate (float rot_angle)
219{
220 XFORM mat;
221 float angle;
222 angle = - rot_angle * M_PI / 180.;
223 mat.eM11 = cos(angle);
224 mat.eM12 = sin(angle);
225 mat.eM21 = - mat.eM12;
226 mat.eM22 = mat.eM11;
227 mat.eDx = mat.eDy = 0;
228 SetWorldTransform(fl_gc, &mat);
229}
230
231int Fl_System_Printer::end_page (void)
232{
233 int rsult;
234
235 rsult = 0;
236 if (hPr != NULL) {
237 prerr = EndPage (hPr);
238 if (prerr < 0) {
239 abortPrint = TRUE;
240 fl_alert ("EndPage error %d", prerr);
241 rsult = 1;
242 }
243 }
244 gc = NULL;
245 return rsult;
246}
247
248static int translate_stack_depth = 0;
249const int translate_stack_max = 5;
250static int translate_stack_x[translate_stack_max];
251static int translate_stack_y[translate_stack_max];
252
253static void do_translate(int x, int y)
254{
255 XFORM tr;
256 tr.eM11 = tr.eM22 = 1;
257 tr.eM12 = tr.eM21 = 0;
258 tr.eDx = x;
259 tr.eDy = y;
260 ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY);
261}
262
263void Fl_System_Printer::translate (int x, int y)
264{
265 do_translate(x, y);
266 if (translate_stack_depth < translate_stack_max) {
267 translate_stack_x[translate_stack_depth] = x;
268 translate_stack_y[translate_stack_depth] = y;
269 translate_stack_depth++;
270 }
271}
272
273void Fl_System_Printer::untranslate (void)
274{
275 if (translate_stack_depth > 0) {
276 translate_stack_depth--;
277 do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth] );
278 }
279}
280
281#endif // WIN32
282
283//
284// End of "$Id: Fl_GDI_Printer.cxx 8467 2011-02-23 14:36:18Z manolo $".
285//