summaryrefslogtreecommitdiff
path: root/src/Fl_GDI_Printer.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2010-03-14 18:07:24 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2010-03-14 18:07:24 +0000
commit998cc6df521a115454727d1ecf6bc7d4fee96f68 (patch)
tree70a1c9afffb294a75bd38484c2e6e4a042ac3426 /src/Fl_GDI_Printer.cxx
parent5bc66fafc348c547870bbf51c9c4a7215ad4ff25 (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.cxx253
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
+