summaryrefslogtreecommitdiff
path: root/src/Fl_Image_Surface.cxx
blob: b64004a61938d13388ebae3c180403c7567b5716 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
// "$Id$"
//
// Draw-to-image code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2014 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_Image_Surface.H>
#include <FL/Fl_Printer.H>
#include <FL/Fl.H>


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

/** The constructor.
 \param w and \param h give the size in pixels of the resulting image.
 */
Fl_Image_Surface::Fl_Image_Surface(int w, int h) : Fl_Surface_Device(NULL) {
  width = w;
  height = h;
#if !(defined(__APPLE__) || defined(WIN32))
  gc = 0;
  if (!fl_display) { // allows use of this class before any window is shown
    fl_open_display();
    gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0);
    fl_gc = gc;
    }
#endif
  offscreen = fl_create_offscreen(w, h);
#ifdef __APPLE__
  helper = new Fl_Quartz_Flipped_Surface_(width, height);
  driver(helper->driver());
#elif defined(WIN32)
  helper = new Fl_GDI_Surface_();
  driver(helper->driver());
#else
  helper = new Fl_Xlib_Surface_();
  driver(helper->driver());
#endif
}

/** The destructor.
 */
Fl_Image_Surface::~Fl_Image_Surface() {
  fl_delete_offscreen(offscreen);
#ifdef __APPLE__
  delete (Fl_Quartz_Flipped_Surface_*)helper;
#elif defined(WIN32)
  delete (Fl_GDI_Surface_*)helper;
#else
  if (gc) { XFreeGC(fl_display, gc); fl_gc = 0; }
  delete (Fl_Xlib_Surface_*)helper;
#endif
}

/** Returns an image made of all drawings sent to the Fl_Image_Surface object.
 The returned object contains its own copy of the RGB data.
 */
Fl_RGB_Image* Fl_Image_Surface::image()
{
  unsigned char *data;
#ifdef __APPLE__
  CGContextFlush(offscreen);
  data = fl_read_image(NULL, 0, 0, width, height, 0);
  fl_end_offscreen();
#elif defined(WIN32)
  fl_pop_clip(); 
  data = fl_read_image(NULL, 0, 0, width, height, 0);
  RestoreDC(fl_gc, _savedc); 
  DeleteDC(fl_gc); 
  _ss->set_current(); 
  fl_window=_sw; 
  fl_gc = _sgc;
#else
  fl_pop_clip(); 
  data = fl_read_image(NULL, 0, 0, width, height, 0);
  fl_window = pre_window; 
  previous->set_current();
#endif
  Fl_RGB_Image *image = new Fl_RGB_Image(data, width, height);
  image->alloc_array = 1;
  return image;
}

/** Draws a widget in the image surface
 
 \param widget any FLTK widget (e.g., standard, custom, window, GL view) 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 widget
 */
void Fl_Image_Surface::draw(Fl_Widget *widget, int delta_x, int delta_y)
{
  helper->print_widget(widget, delta_x, delta_y);
}


void Fl_Image_Surface::set_current()
{
#if defined(__APPLE__)
  fl_begin_offscreen(offscreen);
  fl_pop_clip();
  Fl_Surface_Device::set_current(); 
  fl_push_no_clip();
#elif defined(WIN32)
  _sgc=fl_gc; 
  _sw=fl_window;
  _ss = Fl_Surface_Device::surface(); 
  Fl_Surface_Device::set_current();
  fl_gc = fl_makeDC(offscreen); 
   _savedc = SaveDC(fl_gc); 
  fl_window=(HWND)offscreen; 
  fl_push_no_clip();
#else
  pre_window = fl_window; 
  fl_window = offscreen; 
  previous = Fl_Surface_Device::surface(); 
  Fl_Surface_Device::set_current();
  fl_push_no_clip();
#endif
}

#if defined(__APPLE__)

Fl_Quartz_Flipped_Surface_::Fl_Quartz_Flipped_Surface_(int w, int h) : Fl_Quartz_Surface_(w, h) {
}

void Fl_Quartz_Flipped_Surface_::translate(int x, int y) {
  CGContextRestoreGState(fl_gc);
  CGContextSaveGState(fl_gc);
  CGContextTranslateCTM(fl_gc, x, -y);
  CGContextSaveGState(fl_gc);
  CGContextTranslateCTM(fl_gc, 0, height);
  CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
}

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$".
//