source: branches/alilink/WINDOW/aw_common.hxx

Last change on this file was 17080, checked in by westram, 7 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1// =========================================================== //
2//                                                             //
3//   File      : aw_common.hxx                                 //
4//   Purpose   :                                               //
5//                                                             //
6//   Coded by Ralf Westram (coder@reallysoft.de) in May 2011   //
7//   Institute of Microbiology (Technical University Munich)   //
8//   http://www.arb-home.de/                                   //
9//                                                             //
10// =========================================================== //
11
12#ifndef AW_COMMON_HXX
13#define AW_COMMON_HXX
14
15#ifndef AW_DEVICE_HXX
16#include "aw_device.hxx"
17#endif
18#ifndef DOWNCAST_H
19#include <downcast.h>
20#endif
21#ifndef ARB_DEFS_H
22#include <arb_defs.h>
23#endif
24
25
26#define AW_FONTINFO_CHAR_ASCII_MIN 32
27#define AW_FONTINFO_CHAR_ASCII_MAX 127
28
29#define GC_DEFAULT_LINE_WIDTH 1
30
31class AW_common;
32
33class AW_GC_config { // variable part of AW_GC
34protected:
35    AW_function   function;
36    AW_grey_level grey_level;
37    short         line_width;
38    AW_linestyle  style;
39
40public:
41    AW_GC_config()
42        : function(AW_COPY),
43          grey_level(0),
44          line_width(GC_DEFAULT_LINE_WIDTH),
45          style(AW_SOLID)
46    {}
47
48    AW_function get_function() const { return function; }
49
50    // fill style
51    AW_grey_level get_grey_level() const { return grey_level; }
52    void set_grey_level(AW_grey_level grey_level_) {
53        // <0 = don't fill, 0.0 = white, 1.0 = black
54        grey_level = grey_level_;
55    }
56
57    // lines
58    short get_line_width() const { return line_width; }
59    AW_linestyle get_line_style() const { return style; }
60
61    bool operator == (const AW_GC_config& other) const {
62        return
63            function == other.function &&
64            grey_level == other.grey_level &&
65            line_width == other.line_width &&
66            style == other.style;
67    }
68};
69
70class AW_GC : public AW_GC_config, virtual Noncopyable {
71    AW_common    *common;
72    AW_GC_config *default_config; // NULp means "no special default"
73
74    // foreground color
75    AW_rgb color;
76    AW_rgb last_fg_color; // effective color (as modified by 'function')
77
78    // font
79    AW_font_limits         font_limits;
80    mutable AW_font_limits one_letter;
81
82    short width_of_chars[256];
83    short ascent_of_chars[256];
84    short descent_of_chars[256];
85
86    short   fontsize;
87    AW_font fontnr;
88
89    void init_char_widths() {
90        memset(width_of_chars, 0, ARRAY_ELEMS(width_of_chars)*sizeof(*width_of_chars));
91        memset(ascent_of_chars, 0, ARRAY_ELEMS(ascent_of_chars)*sizeof(*ascent_of_chars));
92        memset(descent_of_chars, 0, ARRAY_ELEMS(descent_of_chars)*sizeof(*descent_of_chars));
93    }
94
95    void set_effective_color();
96
97    virtual void wm_set_foreground_color(AW_rgb col)                      = 0;
98    virtual void wm_set_function(AW_function mode)                        = 0;
99    virtual void wm_set_lineattributes(short lwidth, AW_linestyle lstyle) = 0;
100    virtual void wm_set_font(AW_font font_nr, int size, int *found_size)  = 0;
101
102protected:
103
104    void set_char_size(int i, int ascent, int descent, int width) {
105        ascent_of_chars[i]  = ascent;
106        descent_of_chars[i] = descent;
107        width_of_chars[i]   = width;
108        font_limits.notify(ascent, descent, width);
109    }
110    void set_no_char_size(int i) {
111        ascent_of_chars[i]  = 0;
112        descent_of_chars[i] = 0;
113        width_of_chars[i]   = 0;
114    }
115
116public:
117    AW_GC(AW_common *common_)
118        : common(common_),
119          default_config(NULp),
120          color(0),
121          last_fg_color(0),
122          fontsize(-1),
123          fontnr(-1)
124    {
125        init_char_widths();
126    }
127    virtual ~AW_GC() { delete default_config; }
128
129    virtual int get_available_fontsizes(AW_font font_nr, int *available_sizes) const = 0;
130
131    AW_common *get_common() const { return common; }
132
133    const AW_font_limits& get_font_limits() const { return font_limits; }
134    const AW_font_limits& get_font_limits(char c) const {
135        aw_assert(c); // you want to use the version w/o parameter
136        one_letter.ascent    = ascent_of_chars[safeCharIndex(c)];
137        one_letter.descent   = descent_of_chars[safeCharIndex(c)];
138        one_letter.min_width = one_letter.width = width_of_chars[safeCharIndex(c)];
139        return one_letter;
140    }
141
142    short get_width_of_char(char c) const { return width_of_chars[safeCharIndex(c)]; }
143    short get_ascent_of_char(char c) const { return ascent_of_chars[safeCharIndex(c)]; }
144    short get_descent_of_char(char c) const { return descent_of_chars[safeCharIndex(c)]; }
145
146    int get_string_size(long textlen) const;
147    int get_string_size(const SizedCstr& cstr) const;
148
149    // foreground color
150    AW_rgb get_fg_color() const { return color; }
151    AW_rgb get_last_fg_color() const { return last_fg_color; }
152    void set_fg_color(AW_rgb col) { color = col; set_effective_color(); }
153
154    void set_function(AW_function mode) {
155        if (function != mode) {
156            wm_set_function(mode);
157            function = mode;
158            set_effective_color();
159        }
160    }
161
162    // lines
163    void set_line_attributes(short new_width, AW_linestyle new_style) {
164        aw_assert(new_width >= 1);
165        if (new_style != style || new_width != line_width) {
166            line_width = new_width;
167            style      = new_style;
168            wm_set_lineattributes(line_width, style);
169        }
170    }
171
172    // font
173    void set_font(AW_font font_nr, int size, int *found_size);
174    short get_fontsize() const { return fontsize; }
175    AW_font get_fontnr() const { return fontnr; }
176
177    void establish_default() {
178        aw_assert(!default_config); // can't establish twice
179        default_config = new AW_GC_config(*this);
180        aw_assert(!(*default_config == AW_GC_config())); // you are trying to store the general default
181    }
182    void apply_config(const AW_GC_config& conf) {
183        set_line_attributes(conf.get_line_width(), conf.get_line_style());
184        set_grey_level(conf.get_grey_level());
185        set_function(conf.get_function());
186    }
187    void reset() { apply_config(default_config ? *default_config : AW_GC_config()); }
188};
189
190class AW_GC_set : virtual Noncopyable {
191    int     count;
192    AW_GC **gcs;
193
194public:
195    AW_GC_set() : count(0), gcs(NULp) {}
196    ~AW_GC_set() {
197        for (int i = 0; i<count; ++i) delete gcs[i];
198        free(gcs);
199    }
200    void reset_style() {
201        for (int i = 0; i<count; ++i) {
202            if (gcs[i]) gcs[i]->reset();
203        }
204    }
205    bool gc_mapable(int gc) const { return gc<count && gcs[gc]; }
206    const AW_GC *map_gc(int gc) const { aw_assert(gc_mapable(gc)); return gcs[gc]; }
207    AW_GC *map_mod_gc(int gc) { aw_assert(gc_mapable(gc)); return gcs[gc]; }
208
209    void add_gc(int gi, AW_GC *agc);
210};
211
212
213class AW_common {
214    AW_rgb*& frame_colors;
215    AW_rgb*& data_colors;
216    long&    data_colors_size;
217
218    AW_GC_set gcset;
219
220    AW_screen_area screen;
221
222    virtual AW_GC *create_gc() = 0;
223
224public:
225    AW_common(AW_rgb*& fcolors,
226              AW_rgb*& dcolors,
227              long&    dcolors_count)
228        : frame_colors(fcolors),
229          data_colors(dcolors),
230          data_colors_size(dcolors_count)
231    {
232        screen.t = 0;
233        screen.b = -1;
234        screen.l = 0;
235        screen.r = -1;
236    }
237    virtual ~AW_common() {}
238
239    void reset_style() { gcset.reset_style(); }
240
241    const AW_screen_area& get_screen() const { return screen; }
242    void set_screen_size(unsigned int width, unsigned int height) {
243        screen.t = 0;               // set clipping coordinates
244        screen.b = height;
245        screen.l = 0;
246        screen.r = width;
247    }
248    void set_screen(const AW_screen_area& screen_) {
249        // set clipping coordinates
250        screen = screen_;
251        aw_assert(screen.t == 0 && screen.l == 0);
252    }
253
254    AW_rgb get_color(AW_color_idx color) const {
255        return color>=AW_DATA_BG ? data_colors[color] : frame_colors[color];
256    }
257    AW_rgb get_data_color(int i) const { return data_colors[i]; }
258    int find_data_color_idx(AW_rgb color) const;
259    int get_data_color_size() const { return data_colors_size; }
260
261    AW_rgb get_XOR_color() const {
262        return data_colors ? data_colors[AW_DATA_BG] : frame_colors[AW_WINDOW_BG];
263    }
264
265    void new_gc(int gc) { gcset.add_gc(gc, create_gc()); }
266    bool gc_mapable(int gc) const { return gcset.gc_mapable(gc); }
267    const AW_GC *map_gc(int gc) const { return gcset.map_gc(gc); }
268    AW_GC *map_mod_gc(int gc) { return gcset.map_mod_gc(gc); }
269
270    const AW_font_limits& get_font_limits(int gc, char c) const {
271        // for one characters (c == 0 -> for all characters)
272        return c
273            ? map_gc(gc)->get_font_limits(c)
274            : map_gc(gc)->get_font_limits();
275    }
276};
277
278inline void AW_GC::set_effective_color() {
279    AW_rgb col = color^(function == AW_XOR ? common->get_XOR_color(): AW_rgb(0));
280    if (col != last_fg_color) {
281        last_fg_color = col;
282        wm_set_foreground_color(col);
283    }
284}
285
286#else
287#error aw_common.hxx included twice
288#endif // AW_COMMON_HXX
289
Note: See TracBrowser for help on using the repository browser.