source: tags/ms_r18q1/WINDOW/aw_device.hxx

Last change on this file was 17002, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1#ifndef AW_DEVICE_HXX
2#define AW_DEVICE_HXX
3
4#ifndef SIZED_CSTR_H
5#include <sized_cstr.h>
6#endif
7#ifndef AW_POSITION_HXX
8#include <aw_position.hxx>
9#endif
10#ifndef AW_FONT_LIMITS_HXX
11#include <aw_font_limits.hxx>
12#endif
13#ifndef ATTRIBUTES_H
14#include <attributes.h>
15#endif
16#ifndef ARBTOOLS_H
17#include <arbtools.h>
18#endif
19
20#if defined(DEBUG) && defined(DEBUG_GRAPHICS)
21// if you want flush() to be called after every motif command :
22#define AUTO_FLUSH(device) (device)->flush()
23#else
24#define AUTO_FLUSH(device)
25#endif
26
27#define AW_INT(x) ((int)(((x)>=0.0) ? ((float)(x)+.5) : ((float)(x)-.5)))
28
29// #define AW_PIXELS_PER_MM 1.0001 // stupid and wrong
30
31#define DPI_SCREEN  80   // fixed
32#define DPI_PRINTER 1200 // default resolution of xfig 3.2
33
34const AW_bitset AW_SCREEN        = 1;
35const AW_bitset AW_CLICK         = 2;
36const AW_bitset AW_CLICK_DROP    = 4;
37const AW_bitset AW_SIZE          = 8;
38const AW_bitset AW_SIZE_UNSCALED = 16;  // for text and text-size dependant parts
39const AW_bitset AW_PRINTER       = 32;  // print/xfig-export
40const AW_bitset AW_PRINTER_EXT   = 64;  // (+Handles) use combined with AW_PRINTER only
41const AW_bitset AW_PRINTER_CLIP  = 128; // print screen only
42const AW_bitset AW_TRACK         = 256; // species tracking
43
44const AW_bitset AW_ALL_DEVICES          = (AW_bitset)-1; // @@@ allowed to used this ?
45const AW_bitset AW_ALL_DEVICES_SCALED   = (AW_ALL_DEVICES & ~AW_SIZE_UNSCALED);
46const AW_bitset AW_ALL_DEVICES_UNSCALED = (AW_ALL_DEVICES & ~AW_SIZE);
47
48enum AW_DEVICE_TYPE {
49    AW_DEVICE_SCREEN  = AW_SCREEN,
50    AW_DEVICE_CLICK   = AW_CLICK,
51    AW_DEVICE_SIZE    = AW_SIZE,
52    AW_DEVICE_PRINTER = AW_PRINTER,
53};
54
55enum {
56    AW_FIXED             = -1,
57    AW_TIMES             = 0,
58    AW_TIMES_ITALIC      = 1,
59    AW_TIMES_BOLD        = 2,
60    AW_TIMES_BOLD_ITALIC = 3,
61
62    AW_COURIER              = 12,
63    AW_COURIER_OBLIQUE      = 13,
64    AW_COURIER_BOLD         = 14,
65    AW_COURIER_BOLD_OBLIQUE = 15,
66
67    AW_HELVETICA                     = 16,
68    AW_HELVETICA_OBLIQUE             = 17,
69    AW_HELVETICA_BOLD                = 18,
70    AW_HELVETICA_BOLD_OBLIQUE        = 19,
71    AW_HELVETICA_NARROW              = 20,
72    AW_HELVETICA_NARROW_OBLIQUE      = 21,
73    AW_HELVETICA_NARROW_BOLD         = 22,
74    AW_HELVETICA_NARROW_BOLD_OBLIQUE = 23,
75
76    AW_LUCIDA_SANS                 = 35,
77    AW_LUCIDA_SANS_OBLIQUE         = 36,
78    AW_LUCIDA_SANS_BOLD            = 37,
79    AW_LUCIDA_SANS_BOLD_OBLIQUE    = 38,
80    AW_LUCIDA_SANS_TYPEWRITER      = 39,
81    AW_LUCIDA_SANS_TYPEWRITER_BOLD = 40,
82    AW_SCREEN_MEDIUM               = 41,
83    AW_SCREEN_BOLD                 = 42,
84    AW_CLEAN_MEDIUM                = 43,
85    AW_CLEAN_BOLD                  = 44,
86    AW_TERMINAL_MEDIUM             = 45,
87    AW_TERMINAL_BOLD               = 46,
88
89    AW_NUM_FONTS      = 68,
90    AW_NUM_FONTS_XFIG = 35, // immutable
91
92    AW_DEFAULT_NORMAL_FONT = AW_LUCIDA_SANS,
93    AW_DEFAULT_BOLD_FONT   = AW_LUCIDA_SANS_BOLD,
94    AW_DEFAULT_FIXED_FONT  = AW_LUCIDA_SANS_TYPEWRITER,
95};
96
97enum AW_cursor_type {
98    AW_cursor_insert,
99    AW_cursor_overwrite
100};
101
102// --------------------------------------------------
103// general note on world- vs. pixel-positions:(WORLD_vs_PIXEL)
104//
105// A position is interpreted as the center of the corresponding pixel
106// (pixel refers to screen; printer pixel are 15 times smaller!)
107//
108// Hence, when scaling factor is 1.0, then
109// - any position inside [-0.5, 0.5[ will fall into the pixel 0, any inside [0.5, 1.5[ into pixel 1.
110// - a line from 0.0 to 2.0 will paint THREE pixels (0, 1 and 2). A line from -0.5 to 2.499 will to the same
111// - clipping to area [0, 100] should in fact clip to [-0.5, 100.5[ (@@@ check this)
112
113class AW_zoomable {
114    AW::Vector offset;
115    AW_pos     scale;
116    AW_pos     unscale;         // = 1.0/scale
117
118public:
119    AW_zoomable() { this->reset(); };
120    virtual ~AW_zoomable() {}
121
122    void zoom(AW_pos scale);
123
124    AW_pos get_scale() const { return scale; };
125    AW_pos get_unscale() const { return unscale; };
126    AW::Vector get_offset() const { return offset; }
127
128    void rotate(AW_pos angle);
129
130    void set_offset(const AW::Vector& off) { offset = off*scale; }
131    void shift(const AW::Vector& doff) { offset += doff*scale; }
132
133    void reset();
134
135    double transform_size(const double& size) const { return size*scale; }
136    double rtransform_size(const double& size) const { return size*unscale; }
137
138    double rtransform_pixelsize(int pixelsize) const {
139        // return world-size needed to draw line/box with length/size == 'pixelsize'
140        return (pixelsize-1)*unscale;
141    }
142
143    // transforming a Vector only scales the vector (a Vector has no position!)
144    AW::Vector transform (const AW::Vector& vec) const { return vec*scale; }
145    AW::Vector rtransform(const AW::Vector& vec) const { return vec*unscale; }
146
147    // transform a Position
148    AW::Position transform (const AW::Position& pos) const { return transform(AW::Vector(pos+offset)).endpoint(); }
149    AW::Position rtransform(const AW::Position& pos) const { return rtransform(AW::Vector(pos)).endpoint()-offset; }
150#if defined(WARN_TODO) && 0
151#warning fix transformations
152    // @@@ I think this calculation is wrong, cause offset is already scaled
153    //     (same applies to old-style transform/rtransform below)
154#endif
155
156    AW::LineVector transform (const AW::LineVector& lvec) const { return AW::LineVector(transform(lvec.start()), transform(lvec.line_vector())); }
157    AW::LineVector rtransform(const AW::LineVector& lvec) const { return AW::LineVector(rtransform(lvec.start()), rtransform(lvec.line_vector())); }
158
159    AW::Rectangle transform (const AW::Rectangle& rect) const { return AW::Rectangle(transform(static_cast<const AW::LineVector&>(rect))); }
160    AW::Rectangle rtransform(const AW::Rectangle& rect) const { return AW::Rectangle(rtransform(static_cast<const AW::LineVector&>(rect))); }
161
162    // old style functions, not preferred:
163    void transform(AW_pos x, AW_pos y, AW_pos& xout, AW_pos& yout) const {
164        xout = (x+offset.x())*scale;
165        yout = (y+offset.y())*scale;
166    }
167    void rtransform(AW_pos x, AW_pos y, AW_pos& xout, AW_pos& yout) const {
168        xout = x*unscale - offset.x();
169        yout = y*unscale - offset.y();
170    }
171};
172
173struct AW_font_overlap { bool top, bottom, left, right; };
174
175class AW_clipable {
176    const AW_screen_area& common_screen;
177    const AW_screen_area& get_screen() const { return common_screen; }
178
179    AW_screen_area  clip_rect;    // holds the clipping rectangle coordinates
180    AW_font_overlap font_overlap;
181
182    void set_cliprect_oversize(const AW_screen_area& rect, bool allow_oversize);
183
184    bool need_extra_clip_position(const AW::Position& p1, const AW::Position& p2, AW::Position& extra);
185
186protected:
187    int compoutcode(AW_pos xx, AW_pos yy) const {
188        // calculate outcode for clipping the current line
189        // order - top,bottom,right,left
190        int code = 0;
191        if (clip_rect.b - yy < 0)       code = 4;
192        else if (yy - clip_rect.t < 0)  code = 8;
193        if (clip_rect.r - xx < 0)       code |= 2;
194        else if (xx - clip_rect.l < 0)  code |= 1;
195        return code;
196    };
197
198    void set_cliprect(const AW_screen_area& rect) { clip_rect = rect; }
199
200public:
201
202    AW_clipable(const AW_screen_area& screen)
203        : common_screen(screen)
204    {
205        clip_rect.clear();
206        set_font_overlap(false);
207    }
208    virtual ~AW_clipable() {}
209
210    bool is_below_clip(double ypos) const { return ypos > clip_rect.b; }
211    bool is_above_clip(double ypos) const { return ypos < clip_rect.t; }
212    bool is_leftof_clip(double xpos) const { return xpos < clip_rect.l; }
213    bool is_rightof_clip(double xpos) const { return xpos > clip_rect.r; }
214
215    bool is_outside_clip(AW::Position pos) const {
216        return
217            is_below_clip(pos.ypos()) || is_above_clip(pos.ypos()) ||
218            is_leftof_clip(pos.xpos()) || is_rightof_clip(pos.xpos());
219    }
220    bool is_outside_clip(AW::Rectangle rect) const {
221        return !rect.overlaps_with(AW::Rectangle(get_cliprect(), AW::INCLUSIVE_OUTLINE));
222    }
223
224    bool clip(AW_pos x0, AW_pos y0, AW_pos x1, AW_pos y1, AW_pos& x0out, AW_pos& y0out, AW_pos& x1out, AW_pos& y1out);
225    bool clip(const AW::LineVector& line, AW::LineVector& clippedLine);
226
227    bool box_clip(AW_pos x0, AW_pos y0, AW_pos x1, AW_pos y1, AW_pos& x0out, AW_pos& y0out, AW_pos& x1out, AW_pos& y1out);
228    bool box_clip(const AW::Rectangle& rect, AW::Rectangle& clippedRect);
229    bool box_clip(int npos, const AW::Position *pos, int& nclippedPos, AW::Position*& clippedPos);
230    bool force_into_clipbox(const AW::Position& pos, AW::Position& forcedPos);
231
232    void set_top_clip_border(int top, bool allow_oversize = false);
233    void set_bottom_clip_border(int bottom, bool allow_oversize = false); // absolute
234    void set_bottom_clip_margin(int bottom, bool allow_oversize = false); // relative
235    void set_left_clip_border(int left, bool allow_oversize = false);
236    void set_right_clip_border(int right, bool allow_oversize = false);
237    const AW_screen_area& get_cliprect() const { return clip_rect; }
238
239    void set_clipall() {
240        // clip all -> nothing drawn afterwards
241        AW_screen_area rect = { 0, -1, 0, -1};
242        set_cliprect_oversize(rect, false);
243    }
244
245    bool completely_clipped() const { return clip_rect.l>clip_rect.r || clip_rect.t>clip_rect.b; }
246
247    bool allow_top_font_overlap() const { return font_overlap.top; }
248    bool allow_bottom_font_overlap() const { return font_overlap.bottom; }
249    bool allow_left_font_overlap() const { return font_overlap.left; }
250    bool allow_right_font_overlap() const { return font_overlap.right; }
251    const AW_font_overlap& get_font_overlap() const { return font_overlap; }
252
253    void set_top_font_overlap(bool allow) { font_overlap.top = allow; }
254    void set_bottom_font_overlap(bool allow) { font_overlap.bottom = allow; }
255    void set_left_font_overlap(bool allow) { font_overlap.left = allow; }
256    void set_right_font_overlap(bool allow) { font_overlap.right = allow; }
257
258    void set_vertical_font_overlap(bool allow) { font_overlap.top = font_overlap.bottom = allow; }
259    void set_horizontal_font_overlap(bool allow) { font_overlap.left = font_overlap.right = allow; }
260    void set_font_overlap(bool allow) { set_vertical_font_overlap(allow); set_horizontal_font_overlap(allow); }
261    void set_font_overlap(const AW_font_overlap& fo) { font_overlap = fo; }
262
263    // like set_xxx_clip_border but make window only smaller:
264
265    void reduce_top_clip_border(int top);
266    void reduce_bottom_clip_border(int bottom);
267    void reduce_left_clip_border(int left);
268    void reduce_right_clip_border(int right);
269
270    int reduceClipBorders(int top, int bottom, int left, int right);
271};
272
273// -----------------------------------------------
274//      Graphic context (linestyle, width ...)
275
276enum AW_linestyle {
277    AW_SOLID,
278    AW_DASHED,
279    AW_DOTTED,
280};
281
282
283enum AW_function {
284    AW_COPY,
285    AW_XOR
286};
287
288class AW_common;
289
290class AW_stylable : virtual Noncopyable {
291    AW_common *common;
292public:
293    AW_stylable(AW_common *common_) : common(common_) {}
294    virtual ~AW_stylable() {};
295
296    AW_common *get_common() const { return common; }
297
298    void new_gc(int gc);
299
300    void          set_grey_level(int gc, AW_grey_level grey_level);
301    AW_grey_level get_grey_level(int gc);
302
303    void set_font(int gc, AW_font fontnr, int size, int *found_size);
304    void set_line_attributes(int gc, short width, AW_linestyle style);
305    void set_function(int gc, AW_function function);
306    void establish_default(int gc);
307    void set_foreground_color(int gc, AW_color_idx color);
308
309    int get_string_size(int gc, long textlen) const;
310    int get_string_size(int gc, const SizedCstr& cstr) const;
311
312    const AW_font_limits& get_font_limits(int gc, char c) const; // for one characters (c == 0 -> for all characters)
313
314    int get_available_fontsizes(int gc, AW_font font_nr, int *available_sizes);
315
316    void reset_style();
317};
318
319class  AW_clip_scale_stack;
320struct AW_world;
321class  AW_device;
322
323class AW_click_cd : virtual Noncopyable {
324    AW_CL              cd1;
325    AW_CL              cd2;
326    AW_device         *my_device;
327    const AW_click_cd *previous;
328
329    void link();
330
331public:
332    AW_click_cd(AW_device *device, AW_CL CD1, AW_CL CD2)
333        : cd1(CD1),
334          cd2(CD2),
335          my_device(device)
336    { link(); }
337    AW_click_cd(AW_device *device, AW_CL CD1)
338        : cd1(CD1),
339          cd2(0),
340          my_device(device)
341    { link(); }
342    ~AW_click_cd();
343
344    void disable();
345    void enable();
346
347    AW_CL get_cd1() const { return cd1; }
348    AW_CL get_cd2() const { return cd2; }
349
350    void set_cd1(AW_CL cd) { cd1 = cd; }
351    void set_cd2(AW_CL cd) { cd2 = cd; }
352};
353
354typedef bool (*TextOverlayCallback)(AW_device *device, int gc, const char *textBuffer, size_t textStart, size_t textLen, const AW::Position& pos, AW_CL cduser);
355
356class AW_device : public AW_zoomable, public AW_stylable, public AW_clipable {
357    AW_device(const AW_device& other);
358    AW_device& operator=(const AW_device& other);
359
360protected:
361    AW_clip_scale_stack *clip_scale_stack;
362
363    const AW_click_cd *click_cd;
364    friend class       AW_click_cd;
365
366    AW_bitset filter;
367
368    static const AW_screen_area& get_common_screen(const AW_common *common_);
369
370public:
371    AW_device(class AW_common *common_) :
372        AW_stylable(common_),
373        AW_clipable(get_common_screen(common_)),
374        clip_scale_stack(NULp),
375        click_cd(NULp),
376        filter(AW_ALL_DEVICES)
377    {}
378    virtual ~AW_device() {}
379
380    const AW_click_cd *get_click_cd() const { return click_cd; }
381    AW_bitset get_filter() const { return filter; }
382
383    void reset(); // pops all clip_scales
384
385    const AW_screen_area& get_area_size() const;
386    AW::Rectangle get_rtransformed_cliprect() const { return rtransform(AW::Rectangle(get_cliprect(), AW::INCLUSIVE_OUTLINE)); }
387
388    void set_filter(AW_bitset filteri);   // set the main filter mask
389
390    void push_clip_scale();     // push clipping area and scale
391    void pop_clip_scale();     // pop them
392
393    virtual AW_DEVICE_TYPE type() = 0;
394
395    bool ready_to_draw(int gc); // unused atm
396
397private:
398    // * functions below return 1 if any pixel is drawn, 0 otherwise
399    // * primary functions (always virtual; pure virtual in all devices used as baseclass)
400
401    virtual bool line_impl(int gc, const AW::LineVector& Line, AW_bitset filteri)                                       = 0;
402    virtual bool text_impl(int gc, const SizedCstr& cstr, const AW::Position& pos, AW_pos alignment, AW_bitset filteri) = 0;
403    virtual bool box_impl(int gc, AW::FillStyle filled, const AW::Rectangle& rect, AW_bitset filteri)                   = 0;
404    virtual bool polygon_impl(int gc, AW::FillStyle filled, int npos, const AW::Position *pos, AW_bitset filteri)       = 0;
405
406    virtual bool circle_impl(int gc, AW::FillStyle filled, const AW::Position& center, const AW::Vector& radius, AW_bitset filteri)                                  = 0;
407    virtual bool arc_impl(int gc, AW::FillStyle filled, const AW::Position& center, const AW::Vector& radius, int start_degrees, int arc_degrees, AW_bitset filteri) = 0;
408
409    virtual bool invisible_impl(const AW::Position& pos, AW_bitset filteri) = 0;
410
411    virtual void specific_reset() = 0;
412
413protected:
414
415    // * second level functions
416    // generic implementations which may be used by primary functions of derived classes
417
418    bool generic_box(int gc, const AW::Rectangle& rect, AW_bitset filteri);
419    bool generic_circle(int gc, const AW::Position& center, const AW::Vector& radius, AW_bitset filteri) {
420        return generic_box(gc, AW::Rectangle(center-radius, center+radius), filteri);
421    }
422    bool generic_polygon(int gc, int npos, const AW::Position *pos, AW_bitset filteri);
423    bool generic_invisible(const AW::Position& pos, AW_bitset filteri);
424
425public:
426    // * third level functions (never virtual/overloaded by derived classes)
427
428    bool line(int gc, const AW::LineVector& Line, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
429        return line_impl(gc, Line, filteri);
430    }
431    bool line(int gc, const AW::Position& pos1, const AW::Position& pos2, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
432        return line_impl(gc, AW::LineVector(pos1, pos2), filteri);
433    }
434    bool line(int gc, AW_pos x0, AW_pos y0, AW_pos x1, AW_pos y1, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
435        return line_impl(gc, AW::LineVector(x0, y0, x1, y1), filteri);
436    }
437
438    bool text(int                 gc,
439              const SizedCstr&    cstr,
440              const AW::Position& pos,
441              AW_pos              alignment   = 0.0, // 0.0 alignment left 0.5 centered 1.0 right justified
442              AW_bitset           filteri     = AW_ALL_DEVICES_UNSCALED)
443    {
444        return text_impl(gc, cstr, pos, alignment, filteri);
445    }
446    bool text(int                  gc,
447              const char          *str,
448              const AW::Position&  pos,
449              AW_pos               alignment  = 0.0, // 0.0 alignment left 0.5 centered 1.0 right justified
450              AW_bitset            filteri    = AW_ALL_DEVICES_UNSCALED)
451    {
452        return text_impl(gc, SizedCstr(str), pos, alignment, filteri);
453    }
454
455    bool text(int         gc,
456              const char *str,
457              AW_pos      x,
458              AW_pos      y,
459              AW_pos      alignment  = 0.0, // 0.0 alignment left 0.5 centered 1.0 right justified
460              AW_bitset   filteri    = AW_ALL_DEVICES_UNSCALED)
461    {
462        return text_impl(gc, SizedCstr(str), AW::Position(x, y), alignment, filteri);
463    }
464
465    bool invisible(const AW::Position& pos, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
466        return invisible_impl(pos, filteri);
467    }
468
469    bool box(int gc, AW::FillStyle filled, const AW::Rectangle& rect, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
470        return box_impl(gc, filled, rect, filteri);
471    }
472    bool box(int gc, AW::FillStyle filled, const AW::Position& pos, const AW::Vector& size, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
473        return box_impl(gc, filled, AW::Rectangle(pos, size), filteri);
474    }
475    bool box(int gc, AW::FillStyle filled, AW_pos x0, AW_pos y0, AW_pos width, AW_pos height, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
476        return box_impl(gc, filled, AW::Rectangle(AW::Position(x0, y0), AW::Vector(width, height)), filteri);
477    }
478
479    bool circle(int gc, AW::FillStyle filled, const AW::Position& center, const AW::Vector& radius, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
480        return circle_impl(gc, filled, center, radius, filteri);
481    }
482    bool circle(int gc, AW::FillStyle filled, AW_pos x0, AW_pos y0, AW_pos xradius, AW_pos yradius, AW_bitset filteri = AW_ALL_DEVICES_SCALED)  {
483        return circle_impl(gc, filled, AW::Position(x0, y0), AW::Vector(xradius, yradius), filteri);
484    }
485    bool circle(int gc, AW::FillStyle filled, const AW::Rectangle& rect, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
486        // draw ellipse into Rectangle
487        return circle_impl(gc, filled, rect.centroid(), AW::Vector(rect.width()/2, rect.height()/2), filteri);
488    }
489
490    // draw arcs (Note: passed degrees are non-standard: 90 degrees = downwards)
491    bool arc(int gc, AW::FillStyle filled, AW_pos x0, AW_pos y0, AW_pos xradius, AW_pos yradius, int start_degrees, int arc_degrees, AW_bitset filteri = AW_ALL_DEVICES_SCALED)  {
492        return arc_impl(gc, filled, AW::Position(x0, y0), AW::Vector(xradius, yradius), start_degrees, arc_degrees, filteri);
493    }
494    bool arc(int gc, AW::FillStyle filled, const AW::Position& pos, const AW::Vector& radius, int start_degrees, int arc_degrees, AW_bitset filteri = AW_ALL_DEVICES_SCALED) {
495        return arc_impl(gc, filled, pos, radius, start_degrees, arc_degrees, filteri);
496    }
497
498    bool polygon(int gc, AW::FillStyle filled, int npoints, const AW_pos *points, AW_bitset filteri = AW_ALL_DEVICES_SCALED)  {
499        AW::Position *pos = new AW::Position[npoints];
500        for (int n = 0; n<npoints; ++n) {
501            pos[n].setx(points[n*2]);
502            pos[n].sety(points[n*2+1]);
503        }
504        bool result = polygon_impl(gc, filled, npoints, pos, filteri);
505        delete [] pos;
506        return result;
507    }
508    bool polygon(int gc, AW::FillStyle filled, int npos, const AW::Position *pos, AW_bitset filteri = AW_ALL_DEVICES_SCALED)  {
509        return polygon_impl(gc, filled, npos, pos, filteri);
510    }
511
512    bool text_overlay(int gc, const SizedCstr& cstr, const AW::Position& pos, AW_pos alignment, AW_bitset filteri, TextOverlayCallback toc, AW_CL cduser = 0);
513
514    // ********* X11 Device only ********
515    virtual void clear(AW_bitset filteri);
516    virtual void clear_part(const AW::Rectangle& rect, AW_bitset filteri);
517
518    void clear_part(AW_pos x, AW_pos y, AW_pos width, AW_pos height, AW_bitset filteri) {
519        clear_part(AW::Rectangle(AW::Position(x, y), AW::Vector(width, height)), filteri);
520    }
521
522    virtual void move_region(AW_pos src_x, AW_pos src_y, AW_pos width, AW_pos height, AW_pos dest_x, AW_pos dest_y);
523    virtual void fast();                                         // e.g. zoom linewidth off
524    virtual void slow();
525    virtual void flush();                                        // empty X11 buffers
526};
527MARK_NONFINAL_METHOD(AW_device,void,move_region,(AW_pos,AW_pos,AW_pos,AW_pos,AW_pos,AW_pos));
528MARK_NONFINAL_METHOD(AW_device,void,clear,(AW_bitset));
529MARK_NONFINAL_METHOD(AW_device,void,clear_part,(const AW::Rectangle&,AW_bitset));
530MARK_NONFINAL_METHOD(AW_device,void,flush,());
531
532inline void AW_click_cd::link() {
533    previous            = my_device->click_cd;
534    my_device->click_cd = this;
535}
536inline AW_click_cd::~AW_click_cd() { my_device->click_cd = previous; }
537inline void AW_click_cd::disable() { my_device->click_cd = NULp; }
538inline void AW_click_cd::enable() { my_device->click_cd = this; }
539
540class AW_device_print FINAL_TYPE : public AW_device { // derived from a Noncopyable
541    FILE          *xfig;
542    class SPOOLER *spooler;
543    bool           color_mode;
544
545    bool line_impl(int gc, const AW::LineVector& Line, AW_bitset filteri) OVERRIDE;
546    bool text_impl(int gc, const SizedCstr& cstr, const AW::Position& pos, AW_pos alignment, AW_bitset filteri) OVERRIDE;
547    bool box_impl(int gc, AW::FillStyle filled, const AW::Rectangle& rect, AW_bitset filteri) OVERRIDE;
548    bool circle_impl(int gc, AW::FillStyle filled, const AW::Position& center, const AW::Vector& radius, AW_bitset filteri) OVERRIDE;
549    bool arc_impl(int gc, AW::FillStyle filled, const AW::Position& center, const AW::Vector& radius, int start_degrees, int arc_degrees, AW_bitset filteri) OVERRIDE;
550    bool polygon_impl(int gc, AW::FillStyle filled, int npos, const AW::Position *pos, AW_bitset filteri) OVERRIDE;
551    bool invisible_impl(const AW::Position& pos, AW_bitset filteri) OVERRIDE;
552
553    void specific_reset() {}
554
555    int find_color_idx(AW_rgb color);
556
557    friend class SPOOLER;
558
559public:
560    AW_device_print(AW_common *common_) :
561        AW_device(common_),
562        xfig(NULp),
563        spooler(NULp),
564        color_mode(false)
565    {}
566
567    GB_ERROR open(const char *path) __ATTR__USERESULT;
568    void close();
569
570    void set_color_mode(bool mode) { color_mode = mode; }
571
572    // AW_device interface:
573    AW_DEVICE_TYPE type();
574
575    // internal (do not use):
576    void draw_text(int gc, const char *textBuffer, size_t textStart, size_t textLen, const AW::Position& pos);
577};
578
579class AW_simple_device : public AW_device {
580    bool box_impl(int gc, AW::FillStyle /*filled*/, const AW::Rectangle& rect, AW_bitset filteri) OVERRIDE {
581        return generic_box(gc, rect, filteri);
582    }
583    bool polygon_impl(int gc, AW::FillStyle /*filled*/, int npos, const AW::Position *pos, AW_bitset filteri) OVERRIDE {
584        return generic_polygon(gc, npos, pos, filteri);
585    }
586    bool circle_impl(int gc, AW::FillStyle /*filled*/, const AW::Position& center, const AW::Vector& radius, AW_bitset filteri) OVERRIDE {
587        return generic_circle(gc, center, radius, filteri);
588    }
589    bool arc_impl(int gc, AW::FillStyle /*filled*/, const AW::Position& center, const AW::Vector& radius, int /*start_degrees*/, int /*arc_degrees*/, AW_bitset filteri) OVERRIDE {
590        return generic_circle(gc, center, radius, filteri);
591    }
592public:
593    AW_simple_device(AW_common *common_) : AW_device(common_) {}
594};
595
596class AW_size_tracker {
597    bool     drawn;
598    AW_world size;
599
600    void extend(AW_pos& low, AW_pos val, AW_pos& high) {
601        low = std::min(low, val);
602        high = std::max(high, val);
603    }
604public:
605    AW_size_tracker() { restart(); }
606
607    void restart() { drawn = false; size.clear(); }
608    void track(const AW::Position& pos) {
609        if (drawn) {
610            extend(size.l, pos.xpos(), size.r);
611            extend(size.t, pos.ypos(), size.b);
612        }
613        else {
614            size.l = size.r = pos.xpos();
615            size.t = size.b = pos.ypos();
616            drawn  = true;
617        }
618    }
619
620    bool was_drawn() const { return drawn; }
621    const AW_world& get_size() const { return size; }
622    AW::Rectangle get_size_as_Rectangle() const {
623        return AW::Rectangle(AW::Position(size.l, size.t), AW::Position(size.r, size.b));
624    }
625};
626
627class AW_device_size : public AW_simple_device {
628    AW_size_tracker scaled;   // all zoomable parts (e.g. tree skeleton)
629    AW_size_tracker unscaled; // all unzoomable parts (e.g. text at tree-tips or group-brackets)
630
631    void dot_transformed(const AW::Position& pos, AW_bitset filteri);
632    void dot_transformed(AW_pos X, AW_pos Y, AW_bitset filteri) { dot_transformed(AW::Position(X, Y), filteri); }
633
634    void dot(const AW::Position& p, AW_bitset filteri) { dot_transformed(transform(p), filteri); }
635    void dot(AW_pos x, AW_pos y, AW_bitset filteri) { dot(AW::Position(x, y), filteri); }
636
637    bool line_impl(int gc, const AW::LineVector& Line, AW_bitset filteri) OVERRIDE;
638    bool text_impl(int gc, const SizedCstr& cstr, const AW::Position& pos, AW_pos alignment, AW_bitset filteri) OVERRIDE;
639    bool invisible_impl(const AW::Position& pos, AW_bitset filteri) OVERRIDE;
640
641    void specific_reset();
642
643public:
644    AW_device_size(AW_common *common_) : AW_simple_device(common_) {}
645
646    void restart_tracking();
647
648    AW_DEVICE_TYPE type();
649
650    // all get_size_information...() return screen coordinates
651
652    void get_size_information(AW_world *ptr) const __ATTR__DEPRECATED_TODO("whole AW_world is deprecated") {
653        *ptr = scaled.get_size();
654    }
655    AW::Rectangle get_size_information() const { return scaled.get_size_as_Rectangle(); }
656    AW::Rectangle get_size_information_unscaled() const { return unscaled.get_size_as_Rectangle(); }
657    AW::Rectangle get_size_information_inclusive_text() const {
658        return get_size_information().bounding_box(get_size_information_unscaled());
659    }
660
661    AW_borders get_unscaleable_overlap() const;
662};
663
664#else
665#error aw_device.hxx included twice
666#endif
Note: See TracBrowser for help on using the repository browser.