fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Paged_Device.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_Paged_Device.cxx 8190 2011-01-05 10:21:45Z manolo $"
00003 //
00004 // implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems to:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00031 #include <FL/Fl_Paged_Device.H>
00032 #include <FL/Fl.H>
00033 #include <FL/fl_draw.H>
00034 
00035 const char *Fl_Paged_Device::class_id = "Fl_Paged_Device";
00036 
00037 
00049 void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y) 
00050 { 
00051   int old_x, old_y, new_x, new_y, is_window;
00052   if ( ! widget->visible() ) return;
00053   is_window = (widget->as_window() != NULL);
00054   widget->damage(FL_DAMAGE_ALL);
00055   // set origin to the desired top-left position of the widget
00056   origin(&old_x, &old_y);
00057   new_x = old_x + delta_x;
00058   new_y = old_y + delta_y;
00059   if (!is_window) {
00060     new_x -= widget->x();
00061     new_y -= widget->y();
00062   }
00063   if (new_x != old_x || new_y != old_y) {
00064     translate(new_x - old_x, new_y - old_y );
00065   }
00066   // if widget is a window, clip all drawings to the window area
00067   if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() );
00068   // we do some trickery to recognize OpenGL windows and draw them via a plugin
00069   int drawn_by_plugin = 0;
00070   if (widget->as_gl_window()) {
00071     Fl_Plugin_Manager pm("fltk:device");  
00072     Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
00073     if (pi) {
00074       int width, height;
00075       this->printable_rect(&width, &height);
00076       drawn_by_plugin = pi->print(widget, 0, 0, height);
00077       }
00078   }
00079   if (!drawn_by_plugin) {
00080     widget->draw();
00081   }
00082   if (is_window) fl_pop_clip();
00083   // find subwindows of widget and print them
00084   traverse(widget);
00085   // reset origin to where it was
00086   if (new_x != old_x || new_y != old_y) {
00087     untranslate();
00088   }
00089 }
00090 
00091 
00092 void Fl_Paged_Device::traverse(Fl_Widget *widget)
00093 {
00094   Fl_Group *g = widget->as_group();
00095   if (!g) return;
00096   int n = g->children();
00097   for (int i = 0; i < n; i++) {
00098     Fl_Widget *c = g->child(i);
00099     if ( !c->visible() ) continue;
00100     if ( c->as_window() ) {
00101       print_widget(c, c->x(), c->y());
00102     }
00103     else traverse(c);
00104   }
00105 }
00106 
00113 void Fl_Paged_Device::origin(int *x, int *y)
00114 {
00115   if (x) *x = x_offset;
00116   if (y) *y = y_offset;
00117 }
00118 
00130 void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
00131 {
00132   int slice, width, offset, count = 0;
00133   Fl_Surface_Device *current = Fl_Surface_Device::surface();
00134   Fl_Display_Device::display_device()->set_current();
00135   Fl_Window *save_front = Fl::first_window();
00136   win->show();
00137   fl_gc = NULL;
00138   Fl::check();
00139   win->make_current();
00140   uchar *image_data[20];
00141 #ifdef WIN32 // because of bug in StretchDIBits, vertically cut image in pieces of width slice
00142   slice = 500;
00143 #else
00144   slice = w;
00145 #endif
00146   for ( offset = 0; offset < w; offset += slice) {
00147     width = slice; 
00148     if (offset + width > w) width = w - offset;
00149     image_data[count++] = fl_read_image(NULL, x + offset, y, width, h);
00150   }  
00151   save_front->show();
00152   current->set_current();
00153   offset = 0;
00154   for ( int i = 0; i < count; i++, offset += slice) {
00155     width = slice; 
00156     if (offset + width > w) width = w - offset;
00157     fl_draw_image(image_data[i], delta_x + offset, delta_y, width, h, 3);
00158 #ifdef __APPLE__
00159     add_image(NULL, image_data[i]);
00160 #else
00161     delete image_data[i];
00162 #endif
00163   }
00164 }
00165 
00166 #ifdef __APPLE__
00167 void Fl_Paged_Device::add_image(Fl_Image *image, const uchar *data)
00168 {
00169   struct chain_elt *elt =  (struct chain_elt *)calloc(sizeof(struct chain_elt), 1);
00170   elt->image = image;
00171   elt->data = data;
00172   if (image_list_) { elt->next = image_list_; }
00173   image_list_ = elt;
00174 }
00175 
00176 void Fl_Paged_Device::delete_image_list()
00177 {
00178   while(image_list_) {
00179     struct chain_elt *next = image_list_->next;
00180     if(image_list_->image) delete image_list_->image;
00181     if (image_list_->data) delete (uchar*) image_list_->data; // msvc6 compilation fix
00182     free(image_list_);
00183     image_list_ = next;
00184   }
00185 }
00186 #endif
00187 
00188 
00197 int Fl_Paged_Device::start_job(int pagecount, int *frompage, int *topage) {return 1;}
00198 
00206 int Fl_Paged_Device::start_page (void) {return 1;}
00207 
00216 int Fl_Paged_Device::printable_rect(int *w, int *h) {return 1;}
00217 
00229 void Fl_Paged_Device::margins(int *left, int *top, int *right, int *bottom) {}
00230 
00242 void Fl_Paged_Device::origin(int x, int y) {}
00243 
00253 void Fl_Paged_Device::scale (float scale_x, float scale_y) {}
00254 
00262 void Fl_Paged_Device::rotate(float angle) {}
00263 
00269 int Fl_Paged_Device::end_page (void) {return 1;}
00270 
00274 void Fl_Paged_Device::end_job (void) {}
00275 
00283 void Fl_Paged_Device::translate(int x, int y) {}
00284 
00288 void Fl_Paged_Device::untranslate(void) {}
00289 
00290 const Fl_Paged_Device::page_format Fl_Paged_Device::page_formats[NO_PAGE_FORMATS] = { 
00291   // order of enum Page_Format
00292   // comes from appendix B of 5003.PPD_Spec_v4.3.pdf
00293   
00294   // A* // index(Ai) = i
00295   {2384, 3370, "A0"},
00296   {1684, 2384, "A1"},
00297   {1191, 1684, "A2"},
00298   { 842, 1191, "A3"},
00299   { 595,  842, "A4"},
00300   { 420,  595, "A5"},
00301   { 297,  420, "A6"},
00302   { 210,  297, "A7"},
00303   { 148,  210, "A8"},
00304   { 105,  148, "A9"},
00305   
00306   // B* // index(Bi) = i+10
00307   {2920, 4127, "B0"},
00308   {2064, 2920, "B1"},
00309   {1460, 2064, "B2"},
00310   {1032, 1460, "B3"},
00311   { 729, 1032, "B4"},
00312   { 516,  729, "B5"},
00313   { 363,  516, "B6"},
00314   { 258,  363, "B7"},
00315   { 181,  258, "B8"},
00316   { 127,  181, "B9"},
00317   {  91,  127, "B10"},
00318   
00319   // others
00320   { 459,  649, "EnvC5"}, // envelope
00321   { 312,  624, "EnvDL"}, // envelope
00322   { 522,  756, "Executive"},
00323   { 595,  935, "Folio"},
00324   {1224,  792, "Ledger"}, // landscape
00325   { 612, 1008, "Legal"},
00326   { 612,  792, "Letter"},
00327   { 792, 1224, "Tabloid"},
00328   { 297,  684, "Env10"} // envelope
00329 };
00330 
00331 //
00332 // End of "$Id: Fl_Paged_Device.cxx 8190 2011-01-05 10:21:45Z manolo $".
00333 //
00334