themes: Workaround for bug where a background color of RGB 0,0,0 in Black color schem...
[ntk.git] / src / Fl_Paged_Device.cxx
blobd3ea07b66c7f6d52d139b1dea8abc89666b55d5d
1 //
2 // "$Id: Fl_Paged_Device.cxx 8621 2011-04-23 15:46:30Z AlbrechtS $"
3 //
4 // implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 2010-2011 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.
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.
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.
23 // Please report all bugs and problems to:
25 // http://www.fltk.org/str.php
27 /** \file Fl_Paged_Device.cxx
28 \brief implementation of class Fl_Paged_Device.
31 #include <FL/Fl_Paged_Device.H>
32 #include <FL/Fl.H>
33 #include <FL/fl_draw.H>
35 const char *Fl_Paged_Device::class_id = "Fl_Paged_Device";
38 /**
39 @brief Draws the widget on the printed page.
41 The widget's position on the printed page is determined by the last call to origin()
42 and by the optional delta_x and delta_y arguments.
43 Its dimensions are in points unless there was a previous call to scale().
44 @param[in] widget Any FLTK widget (e.g., standard, custom, window).
45 @param[in] delta_x Optional horizontal offset for positioning the widget relatively
46 to the current origin of graphics functions.
47 @param[in] delta_y Same as above, vertically.
49 void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y)
51 int old_x, old_y, new_x, new_y, is_window;
52 if ( ! widget->visible() ) return;
53 is_window = (widget->as_window() != NULL);
54 widget->damage(FL_DAMAGE_ALL);
55 // set origin to the desired top-left position of the widget
56 origin(&old_x, &old_y);
57 new_x = old_x + delta_x;
58 new_y = old_y + delta_y;
59 if (!is_window) {
60 new_x -= widget->x();
61 new_y -= widget->y();
63 if (new_x != old_x || new_y != old_y) {
64 translate(new_x - old_x, new_y - old_y );
66 // if widget is a window, clip all drawings to the window area
67 if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() );
68 // we do some trickery to recognize OpenGL windows and draw them via a plugin
69 int drawn_by_plugin = 0;
70 if (widget->as_gl_window()) {
71 Fl_Plugin_Manager pm("fltk:device");
72 Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
73 if (pi) {
74 int width, height;
75 this->printable_rect(&width, &height);
76 drawn_by_plugin = pi->print(widget, 0, 0, height);
79 if (!drawn_by_plugin) {
80 widget->draw();
82 if (is_window) fl_pop_clip();
83 // find subwindows of widget and print them
84 traverse(widget);
85 // reset origin to where it was
86 if (new_x != old_x || new_y != old_y) {
87 untranslate();
92 void Fl_Paged_Device::traverse(Fl_Widget *widget)
94 Fl_Group *g = widget->as_group();
95 if (!g) return;
96 int n = g->children();
97 for (int i = 0; i < n; i++) {
98 Fl_Widget *c = g->child(i);
99 if ( !c->visible() ) continue;
100 if ( c->as_window() ) {
101 print_widget(c, c->x(), c->y());
103 else traverse(c);
108 @brief Computes the page coordinates of the current origin of graphics functions.
110 @param[out] x If non-null, *x is set to the horizontal page offset of graphics origin.
111 @param[out] y Same as above, vertically.
113 void Fl_Paged_Device::origin(int *x, int *y)
115 if (x) *x = x_offset;
116 if (y) *y = y_offset;
120 @brief Prints a rectangular part of an on-screen window.
122 @param win The window from where to capture.
123 @param x The rectangle left
124 @param y The rectangle top
125 @param w The rectangle width
126 @param h The rectangle height
127 @param delta_x Optional horizontal offset from current graphics origin where to print the captured rectangle.
128 @param delta_y As above, vertically.
130 void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
132 Fl_Surface_Device *current = Fl_Surface_Device::surface();
133 Fl_Display_Device::display_device()->set_current();
134 Fl_Window *save_front = Fl::first_window();
135 win->show();
136 fl_gc = NULL;
137 Fl::check();
138 win->make_current();
139 uchar *image_data;
140 image_data = fl_read_image(NULL, x, y, w, h);
141 if (save_front != win) save_front->show();
142 current->set_current();
143 fl_draw_image(image_data, delta_x, delta_y, w, h, 3);
144 delete[] image_data;
145 #ifdef WIN32
146 fl_gc = GetDC(fl_xid(win));
147 ReleaseDC(fl_xid(win), fl_gc);
148 #endif
152 @brief Starts a print job.
154 @param[in] pagecount the total number of pages of the job
155 @param[out] frompage if non-null, *frompage is set to the first page the user wants printed
156 @param[out] topage if non-null, *topage is set to the last page the user wants printed
157 @return 0 if OK, non-zero if any error
159 int Fl_Paged_Device::start_job(int pagecount, int *frompage, int *topage) {return 1;}
162 @brief Starts a new printed page
164 The page coordinates are initially in points, i.e., 1/72 inch,
165 and with origin at the top left of the printable page area.
166 @return 0 if OK, non-zero if any error
168 int Fl_Paged_Device::start_page (void) {return 1;}
171 @brief Computes the width and height of the printable area of the page.
173 Values are in the same unit as that used by FLTK drawing functions,
174 are unchanged by calls to origin(), but are changed by scale() calls.
175 Values account for the user-selected paper type and print orientation.
176 @return 0 if OK, non-zero if any error
178 int Fl_Paged_Device::printable_rect(int *w, int *h) {return 1;}
181 @brief Computes the dimensions of margins that lie between the printable page area and
182 the full page.
184 Values are in the same unit as that used by FLTK drawing functions. They are changed
185 by scale() calls.
186 @param[out] left If non-null, *left is set to the left margin size.
187 @param[out] top If non-null, *top is set to the top margin size.
188 @param[out] right If non-null, *right is set to the right margin size.
189 @param[out] bottom If non-null, *bottom is set to the bottom margin size.
191 void Fl_Paged_Device::margins(int *left, int *top, int *right, int *bottom) {}
194 @brief Sets the position in page coordinates of the origin of graphics functions.
196 Arguments should be expressed relatively to the result of a previous printable_rect() call.
197 That is, <tt>printable_rect(&w, &h); origin(w/2, 0);</tt> sets the graphics origin at the
198 top center of the page printable area.
199 Origin() calls are not affected by rotate() calls.
200 Successive origin() calls don't combine their effects.
201 @param[in] x Horizontal position in page coordinates of the desired origin of graphics functions.
202 @param[in] y Same as above, vertically.
204 void Fl_Paged_Device::origin(int x, int y) {}
207 @brief Changes the scaling of page coordinates.
209 This function also resets the origin of graphics functions at top left of printable page area.
210 After a scale() call, do a printable_rect() call to get the new dimensions of the printable page area.
211 Successive scale() calls don't combine their effects.
212 @param scale_x Horizontal dimensions of plot are multiplied by this quantity.
213 @param scale_y Same as above, vertically.
214 The value 0. is equivalent to setting \p scale_y = \p scale_x. Thus, scale(factor);
215 is equivalent to scale(factor, factor);
217 void Fl_Paged_Device::scale (float scale_x, float scale_y) {}
220 @brief Rotates the graphics operations relatively to paper.
222 The rotation is centered on the current graphics origin.
223 Successive rotate() calls don't combine their effects.
224 @param angle Rotation angle in counter-clockwise degrees.
226 void Fl_Paged_Device::rotate(float angle) {}
229 @brief To be called at the end of each page.
231 @return 0 if OK, non-zero if any error.
233 int Fl_Paged_Device::end_page (void) {return 1;}
236 @brief To be called at the end of a print job.
238 void Fl_Paged_Device::end_job (void) {}
241 @brief Translates the current graphics origin accounting for the current rotation.
243 This function is only useful after a rotate() call.
244 Each translate() call must be matched by an untranslate() call.
245 Successive translate() calls add up their effects.
247 void Fl_Paged_Device::translate(int x, int y) {}
250 @brief Undoes the effect of a previous translate() call.
252 void Fl_Paged_Device::untranslate(void) {}
254 const Fl_Paged_Device::page_format Fl_Paged_Device::page_formats[NO_PAGE_FORMATS] = {
255 // order of enum Page_Format
256 // comes from appendix B of 5003.PPD_Spec_v4.3.pdf
258 // A* // index(Ai) = i
259 {2384, 3370, "A0"},
260 {1684, 2384, "A1"},
261 {1191, 1684, "A2"},
262 { 842, 1191, "A3"},
263 { 595, 842, "A4"},
264 { 420, 595, "A5"},
265 { 297, 420, "A6"},
266 { 210, 297, "A7"},
267 { 148, 210, "A8"},
268 { 105, 148, "A9"},
270 // B* // index(Bi) = i+10
271 {2920, 4127, "B0"},
272 {2064, 2920, "B1"},
273 {1460, 2064, "B2"},
274 {1032, 1460, "B3"},
275 { 729, 1032, "B4"},
276 { 516, 729, "B5"},
277 { 363, 516, "B6"},
278 { 258, 363, "B7"},
279 { 181, 258, "B8"},
280 { 127, 181, "B9"},
281 { 91, 127, "B10"},
283 // others
284 { 459, 649, "EnvC5"}, // envelope
285 { 312, 624, "EnvDL"}, // envelope
286 { 522, 756, "Executive"},
287 { 595, 935, "Folio"},
288 {1224, 792, "Ledger"}, // landscape
289 { 612, 1008, "Legal"},
290 { 612, 792, "Letter"},
291 { 792, 1224, "Tabloid"},
292 { 297, 684, "Env10"} // envelope
296 // End of "$Id: Fl_Paged_Device.cxx 8621 2011-04-23 15:46:30Z AlbrechtS $".