Hi,
I worked it out! here follows my minimal example with a screenshot being saved
as a pmg; to this end I used pngwriter (http://pngwriter.sourceforge.net/).
Hopefuly will serve to the next one willing to learn the offscreen use.
the tricky thing here is that even fl_read_image( offscreenImage,...) is
sensitive for the context i.e. it needs to be called while the offsceen is
active.
Actually I would expect the offscreen just need to exist, just the drawing
should be enclosed by fl_begin_offscreen and fl_end_offscreen, but within this
program it's not possible to test: as soon as the window with the black and red
boxes is terminated, all the fltk threads exit so the offscreen gets freed, I
guess.
In any case, a call to fl_read_image( offscreenImage, ... ) in the main()
results in a segmentation fault ...
Now I can use what I learned in my real system!
#include <iostream>
#include <string>
#include <cassert>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/Fl_Double_Window.H>
#include "../pngwriter-0.5.3/src/pngwriter.h"
uchar *offscreenImage = NULL;
Fl_Offscreen offscr = NULL;
int offscrW = 400, offscrH = 400;
void writeScreenshot( ) {
std::cout << "writeScreenshot()" << std::endl;
pngwriter screenshot( offscrW, offscrH, 0.0, "shapedemo-screenshot.png" );
// Image writeout.
for ( int row = 0; row < offscrH; ++row ) {
for ( int col = 0; col < offscrW; ++col ) {
assert( col + row * offscrW < offscrH * offscrW );
uchar *pixel = &offscreenImage[ 3 * (col + row * offscrW) ];
int pixelR = pixel[0] * 256;
int pixelG = pixel[1] * 256;
int pixelB = pixel[2] * 256;
screenshot.plot( col, offscrH - row, pixelR, pixelG, pixelB );
}
}
screenshot.plot_text( "/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf",
10, 10, 10, 0.0, "test pngwriter", 1.0, 1.0, 1.0 );
screenshot.close( );
}
void drawRectangles( int winW, int winH ) {
std::cout << "drawRectangles( int winW, int winH ) START" << std::endl;
int x = 0, y = 0;
std::cout << "aWin x=" << x << " y=" << y << " w=" << winW << " h=" << winH
<< std::endl;
fl_color( FL_BLACK );
fl_rectf( x, y, x + winW, y + winH );
std::cout << "screen filled in black" << std::endl;
fl_color( FL_BLUE );
fl_font( FL_TIMES, 15 );
fl_draw( "test", 10, 10 );
int margin = 100;
int redRectX = x + margin;
int redRectY = y + margin;
int redRectW = winW - 2 * margin;
int redRectH = winH - 2 * margin;
std::cout << "RECTANGLE x=" << redRectX << " y=" << redRectY
<< " w=" << redRectW << " h=" << redRectH << std::endl;
fl_color( FL_RED );
fl_rectf( redRectX, redRectY, redRectW, redRectH );
std::cout << "screen filled in red" << std::endl;
std::cout << "drawRectangles( int winW, int winH ) END" << std::endl;
}
void drawOffscreen( Fl_Double_Window *aWin ) {
std::cout << "drawOffscreen( Fl_Double_Window *aWin ) START" << std::endl;
std::cout << "*aWin is " << (aWin->shown( ) ? "shown" : "not shown") <<
std::endl;
fl_begin_offscreen( offscr );
std::cout << "Fl_Offscreen OPENED" << std::endl;
drawRectangles( aWin->w( ), aWin->h( ) );
fl_end_offscreen( );
std::cout << "Fl_Offscreen CLOSED" << std::endl;
int srcX = 0, srcY = 0, destX = 0, destY = 0;
fl_copy_offscreen( destX, destY, offscrW, offscrH, offscr, srcX, srcY );
std::cout << "Fl_Offscreen COPIED" << std::endl;
delete[] offscreenImage;
offscreenImage = fl_read_image( offscreenImage, 0, 0, offscrW, offscrH );
std::cout << "offscreen pixmap retrieved..." << std::endl;
std::cout << "offscreenImage:" << unsigned(offscreenImage) << std::endl;
std::cout << "drawOffscreen( Fl_Double_Window *aWin ) E" << std::endl;
}
class MyWin : public Fl_Double_Window {
protected:
void draw( ) {
std::cout << "MyWin::draw()" << std::endl;
// if ( !offscr ) {
// offscr = fl_create_offscreen( offscrW, offscrH );
// std::cout << "Fl_Offscreen CREATED" << std::endl;
// }
Fl_Double_Window::draw( );
drawOffscreen( this );
// ALTERNATIVELY COMMENT OUT THE ABOVE LINE OR THE LINE BELOW TO DRAW
WITHOUT OR WITH OFFSCREEN
// drawRectangles( w( ), h( ) );
}
public:
MyWin( int a, int b, char const *label = "Fl_Offscreen test" )
:
Fl_Double_Window( a, b, label ) { }
~MyWin( ) {
// never called ... ?
std::cout << "MyWin DESTRUCTOR" << std::endl;
}
};
int runWin( ) {
Fl_Double_Window *aWin = new MyWin( 400, 400, "Fl_Offscreen test" );
aWin->resizable( );
aWin->show( );
std::cout << "Fl_Double_Window started" << std::endl;
// ALTERNATIVELY COMMENT OUT THE OFFSCREEN SETUP BELOW OR IN MyWin::Draw()
Fl::flush( );
aWin->make_current( );
offscr = fl_create_offscreen( offscrW, offscrH );
std::cout << "Fl_Offscreen created" << std::endl;
return Fl::run( );
}
int main( ) {
int retval = runWin( );
std::cout << "back to main() ..." << std::endl;
writeScreenshot( );
delete[] offscreenImage;
return retval;
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk