summaryrefslogtreecommitdiff
path: root/src/Fl_Gl_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_Gl_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_Gl_Printer.cxx')
-rw-r--r--src/Fl_Gl_Printer.cxx82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/Fl_Gl_Printer.cxx b/src/Fl_Gl_Printer.cxx
new file mode 100644
index 000000000..ddea19aca
--- /dev/null
+++ b/src/Fl_Gl_Printer.cxx
@@ -0,0 +1,82 @@
+/*
+ * Fl_Gl_Printer.cxx
+ */
+
+#include "FL/Fl_Gl_Printer.H"
+#include "Fl_Gl_Choice.H"
+#include "FL/Fl.H"
+#ifndef __APPLE__
+#include "FL/fl_draw.H"
+#endif
+
+void Fl_Gl_Printer::print_gl_window(Fl_Gl_Window *glw, int x, int y)
+{
+#ifdef WIN32
+ HDC save_gc = fl_gc;
+ const int bytesperpixel = 3;
+#elif defined(__APPLE__)
+ CGContextRef save_gc = fl_gc;
+ const int bytesperpixel = 4;
+#else
+ _XGC *save_gc = fl_gc; // FIXME Linux/Unix
+ const int bytesperpixel = 3;
+#endif
+ glw->redraw();
+ Fl::check();
+ glw->make_current();
+ // select front buffer as our source for pixel data
+ glReadBuffer(GL_FRONT);
+ // Read OpenGL context pixels directly.
+ // For extra safety, save & restore OpenGL states that are changed
+ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ // Read a block of pixels from the frame buffer
+ int mByteWidth = glw->w() * bytesperpixel;
+ mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
+ uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h());
+ glReadPixels(0, 0, glw->w(), glw->h(),
+#ifdef WIN32
+ GL_RGB, GL_UNSIGNED_BYTE,
+#elif defined(__APPLE__)
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+#else // FIXME Linux/Unix
+ GL_RGB, GL_UNSIGNED_BYTE,
+#endif
+ baseAddress);
+ glPopClientAttrib();
+ fl_gc = save_gc;
+#ifdef WIN32
+ fl_draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth);
+#elif defined(__APPLE__)
+ CGColorSpaceRef cSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
+ CGContextRef bitmap = CGBitmapContextCreate(baseAddress, glw->w(), glw->h(), 8, mByteWidth, cSpace,
+#if __BIG_ENDIAN__
+ kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big /* XRGB Big Endian */);
+#else
+ kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little /* XRGB Little Endian */);
+#endif
+ if(bitmap == NULL) return;
+ CFRelease(cSpace);
+ // Make an image out of our bitmap
+ CGImageRef image = CGBitmapContextCreateImage(bitmap);
+ if(image == NULL) return;
+ CFRelease(bitmap);
+ CGContextSaveGState(fl_gc);
+ int w, h;
+ this->printable_rect(&w, &h);
+ CGContextTranslateCTM(fl_gc, 0, h);
+ CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
+ CGRect rect = { { x, h - y - glw->h() }, { glw->w(), glw->h() } };
+ Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h());
+ CGContextDrawImage(fl_gc, rect, image);
+ Fl_X::q_end_image();
+ CGContextRestoreGState(fl_gc);
+ CFRelease(image);
+#else // FIXME Linux/Unix
+ fl_draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth);
+#endif // WIN32
+ free(baseAddress);
+}