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_GDI_Printer.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_GDI_Printer.cxx 8190 2011-01-05 10:21:45Z manolo $"
00003 //
00004 // Support for WIN32 printing 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 on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #ifdef WIN32
00029 #include <FL/Fl_Printer.H>
00030 
00031 
00032 #include <FL/fl_ask.H>
00033 #include <FL/math.h>
00034 
00035 extern HWND fl_window;
00036 
00037 Fl_System_Printer::Fl_System_Printer(void) : Fl_Paged_Device() {
00038   hPr = NULL;
00039   class_name(class_id);
00040   driver(fl_graphics_driver);
00041 }
00042 
00043 Fl_System_Printer::~Fl_System_Printer(void) {
00044   if (hPr) end_job();
00045 }
00046 
00047 static void WIN_SetupPrinterDeviceContext(HDC prHDC)
00048 {
00049   if ( !prHDC ) return;
00050   
00051   fl_window = 0;
00052   fl_gc = prHDC;
00053   SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations
00054   SetMapMode(prHDC, MM_ANISOTROPIC);
00055   SetTextAlign(prHDC, TA_BASELINE|TA_LEFT);
00056   SetBkMode(prHDC, TRANSPARENT);        
00057   // this matches 720 logical units to the number of device units in 10 inches of paper
00058   // thus the logical unit is the point (= 1/72 inch)
00059   SetWindowExtEx(prHDC, 720, 720, NULL);
00060   SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL);
00061 }
00062 
00063 
00064 int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
00065 // returns 0 iff OK
00066 {
00067   DWORD       commdlgerr;
00068   DOCINFO     di;
00069   char        docName [256];
00070   int err = 0;
00071   
00072   abortPrint = FALSE;
00073   memset (&pd, 0, sizeof (PRINTDLG));
00074   pd.lStructSize = sizeof (PRINTDLG);
00075   pd.hwndOwner = GetForegroundWindow();
00076   pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION;
00077   pd.nMinPage = 1;
00078   pd.nMaxPage = pagecount;
00079   if (PrintDlg (&pd) != 0) {
00080     hPr = pd.hDC;
00081     if (hPr != NULL) {
00082       strcpy (docName, "FLTK");
00083       memset(&di, 0, sizeof(DOCINFO));
00084       di.cbSize = sizeof (DOCINFO);
00085       di.lpszDocName = (LPCSTR) docName;
00086       prerr = StartDoc (hPr, &di);
00087       if (prerr < 1) {
00088         abortPrint = TRUE;
00089         //fl_alert ("StartDoc error %d", prerr);
00090         err = 1;
00091       }
00092     } else {
00093       commdlgerr = CommDlgExtendedError ();
00094       fl_alert ("Unable to create print context, error %lu",
00095                 (unsigned long) commdlgerr);
00096       err = 1;
00097     }
00098   } else {
00099     err = 1;
00100   }
00101   if(!err) {
00102     if((pd.Flags & PD_PAGENUMS) != 0 ) {
00103       if (frompage) *frompage = pd.nFromPage;
00104       if (topage) *topage = pd.nToPage;
00105     }
00106     else {
00107       if (frompage) *frompage = 1;
00108       if (topage) *topage = pagecount;
00109     }
00110     x_offset = 0;
00111     y_offset = 0;
00112     WIN_SetupPrinterDeviceContext (hPr);
00113     gc = (void *)fl_gc;
00114     this->set_current();
00115   }
00116   return err;
00117 }
00118 
00119 void Fl_System_Printer::end_job (void)
00120 {
00121   Fl_Display_Device::display_device()->set_current();
00122   if (hPr != NULL) {
00123     if (! abortPrint) {
00124       prerr = EndDoc (hPr);
00125       if (prerr < 0) {
00126         fl_alert ("EndDoc error %d", prerr);
00127       }
00128     }
00129     DeleteDC (hPr);
00130     if (pd.hDevMode != NULL) {
00131       GlobalFree (pd.hDevMode);
00132     }
00133     if (pd.hDevNames != NULL) {
00134       GlobalFree (pd.hDevNames);
00135     }
00136   }
00137   hPr = NULL;
00138 }
00139 
00140 void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h)
00141 {
00142   POINT         physPageSize;
00143   POINT         pixelsPerInch;
00144     
00145   if (hPr == NULL) return;
00146   SetWindowOrgEx(fl_gc, 0, 0, NULL);
00147   
00148   physPageSize.x = GetDeviceCaps(hPr, HORZRES);
00149   physPageSize.y = GetDeviceCaps(hPr, VERTRES);
00150   DPtoLP(hPr, &physPageSize, 1);
00151   *w = physPageSize.x + 1;
00152   *h = physPageSize.y + 1;
00153   pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX);
00154   pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY);
00155   DPtoLP(hPr, &pixelsPerInch, 1);
00156   left_margin = (pixelsPerInch.x / 4);
00157   *w -= (pixelsPerInch.x / 2);
00158   top_margin = (pixelsPerInch.y / 4);
00159   *h -= (pixelsPerInch.y / 2);
00160   
00161   *x = left_margin;
00162   *y = top_margin;
00163   origin(x_offset, y_offset);
00164 }
00165 
00166 void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom)
00167 {
00168   int x, y, w, h;
00169   absolute_printable_rect(&x, &y, &w, &h);
00170   if (left) *left = x;
00171   if (top) *top = y;
00172   if (right) *right = x;
00173   if (bottom) *bottom = y;
00174 }
00175 
00176 int Fl_System_Printer::printable_rect(int *w, int *h)
00177 {
00178   int x, y;
00179   absolute_printable_rect(&x, &y, w, h);
00180   return 0;
00181 }
00182 
00183 int Fl_System_Printer::start_page (void)
00184 {
00185   int  rsult, w, h;
00186   
00187   rsult = 0;
00188   if (hPr != NULL) {
00189     WIN_SetupPrinterDeviceContext (hPr);
00190     prerr = StartPage (hPr);
00191     if (prerr < 0) {
00192       fl_alert ("StartPage error %d", prerr);
00193       rsult = 1;
00194     }
00195     printable_rect(&w, &h);
00196     origin(0, 0);
00197     image_list_ = NULL;
00198     fl_clip_region(0);
00199     gc = (void *)fl_gc;
00200   }
00201   return rsult;
00202 }
00203 
00204 void Fl_System_Printer::origin (int deltax, int deltay)
00205 {
00206   SetWindowOrgEx(fl_gc, - left_margin - deltax, - top_margin - deltay, NULL);
00207   x_offset = deltax;
00208   y_offset = deltay;
00209 }
00210 
00211 void Fl_System_Printer::scale (float scalex, float scaley)
00212 {
00213   int w, h;
00214   SetWindowExtEx(fl_gc, (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL);
00215   printable_rect(&w, &h);
00216   origin(0, 0);
00217 }
00218 
00219 void Fl_System_Printer::rotate (float rot_angle)
00220 {
00221   XFORM mat;
00222   float angle;
00223   angle = - rot_angle * M_PI / 180.;
00224   mat.eM11 = cos(angle);
00225   mat.eM12 = sin(angle);
00226   mat.eM21 = - mat.eM12;
00227   mat.eM22 = mat.eM11;
00228   mat.eDx = mat.eDy = 0;
00229   SetWorldTransform(fl_gc, &mat);
00230 }
00231 
00232 int Fl_System_Printer::end_page (void)
00233 {
00234   int  rsult;
00235   
00236   rsult = 0;
00237   if (hPr != NULL) {
00238     prerr = EndPage (hPr);
00239     if (prerr < 0) {
00240       abortPrint = TRUE;
00241       fl_alert ("EndPage error %d", prerr);
00242       rsult = 1;
00243     }
00244   }
00245   gc = NULL;
00246   return rsult;
00247 }
00248 
00249 static int translate_stack_depth = 0;
00250 const int translate_stack_max = 5;
00251 static int translate_stack_x[translate_stack_max];
00252 static int translate_stack_y[translate_stack_max];
00253 
00254 static void do_translate(int x, int y)
00255 {
00256   XFORM tr;
00257   tr.eM11 = tr.eM22 = 1;
00258   tr.eM12 = tr.eM21 = 0;
00259   tr.eDx =  x;
00260   tr.eDy =  y;
00261   ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY);
00262 }
00263 
00264 void Fl_System_Printer::translate (int x, int y)
00265 {
00266   do_translate(x, y);
00267   if (translate_stack_depth < translate_stack_max) {
00268     translate_stack_x[translate_stack_depth] = x;
00269     translate_stack_y[translate_stack_depth] = y;
00270     translate_stack_depth++;
00271     }
00272 }
00273 
00274 void Fl_System_Printer::untranslate (void)
00275 {
00276   if (translate_stack_depth > 0) {
00277     translate_stack_depth--;
00278     do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth] );
00279     }
00280 }
00281 
00282 #endif // WIN32
00283 
00284 //
00285 // End of "$Id: Fl_GDI_Printer.cxx 8190 2011-01-05 10:21:45Z manolo $".
00286 //