source: tags/arb_5.3/WINDOW/aw_device.hxx

Last change on this file was 5901, checked in by westram, 15 years ago
  • AW_BOOL → bool
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1#ifndef AW_DEVICE_HXX
2#define AW_DEVICE_HXX
3
4#ifndef AW_ROOT_HXX
5#include <aw_root.hxx>
6#endif
7#ifndef AW_POSITION_HXX
8#include <aw_position.hxx>
9#endif
10
11#if defined(DEBUG) && defined(DEBUG_GRAPHICS)
12// if you want flush() to be called after every motif command :
13#define AUTO_FLUSH(device) (device)->flush()
14#else
15#define AUTO_FLUSH(device)
16#endif
17
18// #define AW_PIXELS_PER_MM 1.0001 // stupid and wrong
19
20const AW_bitset AW_ALL_DEVICES = (AW_bitset)-1; 
21const AW_bitset AW_SCREEN      = 1;
22const AW_bitset AW_CLICK       = 2;
23const AW_bitset AW_CLICK_DRAG  = 4;
24const AW_bitset AW_SIZE        = 8;
25const AW_bitset AW_PRINTER     = 16; // print/xfig-export
26const AW_bitset AW_PRINTER_EXT = 32; // (+Handles) use combined with AW_PRINTER only
27
28typedef enum {
29    AW_DEVICE_SCREEN  = 1,
30    AW_DEVICE_CLICK   = 2,
31    AW_DEVICE_SIZE    = 8,
32    AW_DEVICE_PRINTER = 16
33} AW_DEVICE_TYPE;
34
35typedef enum {
36    AW_INFO_AREA,
37    AW_MIDDLE_AREA,
38    AW_BOTTOM_AREA,
39    AW_MAX_AREA
40} AW_area;
41
42enum {
43    AW_FIXED             = -1,
44    AW_TIMES             = 0,
45    AW_TIMES_ITALIC      = 1,
46    AW_TIMES_BOLD        = 2,
47    AW_TIMES_BOLD_ITALIC = 3,
48
49    AW_COURIER              = 12,
50    AW_COURIER_OBLIQUE      = 13,
51    AW_COURIER_BOLD         = 14,
52    AW_COURIER_BOLD_OBLIQUE = 15,
53
54    AW_HELVETICA                     = 16,
55    AW_HELVETICA_OBLIQUE             = 17,
56    AW_HELVETICA_BOLD                = 18,
57    AW_HELVETICA_BOLD_OBLIQUE        = 19,
58    AW_HELVETICA_NARROW              = 20,
59    AW_HELVETICA_NARROW_OBLIQUE      = 21,
60    AW_HELVETICA_NARROW_BOLD         = 22,
61    AW_HELVETICA_NARROW_BOLD_OBLIQUE = 23,
62
63    AW_LUCIDA_SANS                 = 35,
64    AW_LUCIDA_SANS_OBLIQUE         = 36,
65    AW_LUCIDA_SANS_BOLD            = 37,
66    AW_LUCIDA_SANS_BOLD_OBLIQUE    = 38,
67    AW_LUCIDA_SANS_TYPEWRITER      = 39,
68    AW_LUCIDA_SANS_TYPEWRITER_BOLD = 40,
69    AW_SCREEN_MEDIUM               = 41,
70    AW_SCREEN_BOLD                 = 42,
71    AW_CLEAN_MEDIUM                = 43,
72    AW_CLEAN_BOLD                  = 44,
73    AW_TERMINAL_MEDIUM             = 45,
74    AW_TERMINAL_BOLD               = 46,
75
76    AW_NUM_FONTS = 47,
77
78    AW_DEFAULT_NORMAL_FONT = AW_LUCIDA_SANS,
79    AW_DEFAULT_BOLD_FONT   = AW_LUCIDA_SANS_BOLD,
80    AW_DEFAULT_FIXED_FONT  = AW_LUCIDA_SANS_TYPEWRITER,
81
82};      // AW_font
83
84typedef enum {
85    AW_WINDOW_BG,
86    AW_WINDOW_FG,
87    AW_WINDOW_C1,
88    AW_WINDOW_C2,
89    AW_WINDOW_C3,
90    AW_WINDOW_DRAG,
91    AW_DATA_BG,
92    AW_COLOR_MAX
93} AW_color;
94
95typedef enum {
96    AW_cursor_insert,
97    AW_cursor_overwrite
98} AW_cursor_type;
99
100
101// @@@ FIXME: elements of the following classes should go private!
102
103class AW_clicked_element {
104public:
105    AW_CL client_data1;
106    AW_CL client_data2;
107    bool  exists;                                   // true if a drawn element was clicked, else false
108};
109
110class AW_clicked_line : public AW_clicked_element {
111public:
112    AW_pos  x0,y0,x1,y1;
113    AW_pos  height;
114    AW_pos  length;
115
116    double distanceTo(const AW::Position& click);
117};
118
119class AW_clicked_text : public AW_clicked_element {
120public:
121    AW::Rectangle textArea;     // world coordinates of text
122    AW_pos        alignment;
123    AW_pos        rotation;
124    AW_pos        distance;     // y-Distance to text, <0 -> above, >0 -> below
125    AW_pos        dist2center;  // Distance to center of text
126    int           cursor;       // which letter was selected, from 0 to strlen-1
127    bool          exactHit;     // true -> real click on text (not only near text)
128};
129
130bool AW_getBestClick(const AW::Position& click, AW_clicked_line *cl, AW_clicked_text *ct, AW_CL *cd1, AW_CL *cd2);
131
132class AW_matrix {
133    AW::Vector offset;
134    AW_pos     scale;
135    AW_pos     unscale;         // = 1.0/scale
136
137public:
138    AW_matrix(void) { this->reset();};
139    virtual ~AW_matrix() {}
140
141    void zoom(AW_pos scale);
142
143    AW_pos get_scale() { return scale; };
144    AW_pos get_unscale() { return unscale; };
145    AW::Vector get_offset() const { return offset; }
146
147    void rotate(AW_pos angle);
148
149public:
150    void set_offset(const AW::Vector& off) { offset = off*scale; }
151    void shift(const AW::Vector& doff) { offset += doff*scale; }
152
153    void reset(void);
154
155    double transform_size(const double& size) const { return size*scale; }
156    double rtransform_size(const double& size) const { return size*unscale; }
157
158    // transforming a Vector only scales the vector (a Vector has no position!)
159    AW::Vector transform (const AW::Vector& vec) const { return vec*scale; }
160    AW::Vector rtransform(const AW::Vector& vec) const { return vec*unscale; }
161
162    // transform a Position
163    AW::Position transform (const AW::Position& pos) const { return transform(AW::Vector(pos+offset)).endpoint(); }
164    AW::Position rtransform(const AW::Position& pos) const { return rtransform(AW::Vector(pos)).endpoint()-offset; }
165#if defined(DEVEL_RALF) && 0
166#warning fix transformations
167    // @@@ I think this calculation is wrong, cause offset is already scaled
168    //     (same applies to old-style transform/rtransform below)
169#endif // DEVEL_RALF
170
171    AW::LineVector transform (const AW::LineVector& lvec) const { return AW::LineVector(transform(lvec.start()), transform(lvec.line_vector())); }
172    AW::LineVector rtransform(const AW::LineVector& lvec) const { return AW::LineVector(rtransform(lvec.start()), rtransform(lvec.line_vector())); }
173
174    // old style functions, not preferred:
175    void transform(int x,int y,int& xout,int& yout) const {
176        xout = int((x+offset.x())*scale);
177        yout = int((y+offset.y())*scale);
178    }
179    void transform(AW_pos x,AW_pos y,AW_pos& xout,AW_pos& yout) const {
180        xout = (x+offset.x())*scale;
181        yout = (y+offset.y())*scale;
182    }
183
184    void rtransform(int x,int y,int& xout,int& yout) const {
185        xout = int(x*unscale - offset.x());
186        yout = int(y*unscale - offset.y());
187    }
188    void rtransform(AW_pos x,AW_pos y,AW_pos& xout,AW_pos& yout) const {
189        xout = x*unscale - offset.x();
190        yout = y*unscale - offset.y();
191    }
192};
193
194class AW_common;
195
196class AW_clip {
197    friend class AW_device;
198protected:
199    int compoutcode(AW_pos xx, AW_pos yy) {
200        /* calculate outcode for clipping the current line */
201        /* order - top,bottom,right,left */
202        int code = 0;
203        if (clip_rect.b - yy < 0)       code = 4;
204        else if (yy - clip_rect.t < 0)  code = 8;
205        if (clip_rect.r - xx < 0)       code |= 2;
206        else if (xx - clip_rect.l < 0)  code |= 1;
207        return(code);
208    };
209public:
210    class AW_common *common;
211
212    // ****** read only section
213    AW_rectangle clip_rect;     //holds the clipping rectangle coordinates
214    int top_font_overlap;
215    int bottom_font_overlap;
216    int left_font_overlap;
217    int right_font_overlap;
218
219    // ****** real public
220    int 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);
221    int 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);
222
223    void set_top_clip_border(int top, bool allow_oversize = false);
224    void set_bottom_clip_border(int bottom, bool allow_oversize = false); // absolut
225    void set_bottom_clip_margin(int bottom, bool allow_oversize = false); // relativ
226    void set_left_clip_border(int left, bool allow_oversize = false);
227    void set_right_clip_border(int right, bool allow_oversize = false);
228    void set_cliprect(AW_rectangle *rect, bool allow_oversize = false);
229    void set_clipall() {
230        AW_rectangle rect;
231        rect.t = rect.b = rect.l = rect.r = 0;
232        set_cliprect(&rect);     // clip all -> nothing drawn afterwards
233    }
234
235
236    void set_top_font_overlap(int val=1);
237    void set_bottom_font_overlap(int val=1);
238    void set_left_font_overlap(int val=1);
239    void set_right_font_overlap(int val=1);
240
241    // like set_xxx_clip_border but make window only smaller:
242
243    void reduce_top_clip_border(int top);
244    void reduce_bottom_clip_border(int bottom);
245    void reduce_left_clip_border(int left);
246    void reduce_right_clip_border(int right);
247
248    int reduceClipBorders(int top, int bottom, int left, int right);
249
250    AW_clip();
251    virtual ~AW_clip() {}
252};
253
254struct AW_font_limits {
255    short ascent;
256    short descent;
257    short height;
258    short width;
259
260    void reset() { ascent = descent = height = width = 0; }
261
262    void notify_ascent (int a_ascent ){ if(a_ascent >ascent ) ascent  = a_ascent;  }
263    void notify_descent(int a_descent){ if(a_descent>descent) descent = a_descent; }
264    void notify_width  (int a_width  ){ if(a_width  >width  ) width   = a_width;   }
265
266    void notify_all(int a_ascent, int a_descent, int a_width) {
267        notify_ascent (a_ascent);
268        notify_descent(a_descent);
269        notify_width  (a_width);
270    }
271
272    void calc_height() { height = ascent+descent+1; }
273
274    static int max(int i1, int i2) { return i1<i2 ? i2 : i1; }
275
276    AW_font_limits() { reset(); }
277    AW_font_limits(const AW_font_limits& lim1, const AW_font_limits& lim2)
278        : ascent(max(lim1.ascent, lim2.ascent))
279        , descent(max(lim1.descent, lim2.descent))
280        , width(max(lim1.width, lim2.width))
281    {
282        calc_height();
283    }
284};
285
286#define AW_FONTINFO_CHAR_MIN       32
287#define AW_FONTINFO_CHAR_MAX       255
288
289#define AW_FONTINFO_CHAR_ASCII_MIN 32
290#define AW_FONTINFO_CHAR_ASCII_MAX 127
291
292class AW_font_information {
293public:
294    // maximas of ..
295    AW_font_limits this_letter; // letter specified in call to get_font_information()
296    AW_font_limits max_letter;  // max of all ASCII characters (AW_FONTINFO_CHAR_ASCII_MIN..AW_FONTINFO_CHAR_ASCII_MAX)
297    AW_font_limits max_all_letter; // max of all characters (AW_FONTINFO_CHAR_MIN..AW_FONTINFO_CHAR_MAX)
298};
299
300
301/***************************************************************************************************
302 ***********                     Graphic Context (Linestyle, width ...                   ************
303 ***************************************************************************************************/
304typedef enum {
305    AW_SOLID,
306    AW_DOTTED
307} AW_linestyle;
308
309
310typedef enum {
311    AW_COPY,
312    AW_XOR
313} AW_function;
314
315class AW_gc: public AW_clip {
316public:
317    void new_gc(int gc);
318    int  new_gc(void);
319    void set_fill(int gc,AW_grey_level grey_level); // <0 dont fill  0.0 white 1.0 black
320    void set_font(int gc,AW_font fontnr, int size, int *found_size); 
321    void set_line_attributes(int gc,AW_pos width,AW_linestyle style);
322    void set_function(int gc,AW_function function);
323    void set_foreground_color(int gc,AW_color color); // lines ....
324    void set_background_color(int gc,AW_color color); // for box
325    int  get_string_size(int gc,const  char *string,long textlen); // get the size of the string
326
327    const AW_font_information *get_font_information(int gc, unsigned char c);
328   
329    int get_available_fontsizes(int gc, AW_font font_nr, int *available_sizes);
330   
331    AW_gc();
332    virtual ~AW_gc() {};
333};
334
335/***************************************************************************************************
336 ***********                     The abstract class AW_device ...                        ************
337 ***************************************************************************************************/
338
339class AW_clip_scale_stack;
340
341class AW_device: public AW_matrix, public AW_gc
342{
343    AW_device(const AW_device& other);
344    AW_device& operator=(const AW_device& other);
345   
346protected:
347    AW_clip_scale_stack *clip_scale_stack;
348    virtual         void  privat_reset(void);
349
350public:
351    AW_device(AW_common *common); // get the device from  AW_window
352    virtual ~AW_device() {}
353    // by device = get_device(area);
354    /***************** The Read Only  Section ******************/
355    AW_bitset filter;
356    /***************** The real Public Section ******************/
357
358    void reset(void);
359
360    void          get_area_size(AW_rectangle *rect); //read the frame size
361    void          get_area_size(AW_world *rect); //read the frame size
362    AW::Rectangle get_area_size();
363
364    void set_filter( AW_bitset filteri ); //set the main filter mask
365
366    void push_clip_scale(void); // push clipping area and scale
367    void pop_clip_scale(void); // pop them
368
369    virtual AW_DEVICE_TYPE type(void) =0;
370
371    // * functions below return 1 if any pixel is drawn, 0 otherwise
372    // * primary functions (always virtual)
373
374    virtual bool ready_to_draw(int gc);
375
376    virtual int line(int gc, AW_pos x0,AW_pos y0, AW_pos x1,AW_pos y1,
377                     AW_bitset filteri = (AW_bitset)-1, AW_CL cd1 = 0, AW_CL cd2 = 0) = 0; // used by click device
378
379    virtual int text(int gc, const char *string,AW_pos x,AW_pos y,
380                     AW_pos alignment  = 0.0, // 0.0 alignment left 0.5 centered 1.0 right justified
381                     AW_bitset filteri    = (AW_bitset)-1, AW_CL cd1 = 0, AW_CL cd2 = 0, // used by click device
382                     long opt_strlen = 0) = 0;
383
384    // * second level functions (maybe non virtual)
385
386    virtual bool invisible(int gc, AW_pos x, AW_pos y, AW_bitset filteri, AW_CL cd1, AW_CL cd2); // returns true if x/y is outside viewport (or if it would now be drawn undrawn)
387    virtual int cursor(int gc, AW_pos x0,AW_pos y0, AW_cursor_type type, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
388
389    virtual int zoomtext(int gc, const char *string, AW_pos x,AW_pos y, AW_pos height, AW_pos alignment,AW_pos rotation,AW_bitset filteri,AW_CL cd1,AW_CL cd2);
390    virtual int zoomtext1(int gc, const char *string, AW_pos x,AW_pos y, AW_pos scale, AW_pos alignment,AW_pos rotation, AW_bitset filteri,AW_CL cd1,AW_CL cd2);
391    virtual int zoomtext4line(int gc, const char *string, AW_pos height, AW_pos lx0, AW_pos ly0, AW_pos lx1, AW_pos ly1, AW_pos alignmentx, AW_pos alignmenty, AW_bitset filteri,AW_CL cd1,AW_CL cd2);
392
393protected:
394    int generic_box(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
395    int generic_circle(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
396    int generic_arc(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, int start_degrees, int arc_degrees, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
397    int generic_filled_area(int gc, int npoints, AW_pos *points, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
398
399public:
400    virtual int box(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, AW_bitset filteri, AW_CL cd1, AW_CL cd2)                                     = 0;
401    virtual int circle(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, AW_bitset filteri, AW_CL cd1, AW_CL cd2)                                  = 0;
402    virtual int arc(int gc, bool filled, AW_pos x0,AW_pos y0,AW_pos width,AW_pos heigth, int start_degrees, int arc_degrees, AW_bitset filteri, AW_CL cd1, AW_CL cd2) = 0;
403    virtual int filled_area(int gc, int npoints, AW_pos *points, AW_bitset filteri, AW_CL cd1, AW_CL cd2)                                                                = 0;
404
405    // * third level functions (never virtual)
406
407    // convenience functions
408   
409    int line(int gc, const AW::Position& pos1, const AW::Position& pos2, AW_bitset filteri = (AW_bitset)-1, AW_CL cd1 = 0, AW_CL cd2 = 0) {
410        return line(gc, pos1.xpos(), pos1.ypos(), pos2.xpos(), pos2.ypos(), filteri, cd1, cd2);
411    }
412    int line(int gc, const AW::LineVector& Line, AW_bitset filteri = (AW_bitset)-1, AW_CL cd1 = 0, AW_CL cd2 = 0) {
413        return line(gc, Line.start(), Line.head(), filteri, cd1, cd2);
414    }
415    int text(int gc, const char *string, const AW::Position& pos,
416             AW_pos alignment  = 0.0, // 0.0 alignment left 0.5 centered 1.0 right justified
417             AW_bitset filteri = (AW_bitset)-1, AW_CL cd1 = 0, AW_CL cd2 = 0,
418             long opt_strlen = 0)
419    {
420        return text(gc, string, pos.xpos(), pos.ypos(), alignment, filteri, cd1, cd2, opt_strlen);
421    }
422    bool invisible(int gc, AW::Position pos, AW_bitset filteri, AW_CL cd1, AW_CL cd2) {
423        return invisible(gc, pos.xpos(), pos.ypos(), filteri, cd1, cd2);
424    }
425    int box(int gc, bool filled, const AW::Position& pos, const AW::Vector& size, AW_bitset filteri, AW_CL cd1, AW_CL cd2) {
426        return box(gc, filled, pos.xpos(), pos.ypos(), size.x(), size.y(), filteri, cd1, cd2);
427    }
428    int box(int gc, bool filled, const AW::Rectangle& rect, AW_bitset filteri, AW_CL cd1, AW_CL cd2) {
429        return box(gc, filled, rect.upper_left_corner(), rect.diagonal(), filteri, cd1, cd2);
430    }
431   
432    int circle(int gc, bool filled, const AW::Position& pos, AW_pos width, AW_pos heigth, AW_bitset filteri, AW_CL cd1, AW_CL cd2) {
433        return circle(gc, filled, pos.xpos(), pos.ypos(), width, heigth, filteri, cd1, cd2);
434    }
435    int circle(int gc, bool filled, const AW::Rectangle& rect, AW_bitset filteri, AW_CL cd1, AW_CL cd2) { // paint a circle/ellipsoid into a rectangle
436        return circle(gc, filled, rect.centroid(), rect.width(), rect.height(), filteri, cd1, cd2);
437    }
438   
439    int arc(int gc, bool filled, const AW::Position& pos, AW_pos width, AW_pos heigth, int start_degrees, int arc_degrees, AW_bitset filteri, AW_CL cd1, AW_CL cd2) {
440        return arc(gc, filled, pos.xpos(), pos.ypos(), width, heigth, start_degrees, arc_degrees, filteri, cd1, cd2);
441    }
442
443    // reduces any string (or virtual string) to its actual drawn size and calls the function f with the result
444    int     text_overlay( int gc, const char *opt_string, long opt_strlen,  // either string or strlen != 0
445                          AW_pos x,AW_pos y, AW_pos alignment, AW_bitset filteri, AW_CL cduser, AW_CL cd1, AW_CL cd2,
446                          AW_pos opt_ascent,AW_pos opt_descent,   // optional height (if == 0 take font height)
447                          int (*f)(AW_device *device, int gc, const char *opt_string, size_t opt_string_len, size_t start, size_t size,
448                                   AW_pos x,AW_pos y, AW_pos opt_ascent,AW_pos opt_descent,
449                                   AW_CL cduser, AW_CL cd1, AW_CL cd2));
450
451
452    // ********* X11 Device only ********
453    virtual void    clear(AW_bitset filteri);
454    virtual void    clear_part(AW_pos x, AW_pos y, AW_pos width, AW_pos height, AW_bitset filteri);
455
456    void clear_part(const AW::Rectangle&rect, AW_bitset filteri) { clear_part(rect.xpos(), rect.ypos(), rect.width(), rect.height(), filteri); }
457
458    virtual void    clear_text(int gc, const char *string, AW_pos x, AW_pos y, AW_pos alignment, AW_bitset filteri, AW_CL cd1, AW_CL cd2);
459    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 );
460    virtual void    fast(void);                                     // e.g. zoom linewidth off
461    virtual void    slow(void);
462    virtual void    flush(void);                                    // empty X11 buffers
463    // ********* click device only ********
464    virtual void    get_clicked_line(AW_clicked_line *ptr);
465    virtual void    get_clicked_text(AW_clicked_text *ptr);
466    // ********* size device only ********
467    virtual void    get_size_information(AW_world *ptr);
468    // ********* print device only (xfig compatible) ********
469    virtual const char *open(const char *path);
470    virtual void    close(void);
471    virtual void    set_color_mode(bool mode);
472};
473
474#else
475#error aw_device.hxx included twice
476#endif
Note: See TracBrowser for help on using the repository browser.