mirror of https://github.com/fltk/fltk
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. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8593 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
c473215f2a
commit
9ff9cf1230
|
@ -132,6 +132,14 @@ public:
|
|||
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);
|
||||
|
|
|
@ -443,6 +443,18 @@ public:
|
|||
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();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1417,12 +1417,20 @@ void fl_close_display() {
|
|||
|
||||
// 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 @@ int Fl_X::screen_init(XRectangle screens[], float dpi[])
|
|||
{
|
||||
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 @@ int Fl_X::screen_init(XRectangle screens[], float dpi[])
|
|||
// 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 @@ int Fl_X::screen_init(XRectangle screens[], float dpi[])
|
|||
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 @@ Window fl_xid(const Fl_Window* w)
|
|||
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.
|
||||
|
|
|
@ -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 @@ Window fl_xid_(const Fl_Window *w) {
|
|||
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 @@ void printFront(Fl_Widget *o, void *data)
|
|||
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 @@ void printFront(Fl_Widget *o, void *data)
|
|||
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();
|
||||
|
|
77
src/Fl_x.cxx
77
src/Fl_x.cxx
|
@ -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 @@ Window fl_xid_(const Fl_Window* w)
|
|||
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 @@ void printFront(Fl_Widget *o, void *data)
|
|||
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 @@ void printFront(Fl_Widget *o, void *data)
|
|||
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();
|
||||
|
|
|
@ -92,6 +92,7 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
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 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
// 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 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
// 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);
|
||||
|
|
|
@ -34,10 +34,13 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
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,15 +61,17 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
|||
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 (Y < 0) {
|
||||
shift_y = -Y;
|
||||
h += Y;
|
||||
Y = 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 (h < 1 || w < 1) return p; // nothing to copy
|
||||
|
|
Loading…
Reference in New Issue