Author: manolo
Date: 2011-04-15 14:38:05 -0700 (Fri, 15 Apr 2011)
New Revision: 8593
Log:
Added Fl_Paged_Device::print_window() to print a window with its title bar and 
frame.
Added Fl_Window::decorated_w() and Fl_Window::decorated_h() that return the size
of a window with its title bar and frame.

Modified:
   branches/branch-1.3/FL/Fl_Paged_Device.H
   branches/branch-1.3/FL/Fl_Window.H
   branches/branch-1.3/src/Fl_cocoa.mm
   branches/branch-1.3/src/Fl_win32.cxx
   branches/branch-1.3/src/Fl_x.cxx
   branches/branch-1.3/src/fl_read_image.cxx
   branches/branch-1.3/src/fl_read_image_win32.cxx

Modified: branches/branch-1.3/FL/Fl_Paged_Device.H
===================================================================
--- branches/branch-1.3/FL/Fl_Paged_Device.H    2011-04-14 13:22:13 UTC (rev 
8592)
+++ branches/branch-1.3/FL/Fl_Paged_Device.H    2011-04-15 21:38:05 UTC (rev 
8593)
@@ -132,6 +132,14 @@
   virtual void translate(int x, int y);
   virtual void untranslate(void);
   virtual void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 
0);
+  /** Prints 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 print_widget() 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
+   printed window.
+   */
+  void print_window(Fl_Window *win, int x_offset = 0, int y_offset = 0);
   virtual void print_window_part(Fl_Window *win, int x, int y, int w, int h, 
int delta_x = 0, int delta_y = 0);
   virtual int end_page (void);
   virtual void end_job (void);

Modified: branches/branch-1.3/FL/Fl_Window.H
===================================================================
--- branches/branch-1.3/FL/Fl_Window.H  2011-04-14 13:22:13 UTC (rev 8592)
+++ branches/branch-1.3/FL/Fl_Window.H  2011-04-15 21:38:05 UTC (rev 8593)
@@ -443,6 +443,18 @@
   void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform 
dependent
   void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
   static void default_callback(Fl_Window*, void* v);
+  
+  /** Returns the window width including any frame added by the window manager.
+   
+   Same as w() if applied to a subwindow.
+   */
+  int decorated_w();
+  /** Returns the window height including any window title bar and any frame 
+   added by the window manager.
+   
+   Same as h() if applied to a subwindow.
+   */
+  int decorated_h();
 
 };
 

Modified: branches/branch-1.3/src/Fl_cocoa.mm
===================================================================
--- branches/branch-1.3/src/Fl_cocoa.mm 2011-04-14 13:22:13 UTC (rev 8592)
+++ branches/branch-1.3/src/Fl_cocoa.mm 2011-04-15 21:38:05 UTC (rev 8593)
@@ -1417,12 +1417,20 @@
 
 // Gets the border sizes and the titlebar size
 static void get_window_frame_sizes(int &bx, int &by, int &bt) {
-  if (NSApp == nil) fl_open_display();
-  NSRect inside = { {20,20}, {100,100} };
-  NSRect outside = [NSWindow  frameRectForContentRect:inside 
styleMask:NSTitledWindowMask];
-  bx = int(outside.origin.x - inside.origin.x);
-  by = int(outside.origin.y - inside.origin.y);
-  bt = int(outside.size.height - inside.size.height - by);
+  static bool first = true;
+  static int top, left, bottom;
+  if (first) {
+    first = false;
+    if (NSApp == nil) fl_open_display();
+    NSRect inside = { {20,20}, {100,100} };
+    NSRect outside = [NSWindow  frameRectForContentRect:inside 
styleMask:NSTitledWindowMask];
+    left = int(outside.origin.x - inside.origin.x);
+    bottom = int(outside.origin.y - inside.origin.y);
+    top = int(outside.size.height - inside.size.height) - bottom;
+    }
+  bx = left;
+  by = bottom;
+  bt = top;
 }
 
 /*
@@ -2861,7 +2869,7 @@
 {
   Fl_Printer printer;
   //Fl_PostScript_File_Device printer;
-  int w, h, wh;
+  int w, h, ww, wh;
   Fl_Window *win = Fl::first_window();
   if(!win) return;
   if( printer.start_job(1) ) return;
@@ -2869,13 +2877,9 @@
   // scale the printer device so that the window fits on the page
   float scale = 1;
   printer.printable_rect(&w, &h);
-  wh = win->h();
-  int bx, by, bt = 0;
-  if (win->border()) {
-    get_window_frame_sizes(bx, by, bt);
-    wh += bt;
-    }
-  if (win->w()>w || wh>h) {
+  ww = win->decorated_w();
+  wh = win->decorated_h();
+  if (ww>w || wh>h) {
     scale = (float)w/win->w();
     if ((float)h/wh < scale) scale = (float)h/wh;
     printer.scale(scale);
@@ -2888,22 +2892,7 @@
   printer.rotate(20.);
   printer.print_widget( win, - win->w()/2, - win->h()/2 );
 #else
-  if (bt) { // print the window title bar
-    //printer.print_window_part(win, 0, -bt, win->w(), bt, 0, 1);
-    Fl_Display_Device::display_device()->set_current();
-    win->show();
-    fl_gc = NULL;
-    Fl::check();
-    win->make_current();
-    CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
-    printer.set_current();
-    CGRect rect = { { 0, 1 }, { win->w(), bt } };
-    Fl_X::q_begin_image(rect, 0, 0, win->w(), bt);
-    CGContextDrawImage(fl_gc, rect, img);
-    Fl_X::q_end_image();
-    CGImageRelease(img);
-  }
-  printer.print_widget(win, 0, bt);
+  printer.print_window(win);
 #endif
   printer.end_page();
   printer.end_job();
@@ -3401,6 +3390,46 @@
   return Fl_X::i(w)->xid;
 }
 
+int Fl_Window::decorated_w()
+{
+  if (this->parent() || !border()) return w();
+  int bx, by, bt;
+  get_window_frame_sizes(bx, by, bt);
+  return w() + 2 * bx;
+}
+
+int Fl_Window::decorated_h()
+{
+  if (this->parent() || !border()) return h();
+  int bx, by, bt;
+  get_window_frame_sizes(bx, by, bt);
+  return h() + bt + by;
+}
+
+void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
+{
+  if (win->parent() || !win->border()) {
+    this->print_widget(win, x_offset, y_offset);
+    return;
+  }
+  int bx, by, bt;
+  get_window_frame_sizes(bx, by, bt);
+  Fl_Display_Device::display_device()->set_current(); // send win to front and 
make it current
+  win->show();
+  fl_gc = NULL;
+  Fl::check();
+  win->make_current();
+  // capture the window title bar from screen
+  CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
+  this->set_current(); // back to the Fl_Paged_Device
+  CGRect rect = { { 0, 1 }, { win->w(), bt } }; // print the title bar
+  Fl_X::q_begin_image(rect, 0, 0, win->w(), bt);
+  CGContextDrawImage(fl_gc, rect, img);
+  Fl_X::q_end_image();
+  CGImageRelease(img);
+  this->print_widget(win, x_offset, y_offset + bt); // print the window inner 
part
+}
+
 #include <dlfcn.h>
 
 /* Returns the address of a Carbon function after dynamically loading the 
Carbon library if needed.

Modified: branches/branch-1.3/src/Fl_win32.cxx
===================================================================
--- branches/branch-1.3/src/Fl_win32.cxx        2011-04-14 13:22:13 UTC (rev 
8592)
+++ branches/branch-1.3/src/Fl_win32.cxx        2011-04-15 21:38:05 UTC (rev 
8593)
@@ -38,6 +38,7 @@
 #include <FL/fl_draw.H>
 #include <FL/Enumerations.H>
 #include <FL/Fl_Tooltip.H>
+#include <FL/Fl_Paged_Device.H>
 #include "flstring.h"
 #include "Fl_Font.H"
 #include <stdio.h>
@@ -1945,6 +1946,56 @@
   return temp ? temp->xid : 0;
 }
 
+int Fl_Window::decorated_w()
+{
+  if (parent() || !shown()) return w();
+  int X, Y, bt, bx, by;
+  Fl_X::fake_X_wm(this, X, Y, bt, bx, by);
+  return w() + 2 * bx;
+}
+
+int Fl_Window::decorated_h()
+{
+  if (this->parent() || !shown()) return h();
+  int X, Y, bt, bx, by;
+  Fl_X::fake_X_wm(this, X, Y, bt, bx, by);
+  return h() + bt + 2 * by;
+}
+
+void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
+{
+  if (win->parent() || !win->border()) {
+    this->print_widget(win, x_offset, y_offset);
+    return;
+  }
+  int X, Y, bt, bx, by, ww, wh; // compute the window border sizes
+  Fl_X::fake_X_wm(win, X, Y, bt, bx, by);
+  ww = win->w() + 2 * bx;
+  wh = win->h() + bt + 2 * by;
+  Fl_Display_Device::display_device()->set_current(); // make window current
+  win->show();
+  Fl::check();
+  win->make_current();
+  // capture the 4 window sides from screen
+  // use negative 4th argument to allow negative 2nd or 3rd arguments
+  uchar *top_image = fl_read_image(NULL, -bx, - bt - by, -ww, bt + by);
+  uchar *left_image = fl_read_image(NULL, -bx, - bt - by, -bx, wh);
+  uchar *right_image = fl_read_image(NULL, win->w(), - bt - by, -bx, wh);
+  uchar *bottom_image = fl_read_image(NULL, -bx, win->h(), -ww, by);
+  this->set_current();
+  // print the 4 window sides
+  fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3);
+  fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3);
+  fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3);
+  fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 
3);
+  delete[] top_image;
+  delete[] left_image;
+  delete[] right_image;
+  delete[] bottom_image;
+  // print the window inner part
+  this->print_widget(win, x_offset + bx, y_offset + bt + by);
+}  
+
 #ifdef USE_PRINT_BUTTON
 // to test the Fl_Printer class creating a "Print front window" button in a 
separate window
 // contains also preparePrintFront call above
@@ -1960,11 +2011,14 @@
   if( printer.start_job(1) ) { o->window()->show(); return; }
   if( printer.start_page() ) { o->window()->show(); return; }
   printer.printable_rect(&w,&h);
+  int  wh, ww;
+  wh = win->decorated_h();
+  ww = win->decorated_w();
   // scale the printer device so that the window fits on the page
   float scale = 1;
-  if (win->w() > w || win->h() > h) {
-    scale = (float)w/win->w();
-    if ((float)h/win->h() < scale) scale = (float)h/win->h();
+  if (ww > w || wh > h) {
+    scale = (float)w/ww;
+    if ((float)h/wh < scale) scale = (float)h/wh;
     printer.scale(scale, scale);
   }
 // #define ROTATE 20.0
@@ -1975,9 +2029,8 @@
   printer.rotate(ROTATE);
   printer.print_widget( win, - win->w()/2, - win->h()/2 );
   //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - 
win->h()/2 );
-#else
-  printer.print_widget( win );
-  //printer.print_window_part( win, 0,0, win->w(), win->h() );
+#else  
+  printer.print_window(win);
 #endif
   printer.end_page();
   printer.end_job();

Modified: branches/branch-1.3/src/Fl_x.cxx
===================================================================
--- branches/branch-1.3/src/Fl_x.cxx    2011-04-14 13:22:13 UTC (rev 8592)
+++ branches/branch-1.3/src/Fl_x.cxx    2011-04-15 21:38:05 UTC (rev 8593)
@@ -42,6 +42,7 @@
 #  include <FL/fl_utf8.h>
 #  include <FL/Fl_Tooltip.H>
 #  include <FL/fl_draw.H>
+#  include <FL/Fl_Paged_Device.H>
 #  include <stdio.h>
 #  include <stdlib.h>
 #  include "flstring.h"
@@ -1890,6 +1891,69 @@
   return Fl_X::i(w)->xid;
 }
 
+
+int Fl_Window::decorated_h()
+{
+  if (parent() || !shown()) return h();
+  Window root, parent, *children;
+  unsigned n;
+  XQueryTree(fl_display, i->xid, &root, &parent, &children, &n); if (n) 
XFree(children);
+  XWindowAttributes attributes;
+  XGetWindowAttributes(fl_display, parent, &attributes);
+  return attributes.height;
+}
+
+int Fl_Window::decorated_w()
+{
+  if (parent() || !shown()) return w();
+  Window root, parent, *children;
+  unsigned n;
+  XQueryTree(fl_display, i->xid, &root, &parent, &children, &n); if (n) 
XFree(children);
+  XWindowAttributes attributes;
+  XGetWindowAttributes(fl_display, parent, &attributes);
+  return attributes.width;
+}
+
+void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
+{
+  if (win->parent() || !win->border()) {
+    this->print_widget(win, x_offset, y_offset);
+    return;
+    }
+  Fl_Display_Device::display_device()->set_current();
+  win->show();
+  Fl::check();
+  win->make_current();
+  Window root, parent, *children, child_win, from;
+  unsigned n;
+  int bx, bt;
+  from = fl_window;
+  XQueryTree(fl_display, fl_window, &root, &parent, &children, &n); if (n) 
XFree(children);
+  XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &bx, &bt, 
&child_win);
+  fl_window = parent;
+  uchar *top_image, *left_image, *right_image, *bottom_image;
+  top_image = fl_read_image(NULL, 0, 0, - (win->w() + 2 * bx), bt);
+  if (bx) {
+    left_image = fl_read_image(NULL, 0, bt, -bx, win->h() + bx);
+    right_image = fl_read_image(NULL, win->w() + bx, bt, -bx, win->h() + bx);
+    bottom_image = fl_read_image(NULL, 0, bt + win->h(), -(win->w() + 2*bx), 
bx);
+  }
+  fl_window = from;
+  this->set_current();
+  fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3);
+  delete[] top_image;
+  if (bx) {
+    if (left_image) fl_draw_image(left_image, x_offset, y_offset + bt, bx, 
win->h() + bx, 3);
+    if (right_image) fl_draw_image(right_image, x_offset + win->w() + bx, 
y_offset + bt, bx, win->h() + bx, 3);
+    if (bottom_image) fl_draw_image(bottom_image, x_offset, y_offset + bt + 
win->h(), win->w() + 2*bx, bx, 3);
+    if (left_image) delete[] left_image;
+    if (right_image) delete[] right_image;
+    if (bottom_image) delete[] bottom_image;
+  }
+  this->print_widget( win, x_offset + bx, y_offset + bt );
+}
+
+
 #ifdef USE_PRINT_BUTTON
 // to test the Fl_Printer class creating a "Print front window" button in a 
separate window
 // contains also preparePrintFront call above
@@ -1907,9 +1971,11 @@
   printer.printable_rect(&w,&h);
   // scale the printer device so that the window fits on the page
   float scale = 1;
-  if (win->w() > w || win->h() > h) {
-    scale = (float)w/win->w();
-    if ((float)h/win->h() < scale) scale = (float)h/win->h();
+  int ww = win->decorated_w();
+  int wh = win->decorated_h();
+  if (ww > w || wh > h) {
+    scale = (float)w/ww;
+    if ((float)h/wh < scale) scale = (float)h/wh;
     printer.scale(scale, scale);
   }
 
@@ -1921,9 +1987,8 @@
   printer.rotate(ROTATE);
   printer.print_widget( win, - win->w()/2, - win->h()/2 );
   //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - 
win->h()/2 );
-#else
-  printer.print_widget( win );
-  //printer.print_window_part( win, 0,0,win->w(), win->h() );
+#else  
+  printer.print_window(win);
 #endif
 
   printer.end_page();

Modified: branches/branch-1.3/src/fl_read_image.cxx
===================================================================
--- branches/branch-1.3/src/fl_read_image.cxx   2011-04-14 13:22:13 UTC (rev 
8592)
+++ branches/branch-1.3/src/fl_read_image.cxx   2011-04-15 21:38:05 UTC (rev 
8593)
@@ -92,6 +92,7 @@
               int   X,         // I - Left position
              int   Y,          // I - Top position
              int   w,          // I - Width of area to read
+                               // negative allows capture of window title bar 
and frame
              int   h,          // I - Height of area to read
              int   alpha) {    // I - Alpha value for image (0 for none)
   XImage       *image;         // Captured image
@@ -118,6 +119,8 @@
   // ReadDisplay extension which does all of the really hard work for
   // us...
   //
+  int allow_outside = w < 0;    // negative w allows negative X or Y, that is, 
window frame
+  if (w < 0) w = - w;
 
 #  ifdef __sgi
   if (XReadDisplayQueryExtension(fl_display, &i, &i)) {
@@ -131,7 +134,10 @@
     // fetch absolute coordinates
     int dx, dy, sx, sy, sw, sh;
     Window child_win;
-    Fl_Window *win = fl_find(fl_window);
+    
+    Fl_Window *win;
+    if (allow_outside) win = (Fl_Window*)1;
+    else win = fl_find(fl_window);
     if (win) {
       XTranslateCoordinates(fl_display, fl_window,
           RootWindow(fl_display, fl_screen), X, Y, &dx, &dy, &child_win);

Modified: branches/branch-1.3/src/fl_read_image_win32.cxx
===================================================================
--- branches/branch-1.3/src/fl_read_image_win32.cxx     2011-04-14 13:22:13 UTC 
(rev 8592)
+++ branches/branch-1.3/src/fl_read_image_win32.cxx     2011-04-15 21:38:05 UTC 
(rev 8593)
@@ -34,10 +34,13 @@
               int   X,         // I - Left position
              int   Y,          // I - Top position
              int   w,          // I - Width of area to read
+                               //     negative w means negative X or Y are 
allowed
              int   h,          // I - Height of area to read
              int   alpha) {    // I - Alpha value for image (0 for none)
 
   int  d;                      // Depth of image
+  int allow_outside = w < 0;    // negative w allows negative X or Y, that is, 
window border
+  if (w < 0) w = - w;
 
   // Allocate the image data array as needed...
   d = alpha ? 4 : 3;
@@ -58,16 +61,18 @@
   int shift_x = 0; // X target shift if X modified
   int shift_y = 0; // Y target shift if X modified
 
-  if (X < 0) {
-    shift_x = -X;
-    w += X;
-    X = 0;
+  if (!allow_outside) {
+    if (X < 0) {
+      shift_x = -X;
+      w += X;
+      X = 0;
+    }
+    if (Y < 0) {
+      shift_y = -Y;
+      h += Y;
+      Y = 0;
+    }
   }
-  if (Y < 0) {
-    shift_y = -Y;
-    h += Y;
-    Y = 0;
-  }
 
   if (h < 1 || w < 1) return p;                // nothing to copy
 

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to