~ubuntu-branches/debian/jessie/arb/jessie

« back to all changes in this revision

Viewing changes to WINDOW/AW_device.cxx

  • Committer: Package Import Robot
  • Author(s): Elmar Pruesse, Andreas Tille, Elmar Pruesse
  • Date: 2014-09-02 15:15:06 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140902151506-jihq58b3iz342wif
Tags: 6.0.2-1
[ Andreas Tille ]
* New upstream version
  Closes: #741890
* debian/upstream -> debian/upstream/metadata
* debian/control:
   - Build-Depends: added libglib2.0-dev
   - Depends: added mafft, mrbayes
* debian/rules
   - Add explicite --remove-section=.comment option to manual strip call
* cme fix dpkg-control
* arb-common.dirs: Do not create unneeded lintian dir
* Add turkish debconf translation (thanks for the patch to Mert Dirik
  <mertdirik@gmail.com>)
  Closes: #757497

[ Elmar Pruesse ]
* patches removed:
   - 10_config.makefiles.patch,
     80_no_GL.patch
       removed in favor of creating file from config.makefile.template via 
       sed in debian/control
   - 20_Makefile_main.patch
       merged upstream
   - 21_Makefiles.patch
       no longer needed
   - 30_tmpfile_CVE-2008-5378.patch: 
       merged upstream
   - 50_fix_gcc-4.8.patch:
       merged upstream
   - 40_add_libGLU.patch:
       libGLU not needed for arb_ntree)
   - 60_use_debian_packaged_raxml.patch:
       merged upstream
   - 70_hardening.patch
       merged upstream
   - 72_add_math_lib_to_linker.patch
       does not appear to be needed
* patches added:
   - 10_upstream_r12793__show_db_load_progress:
       backported patch showing progress while ARB is loading a database
       (needed as indicator/splash screen while ARB is launching)
   - 20_upstream_r12794__socket_permissions:
       backported security fix
   - 30_upstream_r12814__desktop_keywords:
       backported add keywords to desktop (fixes lintian warning)
   - 40_upstream_r12815__lintian_spelling:
       backported fix for lintian reported spelling errors
   - 50_private_nameservers
       change configuration to put nameservers into users home dirs
       (avoids need for shared writeable directory)
   - 60_use_debian_phyml
       use phyml from debian package for both interfaces in ARB
* debian/rules:
   - create config.makefile from override_dh_configure target
   - use "make tarfile" in override_dh_install
   - remove extra cleaning not needed for ARB 6
   - use "dh_install --list-missing" to avoid missing files
   - added override_dh_fixperms target
* debian/control:
   - added libarb-dev package
   - Depends: added phyml, xdg-utils
   - Suggests: removed phyml
   - fix lintian duplicate-short-description (new descriptions)
* debian/*.install:
   - "unrolled" confusing globbing to select files
   - pick files from debian/tmp
   - moved all config files to /etc/arb
* debian/arb-common.templates: updated
* scripts:
   - removed arb-add-pt-server
   - launch-wrapper: 
     - only add demo.arb to newly created $ARBUSERDATA
     - pass commandline arguments through bin/arb wrapper
   - preinst: removing old PT server index files on upgrade from 5.5*
   - postinst: set setgid on shared PT dir
* rewrote arb.1 manfile
* added file icon for ARB databases
* using upstream arb_tcp.dat

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdio.h>
2
 
#include <stdlib.h>
3
 
#include <string.h>
4
 
#include <X11/X.h>
5
 
#include <X11/Xlib.h>
 
1
// =============================================================== //
 
2
//                                                                 //
 
3
//   File      : AW_device.cxx                                     //
 
4
//   Purpose   :                                                   //
 
5
//                                                                 //
 
6
//   Institute of Microbiology (Technical University Munich)       //
 
7
//   http://www.arb-home.de/                                       //
 
8
//                                                                 //
 
9
// =============================================================== //
6
10
 
 
11
#include "aw_window.hxx"
7
12
#include "aw_root.hxx"
8
 
#include "aw_device.hxx"
9
 
#include "aw_window.hxx"
10
 
#include "aw_commn.hxx"
11
 
 
12
 
#include <inline.h>
13
 
 
14
 
void AW_clip::set_cliprect(AW_rectangle *rect, bool allow_oversize) {
15
 
    clip_rect = *rect;  // coordintes : (0,0) = top-left-corner
16
 
    if (!allow_oversize){
17
 
        if (clip_rect.t < common->screen.t) clip_rect.t = common->screen.t;
18
 
        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
19
 
        if (clip_rect.l < common->screen.l) clip_rect.l = common->screen.l;
20
 
        if (clip_rect.r > common->screen.r) clip_rect.r = common->screen.r;
21
 
    }
22
 
 
23
 
    top_font_overlap    = 0;
24
 
    bottom_font_overlap = 0;
25
 
    left_font_overlap   = 0;
26
 
    right_font_overlap  = 0;
27
 
 
28
 
    if (allow_oversize) { // added 21.6.02 --ralf
29
 
        if (clip_rect.t < common->screen.t) set_top_font_overlap(true);
30
 
        if (clip_rect.b > common->screen.b) set_bottom_font_overlap(true);
31
 
        if (clip_rect.l < common->screen.l) set_left_font_overlap(true);
32
 
        if (clip_rect.r > common->screen.r) set_right_font_overlap(true);
33
 
    }
34
 
}
35
 
 
36
 
int AW_clip::reduceClipBorders(int top, int bottom, int left, int right) {
37
 
    // return 0 if no clipping area left
38
 
    if (top    > clip_rect.t) clip_rect.t = top;
39
 
    if (bottom < clip_rect.b) clip_rect.b = bottom;
40
 
    if (left   > clip_rect.l) clip_rect.l = left;
41
 
    if (right  < clip_rect.r) clip_rect.r = right;
42
 
 
43
 
    return !(clip_rect.b<clip_rect.t || clip_rect.r<clip_rect.l);
44
 
}
45
 
 
46
 
void AW_clip::reduce_top_clip_border(int top){
47
 
    if (top > clip_rect.t) clip_rect.t = top;
48
 
}
49
 
 
50
 
void AW_clip::set_top_clip_border(int top, bool allow_oversize) {
51
 
    clip_rect.t = top;
52
 
    if (!allow_oversize){
53
 
        if (clip_rect.t < common->screen.t) clip_rect.t = common->screen.t;
54
 
    }
55
 
    else {
56
 
        set_top_font_overlap(true); // added 21.6.02 --ralf
57
 
    }
58
 
}
59
 
 
60
 
void AW_clip::reduce_bottom_clip_border(int bottom) {
61
 
    if ( bottom < clip_rect.b)    clip_rect.b = bottom;
62
 
}
63
 
 
64
 
void AW_clip::set_bottom_clip_border(int bottom, bool allow_oversize) {
65
 
    clip_rect.b = bottom;
66
 
    if (!allow_oversize){
67
 
        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
68
 
    }
69
 
    else {
70
 
        set_bottom_font_overlap(true); // added 21.6.02 --ralf
71
 
    }
72
 
}
73
 
 
74
 
void AW_clip::set_bottom_clip_margin(int bottom,bool allow_oversize) {
75
 
    clip_rect.b -= bottom;
76
 
    if (!allow_oversize){
77
 
        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
78
 
    }
79
 
    else {
80
 
        set_bottom_font_overlap(true); // added 21.6.02 --ralf
81
 
    }
82
 
}
83
 
void AW_clip::reduce_left_clip_border(int left) {
84
 
    if (left > clip_rect.l)clip_rect.l = left;
85
 
}
86
 
void AW_clip::set_left_clip_border(int left, bool allow_oversize) {
87
 
    clip_rect.l = left;
88
 
    if (!allow_oversize){
89
 
        if (clip_rect.l < common->screen.l) clip_rect.l = common->screen.l;
90
 
    }
91
 
    else {
92
 
        set_left_font_overlap(true); // added 21.6.02 --ralf
93
 
    }
94
 
}
95
 
 
96
 
void AW_clip::reduce_right_clip_border(int right) {
97
 
    if (right < clip_rect.r)    clip_rect.r = right;
98
 
}
99
 
 
100
 
void AW_clip::set_right_clip_border(int right, bool allow_oversize) {
101
 
    clip_rect.r = right;
102
 
    if (!allow_oversize){
103
 
        if (clip_rect.r > common->screen.r) clip_rect.r = common->screen.r;
104
 
    }
105
 
    else {
106
 
        set_right_font_overlap(true); // added to correct problem with last char skipped (added 21.6.02 --ralf)
107
 
    }
108
 
}
109
 
 
110
 
void AW_clip::set_top_font_overlap(int val){
111
 
    top_font_overlap = val;
112
 
}
113
 
void AW_clip::set_bottom_font_overlap(int val){
114
 
    bottom_font_overlap = val;
115
 
}
116
 
void AW_clip::set_left_font_overlap(int val){
117
 
    left_font_overlap = val;
118
 
}
119
 
void AW_clip::set_right_font_overlap(int val){
120
 
    right_font_overlap = val;
121
 
}
122
 
 
123
 
AW_clip::AW_clip(){
124
 
    memset((char *)this,0,sizeof(*this));
125
 
}
126
 
 
127
 
/**********************************************************************/
128
 
 
129
 
inline AW_pos clip_in_range(AW_pos low, AW_pos val, AW_pos high) {
130
 
    if (val <= low) return low;
131
 
    if (val >= high) return high;
132
 
    return val;
133
 
}
134
 
 
135
 
int AW_clip::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)
136
 
// clip coordinates of a box
137
 
{
138
 
    if (x1<clip_rect.l || x0>clip_rect.r) return 0;
139
 
    if (y1<clip_rect.t || y0>clip_rect.b) return 0;
140
 
 
141
 
    if (clip_rect.l>clip_rect.r) return 0;
142
 
    if (clip_rect.t>clip_rect.b) return 0;
143
 
 
144
 
    x0out = clip_in_range(clip_rect.l, x0, clip_rect.r);
145
 
    x1out = clip_in_range(clip_rect.l, x1, clip_rect.r);
146
 
    y0out = clip_in_range(clip_rect.t, y0, clip_rect.b);
147
 
    y1out = clip_in_range(clip_rect.t, y1, clip_rect.b);
148
 
 
149
 
    return 1;
150
 
}
151
 
/**********************************************************************/
152
 
 
153
 
int AW_clip::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)
154
 
// clip coordinates of a line
155
 
{
156
 
    int    outcodeout;
157
 
    AW_pos x = 0;
158
 
    AW_pos y = 0;
159
 
 
160
 
    bool is_visible = false;    // indicates whether part of line is visible
161
 
    bool done       = false;    // true soon as line is completely inside or outside rectangle
162
 
 
163
 
    while (!done) {
164
 
        int outcode0 = compoutcode(x0,y0);
165
 
        int outcode1 = compoutcode(x1,y1);
166
 
 
167
 
        if ((outcode0 | outcode1) == 0) { // line is inside the rectangle
168
 
            x0out = x0; y0out = y0; // clipped coordinates of line
169
 
            x1out = x1; y1out = y1;
170
 
 
171
 
            done    = true;
172
 
            is_visible = true;
173
 
        }
174
 
        else if ((outcode0 & outcode1) != 0) { // line is outside the rectangle
175
 
            done = true;
176
 
        }
177
 
        else { // line overlaps with at least one rectangle border
178
 
            outcodeout = outcode0>0 ? outcode0 : outcode1;
179
 
 
180
 
            if ((outcodeout & 8) != 0) { // overlap at top
181
 
                x = x0+(x1-x0)*(clip_rect.t-y0)/(y1-y0);
182
 
                y = clip_rect.t;
183
 
            }
184
 
            else if ((outcodeout & 4) != 0) { // overlap at bottom
185
 
                x = x0+(x1-x0)*(clip_rect.b-y0)/(y1-y0);
186
 
                y = clip_rect.b;
187
 
            }
188
 
            else if ((outcodeout & 2) != 0) { // overlap at right side
189
 
                y = y0+(y1-y0)*(clip_rect.r-x0)/(x1-x0);
190
 
                x = clip_rect.r;
191
 
            }
192
 
            else if ((outcodeout & 1) != 0) {
193
 
                y = y0+(y1-y0)*(clip_rect.l-x0)/(x1-x0); // overlap at left side
194
 
                x = clip_rect.l;
195
 
            }
196
 
 
197
 
            // set corrected point and iterate :
198
 
            if (outcode0 > 0) {
199
 
                x0 = x;
200
 
                y0 = y;
201
 
            }
202
 
            else {
203
 
                x1 = x;
204
 
                y1 = y;
205
 
            }
206
 
        }
207
 
    }
208
 
 
209
 
    return is_visible;
210
 
}
211
 
 
212
 
void AW_matrix::zoom(AW_pos val) {
213
 
    scale   *= val;
214
 
    unscale  = 1.0/scale;
215
 
}
216
 
 
217
 
void AW_matrix::reset(void) {
218
 
    unscale = scale   = 1.0;
219
 
    offset  = AW::Vector(0, 0);
220
 
}
221
 
 
222
 
/**********************************************************************************************
223
 
                                                GC_XM
224
 
**********************************************************************************************/
225
 
AW_GC_Xm::AW_GC_Xm(AW_common *commoni) {
226
 
    common     = commoni;
227
 
    line_width = 1;
228
 
    style      = AW_SOLID;
229
 
    function   = AW_COPY;
230
 
    color      = 0;
231
 
    grey_level = 0;
232
 
 
233
 
    XGCValues val;
234
 
    val.line_width = 1;
235
 
    unsigned long value_mask = GCLineWidth;
236
 
 
237
 
    gc = XCreateGC(common->display,common->window_id,value_mask,&val);
238
 
}
239
 
 
240
 
 
241
 
AW_GC_Xm::~AW_GC_Xm(void) {
242
 
    if (gc) XFreeGC(common->display,gc);
243
 
}
244
 
 
245
 
 
246
 
void AW_GC_Xm::set_fill(AW_grey_level grey_leveli) {    // <0 dont fill  0.0 white 1.0 black
247
 
    grey_level = grey_leveli;
248
 
}
249
 
 
250
 
 
251
 
void AW_GC_Xm::set_lineattributes(AW_pos width,AW_linestyle stylei) {
252
 
    int lwidth = AW_INT(width);
253
 
    if (stylei == style && line_width == lwidth) return;
254
 
 
255
 
    switch (style){
256
 
        case AW_SOLID:
257
 
            XSetLineAttributes(common->display, gc, lwidth, LineSolid, CapButt, JoinBevel);
258
 
            break;
259
 
        case AW_DOTTED:
260
 
            XSetLineAttributes(common->display, gc, lwidth, LineOnOffDash, CapButt, JoinBevel);
261
 
            break;
262
 
        default:
263
 
            break;
264
 
    }
265
 
    line_width = lwidth;
266
 
    style = style;
267
 
}
268
 
 
269
 
 
270
 
void AW_GC_Xm::set_function(AW_function mode)
271
 
{
272
 
    if (function != mode) {
273
 
        switch(mode) {
274
 
            case AW_XOR:
275
 
                XSetFunction(common->display,gc,GXxor);
276
 
                break;
277
 
            case AW_COPY:
278
 
                XSetFunction(common->display,gc,GXcopy);
279
 
                break;
280
 
        }
281
 
        function = mode;
282
 
        set_foreground_color(color);
283
 
    }
284
 
}
285
 
 
286
 
void AW_GC_Xm::set_foreground_color(unsigned long col) {
287
 
    color = (short)col;
288
 
    if (function == AW_XOR) {
289
 
        if (common->data_colors[0]) {
290
 
            col ^= common->data_colors[0][AW_DATA_BG];
291
 
        }else{
292
 
            col ^= common->frame_colors[AW_WINDOW_BG];
293
 
        }
294
 
    }
295
 
    XSetForeground(common->display,gc, col );
296
 
    last_fg_color =  col;
297
 
}
298
 
 
299
 
void AW_GC_Xm::set_background_color(unsigned long colori) {
300
 
    XSetBackground(common->display,gc, colori );
301
 
    last_bg_color = colori;
302
 
}
303
 
 
304
 
const AW_font_information *AW_gc::get_font_information(int gc, unsigned char c) {
305
 
    AW_GC_Xm            *gcm = (common->gcs[gc]);
306
 
    AW_font_information *ptr = &common->gcs[gc]->fontinfo;
307
 
 
308
 
    ptr->this_letter.ascent  = gcm->ascent_of_chars[c];
309
 
    ptr->this_letter.descent = gcm->descent_of_chars[c];
310
 
    ptr->this_letter.width   = gcm->width_of_chars[c];
311
 
    ptr->this_letter.calc_height();
312
 
    return ptr;
313
 
}
314
 
 
315
 
 
316
 
/**********************************************************************************************
317
 
                                                GC
318
 
**********************************************************************************************/
319
 
 
320
 
int AW_gc::get_string_size(int gc, const char *str, long textlen) {
321
 
    // get the size of the string
322
 
    XFontStruct *xfs           = &common->gcs[gc]->curfont;
323
 
    short       *size_per_char = common->gcs[gc]->width_of_chars;
324
 
    if (!textlen) {
325
 
        if (!str) return 0;
326
 
        textlen = strlen(str);
327
 
    }
328
 
    int  c;
329
 
    long l_width;
330
 
 
331
 
    if (xfs->max_bounds.width == xfs->min_bounds.width || !str) {
332
 
        // monospaced font
333
 
        l_width = textlen * xfs->max_bounds.width;
334
 
    }
335
 
    else {             // non-monospaced font
336
 
        l_width = 0;
337
 
        for (c = *(str++); c; c = *(str++)) {
338
 
            l_width += size_per_char[c];
339
 
        }
340
 
    }
341
 
    return (int)l_width;
342
 
}
343
 
void AW_gc::new_gc(int gc) {
344
 
    if (gc>= common->ngcs) {
345
 
        common->gcs = (AW_GC_Xm **)realloc((char *)common->gcs,sizeof(void *)*(gc+10));
346
 
        memset( &common->gcs[common->ngcs],0,sizeof(void *) * (gc-common->ngcs+10));
347
 
        common->ngcs = gc+10;
348
 
    }
349
 
    if (common->gcs[gc])delete (common->gcs[gc]);
350
 
    common->gcs[gc] = new AW_GC_Xm(common);
351
 
}
352
 
 
353
 
 
354
 
void AW_gc::set_fill(int gc,AW_grey_level grey_level){
355
 
    aw_assert(common->gcs[gc]);
356
 
    common->gcs[gc]->set_fill(grey_level);}
357
 
 
358
 
 
359
 
void AW_gc::set_font(int gc,AW_font font_nr, int size, int *found_size) {
360
 
    // if found_size != 0 -> return value for used font size
361
 
    aw_assert(common->gcs[gc]);
362
 
    common->gcs[gc]->set_font(font_nr, size, found_size);
363
 
}
364
 
 
365
 
int AW_gc::get_available_fontsizes(int gc, AW_font font_nr, int *available_sizes) {
366
 
    aw_assert(common->gcs[gc]);
367
 
    return common->gcs[gc]->get_available_fontsizes(font_nr, available_sizes);
368
 
}
369
 
 
370
 
 
371
 
void AW_gc::set_line_attributes(int gc,AW_pos width,AW_linestyle style){
372
 
    aw_assert(common->gcs[gc]);
373
 
    common->gcs[gc]->set_lineattributes(width,style);
374
 
}
375
 
 
376
 
 
377
 
void AW_gc::set_function(int gc,AW_function function){
378
 
    aw_assert(common->gcs[gc]);
379
 
    common->gcs[gc]->set_function(function);
380
 
}
381
 
 
382
 
 
383
 
void AW_gc::set_foreground_color(int gc, AW_color color) {
384
 
    unsigned long col;
385
 
    if (color>=AW_DATA_BG) {
386
 
        col = common->data_colors[0][color];
387
 
    }else{
388
 
        col = common->frame_colors[color];
389
 
    }
390
 
    common->gcs[gc]->set_foreground_color(col);
391
 
}
392
 
 
393
 
 
394
 
void AW_gc::set_background_color(int gc, AW_color color) {
395
 
    unsigned long col;
396
 
    if (color>=AW_DATA_BG) {
397
 
        col = common->data_colors[0][color];
398
 
    }else{
399
 
        col = common->frame_colors[color];
400
 
    }
401
 
    common->gcs[gc]->set_background_color(col);
402
 
}
403
 
 
404
 
 
405
 
 
406
 
/**********************************************************************************************
407
 
                                                COMMON
408
 
**********************************************************************************************/
409
 
void AW_get_common_extends_cb(AW_window *aww,AW_common *common) {
410
 
    AWUSE(aww);
411
 
    Window       root;
412
 
    unsigned int width,height;
413
 
    unsigned int depth, borderwidth;
414
 
    
415
 
    XGetGeometry(common->display,common->window_id,
416
 
                 &root,
417
 
                 &common->screen_x_offset, // xoffset
418
 
                 &common->screen_y_offset, // yoffset
419
 
                 &width,
420
 
                 &height,
421
 
                 &borderwidth,  // border width
422
 
                 &depth);       // depth of display
423
 
 
424
 
    common->screen.t = 0;               // set clipping coordinates
425
 
    common->screen.b = height;
426
 
    common->screen.l = 0;
427
 
    common->screen.r = width;
428
 
}
429
 
 
430
 
AW_common::AW_common(AW_window *aww, AW_area area, Display *display_in,
431
 
                     XID window_id_in,unsigned long *fcolors,
432
 
                     unsigned int **dcolors, long *data_colors_size_in)
433
 
{
434
 
    memset((char *)this,0,sizeof(AW_common));
435
 
 
436
 
    root             = aww->get_root();
437
 
    window_id        = window_id_in;
438
 
    display          = display_in;
439
 
    frame_colors     = fcolors;
440
 
    data_colors      = (unsigned long **)dcolors;
441
 
    data_colors_size = data_colors_size_in;
442
 
    ngcs             = 8;
443
 
    gcs              = (AW_GC_Xm **)malloc(sizeof(void *)*ngcs);
444
 
    
445
 
    memset((char *)gcs,0,sizeof(void *)*ngcs);
446
 
    aww->set_resize_callback(area,(AW_CB2)AW_get_common_extends_cb,(AW_CL)this,0);
447
 
    AW_get_common_extends_cb(aww,this);
448
 
}
449
 
 
450
 
/**********************************************************************************************
451
 
                                                DEVICE and GCS
452
 
**********************************************************************************************/
453
 
 
454
 
// ----------------------------
455
 
//      AW_clip_scale_stack
456
 
// ----------------------------
 
13
#include "aw_common_xm.hxx"
 
14
 
 
15
#include <arb_msg.h>
457
16
 
458
17
#if defined(DEBUG)
459
18
// #define SHOW_CLIP_STACK_CHANGES
463
22
    // completely private, but accessible by AW_device
464
23
    friend class AW_device;
465
24
 
466
 
    AW_rectangle clip_rect;
467
 
 
468
 
    int top_font_overlap;
469
 
    int bottom_font_overlap;
470
 
    int left_font_overlap;
471
 
    int right_font_overlap;
 
25
    AW_screen_area  clip_rect;
 
26
    AW_font_overlap font_overlap;
472
27
 
473
28
    AW::Vector offset;
474
 
    AW_pos     scale;
 
29
    AW_pos scale;
475
30
 
476
31
    class AW_clip_scale_stack *next;
477
32
};
478
33
 
479
34
#if defined(SHOW_CLIP_STACK_CHANGES)
480
35
static const char *clipstatestr(AW_device *device) {
481
 
    static char   buffer[1024];
482
 
    AW_rectangle& clip_rect = device->clip_rect;
483
 
    
484
 
    sprintf(buffer, "clip_rect={t=%i, b=%i, l=%i, r=%i}",
485
 
            clip_rect.t, clip_rect.b, clip_rect.l, clip_rect.r);
 
36
    static char buffer[1024];
 
37
 
 
38
    const AW_screen_area&  clip_rect = device->get_cliprect();
 
39
    const AW_font_overlap& fo        = device->get_font_overlap();
 
40
    const AW::Vector&      offset    = device->get_offset();
 
41
 
 
42
    sprintf(buffer,
 
43
            "clip_rect={t=%i, b=%i, l=%i, r=%i} "
 
44
            "font_overlap={t=%i, b=%i, l=%i, r=%i} "
 
45
            "scale=%f unscale=%f "
 
46
            "offset={x=%f y=%f}" ,
 
47
            clip_rect.t, clip_rect.b, clip_rect.l, clip_rect.r,
 
48
            fo.top, fo.bottom, fo.left, fo.right,
 
49
            device->get_scale(), device->get_unscale(), 
 
50
            offset.x(), offset.y());
486
51
 
487
52
    return buffer;
488
53
}
489
54
#endif // SHOW_CLIP_STACK_CHANGES
490
55
 
491
 
 
492
 
 
493
 
void AW_device::push_clip_scale(void)
494
 
{
495
 
    AW_clip_scale_stack *stack = new AW_clip_scale_stack;
496
 
 
497
 
    stack->next      = clip_scale_stack;
498
 
    clip_scale_stack = stack;
499
 
 
500
 
    stack->scale  = get_scale();
501
 
    stack->offset = get_offset();
502
 
 
503
 
    stack->top_font_overlap    = top_font_overlap;
504
 
    stack->bottom_font_overlap = bottom_font_overlap;
505
 
    stack->left_font_overlap   = left_font_overlap;
506
 
    stack->right_font_overlap  = right_font_overlap;
507
 
 
508
 
    stack->clip_rect = clip_rect;
509
 
 
510
 
#if defined(SHOW_CLIP_STACK_CHANGES)
511
 
    printf("push_clip_scale: %s\n", clipstatestr(this));
512
 
#endif // SHOW_CLIP_STACK_CHANGES
 
56
const AW_screen_area& AW_device::get_area_size() const {
 
57
    return get_common()->get_screen();
513
58
}
514
 
void AW_device::pop_clip_scale(void){
 
59
 
 
60
 
 
61
void AW_device::pop_clip_scale() {
515
62
    if (!clip_scale_stack) {
516
 
        AW_ERROR("Too many pop_clip_scale on that device");
 
63
        aw_assert(0); // Too many pop_clip_scale on that device
517
64
        return;
518
65
    }
519
66
 
521
68
    char *state_before_pop = strdup(clipstatestr(this));
522
69
#endif // SHOW_CLIP_STACK_CHANGES
523
70
 
 
71
    AW_zoomable::reset();
 
72
    set_offset(clip_scale_stack->offset); // needs to be called before zoom()
524
73
    zoom(clip_scale_stack->scale);
525
 
    set_offset(clip_scale_stack->offset);
526
 
 
527
 
    clip_rect = clip_scale_stack->clip_rect;
528
 
 
529
 
    top_font_overlap    = clip_scale_stack->top_font_overlap;
530
 
    bottom_font_overlap = clip_scale_stack->bottom_font_overlap;
531
 
    left_font_overlap   = clip_scale_stack->left_font_overlap;
532
 
    right_font_overlap  = clip_scale_stack->right_font_overlap;
 
74
    set_cliprect(clip_scale_stack->clip_rect);
 
75
    set_font_overlap(clip_scale_stack->font_overlap);
 
76
 
 
77
    aw_assert(get_scale() == clip_scale_stack->scale);
533
78
 
534
79
    AW_clip_scale_stack *oldstack = clip_scale_stack;
535
80
    clip_scale_stack              = clip_scale_stack->next;
536
81
    delete oldstack;
537
82
 
538
83
#if defined(SHOW_CLIP_STACK_CHANGES)
539
 
    printf("pop_clip_scale: %s -> %s\n", state_before_pop, clipstatestr(this));
 
84
    printf(" pop_clip_scale: %s\n", state_before_pop);
 
85
    printf("    [after pop]: %s\n\n", clipstatestr(this));
540
86
    free(state_before_pop);
541
87
#endif // SHOW_CLIP_STACK_CHANGES
542
88
}
543
89
 
544
 
// --------------------------------------------------------------------------------
545
 
 
546
 
void AW_device::get_area_size(AW_rectangle *rect) {     //get the extends from the class AW_device
547
 
    *rect = common->screen;
548
 
}
549
 
 
550
 
void AW_device::get_area_size(AW_world *rect) { //get the extends from the class AW_device
551
 
    rect->t = common->screen.t;
552
 
    rect->b = common->screen.b;
553
 
    rect->l = common->screen.l;
554
 
    rect->r = common->screen.r;
555
 
}
556
 
 
557
 
AW::Rectangle AW_device::get_area_size() {
558
 
    AW_rectangle& scr = common->screen;
559
 
    return AW::Rectangle(scr.l, scr.t, scr.r, scr.b);
560
 
}
561
 
 
562
 
void AW_device::privat_reset() {}
563
 
 
564
 
void AW_device::reset(){
565
 
    while (clip_scale_stack){
566
 
        pop_clip_scale();
567
 
    }
568
 
    get_area_size(&clip_rect);
569
 
    AW_matrix::reset();
570
 
    privat_reset();
571
 
}
572
 
 
573
 
AW_device::AW_device(class AW_common *commoni) : AW_gc(){
574
 
    common = commoni;
575
 
    clip_scale_stack = 0;
576
 
    filter = (AW_bitset)-1;
577
 
}
578
 
 
579
 
AW_gc::AW_gc() : AW_clip() {}
580
 
 
581
 
/**********************************************************************************************
582
 
                                                DEVICE and OUTPUT
583
 
**********************************************************************************************/
584
 
 
585
 
bool AW_device::invisible(int gc, AW_pos x, AW_pos y, AW_bitset filteri, AW_CL clientdata1, AW_CL clientdata2) {
586
 
    AWUSE(clientdata1);AWUSE(clientdata2);
587
 
    AWUSE(gc);
588
 
    if(filteri & filter) {
589
 
        AW_pos X,Y;             // Transformed pos
590
 
        transform(x,y,X,Y);
591
 
        return ! (X<clip_rect.l || X>clip_rect.r ||
592
 
                  Y<clip_rect.t || Y>clip_rect.b);
593
 
    }
594
 
    return true;
595
 
}
596
 
 
597
 
bool AW_device::ready_to_draw(int gc) {
598
 
    return AW_GC_MAPABLE(common, gc);
599
 
}
600
 
 
601
 
// PJ: ::zoomtext is defined in AW_xfigfont.cxx
602
 
 
603
 
int AW_device::generic_box(int gc, bool /*filled*/, AW_pos x0,AW_pos y0,AW_pos width,AW_pos height, AW_bitset filteri, AW_CL cd1, AW_CL cd2)
604
 
{
605
 
    int erg = 0;
606
 
    if (filteri & filter) {
607
 
        erg |= line(gc,x0,y0,x0+width,y0,filteri,cd1,cd2);
608
 
        erg |= line(gc,x0,y0,x0,y0+height,filteri,cd1,cd2);
609
 
        erg |= line(gc,x0+width,y0+height,x0+width,y0+height,filteri,cd1,cd2);
610
 
        erg |= line(gc,x0+width,y0+height,x0+width,y0+height,filteri,cd1,cd2);
611
 
    }
612
 
    return erg;
613
 
}
614
 
 
615
 
#if defined(DEVEL_RALF)
616
 
#warning draw in 45-degree-steps (8-cornered-polygones instead of circles)
617
 
#endif // DEVEL_RALF
618
 
 
619
 
int AW_device::generic_circle(int gc, bool /*filled has no effect here*/, AW_pos x0,AW_pos y0,AW_pos width,AW_pos height, AW_bitset filteri, AW_CL cd1, AW_CL cd2)
620
 
{
621
 
    int erg = 0;
622
 
    if (filteri & filter) {
623
 
        erg |= line(gc,x0,y0+height,x0+width,y0,filteri,cd1,cd2);
624
 
        erg |= line(gc,x0,y0+height,x0-width,y0,filteri,cd1,cd2);
625
 
        erg |= line(gc,x0,y0-height,x0+width,y0,filteri,cd1,cd2);
626
 
        erg |= line(gc,x0,y0-height,x0-width,y0,filteri,cd1,cd2);
627
 
    }
628
 
    return erg;
629
 
}
630
 
 
631
 
int AW_device::generic_arc(int gc, bool /*filled has no effect here*/, AW_pos x0,AW_pos y0,AW_pos width,AW_pos height, int /*start_degrees*/, int /*arc_degrees*/, AW_bitset filteri, AW_CL cd1, AW_CL cd2)
632
 
{
633
 
    int erg = 0;
634
 
    if (filteri & filter) {
635
 
        erg |= line(gc,x0,y0+height,x0+width,y0,filteri,cd1,cd2);
636
 
        erg |= line(gc,x0,y0+height,x0-width,y0,filteri,cd1,cd2);
637
 
        erg |= line(gc,x0,y0-height,x0+width,y0,filteri,cd1,cd2);
638
 
        erg |= line(gc,x0,y0-height,x0-width,y0,filteri,cd1,cd2);
639
 
    }
640
 
    return erg;
641
 
}
642
 
int AW_device::generic_filled_area(int gc, int npoints, AW_pos *points, AW_bitset filteri, AW_CL cd1, AW_CL cd2){
643
 
    int erg = 0;
644
 
    if (filteri & filter) {
645
 
        npoints--;
646
 
        erg |= line(gc,points[0],points[1],points[npoints*2],points[npoints*2+1],filteri,cd1,cd2);
647
 
        while (npoints>0) {
648
 
            AW_pos x = *(points++);
649
 
            AW_pos y = *(points++);
650
 
            erg |= line(gc,x,y,points[0],points[1],filteri,cd1,cd2);
651
 
            npoints--;
652
 
        }
653
 
    }
654
 
    return erg;
655
 
}
656
 
 
657
 
 
658
 
void AW_device::clear(AW_bitset /*filteri*/) {}
659
 
void AW_device::clear_part(AW_pos /*x*/, AW_pos /*y*/, AW_pos /*width*/, AW_pos /*height*/, AW_bitset /*filteri*/) {}
660
 
void AW_device::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*/) {}
661
 
void AW_device::move_region( AW_pos /*src_x*/, AW_pos /*src_y*/, AW_pos /*width*/, AW_pos /*height*/, AW_pos /*dest_x*/, AW_pos /*dest_y*/ ) {}
662
 
void AW_device::fast(void) {}
663
 
void AW_device::slow(void) {}
664
 
void AW_device::flush(void) {}
665
 
 
666
 
// forbidden operations:
667
 
static void forbidden(const char *toUse) { AW_ERROR("It's not allowed to use '%s' with this device", toUse); }
668
 
const char *AW_device::open(const char */*path*/) { forbidden("open"); return 0; }
669
 
void AW_device::close(void) { forbidden("close"); }
670
 
void AW_device::set_color_mode(bool /*mode*/) { forbidden("set_color_mode"); }
671
 
void AW_device::get_clicked_line(AW_clicked_line */*ptr*/) { forbidden("get_clicked_line"); }
672
 
void AW_device::get_clicked_text(AW_clicked_text */*ptr*/) { forbidden("get_clicked_text"); }
673
 
void AW_device::get_size_information(AW_world */*ptr*/) { forbidden("get_size_information"); }
674
 
 
675
 
int AW_device::cursor(int gc, AW_pos x0,AW_pos y0, AW_cursor_type cur_type, AW_bitset filteri, AW_CL clientdata1, AW_CL clientdata2) {
676
 
    class AW_GC_Xm *gcm = AW_MAP_GC(gc);
677
 
    XFontStruct    *xfs = &gcm->curfont;
678
 
    AW_pos          x1,x2,y1,y2;
679
 
    AW_pos          X0,Y0;      // Transformed pos
680
 
 
681
 
    //  cursor insert         cursor overwrite
682
 
    //     (X0,Y0)
683
 
    //       /\                       .
684
 
    //      /  \                      .
685
 
    //      ----
686
 
    // (X1,Y1)(X2,Y2)
687
 
 
688
 
    if(filteri & filter) {
689
 
        if( cur_type == AW_cursor_insert ) {
690
 
            transform(x0,y0,X0,Y0);
691
 
 
692
 
            if (X0 > clip_rect.r) return 0;
693
 
            if (X0 < clip_rect.l) return 0;
694
 
            if (Y0+(AW_pos)(xfs->max_bounds.descent) < clip_rect.t) return 0;
695
 
            if (Y0-(AW_pos)(xfs->max_bounds.ascent) > clip_rect.b) return 0;
696
 
 
697
 
            x1 = x0-4;
698
 
            y1 = y0+4;
699
 
            x2 = x0+4;
700
 
            y2 = y0+4;
701
 
 
702
 
            line(gc,x1,y1,x0,y0,filteri,clientdata1, clientdata2);
703
 
            line(gc,x2,y2,x0,y0,filteri,clientdata1, clientdata2);
704
 
            line(gc,x1,y1,x2,y2,filteri,clientdata1, clientdata2);
705
 
        }
706
 
    }
707
 
    return 1;
708
 
}
709
 
 
710
 
int AW_device::text_overlay( int gc, const char *opt_str, long opt_len, // either string or strlen != 0
711
 
                             AW_pos x,AW_pos y, AW_pos alignment, AW_bitset filteri, AW_CL cduser, AW_CL cd1, AW_CL cd2,
712
 
                             AW_pos opt_ascent,AW_pos opt_descent,              // optional height (if == 0 take font height)
713
 
                             int (*f)(AW_device *device, int gc, const char *opt_string, size_t opt_string_len,size_t start, size_t size,
714
 
                                      AW_pos x,AW_pos y, AW_pos opt_ascent,AW_pos opt_descent,
715
 
                                      AW_CL cduser, AW_CL cd1, AW_CL cd2))
716
 
{
717
 
    long         textlen;
718
 
    AW_GC_Xm    *gcm           = AW_MAP_GC(gc);
719
 
    XFontStruct *xfs           = &gcm->curfont;
720
 
    short       *size_per_char = common->gcs[gc]->width_of_chars;
721
 
    int          xi, yi;
722
 
    int          h;
723
 
    int          start;
724
 
    int          l;
725
 
    int          c             = 0;
726
 
    AW_pos       X0,Y0;         // Transformed pos
727
 
    
 
90
void AW_device::push_clip_scale() {
 
91
    AW_clip_scale_stack *stack = new AW_clip_scale_stack;
 
92
 
 
93
    stack->next      = clip_scale_stack;
 
94
    clip_scale_stack = stack;
 
95
 
 
96
    stack->scale        = get_scale();
 
97
    stack->offset       = get_offset();
 
98
    stack->font_overlap = get_font_overlap();
 
99
    stack->clip_rect    = get_cliprect();
 
100
 
 
101
#if defined(SHOW_CLIP_STACK_CHANGES)
 
102
    printf("push_clip_scale: %s\n", clipstatestr(this));
 
103
#endif // SHOW_CLIP_STACK_CHANGES
 
104
}
 
105
 
 
106
bool AW_device::text_overlay(int gc, const char *opt_str, long opt_len,  // either string or strlen != 0
 
107
                             const AW::Position& pos, AW_pos alignment, AW_bitset filteri, AW_CL cduser,
 
108
                             AW_pos opt_ascent, AW_pos opt_descent,             // optional height (if == 0 take font height)
 
109
                             TextOverlayCallback toc)
 
110
{
 
111
    const AW_GC           *gcm         = get_common()->map_gc(gc);
 
112
    const AW_font_limits&  font_limits = gcm->get_font_limits();
 
113
 
 
114
    long   textlen;
 
115
    int    xi;
 
116
    int    h;
 
117
    int    start;
 
118
    int    l;
 
119
    AW_pos X0, Y0;              // Transformed pos
 
120
 
728
121
    bool inside_clipping_left  = true; // clipping at the left edge of the screen is different from clipping right of the left edge.
729
122
    bool inside_clipping_right = true;
730
123
 
736
129
 
737
130
    if (!(filter & filteri)) return 0;
738
131
 
739
 
    if (left_font_overlap || common->screen.l == clip_rect.l) { // was : clip_rect.l == 0
740
 
        inside_clipping_left = false;
741
 
    }
742
 
 
743
 
    if (right_font_overlap || clip_rect.r == common->screen.r) { // was : clip_rect.r == common->screen.r
744
 
 
745
 
        inside_clipping_right = false;
746
 
    }
747
 
 
748
 
    transform(x,y,X0,Y0);
749
 
 
750
 
 
751
 
    if (top_font_overlap || clip_rect.t == 0) {                                                 // check clip border inside screen
752
 
        if (Y0+(AW_pos)(xfs->max_bounds.descent) < clip_rect.t) return 0; // draw outside screen
753
 
    }else {
754
 
        if (Y0-(AW_pos)(xfs->max_bounds.ascent) < clip_rect.t) return 0; // dont cross the clip border
755
 
    }
756
 
 
757
 
    if (bottom_font_overlap || clip_rect.b == common->screen.b) {                               // check clip border inside screen drucken
758
 
        if (Y0-(AW_pos)(xfs->max_bounds.ascent) > clip_rect.b) return 0;             // draw outside screen
759
 
    }else {
760
 
        if (Y0+(AW_pos)(xfs->max_bounds.descent)> clip_rect.b) return 0;             // dont cross the clip border
 
132
    const AW_screen_area& screen   = get_common()->get_screen();
 
133
    const AW_screen_area& clipRect = get_cliprect();
 
134
 
 
135
    if (allow_left_font_overlap() || screen.l == clipRect.l) inside_clipping_left = false;
 
136
    if (allow_right_font_overlap() || clipRect.r == screen.r) inside_clipping_right = false;
 
137
 
 
138
    transform(pos.xpos(), pos.ypos(), X0, Y0);
 
139
 
 
140
    if (allow_top_font_overlap() || clipRect.t == 0) {             // check clip border inside screen
 
141
        if (Y0+font_limits.descent < clipRect.t) return 0; // draw outside screen
 
142
    }
 
143
    else {
 
144
        if (Y0-font_limits.ascent < clipRect.t) return 0;  // don't cross the clip border
 
145
    }
 
146
 
 
147
    if (allow_bottom_font_overlap() || clipRect.b == screen.b) {   // check clip border inside screen
 
148
        if (Y0-font_limits.ascent > clipRect.b) return 0;  // draw outside screen
 
149
    }
 
150
    else {
 
151
        if (Y0+font_limits.descent> clipRect.b) return 0;  // don't cross the clip border
761
152
    }
762
153
 
763
154
    if (!opt_len) {
764
155
        opt_len = textlen = strlen(opt_str);
765
 
    }else{
 
156
    }
 
157
    else {
766
158
        textlen = opt_len;
767
159
    }
768
160
 
769
161
    aw_assert(opt_len == textlen);
770
 
    aw_assert(int(strlen(opt_str)) >= textlen);
771
 
 
772
 
    if (alignment){
773
 
        AW_pos width = get_string_size(gc,opt_str,textlen);
 
162
 
 
163
 
 
164
#if defined(DEBUG)
 
165
    int opt_str_len = int(strlen(opt_str));
 
166
    aw_assert(opt_str_len >= textlen);
 
167
#endif
 
168
 
 
169
    if (alignment) {
 
170
        AW_pos width = get_string_size(gc, opt_str, textlen);
774
171
        X0 = X0-alignment*width;
775
172
    }
776
173
    xi = AW_INT(X0);
777
 
    yi = AW_INT(Y0);
778
 
    if (X0 > clip_rect.r) return 0;                           // right of screen
 
174
    if (X0 > clipRect.r) return 0; // right of screen
779
175
 
780
 
    l = (int)clip_rect.l;
781
 
    if (xi + textlen*xfs->max_bounds.width < l) return 0;               // left of screen
 
176
    l = (int)clipRect.l;
 
177
    if (xi + textlen*font_limits.width < l) return 0; // left of screen
782
178
 
783
179
    start = 0;
784
 
    if (xi < l) {                                                               // now clip left side
785
 
        if (xfs->max_bounds.width == xfs->min_bounds.width) {           //  monospaced font
786
 
            h = (l - xi)/xfs->max_bounds.width;
 
180
 
 
181
    // now clip left side
 
182
    if (xi < l) {
 
183
        if (font_limits.is_monospaced()) {
 
184
            h = (l - xi)/font_limits.width;
787
185
            if (inside_clipping_left) {
788
 
                if ( (l-xi)%xfs->max_bounds.width  >0 ) h += 1;
 
186
                if ((l-xi)%font_limits.width  >0) h += 1;
789
187
            }
790
188
            if (h >= textlen) return 0;
791
189
            start    = h;
792
 
            xi      += h*xfs->max_bounds.width;
 
190
            xi      += h*font_limits.width;
793
191
            textlen -= h;
794
192
 
795
193
            if (textlen < 0) return 0;
796
194
            aw_assert(int(strlen(opt_str)) >= textlen);
797
 
        }else {                                                         // non-monospaced font
 
195
        }
 
196
        else { // proportional font
 
197
            int c = 0;
798
198
            for (h=0; xi < l; h++) {
799
199
                if (!(c = opt_str[h])) return 0;
800
 
                xi += size_per_char[c];
 
200
                xi += gcm->get_width_of_char(c);
801
201
            }
802
202
            if (!inside_clipping_left) {
803
203
                h-=1;
804
 
                xi -= size_per_char[c];
 
204
                xi -= gcm->get_width_of_char(c);
805
205
            }
806
206
            start    = h;
807
207
            textlen -= h;
811
211
        }
812
212
    }
813
213
 
814
 
    // now clipp right side
815
 
    if (xfs->max_bounds.width == xfs->min_bounds.width) {                       // monospaced font
816
 
        h = ((int)clip_rect.r - xi) / xfs->max_bounds.width;
 
214
    // now clip right side
 
215
    if (font_limits.is_monospaced()) {
 
216
        h = ((int)clipRect.r - xi) / font_limits.width;
817
217
        if (h < textlen) {
818
218
            if (inside_clipping_right) {
819
219
                textlen = h;
820
 
            }else{
 
220
            }
 
221
            else {
821
222
                textlen = h+1;
822
223
            }
823
224
        }
825
226
        if (textlen < 0) return 0;
826
227
        aw_assert(int(strlen(opt_str)) >= textlen);
827
228
    }
828
 
    else {                                                                      // non-monospaced font
829
 
        l = (int)clip_rect.r - xi;
830
 
        for (h = start; l >= 0 && textlen > 0 ; h++, textlen--) { // was textlen >= 0
831
 
            l -= size_per_char[safeCharIndex(opt_str[h])];
 
229
    else { // proportional font
 
230
        l = (int)clipRect.r - xi;
 
231
        for (h = start; l >= 0 && textlen > 0;  h++, textlen--) { // was textlen >= 0
 
232
            l -= gcm->get_width_of_char(opt_str[h]);
832
233
        }
833
234
        textlen = h - start;
834
 
        if (l <= 0 && inside_clipping_right && textlen  > 0 ) {
 
235
        if (l <= 0 && inside_clipping_right && textlen  > 0) {
835
236
            textlen -= 1;
836
237
        }
837
238
 
839
240
        aw_assert(int(strlen(opt_str)) >= textlen);
840
241
    }
841
242
    X0 = (AW_pos)xi;
842
 
    rtransform(X0,Y0,x,y);
 
243
 
 
244
    AW_pos corrx, corry;
 
245
    rtransform(X0, Y0, corrx, corry);
843
246
 
844
247
    aw_assert(opt_len >= textlen);
845
248
    aw_assert(textlen >= 0 && int(strlen(opt_str)) >= textlen);
846
249
 
847
 
    return f(this,gc,opt_str,opt_len, start ,(size_t)textlen, x,y, opt_ascent, opt_descent, cduser, cd1, cd2);
848
 
}
849
 
 
850
 
/**********************************************************************************************
851
 
                                                DEVICE and ETC
852
 
**********************************************************************************************/
853
 
 
854
 
void AW_device::set_filter(AW_bitset filteri) { filter = filteri; }
 
250
    return toc(this, gc, opt_str, opt_len, start, (size_t)textlen, corrx, corry, opt_ascent, opt_descent, cduser);
 
251
}
 
252
 
 
253
bool AW_device::generic_filled_area(int gc, int npos, const AW::Position *pos, AW_bitset filteri) {
 
254
    bool drawflag = false;
 
255
    if (filteri & filter) {
 
256
        int p = npos-1;
 
257
        for (int n = 0; n<npos; ++n) {
 
258
            drawflag |= line(gc, pos[p], pos[n], filteri);
 
259
            p = n;
 
260
        }
 
261
    }
 
262
    return drawflag;
 
263
}
 
264
 
 
265
void AW_device::move_region(AW_pos /* src_x */, AW_pos /* src_y */, AW_pos /* width */, AW_pos /* height */, 
 
266
                            AW_pos /* dest_x */, AW_pos /* dest_y */) {
 
267
    // empty default
 
268
}
 
269
 
 
270
void AW_device::flush() {
 
271
    // empty default
 
272
}
 
273
 
 
274
static const AW_screen_area& get_universe() {
 
275
    // "unrestricted" area
 
276
    const int UMIN = INT_MIN/10;
 
277
    const int UMAX = INT_MAX/10;
 
278
    static AW_screen_area universe = { UMIN, UMAX, UMIN, UMAX };
 
279
    return universe;
 
280
}
 
281
 
 
282
void AW_device::reset() {
 
283
    while (clip_scale_stack) {
 
284
        pop_clip_scale();
 
285
    }
 
286
    if (type() == AW_DEVICE_SIZE) {
 
287
        set_cliprect(get_universe());
 
288
    }
 
289
    else {
 
290
        set_cliprect(get_area_size());
 
291
    }
 
292
    AW_zoomable::reset();
 
293
    specific_reset();
 
294
}
 
295
 
 
296
bool AW_device::generic_invisible(const AW::Position& pos, AW_bitset filteri) {
 
297
    return (filter & filteri) ? !is_outside_clip(transform(pos)) : false;
 
298
}
 
299
 
 
300
const AW_screen_area& AW_device::get_common_screen(const AW_common *common_) {
 
301
    return common_->get_screen();
 
302
}
 
303
 
 
304
bool AW_device::generic_box(int gc, bool /*filled*/, const AW::Rectangle& rect, AW_bitset filteri) {
 
305
    // Note: 'filled' is not supported on this device
 
306
    int drawflag = 0;
 
307
    if (filteri & filter) {
 
308
        drawflag |= line_impl(gc, rect.upper_edge(), filteri);
 
309
        drawflag |= line_impl(gc, rect.lower_edge(), filteri);
 
310
        drawflag |= line_impl(gc, rect.left_edge(),  filteri);
 
311
        drawflag |= line_impl(gc, rect.right_edge(), filteri);
 
312
    }
 
313
    return drawflag;
 
314
}
 
315
 
 
316
void AW_device::clear(AW_bitset) {
 
317
    // nothing to do
 
318
}
 
319
 
 
320
void AW_device::clear_part(const AW::Rectangle&, AW_bitset) {
 
321
    // nothing to do
 
322
}
 
323
 
 
324
void AW_device::set_filter(AW_bitset filteri) {
 
325
    filter = filteri;
 
326
}
 
327
 
 
328
void AW_device::fast() {}
 
329
void AW_device::slow() {}
 
330
bool AW_device::ready_to_draw(int gc) {
 
331
    return get_common()->gc_mapable(gc);
 
332
}
 
333
 
 
334
void AW_zoomable::reset() {
 
335
    unscale = scale   = 1.0;
 
336
    offset  = AW::Vector(0, 0);
 
337
}
 
338
 
 
339
void AW_zoomable::zoom(AW_pos val) {
 
340
    scale   *= val;
 
341
    unscale  = 1.0/scale;
 
342
}
 
343
 
 
344
// -----------------
 
345
//      AW_GC_Xm
 
346
 
 
347
const int GC_DEFAULT_LINE_STYLE = LineSolid;
 
348
const int GC_DEFAULT_CAP_STYLE  = CapProjecting;
 
349
const int GC_JOIN_STYLE         = JoinMiter;
 
350
 
 
351
AW_GC_Xm::AW_GC_Xm(AW_common *common_)
 
352
    : AW_GC(common_)
 
353
{
 
354
    XGCValues val;
 
355
 
 
356
    val.line_width = GC_DEFAULT_LINE_WIDTH;
 
357
    val.line_style = GC_DEFAULT_LINE_STYLE;
 
358
    val.cap_style  = GC_DEFAULT_CAP_STYLE;
 
359
    val.join_style = GC_JOIN_STYLE;
 
360
 
 
361
    unsigned long value_mask = GCLineWidth|GCLineStyle|GCCapStyle|GCJoinStyle;
 
362
 
 
363
    gc = XCreateGC(get_common()->get_display(), get_common()->get_window_id(), value_mask, &val);
 
364
    wm_set_function(get_function());
 
365
}
 
366
AW_GC_Xm::~AW_GC_Xm() {
 
367
    if (gc) XFreeGC(get_common()->get_display(), gc);
 
368
}
 
369
void AW_GC_Xm::wm_set_lineattributes(short lwidth, AW_linestyle lstyle) {
 
370
    Display            *display = get_common()->get_display();
 
371
    aw_assert(lwidth>0);
 
372
 
 
373
    switch (lstyle) {
 
374
        case AW_SOLID:
 
375
            XSetLineAttributes(display, gc, lwidth, LineSolid, GC_DEFAULT_CAP_STYLE, GC_JOIN_STYLE);
 
376
            break;
 
377
 
 
378
        case AW_DOTTED:
 
379
        case AW_DASHED: {
 
380
            static char dashes[] = { 5, 2 };
 
381
            static char dots[]   = { 1, 1 };
 
382
            XSetDashes(display, gc, 0, lstyle == AW_DOTTED ? dots : dashes, 2);
 
383
            XSetLineAttributes(display, gc, lwidth, LineOnOffDash, CapButt, GC_JOIN_STYLE);
 
384
            break;
 
385
        }
 
386
    }
 
387
}
 
388
void AW_GC_Xm::wm_set_function(AW_function mode) {
 
389
    switch (mode) {
 
390
        case AW_XOR:
 
391
            XSetFunction(get_common()->get_display(), gc, GXxor);
 
392
            break;
 
393
        case AW_COPY:
 
394
            XSetFunction(get_common()->get_display(), gc, GXcopy);
 
395
            break;
 
396
    }
 
397
}
 
398
void AW_GC_Xm::wm_set_foreground_color(AW_rgb col) {
 
399
    XSetForeground(get_common()->get_display(), gc, col);
 
400
}
 
401
 
 
402
const AW_font_limits& AW_stylable::get_font_limits(int gc, char c) const {
 
403
    return get_common()->get_font_limits(gc, c);
 
404
}
 
405
 
 
406
int AW_GC::get_string_size(const char *str, long textlen) const {
 
407
    // calculate display size of 'str'
 
408
    // 'str' and/or 'textlen' may be 0
 
409
    // 'str'     == 0 -> calculate max width of any text with length 'textlen'
 
410
    // 'textlen' == 0 -> calls strlen when needed
 
411
    // both 0 -> return 0
 
412
 
 
413
    int width = 0;
 
414
    if (font_limits.is_monospaced() || !str) {
 
415
        if (!textlen && str) textlen = strlen(str);
 
416
        width = textlen * font_limits.width;
 
417
    }
 
418
    else {
 
419
        for (int c = *(str++); c; c = *(str++)) width += width_of_chars[c];
 
420
    }
 
421
    return width;
 
422
}
 
423
 
 
424
AW_GC *AW_common_Xm::create_gc() {
 
425
    return new AW_GC_Xm(this);
 
426
}
 
427
 
 
428
void AW_GC_set::add_gc(int gi, AW_GC *agc) {
 
429
    if (gi >= count) {
 
430
        int new_count = gi+10;
 
431
        realloc_unleaked(gcs, sizeof(*gcs)*new_count);
 
432
        if (!gcs) GBK_terminate("out of memory");
 
433
        memset(&gcs[count], 0, sizeof(*gcs)*(new_count-count));
 
434
        count = new_count;
 
435
    }
 
436
    if (gcs[gi]) delete gcs[gi];
 
437
    gcs[gi] = agc;
 
438
}
 
439
 
 
440
int AW_stylable::get_string_size(int gc, const char *str, long textlen) const {
 
441
    return get_common()->map_gc(gc)->get_string_size(str, textlen);
 
442
}
 
443
void AW_stylable::new_gc(int gc) { get_common()->new_gc(gc); }
 
444
void AW_stylable::set_grey_level(int gc, AW_grey_level grey_level) {
 
445
    // <0 = don't fill, 0.0 = white, 1.0 = black
 
446
    get_common()->map_mod_gc(gc)->set_grey_level(grey_level);
 
447
}
 
448
void AW_stylable::set_font(int gc, AW_font font_nr, int size, int *found_size) {
 
449
    // if found_size != 0 -> return value for used font size
 
450
    get_common()->map_mod_gc(gc)->set_font(font_nr, size, found_size);
 
451
}
 
452
int AW_stylable::get_available_fontsizes(int gc, AW_font font_nr, int *available_sizes) {
 
453
    return get_common()->map_gc(gc)->get_available_fontsizes(font_nr, available_sizes);
 
454
}
 
455
void AW_stylable::set_line_attributes(int gc, short width, AW_linestyle style) {
 
456
    get_common()->map_mod_gc(gc)->set_line_attributes(width, style);
 
457
}
 
458
void AW_stylable::set_function(int gc, AW_function function) {
 
459
    get_common()->map_mod_gc(gc)->set_function(function);
 
460
}
 
461
void AW_stylable::set_foreground_color(int gc, AW_color_idx color) {
 
462
    get_common()->map_mod_gc(gc)->set_fg_color(get_common()->get_color(color));
 
463
}
 
464
void AW_stylable::establish_default(int gc) {
 
465
    get_common()->map_mod_gc(gc)->establish_default();
 
466
}
 
467
void AW_stylable::reset_style() {
 
468
    get_common()->reset_style();
 
469
}
 
470
 
 
471
static void AW_get_common_extends_cb(AW_window *, AW_common_Xm *common) {
 
472
    Window        root;
 
473
    unsigned int  width, height;
 
474
    unsigned int  depth, borderwidth; // unused
 
475
    int           x_offset, y_offset; // unused
 
476
 
 
477
    XGetGeometry(common->get_display(), common->get_window_id(),
 
478
                 &root,
 
479
                 &x_offset,
 
480
                 &y_offset,
 
481
                 &width,
 
482
                 &height,
 
483
                 &borderwidth,  // border width
 
484
                 &depth);       // depth of display
 
485
 
 
486
    common->set_screen_size(width, height);
 
487
}
 
488
 
 
489
void AW_common_Xm::install_common_extends_cb(AW_window *aww, AW_area area) {
 
490
    aww->set_resize_callback(area, makeWindowCallback(AW_get_common_extends_cb, this));
 
491
    AW_get_common_extends_cb(aww, this);
 
492
}
 
493