summaryrefslogtreecommitdiff
path: root/src/Fl_Device.cxx
blob: 03e8367acb7ab636209885710334456fa0742573 (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
158
159
160
/*
 *  Fl_Device.cxx
 *
 */

#include <FL/Fl.H>
#include <FL/Fl_Device.H>
#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Image.H>

extern Fl_Device *fl_device;

void Fl_Device::draw(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy)
{
  // presently, never gets called
}

void Fl_Device::draw(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy)
{
  // presently, never gets called
}

void Fl_Device::draw(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy)
{
  // presently, never gets called
}

void Fl_Virtual_Printer::print_widget(Fl_Widget* widget, int delta_x, int delta_y) 
{ 
  int old_x, old_y, new_x, new_y, is_window;
  if ( ! widget->visible() ) return;
  is_window = (widget->as_window() != NULL);
  widget->damage(FL_DAMAGE_ALL);
  // set origin to the desired top-left position of the widget
  origin(&old_x, &old_y);
  new_x = old_x + delta_x;
  new_y = old_y + delta_y;
  if (!is_window) {
    new_x -= widget->x();
    new_y -= widget->y();
  }
  if (new_x != old_x || new_y != old_y) {
    translate(new_x - old_x, new_y - old_y );
  }
  // if widget is a window, clip all drawings to the window area
  if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() );
#ifdef __APPLE__
  CGContextRef save_gc = fl_gc;
#elif defined(WIN32) // && !defined(__CYGWIN__)
  HDC save_gc = fl_gc;
#else
  _XGC *save_gc = fl_gc;	// FIXME
#endif
  widget->draw();
  fl_gc = save_gc;
  if (is_window) fl_pop_clip();
  // find subwindows of widget and print them
  traverse(widget);
  // reset origin to where it was
  if (new_x != old_x || new_y != old_y) {
    untranslate();
  }
}


void Fl_Virtual_Printer::traverse(Fl_Widget *widget)
{
  Fl_Group *g = widget->as_group();
  if (!g) return;
  int n = g->children();
  for (int i = 0; i < n; i++) {
    Fl_Widget *c = g->child(i);
    if ( !c->visible() ) continue;
    if ( c->as_window() ) {
      print_widget(c, c->x(), c->y());
    }
    else traverse(c);
  }
}

void Fl_Virtual_Printer::origin(int *x, int *y)
{
  if (x) *x = x_offset;
  if (y) *y = y_offset;
}

void Fl_Virtual_Printer::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
{
  Fl_Device::display_device()->set_current();
  Fl_Window *save_front = Fl::first_window();
  win->show();
  Fl::check();
  win->make_current();
  uchar *image_data = fl_read_image(NULL, x, y, w, h);
  save_front->show();
  this->set_current();
  Fl_RGB_Image *image = new Fl_RGB_Image(image_data, w, h);
  image->draw(delta_x, delta_y);
  add_image(image, image_data);
}

void Fl_Virtual_Printer::add_image(Fl_Image *image, const uchar *data)
{
  struct chain_elt *elt =  (struct chain_elt *)calloc(sizeof(struct chain_elt), 1);
  elt->image = image;
  elt->data = data;
  if (image_list_) { elt->next = image_list_; }
  image_list_ = elt;
}

void Fl_Virtual_Printer::delete_image_list()
{
  while(image_list_) {
    struct chain_elt *next = image_list_->next;
    delete image_list_->image;
    if (image_list_->data) delete image_list_->data;
    free(image_list_);
    image_list_ = next;
  }
}

Fl_Device *Fl_Virtual_Printer::set_current(void)
{
#ifdef __APPLE__
  fl_gc = (CGContextRef)gc;
#elif defined(WIN32)
  fl_gc = (HDC)gc;
#else
  fl_gc = (_XGC*)gc;
#endif
  return this->Fl_Device::set_current();
}


int Fl_Virtual_Printer::start_job(int pagecount, int *frompage, int *topage) {return 1;}
int Fl_Virtual_Printer::start_page (void) {return 1;}
int Fl_Virtual_Printer::printable_rect(int *w, int *h) {return 1;}
void Fl_Virtual_Printer::margins(int *left, int *top, int *right, int *bottom) {}
void Fl_Virtual_Printer::origin(int x, int y) {}
void Fl_Virtual_Printer::scale (float scale_x, float scale_y) {}
void Fl_Virtual_Printer::rotate(float angle) {}
int Fl_Virtual_Printer::end_page (void) {return 1;}
void Fl_Virtual_Printer::end_job (void) {}
void Fl_Virtual_Printer::translate(int x, int y) {}
void Fl_Virtual_Printer::untranslate(void) {}

extern Fl_Device *fl_device;

Fl_Device *Fl_Device::set_current(void)
{
  Fl_Device *current = fl_device;
  fl_device = this;
  return current;
}

Fl_Device *Fl_Device::current(void)
{
  return fl_device;
}