FLTK sandbox

Check-in [b71f77c2cb]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Implemented Fl_Image_Surface::draw_decorated_window(). This gives the same drawing capabilities to all supported drawing surfaces: display, printer, clipboard, in-memory bitmap image, PostScript file. Also, completed the Mac OS implementation of Fl_Copy_Surface::draw_decorated_window(Fl_Window *win, int delta_x=0, int delta_y=0) that did not honor non-zero last arguments. git-svn-id: http://seriss.com/public/fltk/fltk/branches/branch-1.3@10990 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b71f77c2cbe3b224d08a7d5e0dff2c0e84f9ec14
User & Date: manolo@ea41ed52-d2ee-0310-a9c1-e6b18d33e121 2016-01-04 13:16:23
Context
2016-01-05
05:48
1) For the X11 and the Mac OS platforms, a default font (FL_HELVETICA, FL_NORMAL_SIZE) is used when fl_draw() is called while no font has been set before. This commit does the same on the MSWindows platform, for consistency. 2) Slightly improved Fl_Image_Surface::draw_decorated_window() under WIN32. git-svn-id: http://seriss.com/public/fltk/fltk/branches/branch-1.3@10996 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 check-in: 8fd80b6646 user: manolo@ea41ed52-d2ee-0310-a9c1-e6b18d33e121 tags: trunk
2016-01-04
13:16
Implemented Fl_Image_Surface::draw_decorated_window(). This gives the same drawing capabilities to all supported drawing surfaces: display, printer, clipboard, in-memory bitmap image, PostScript file. Also, completed the Mac OS implementation of Fl_Copy_Surface::draw_decorated_window(Fl_Window *win, int delta_x=0, int delta_y=0) that did not honor non-zero last arguments. git-svn-id: http://seriss.com/public/fltk/fltk/branches/branch-1.3@10990 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 check-in: b71f77c2cb user: manolo@ea41ed52-d2ee-0310-a9c1-e6b18d33e121 tags: trunk
2015-12-31
10:39
The changes introduced at r.10921 destroyed program-controlled window resizing. This change hopefully repairs that. git-svn-id: http://seriss.com/public/fltk/fltk/branches/branch-1.3@10987 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 check-in: 8514f9177f user: manolo@ea41ed52-d2ee-0310-a9c1-e6b18d33e121 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to FL/Fl_Image_Surface.H.

63
64
65
66
67
68
69

70
71
72
73
74
75
76
public:
  static const char *class_id;
  const char *class_name() {return class_id;};
  Fl_Image_Surface(int w, int h);
  ~Fl_Image_Surface();
  void set_current();
  void draw(Fl_Widget*, int delta_x = 0, int delta_y = 0);

  Fl_RGB_Image *image();
};

#ifdef __APPLE__
/* Mac class to implement translate()/untranslate() for a flipped bitmap graphics context */
class FL_EXPORT Fl_Quartz_Flipped_Surface_ : public Fl_Quartz_Surface_ {
public:







>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public:
  static const char *class_id;
  const char *class_name() {return class_id;};
  Fl_Image_Surface(int w, int h);
  ~Fl_Image_Surface();
  void set_current();
  void draw(Fl_Widget*, int delta_x = 0, int delta_y = 0);
  void draw_decorated_window(Fl_Window* win, int delta_x = 0, int delta_y = 0);
  Fl_RGB_Image *image();
};

#ifdef __APPLE__
/* Mac class to implement translate()/untranslate() for a flipped bitmap graphics context */
class FL_EXPORT Fl_Quartz_Flipped_Surface_ : public Fl_Quartz_Surface_ {
public:

Changes to FL/Fl_Paged_Device.H.

34
35
36
37
38
39
40

41
42
43
44
45
46
47
 *
 This class has no public constructor: don't instantiate it; use Fl_Printer 
 or Fl_PostScript_File_Device instead.
 */
class FL_EXPORT Fl_Paged_Device : public Fl_Surface_Device {
#ifndef __APPLE__
  friend class Fl_Copy_Surface;

  void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset);
#endif
public:
  /**
   \brief Possible page formats.
   
   All paper formats with pre-defined width and height.







>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 *
 This class has no public constructor: don't instantiate it; use Fl_Printer 
 or Fl_PostScript_File_Device instead.
 */
class FL_EXPORT Fl_Paged_Device : public Fl_Surface_Device {
#ifndef __APPLE__
  friend class Fl_Copy_Surface;
  friend class Fl_Image_Surface;
  void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset);
#endif
public:
  /**
   \brief Possible page formats.
   
   All paper formats with pre-defined width and height.

Changes to FL/mac.H.

207
208
209
210
211
212
213


214
215
216
217
218
219
220
  static int next_marked_length; // next length of marked text after current marked text will have been replaced
  static int insertion_point_location(int *px, int *py, int *pheight); // computes window coordinates & height of insertion point
  static const int CoreText_threshold;  // Mac OS version from which the Core Text API is used to display text
  static Fl_Fontdesc* calc_fl_fonts(void); // computes the fl_fonts global variable
  static int dnd(int use_selection); // call Fl_X::dnd(1) to support text dragging
  static int calc_mac_os_version(void); // computes the fl_mac_os_version global variable
  static void clip_to_rounded_corners(CGContextRef gc, int w, int h);


private:
#if FLTK_ABI_VERSION >= 10304
  CGRect* subRect_;           // makes sure subwindow remains inside its parent window
  // stores 3 binary flags: whether window is mapped to retina display; whether resolution just changed;
  // whether window is OpenGL and is currently being resized.
  unsigned mapped_to_retina_;
#else







>
>







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  static int next_marked_length; // next length of marked text after current marked text will have been replaced
  static int insertion_point_location(int *px, int *py, int *pheight); // computes window coordinates & height of insertion point
  static const int CoreText_threshold;  // Mac OS version from which the Core Text API is used to display text
  static Fl_Fontdesc* calc_fl_fonts(void); // computes the fl_fonts global variable
  static int dnd(int use_selection); // call Fl_X::dnd(1) to support text dragging
  static int calc_mac_os_version(void); // computes the fl_mac_os_version global variable
  static void clip_to_rounded_corners(CGContextRef gc, int w, int h);
  static void *get_titlebar_layer(Fl_Window *win);
  static void draw_layer_to_context(void *layer, CGContextRef ctxt, int w, int h);
private:
#if FLTK_ABI_VERSION >= 10304
  CGRect* subRect_;           // makes sure subwindow remains inside its parent window
  // stores 3 binary flags: whether window is mapped to retina display; whether resolution just changed;
  // whether window is OpenGL and is currently being resized.
  unsigned mapped_to_retina_;
#else

Changes to src/Fl_Copy_Surface.cxx.

205
206
207
208
209
210
211
212
213
214

































215




216
217
218
219

220

221
222
223
224
225
226
227
  CGRect bounds = CGRectMake(0, 0, w, h );	
  CGContextBeginPage (gc, &bounds);
  CGContextTranslateCTM(gc, 0, h);
  CGContextScaleCTM(gc, 1.0f, -1.0f);
  CGContextSaveGState(gc);
}

#endif  // __APPLE__

#if !defined(__APPLE__)

































/** Copies a window and its borders and title bar to the clipboard. */




void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
  helper->draw_decorated_window(win, delta_x, delta_y, this);
}

#endif


#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
/* graphics driver that translates all graphics coordinates before calling Xlib */
class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
  int offset_x, offset_y; // translation between user and graphical coordinates: graphical = user + offset
  unsigned depth; // depth of translation stack
  int stack_x[20], stack_y[20]; // translation stack allowing cumulative translations







|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>




>
|
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
  CGRect bounds = CGRectMake(0, 0, w, h );	
  CGContextBeginPage (gc, &bounds);
  CGContextTranslateCTM(gc, 0, h);
  CGContextScaleCTM(gc, 1.0f, -1.0f);
  CGContextSaveGState(gc);
}

void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
  int bt = win->decorated_h() - win->h();
  draw(win, delta_x, bt + delta_y ); // draw the window content
  if (win->border()) {
    // draw the window title bar
    CGContextSaveGState(gc);
    CGContextTranslateCTM(gc, delta_x, bt + delta_y);
    CGContextScaleCTM(gc, 1, -1);
    Fl_X::clip_to_rounded_corners(gc, win->w(), bt);
    void *layer = Fl_X::get_titlebar_layer(win);
    if (layer) {
      CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
      // for unknown reason, rendering the layer to the Fl_Copy_Surface pdf graphics context does not work;
      // we use an auxiliary bitmap context
      CGContextRef auxgc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
      CGColorSpaceRelease(cspace);
      CGContextTranslateCTM(auxgc, 0, bt);
      CGContextScaleCTM(auxgc, 1, -1);
      Fl_X::draw_layer_to_context(layer, auxgc, win->w(), bt);
      Fl_RGB_Image *image = new Fl_RGB_Image((const uchar*)CGBitmapContextGetData(auxgc), win->w(), bt, 4,
                                             CGBitmapContextGetBytesPerRow(auxgc)); // 10.2
      image->draw(0, 0);
      delete image;
      CGContextRelease(auxgc);
    } else {
      CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
      CGContextDrawImage(gc, CGRectMake(0, 0, win->w(), bt), img);
      CFRelease(img);
    }
    CGContextRestoreGState(gc);
  }
}

#else

/** Copies a window and its borders and title bar to the clipboard. 
 \param win an FLTK window to copy
 \param delta_x and \param delta_y give
 the position in the clipboard of the top-left corner of the window's title bar
*/
void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
  helper->draw_decorated_window(win, delta_x, delta_y, this);
}

#endif // __APPLE__


#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
/* graphics driver that translates all graphics coordinates before calling Xlib */
class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
  int offset_x, offset_y; // translation between user and graphical coordinates: graphical = user + offset
  unsigned depth; // depth of translation stack
  int stack_x[20], stack_y[20]; // translation stack allowing cumulative translations

Changes to src/Fl_Image_Surface.cxx.

147
148
149
150
151
152
153





































154

155



156
157
158

void Fl_Quartz_Flipped_Surface_::untranslate() {
  CGContextRestoreGState(fl_gc);
}

const char *Fl_Quartz_Flipped_Surface_::class_id = "Fl_Quartz_Flipped_Surface_";






































#endif // __APPLE__





//
// End of "$Id$".
//







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

void Fl_Quartz_Flipped_Surface_::untranslate() {
  CGContextRestoreGState(fl_gc);
}

const char *Fl_Quartz_Flipped_Surface_::class_id = "Fl_Quartz_Flipped_Surface_";


void Fl_Image_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
  int bt = win->decorated_h() - win->h();
  draw(win, delta_x, bt + delta_y ); // draw the window content
  if (win->border()) {
    // draw the window title bar
    helper->translate(delta_x, delta_y);
    CGContextTranslateCTM(fl_gc, 0, bt);
    CGContextScaleCTM(fl_gc, 1, -1);
    void *layer = Fl_X::get_titlebar_layer(win);
    if (layer) {
      Fl_X::draw_layer_to_context(layer, fl_gc, win->w(), bt);
    } else {
      CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
      CGContextDrawImage(fl_gc, CGRectMake(0, 0, win->w(), bt), img);
      CFRelease(img);
    }
    helper->untranslate();
    CGContextTranslateCTM(fl_gc, delta_x, height+delta_y);
    CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
  }
}

#else

/** Draws a window and its borders and title bar to the image drawing surface. 
 \param win an FLTK window to draw in the image
 \param delta_x and \param delta_y give
 the position in the image of the top-left corner of the window's title bar
*/
void Fl_Image_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
#ifdef WIN32
  // draw_decorated_window() will change the current drawing surface, and set it
  // back to us; it's necessary to call image() before for this to work
  delete image();
#endif
  helper->draw_decorated_window(win, delta_x, delta_y, this);
}
#endif


//
// End of "$Id$".
//

Changes to src/Fl_Paged_Device.cxx.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    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()->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
      CGContextRestoreGState(fl_gc);
      Fl_X::clip_to_rounded_corners(fl_gc, widget->w(), widget->h());
      CGContextSaveGState(fl_gc);
    }
#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");  







<

<







56
57
58
59
60
61
62

63

64
65
66
67
68
69
70
    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()->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {

      Fl_X::clip_to_rounded_corners(fl_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");  

Changes to src/Fl_cocoa.mm.

3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
....
4419
4420
4421
4422
4423
4424
4425






















4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454

4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
}
- (void)terminate:(id)sender
{
  [NSApp terminate:sender];
}
@end


void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
{
  int bx, by, bt;
  get_window_frame_sizes(bx, by, bt);
  draw(win, 0, bt); // draw the window content
  if (win->border()) {
    // draw the window title bar
    CGContextSaveGState(gc);
    CGContextTranslateCTM(gc, 0, bt);
    CGContextScaleCTM(gc, 1, -1);
    Fl_X::clip_to_rounded_corners(gc, win->w(), bt);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
    CALayer *layer = fl_mac_os_version >= 101000 ?
    [[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer] : nil; // 10.5
    if (layer) {
      CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
      // for unknown reason, rendering the layer to the Fl_Copy_Surface pdf graphics context does not work;
      // we use an auxiliary bitmap context
      CGContextRef auxgc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
      CGColorSpaceRelease(cspace);
      CGContextClearRect(auxgc, CGRectMake(0, 0, win->w(), bt));
      CGContextTranslateCTM(auxgc, 0, bt);
      CGContextScaleCTM(auxgc, 1, -1);
      [layer renderInContext:auxgc]; // 10.5
      fl_draw_image((uchar*)CGBitmapContextGetData(auxgc), 0, 0, win->w(), bt, 4, CGBitmapContextGetBytesPerRow(auxgc));
      CGContextRelease(auxgc);
    } else
#endif
    {
      CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
      CGContextDrawImage(gc, CGRectMake(0, 0, win->w(), bt), img);
      CFRelease(img);
    }
    CGContextRestoreGState(gc);
  }
}


static void createAppleMenu(void)
{
  static BOOL donethat = NO;
  if (donethat) return;
  donethat = YES;
  NSMenu *mainmenu, *services = nil, *appleMenu;
................................................................................
  CGContextAddArcToPoint(gc, 0, h,  radius, h, radius);
  CGContextAddLineToPoint(gc, w - radius, h);
  CGContextAddArcToPoint(gc, w, h, w, h - radius, radius);
  CGContextAddLineToPoint(gc, w, 0);
  CGContextClip(gc);
}























void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
{
  if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
    this->print_widget(win, x_offset, y_offset);
    return;
  }
  int bx, by, bt, bpp;
  get_window_frame_sizes(bx, by, bt);
  BOOL to_quartz =  (this->driver()->class_name() == Fl_Quartz_Graphics_Driver::class_id);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
// a compilation warning appears with SDK 10.5, so we require SDK 10.6 instead
  if (fl_mac_os_version >= 101000) {
    CALayer *layer = [[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer]; // 10.5
    if (layer) { // if program is linked with 10.10, title bar uses a layer
      if (to_quartz) { // to Quartz printer
        CGContextSaveGState(fl_gc);
        CGContextTranslateCTM(fl_gc, x_offset - 0.5, y_offset + bt - 0.5);
        CGContextScaleCTM(fl_gc, 1, -1);
        Fl_X::clip_to_rounded_corners(fl_gc, win->w(), bt);
        [layer renderInContext:fl_gc]; // 10.5 // print all title bar
        CGContextRestoreGState(fl_gc);
      }
      else { // to PostScript
        CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB ();
        CGContextRef gc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(cspace);
        CGContextClearRect(gc, CGRectMake(0, 0, win->w(), bt));
        Fl_X::clip_to_rounded_corners(gc, win->w(), bt);
        [layer renderInContext:gc]; // 10.5 // draw all title bar to bitmap

        Fl_RGB_Image *image = new Fl_RGB_Image((const uchar*)CGBitmapContextGetData(gc), win->w(), bt, 4,
                                               CGBitmapContextGetBytesPerRow(gc)); // 10.2
        image->draw(x_offset, y_offset); // draw title bar to PostScript
        delete image;
        CGContextRelease(gc);
      }
      this->print_widget(win, x_offset, y_offset + bt);
      return;
    }
  }
#endif
  Fl_Display_Device::display_device()->set_current(); // send win to front and make it current
  const char *title = win->label();
  win->label(""); // temporarily set a void window title
  win->show();
  fl_gc = NULL;
  Fl::check();
  // capture the window title bar with no title







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
<
<
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
<
<
>
|
|
|
|
|
|
|
|
|
<
<







3847
3848
3849
3850
3851
3852
3853






































3854
3855
3856
3857
3858
3859
3860
....
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419



4420
4421
4422
4423
4424
4425

4426
4427
4428
4429
4430
4431
4432


4433
4434
4435
4436
4437
4438
4439
4440
4441
4442


4443
4444
4445
4446
4447
4448
4449
}
- (void)terminate:(id)sender
{
  [NSApp terminate:sender];
}
@end








































static void createAppleMenu(void)
{
  static BOOL donethat = NO;
  if (donethat) return;
  donethat = YES;
  NSMenu *mainmenu, *services = nil, *appleMenu;
................................................................................
  CGContextAddArcToPoint(gc, 0, h,  radius, h, radius);
  CGContextAddLineToPoint(gc, w - radius, h);
  CGContextAddArcToPoint(gc, w, h, w, h - radius, radius);
  CGContextAddLineToPoint(gc, w, 0);
  CGContextClip(gc);
}


void *Fl_X::get_titlebar_layer(Fl_Window *win)
{
  // a compilation warning appears with SDK 10.5, so we require SDK 10.6 instead
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
  return fl_mac_os_version >= 101000 ? [[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer] : nil; // 10.5
#else
  return nil;
#endif
}


void Fl_X::draw_layer_to_context(void *layer, CGContextRef gc, int w, int h)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
  Fl_X::clip_to_rounded_corners(gc, w, h);
  CGContextSetRGBFillColor(gc, .79, .79, .79, 1.); // equiv. to FL_DARK1
  CGContextFillRect(gc, CGRectMake(0, 0, w, h));
  [(CALayer*)layer renderInContext:gc]; // 10.5
#endif
}

void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
{
  if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
    this->print_widget(win, x_offset, y_offset);
    return;
  }
  int bx, by, bt, bpp;
  get_window_frame_sizes(bx, by, bt);
  BOOL to_quartz =  (this->driver()->class_name() == Fl_Quartz_Graphics_Driver::class_id);
  void *layer = Fl_X::get_titlebar_layer(win);



  if (layer) { // if title bar uses a layer
    if (to_quartz) { // to Quartz printer
      CGContextSaveGState(fl_gc);
      CGContextTranslateCTM(fl_gc, x_offset - 0.5, y_offset + bt - 0.5);
      CGContextScaleCTM(fl_gc, 1, -1);
      Fl_X::draw_layer_to_context(layer, fl_gc, win->w(), bt);

      CGContextRestoreGState(fl_gc);
    }
    else { // to PostScript
      CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB ();
      CGContextRef gc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
      CGColorSpaceRelease(cspace);
      CGContextClearRect(gc, CGRectMake(0, 0, win->w(), bt));


      Fl_X::draw_layer_to_context(layer, gc, win->w(), bt);
      Fl_RGB_Image *image = new Fl_RGB_Image((const uchar*)CGBitmapContextGetData(gc), win->w(), bt, 4,
                                             CGBitmapContextGetBytesPerRow(gc)); // 10.2
      image->draw(x_offset, y_offset); // draw title bar to PostScript
      delete image;
      CGContextRelease(gc);
    }
    this->print_widget(win, x_offset, y_offset + bt);
    return;
  }


  Fl_Display_Device::display_device()->set_current(); // send win to front and make it current
  const char *title = win->label();
  win->label(""); // temporarily set a void window title
  win->show();
  fl_gc = NULL;
  Fl::check();
  // capture the window title bar with no title

Changes to src/Fl_win32.cxx.

2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
  // print the 4 window sides
  fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image;
  if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; }
  if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; }
  if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; }
  // print the window inner part
  this->print_widget(win, x_offset + bx, y_offset + bt + by);
  fl_gc = GetDC(fl_xid(win));
  ReleaseDC(fl_xid(win), fl_gc);
}  

#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
#include <FL/Fl_Printer.H>
#include <FL/Fl_Button.H>
void printFront(Fl_Widget *o, void *data)







<
<
|







2765
2766
2767
2768
2769
2770
2771


2772
2773
2774
2775
2776
2777
2778
2779
  // print the 4 window sides
  fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image;
  if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; }
  if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; }
  if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); 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
#include <FL/Fl_Printer.H>
#include <FL/Fl_Button.H>
void printFront(Fl_Widget *o, void *data)

Changes to test/device.cxx.

547
548
549
550
551
552
553












554
555
556



557
558
559
560
561

562
563
564
565
566
567
568
569
...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719


Fl_Widget *target;
const  char *operation;

void copy(Fl_Widget *, void *data) {
  if (strcmp(operation, "Fl_Image_Surface") == 0) {












    Fl_Image_Surface *rgb_surf = new Fl_Image_Surface(target->w()+20, target->h()+10);
    rgb_surf->set_current();
    fl_color(FL_BLUE);fl_rectf(0,0,1000,1000);



    rgb_surf->draw(target,10,5);
    Fl_Image *img = rgb_surf->image();
    delete rgb_surf;
    Fl_Display_Device::display_device()->set_current();
    Fl_Window* g2 = new Fl_Window(img->w(), img->h());

    Fl_Box *b = new Fl_Box(FL_NO_BOX,0,0,img->w(), img->h(),0);
    b->image(img);
    g2->end();
    g2->show();
    return;
  }
  
  
................................................................................
  rb = new Fl_Radio_Round_Button(5,5,150,12, "Fl_Image_Surface"); 
  rb->set(); rb->callback(operation_cb, NULL); operation = rb->label();
  rb = new Fl_Radio_Round_Button(5,22,150,12, "Fl_Copy_Surface"); rb->callback(operation_cb, NULL);
  rb = new Fl_Radio_Round_Button(5,39,150,12, "Fl_Printer"); rb->callback(operation_cb, NULL);
  g1->end();
  
  Fl_Group *g2 = new Fl_Group(w3->x(),w3->y(),w3->w(),w3->h());
  rb = new Fl_Radio_Round_Button(170,5,150,12, "Window"); 
  rb->set(); rb->callback(target_cb, w2); target = w2;
  rb = new Fl_Radio_Round_Button(170,22,150,12, "Sub-window"); rb->callback(target_cb, w3);
  rb = new Fl_Radio_Round_Button(170,39,150,12, "Group"); rb->callback(target_cb, group);
  g2->end();
  Fl_Button *b4 = new Fl_Button(330, (w3->h() - 25)/2, 150, 25, "GO");
  b4->callback((Fl_Callback*)copy,NULL);
  w3->end();







>
>
>
>
>
>
>
>
>
>
>
>
|

<
>
>
>
|



|
>
|







 







|







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734


Fl_Widget *target;
const  char *operation;

void copy(Fl_Widget *, void *data) {
  if (strcmp(operation, "Fl_Image_Surface") == 0) {
    Fl_Image_Surface *rgb_surf;
    int W, H, decorated;
    if (target->as_window() && !target->parent()) {
      W = target->as_window()->decorated_w();
      H = target->as_window()->decorated_h();
      decorated = 1;
     }
    else {
      W = target->w();
      H = target->h();
      decorated = 0;
    }
    rgb_surf = new Fl_Image_Surface(W, H);
    rgb_surf->set_current();

    if (decorated)
      rgb_surf->draw_decorated_window(target->as_window());
    else
      rgb_surf->draw(target);
    Fl_Image *img = rgb_surf->image();
    delete rgb_surf;
    Fl_Display_Device::display_device()->set_current();
    Fl_Window* g2 = new Fl_Window(img->w()+10, img->h()+10);
    g2->color(FL_YELLOW);
    Fl_Box *b = new Fl_Box(FL_NO_BOX,5,5,img->w(), img->h(),0);
    b->image(img);
    g2->end();
    g2->show();
    return;
  }
  
  
................................................................................
  rb = new Fl_Radio_Round_Button(5,5,150,12, "Fl_Image_Surface"); 
  rb->set(); rb->callback(operation_cb, NULL); operation = rb->label();
  rb = new Fl_Radio_Round_Button(5,22,150,12, "Fl_Copy_Surface"); rb->callback(operation_cb, NULL);
  rb = new Fl_Radio_Round_Button(5,39,150,12, "Fl_Printer"); rb->callback(operation_cb, NULL);
  g1->end();
  
  Fl_Group *g2 = new Fl_Group(w3->x(),w3->y(),w3->w(),w3->h());
  rb = new Fl_Radio_Round_Button(170,5,150,12, "Decorated Window"); 
  rb->set(); rb->callback(target_cb, w2); target = w2;
  rb = new Fl_Radio_Round_Button(170,22,150,12, "Sub-window"); rb->callback(target_cb, w3);
  rb = new Fl_Radio_Round_Button(170,39,150,12, "Group"); rb->callback(target_cb, group);
  g2->end();
  Fl_Button *b4 = new Fl_Button(330, (w3->h() - 25)/2, 150, 25, "GO");
  b4->callback((Fl_Callback*)copy,NULL);
  w3->end();