summaryrefslogtreecommitdiff
path: root/src/Fl_Widget_Surface.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_Widget_Surface.cxx')
-rw-r--r--src/Fl_Widget_Surface.cxx210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/Fl_Widget_Surface.cxx b/src/Fl_Widget_Surface.cxx
new file mode 100644
index 000000000..f99a333fb
--- /dev/null
+++ b/src/Fl_Widget_Surface.cxx
@@ -0,0 +1,210 @@
+//
+// "$Id: Fl_Widget_Surface.cxx 11217 2016-02-25 17:56:48Z manolo $"
+//
+// Drivers code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Widget_Surface.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl.H>
+#include <FL/Fl_Shared_Image.H>
+
+
+Fl_Widget_Surface::Fl_Widget_Surface(Fl_Graphics_Driver *d) : Fl_Surface_Device(d) {
+ x_offset = 0;
+ y_offset = 0;
+}
+
+/**
+ @brief Draws the widget on the printed page.
+ *
+ The widget's position on the printed page is determined by the last call to origin()
+ and by the optional delta_x and delta_y arguments.
+ Its dimensions are in points unless there was a previous call to scale().
+ @param[in] widget Any FLTK widget (e.g., standard, custom, window).
+ @param[in] delta_x Optional horizontal offset for positioning the widget relatively
+ to the current origin of graphics functions.
+ @param[in] delta_y Same as above, vertically.
+ */
+void Fl_Widget_Surface::draw(Fl_Widget* widget, int delta_x, int delta_y)
+{
+ int old_x, old_y, new_x, new_y, is_window;
+ if ( ! widget->visible() ) return;
+ is_window = (widget->as_window() != NULL);
+ uchar old_damage = widget->damage();
+ widget->damage(FL_DAMAGE_ALL);
+ // set origin to the desired top-left position of the widget
+ origin(&old_x, &old_y);
+ new_x = old_x + delta_x;
+ new_y = old_y + delta_y;
+ if (!is_window) {
+ new_x -= widget->x();
+ new_y -= widget->y();
+ }
+ if (new_x != old_x || new_y != old_y) {
+ translate(new_x - old_x, new_y - old_y );
+ }
+ // if widget is a main window, clip all drawings to the window area
+ if (is_window && !widget->window()) {
+ fl_push_clip(0, 0, widget->w(), widget->h() );
+#ifdef __APPLE__ // for Mac OS X 10.6 and above, make window with rounded bottom corners
+ if ( fl_mac_os_version >= 100600 && driver()->has_feature(Fl_Graphics_Driver::NATIVE) ) {
+ Fl_X::clip_to_rounded_corners((CGContextRef)driver()->gc(), widget->w(), widget->h());
+ }
+#endif
+ }
+ // we do some trickery to recognize OpenGL windows and draw them via a plugin
+ int drawn_by_plugin = 0;
+ if (widget->as_gl_window()) {
+ Fl_Plugin_Manager pm("fltk:device");
+ Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
+ if (pi) {
+ drawn_by_plugin = pi->print(widget, 0, 0, 0);
+ }
+ }
+ if (!drawn_by_plugin) {
+ widget->draw();
+ }
+ if (is_window && !widget->window()) fl_pop_clip();
+ // find subwindows of widget and print them
+ traverse(widget);
+ // reset origin to where it was
+ if (new_x != old_x || new_y != old_y) {
+ untranslate();
+ }
+ if ((old_damage & FL_DAMAGE_CHILD) == 0) widget->clear_damage(old_damage);
+ else widget->damage(FL_DAMAGE_ALL);
+}
+
+
+void Fl_Widget_Surface::traverse(Fl_Widget *widget)
+{
+ Fl_Group *g = widget->as_group();
+ if (!g) return;
+ int n = g->children();
+ for (int i = 0; i < n; i++) {
+ Fl_Widget *c = g->child(i);
+ if ( !c->visible() ) continue;
+ if ( c->as_window() ) {
+ draw(c, c->x(), c->y());
+ }
+ else traverse(c);
+ }
+}
+
+/**
+ @brief Computes the page coordinates of the current origin of graphics functions.
+ *
+ @param[out] x If non-null, *x is set to the horizontal page offset of graphics origin.
+ @param[out] y Same as above, vertically.
+ */
+void Fl_Widget_Surface::origin(int *x, int *y)
+{
+ if (x) *x = x_offset;
+ if (y) *y = y_offset;
+}
+
+/**
+ @brief Sets the position in page coordinates of the origin of graphics functions.
+
+ Arguments should be expressed relatively to the result of a previous printable_rect() call.
+ That is, <tt>printable_rect(&w, &h); origin(w/2, 0);</tt> sets the graphics origin at the
+ top center of the page printable area.
+ Origin() calls are not affected by rotate() calls.
+ Successive origin() calls don't combine their effects.
+ @param[in] x Horizontal position in page coordinates of the desired origin of graphics functions.
+ @param[in] y Same as above, vertically.
+ */
+void Fl_Widget_Surface::origin(int x, int y) {}
+
+/**
+ @brief Prints a rectangular part of an on-screen window.
+
+ @param win The window from where to capture.
+ @param x The rectangle left
+ @param y The rectangle top
+ @param w The rectangle width
+ @param h The rectangle height
+ @param delta_x Optional horizontal offset from current graphics origin where to print the captured rectangle.
+ @param delta_y As above, vertically.
+ */
+void Fl_Widget_Surface::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
+{
+ Fl_Surface_Device *current = Fl_Surface_Device::surface();
+ Fl_Display_Device::display_device()->set_current();
+ Fl_Window *save_front = Fl::first_window();
+ win->show();
+ Fl::check();
+ win->make_current();
+ uchar *image_data;
+ image_data = fl_read_image(NULL, x, y, w, h);
+#ifdef __APPLE__ // PORTME: Fl_Surface_Driver - platform paged device
+ Fl_X::q_release_context(); // matches make_current() call above
+#endif
+ if (save_front != win) save_front->show();
+ current->set_current();
+ fl_draw_image(image_data, delta_x, delta_y, w, h, 3);
+ delete[] image_data;
+#ifdef WIN32
+ HDC gc = GetDC(fl_xid(win));
+ fl_graphics_driver->gc(gc);
+ ReleaseDC(fl_xid(win), gc);
+#endif
+}
+
+/**
+ @brief Computes the width and height of the printable area of the page.
+
+ Values are in the same unit as that used by FLTK drawing functions,
+ are unchanged by calls to origin(), but are changed by scale() calls.
+ Values account for the user-selected paper type and print orientation.
+ @return 0 if OK, non-zero if any error
+ */
+int Fl_Widget_Surface::printable_rect(int *w, int *h) {return 1;}
+
+/** Draws a window with its title bar and frame if any.
+
+ \p x_offset and \p y_offset are optional coordinates of where to position the window top left.
+ Equivalent to draw() if \p win is a subwindow or has no border.
+ Use Fl_Window::decorated_w() and Fl_Window::decorated_h() to get the size of the window.
+ */
+void Fl_Widget_Surface::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset)
+{
+ Fl_Shared_Image *top, *left, *bottom, *right;
+ win->capture_titlebar_and_borders(top, left, bottom, right);
+ int wsides = left ? left->w() : 0;
+ int toph = top ? top->h() : 0;
+ if (top) {
+ top->draw(x_offset, y_offset);
+ top->release();
+ }
+ if (left) {
+ left->draw(x_offset, y_offset + toph);
+ left->release();
+ }
+ if (right) {
+ right->draw(x_offset + wsides + win->w(), y_offset + toph);
+ right->release();
+ }
+ if (bottom) {
+ bottom->draw(x_offset, y_offset + toph + win->h());
+ bottom->release();
+ }
+ this->draw(win, x_offset + wsides, y_offset + toph);
+}
+
+//
+// End of "$Id: Fl_Widget_Surface.cxx 11217 2016-02-25 17:56:48Z manolo $".
+//