diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2010-03-14 18:07:24 +0000 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2010-03-14 18:07:24 +0000 |
| commit | 998cc6df521a115454727d1ecf6bc7d4fee96f68 (patch) | |
| tree | 70a1c9afffb294a75bd38484c2e6e4a042ac3426 /src/Fl_GDI_Printer.cxx | |
| parent | 5bc66fafc348c547870bbf51c9c4a7215ad4ff25 (diff) | |
Merge of branch-1.3-Fl_Printer, with the following main changes:
(1) adding Fl_Device class (and more) for device abstraction
(2) adding Fl_Pinter class (and more) for printing support.
Todo: Code cleanup, update dependencies, remove/replace test print window.
I'm looking into converting the test window popup in a global shortcut
that would pop up the print dialog now...
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7263 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_GDI_Printer.cxx')
| -rw-r--r-- | src/Fl_GDI_Printer.cxx | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx new file mode 100644 index 000000000..a87b0805f --- /dev/null +++ b/src/Fl_GDI_Printer.cxx @@ -0,0 +1,253 @@ +/* + * Fl_GDI_Printer.cxx + */ + +#ifdef WIN32 +#include <FL/Fl_Printer.H> + + +#include <FL/fl_ask.H> +#include <math.h> + +extern HWND fl_window; + +Fl_GDI_Printer::Fl_GDI_Printer(void) : Fl_Virtual_Printer() { + hPr = NULL; + type_ = gdi_printer; +} + +static void WIN_SetupPrinterDeviceContext(HDC prHDC) +{ + if ( !prHDC ) return; + + fl_window = 0; + fl_gc = prHDC; + SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations + SetMapMode(prHDC, MM_ANISOTROPIC); + SetTextAlign(prHDC, TA_BASELINE|TA_LEFT); + SetBkMode(prHDC, TRANSPARENT); + // this matches 720 logical units to the number of device units in 10 inches of paper + // thus the logical unit is the point (= 1/72 inch) + SetWindowExtEx(prHDC, 720, 720, NULL); + SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL); +} + + +int Fl_GDI_Printer::start_job (int pagecount, int *frompage, int *topage) +// returns 0 iff OK +{ + DWORD commdlgerr; + DOCINFO di; + char docName [256]; + int err = 0; + + abortPrint = FALSE; + memset (&pd, 0, sizeof (PRINTDLG)); + pd.lStructSize = sizeof (PRINTDLG); + pd.hwndOwner = GetForegroundWindow(); + pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION; + pd.nMinPage = 1; + pd.nMaxPage = pagecount; + if (PrintDlg (&pd) != 0) { + hPr = pd.hDC; + if (hPr != NULL) { + strcpy (docName, "FLTK"); + memset(&di, 0, sizeof(DOCINFO)); + di.cbSize = sizeof (DOCINFO); + di.lpszDocName = (LPCSTR) docName; + prerr = StartDoc (hPr, &di); + if (prerr < 1) { + abortPrint = TRUE; + fl_alert ("StartDoc error %d", prerr); + err = 1; + } + } else { + commdlgerr = CommDlgExtendedError (); + fl_alert ("Unable to create print context, error %lu", + (unsigned long) commdlgerr); + err = 1; + } + } else { + err = 1; + } + if(!err) { + if((pd.Flags & PD_PAGENUMS) != 0 ) { + if (frompage) *frompage = pd.nFromPage; + if (topage) *topage = pd.nToPage; + } + else { + if (frompage) *frompage = 1; + if (topage) *topage = pagecount; + } + x_offset = 0; + y_offset = 0; + this->set_current(); + } + return err; +} + +void Fl_GDI_Printer::end_job (void) +{ + Fl_Device::display_device()->set_current(); + if (hPr != NULL) { + if (! abortPrint) { + prerr = EndDoc (hPr); + if (prerr < 0) { + fl_alert ("EndDoc error %d", prerr); + } + } + DeleteDC (hPr); + if (pd.hDevMode != NULL) { + GlobalFree (pd.hDevMode); + } + if (pd.hDevNames != NULL) { + GlobalFree (pd.hDevNames); + } + } +} + +void Fl_GDI_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h) +{ + POINT physPageSize; + POINT pixelsPerInch; + + if (hPr == NULL) return; + SetWindowOrgEx(fl_gc, 0, 0, NULL); + + physPageSize.x = GetDeviceCaps(hPr, HORZRES); + physPageSize.y = GetDeviceCaps(hPr, VERTRES); + DPtoLP(hPr, &physPageSize, 1); + *w = physPageSize.x + 1; + *h = physPageSize.y + 1; + pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX); + pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY); + DPtoLP(hPr, &pixelsPerInch, 1); + left_margin = (pixelsPerInch.x / 4); + *w -= (pixelsPerInch.x / 2); + top_margin = (pixelsPerInch.y / 4); + *h -= (pixelsPerInch.y / 2); + + *x = left_margin; + *y = top_margin; + origin(x_offset, y_offset); +} + +void Fl_GDI_Printer::margins(int *left, int *top, int *right, int *bottom) +{ + int x, y, w, h; + absolute_printable_rect(&x, &y, &w, &h); + if (left) *left = x; + if (top) *top = y; + if (right) *right = x; + if (bottom) *bottom = y; +} + +int Fl_GDI_Printer::printable_rect(int *w, int *h) +{ + int x, y; + absolute_printable_rect(&x, &y, w, h); + return 0; +} + +int Fl_GDI_Printer::start_page (void) +{ + int rsult, w, h; + + rsult = 0; + if (hPr != NULL) { + WIN_SetupPrinterDeviceContext (hPr); + prerr = StartPage (hPr); + if (prerr < 0) { + fl_alert ("StartPage error %d", prerr); + rsult = 1; + } + printable_rect(&w, &h); + origin(0, 0); + image_list_ = NULL; + fl_clip_region(0); + gc = (void *)fl_gc; + } + return rsult; +} + +void Fl_GDI_Printer::origin (int deltax, int deltay) +{ + SetWindowOrgEx(fl_gc, - left_margin - deltax, - top_margin - deltay, NULL); + x_offset = deltax; + y_offset = deltay; +} + +void Fl_GDI_Printer::scale (float scalex, float scaley) +{ + int w, h; + SetWindowExtEx(fl_gc, (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); + printable_rect(&w, &h); + origin(0, 0); +} + +void Fl_GDI_Printer::rotate (float rot_angle) +{ + XFORM mat; + float angle; + angle = - rot_angle * M_PI / 180.; + mat.eM11 = cos(angle); + mat.eM12 = sin(angle); + mat.eM21 = - mat.eM12; + mat.eM22 = mat.eM11; + mat.eDx = mat.eDy = 0; + SetWorldTransform(fl_gc, &mat); +} + +int Fl_GDI_Printer::end_page (void) +{ + int rsult; + + rsult = 0; + if (hPr != NULL) { + prerr = EndPage (hPr); + if (prerr < 0) { + abortPrint = TRUE; + fl_alert ("EndPage error %d", prerr); + rsult = 1; + } + } + delete_image_list(); + gc = NULL; + return rsult; +} + +static int translate_stack_depth = 0; +const int translate_stack_max = 5; +static int translate_stack_x[translate_stack_max]; +static int translate_stack_y[translate_stack_max]; + +static void do_translate(int x, int y) +{ + XFORM tr; + tr.eM11 = tr.eM22 = 1; + tr.eM12 = tr.eM21 = 0; + tr.eDx = x; + tr.eDy = y; + ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY); +} + +void Fl_GDI_Printer::translate (int x, int y) +{ + do_translate(x, y); + if (translate_stack_depth < translate_stack_max) { + translate_stack_x[translate_stack_depth] = x; + translate_stack_y[translate_stack_depth] = y; + translate_stack_depth++; + } +} + +void Fl_GDI_Printer::untranslate (void) +{ + if (translate_stack_depth > 0) { + translate_stack_depth--; + do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth] ); + } +} + +#endif // WIN32 + |
