source: tags/initial/WINDOW/AW_device.cxx

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <X11/X.h>
5#include <X11/Xlib.h>
6
7
8#define _AW_COMMON_INCLUDED
9#include "aw_root.hxx"
10#include "aw_device.hxx"
11#include "aw_window.hxx"
12#include "aw_commn.hxx"
13
14
15
16void AW_clip::set_cliprect(AW_rectangle *rect, AW_BOOL allow_oversize) {
17    clip_rect = *rect;  // coordintes : (0,0) = top-left-corner
18    if (!allow_oversize){
19        if (clip_rect.t < common->screen.t) clip_rect.t = common->screen.t;
20        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
21        if (clip_rect.l < common->screen.l) clip_rect.l = common->screen.l;
22        if (clip_rect.r > common->screen.r) clip_rect.r = common->screen.r;
23    }
24       
25    top_font_overlap = 0;
26    bottom_font_overlap = 0;
27    left_font_overlap = 0;
28    right_font_overlap = 0;
29}
30
31void AW_clip::reduceClipBorders(int top, int bottom, int left, int right) {
32    if (top    > clip_rect.t)   clip_rect.t = top;
33    if (bottom < clip_rect.b)   clip_rect.b = bottom;
34    if (left   > clip_rect.l)   clip_rect.l = left;
35    if (right  < clip_rect.r)   clip_rect.r = right;
36}
37
38void AW_clip::reduce_top_clip_border(int top){
39    if (top > clip_rect.t) clip_rect.t = top;
40}
41
42void AW_clip::set_top_clip_border(int top, AW_BOOL allow_oversize) {
43    clip_rect.t = top;
44    if (!allow_oversize){
45        if (clip_rect.t < common->screen.t) clip_rect.t = common->screen.t;
46    }
47}
48
49void AW_clip::reduce_bottom_clip_border(int bottom) {
50    if ( bottom < clip_rect.b)    clip_rect.b = bottom;
51}       
52
53void AW_clip::set_bottom_clip_border(int bottom, AW_BOOL allow_oversize) {
54    clip_rect.b = bottom;
55    if (!allow_oversize){
56        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
57    }
58}
59
60void AW_clip::set_bottom_clip_margin(int bottom,AW_BOOL allow_oversize) {
61    clip_rect.b -= bottom;
62    if (!allow_oversize){
63        if (clip_rect.b > common->screen.b) clip_rect.b = common->screen.b;
64    }
65}
66void AW_clip::reduce_left_clip_border(int left) {
67    if (left > clip_rect.l)clip_rect.l = left;
68}
69void AW_clip::set_left_clip_border(int left, AW_BOOL allow_oversize) {
70    clip_rect.l = left;
71    if (!allow_oversize){
72        if (clip_rect.l < common->screen.l) clip_rect.l = common->screen.l;
73    }
74}
75
76void AW_clip::reduce_right_clip_border(int right) {
77    if (right < clip_rect.r)    clip_rect.r = right;
78}
79
80void AW_clip::set_right_clip_border(int right, AW_BOOL allow_oversize) {
81    clip_rect.r = right;
82    if (!allow_oversize){
83        if (clip_rect.r > common->screen.r) clip_rect.r = common->screen.r;
84    }
85}
86
87void AW_clip::set_top_font_overlap(int val){
88    top_font_overlap = val;
89}
90void AW_clip::set_bottom_font_overlap(int val){
91    bottom_font_overlap = val;
92}
93void AW_clip::set_left_font_overlap(int val){
94    left_font_overlap = val;
95}
96void AW_clip::set_right_font_overlap(int val){
97    right_font_overlap = val;
98}
99
100AW_clip::AW_clip(){
101    memset((char *)this,0,sizeof(*this));
102}
103
104/**********************************************************************/
105
106int 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)
107{
108    if (x0 < clip_rect.r) x0out = x0; else x0out = clip_rect.r;
109    if (y0 < clip_rect.b) y0out = y0; else y0out = clip_rect.b;
110
111    if (x0 < clip_rect.l) x0out = clip_rect.l;
112    if (y0 < clip_rect.t) y0out = clip_rect.t;
113
114    if (x1 < clip_rect.r) x1out = x1; else x1out = clip_rect.r;
115    if (y1 < clip_rect.b) y1out = y1; else y1out = clip_rect.b;
116
117    if (x1 < clip_rect.l) x1out = clip_rect.l;
118    if (y1 < clip_rect.t) y1out = clip_rect.t;
119
120    if (x0out >= x1out || y0out >= y1out) return 0;
121    return 1;
122}
123/**********************************************************************/
124
125int 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)
126{
127    int outcode0, outcode1, outcodeout;
128    int done,success;
129    AW_pos x =0, y =0;
130
131    success=0;                              // indiactes wether part of line is visible
132    done = 0;
133
134    while (done == 0)
135    {       outcode0 = compoutcode(x0,y0);
136    outcode1 = compoutcode(x1,y1);
137
138    if ((outcode0 | outcode1) == 0)
139    {                       // line is inside the rectangle
140
141        x0out=x0;       y0out=y0;               // clipped coordinates of line
142        x1out=x1;       y1out=y1;
143
144        done = 1;
145        success=1;
146    }
147
148    if ((outcode0 & outcode1) != 0)
149        //line is outside the rectangle
150        done = 1;
151    if (done == 0)                //;
152    {
153        if (outcode0 > 0)
154            outcodeout = outcode0;
155        else
156            outcodeout = outcode1;
157        if ((outcodeout & 8) != 0)
158        {
159            x = x0+(x1-x0)*(clip_rect.t-y0)/(y1-y0);
160            y = clip_rect.t;
161        }
162        else
163        {
164            if ((outcodeout & 4) != 0)
165            {
166                x = x0+(x1-x0)*(clip_rect.b-y0)/(y1-y0);
167                y = clip_rect.b;
168            }
169            else
170            {
171                if ((outcodeout & 2) != 0)
172                {
173                    y = y0+(y1-y0)*(clip_rect.r-x0)/(x1-x0);
174                    x = clip_rect.r;
175                }
176                else
177                { if ((outcodeout & 1) != 0)
178                {
179
180                    y = y0+(y1-y0)*(clip_rect.l-x0)/(x1-x0);
181                    x = clip_rect.l;
182                }
183                }
184            }
185        }
186        if (outcode0 > 0)
187        {
188            x0 = x;
189            y0 = y;
190        }
191        else
192        {
193            x1 = x;
194            y1 = y;
195        }
196    }
197    }
198    return success;
199}
200
201
202
203void    AW_matrix::shift_x(AW_pos xoff) {
204    xoffset = xoff*scale;
205}
206
207
208void    AW_matrix::shift_y(AW_pos yoff) {
209    yoffset = yoff*scale;
210}
211
212
213void    AW_matrix::shift_dx(AW_pos xoff) {
214    xoffset += xoff*scale;
215}
216
217
218void    AW_matrix::shift_dy(AW_pos yoff) {
219    yoffset += yoff*scale;
220}
221
222
223void    AW_matrix::zoom(AW_pos val) {
224    scale *= val;
225}
226
227
228void    AW_matrix::reset(void) {
229    scale = 1.0;
230    xoffset = yoffset = 0.0;
231}
232
233/**********************************************************************************************
234                                                GC_XM
235**********************************************************************************************/
236AW_GC_Xm::AW_GC_Xm(class AW_common      *commoni) {
237    common = commoni;
238    XGCValues   val;
239    unsigned long value_mask;
240    val.line_width = 1;
241    value_mask = GCLineWidth;
242    line_width = 1;
243    style = AW_SOLID;
244    function = AW_COPY;
245    color = 0;
246    grey_level = 0;
247    gc  = XCreateGC(common->display,common->window_id,value_mask,&val);
248}
249
250
251AW_GC_Xm::~AW_GC_Xm(void) {
252    if (gc) XFreeGC(common->display,gc);
253}
254
255
256void AW_GC_Xm::set_fill(AW_grey_level grey_leveli) {    // <0 dont fill  0.0 white 1.0 black
257    grey_level = grey_leveli;
258}
259
260
261void AW_GC_Xm::set_lineattributes(AW_pos width,AW_linestyle stylei) {
262    int lwidth = (int)(width*AW_PIXELS_PER_MM);
263    if (stylei == style && line_width == lwidth) return;
264
265    switch (style){
266        case AW_SOLID:
267            XSetLineAttributes(common->display, gc, lwidth, LineSolid, CapButt, JoinBevel);
268            break;
269        case AW_DOTTED:
270            XSetLineAttributes(common->display, gc, lwidth, LineOnOffDash, CapButt, JoinBevel);
271            break;
272        default:
273            break;
274    };
275    line_width = lwidth;
276    style = style;
277}
278
279
280void AW_GC_Xm::set_function(AW_function mode)
281{
282    if (function != mode) {
283        switch(mode) {
284            case AW_XOR:
285                XSetFunction(common->display,gc,GXxor);
286                break;
287            case AW_COPY:
288                XSetFunction(common->display,gc,GXcopy);
289                break;
290        }
291        function = mode;
292        set_foreground_color(color);
293    }
294}
295
296void AW_GC_Xm::set_foreground_color(unsigned long col) {
297    color = (short)col;
298    if (function == AW_XOR) {
299        if (common->data_colors[0]) {
300            col ^= common->data_colors[0][AW_DATA_BG];
301        }else{
302            col ^= common->frame_colors[AW_WINDOW_BG];
303        }
304    }
305    XSetForeground(common->display,gc, col );
306}
307
308void AW_GC_Xm::set_background_color(unsigned long colori) {
309    XSetBackground(common->display,gc, colori );
310}
311
312class AW_font_information *AW_gc::get_font_information(int gc, char c) {
313    register AW_GC_Xm *gcm = (common->gcs[gc]);
314    class AW_font_information *ptr = &common->gcs[gc]->fontinfo;
315    ptr->this_letter_ascent = gcm->ascent_of_chars[c];
316    ptr->this_letter_descent = gcm->descent_of_chars[c];
317    ptr->this_letter_width = gcm->width_of_chars[c];
318    ptr->this_letter_height = ptr->this_letter_ascent + ptr->this_letter_descent;
319    return ptr;
320}
321
322
323/**********************************************************************************************
324                                                GC
325**********************************************************************************************/
326
327int     AW_gc::get_string_size(int gc, const char *str, long textlen)
328    // get the size of the string
329{
330    register XFontStruct *xfs = &common->gcs[gc]->curfont;
331    register short *size_per_char = common->gcs[gc]->width_of_chars;
332    if (!textlen)
333    {
334        if (!str) return 0;
335        textlen = strlen(str);
336    }
337    register int c;
338    register long l_width;
339
340    if (xfs->max_bounds.width == xfs->min_bounds.width || !str) {
341                                // monospaced font
342        l_width = textlen * xfs->max_bounds.width;
343    }else {             // non-monospaced font
344        l_width = 0;
345        for (c = *(str++); c; c = *(str++)) {
346            l_width += size_per_char[c];
347        }
348    }
349    return (int)l_width;
350}
351void AW_gc::new_gc(int gc) {
352    if (gc>= common->ngcs) {
353        common->gcs = (AW_GC_Xm **)realloc((char *)common->gcs,sizeof(void *)*(gc+10));
354        memset( &common->gcs[common->ngcs],0,sizeof(void *) * (gc-common->ngcs+10));
355        common->ngcs = gc+10;
356    }
357    if (common->gcs[gc])delete (common->gcs[gc]);
358    common->gcs[gc] = new AW_GC_Xm(common);
359}
360
361
362void AW_gc::set_fill(int gc,AW_grey_level grey_level){
363    common->gcs[gc]->set_fill(grey_level);}
364
365
366void AW_gc::set_font(int gc,AW_font font_nr, int size){
367    common->gcs[gc]->set_font(font_nr,size);
368}
369
370
371void AW_gc::set_line_attributes(int gc,AW_pos width,AW_linestyle style){
372    common->gcs[gc]->set_lineattributes(width,style);
373}
374
375
376void AW_gc::set_function(int gc,AW_function function){
377    common->gcs[gc]->set_function(function);
378}
379
380
381void AW_gc::set_foreground_color(int gc, AW_color color) {
382    unsigned long col;
383    if (color>=AW_DATA_BG) {
384        col = common->data_colors[0][color];
385    }else{
386        col = common->frame_colors[color];
387    }
388    common->gcs[gc]->set_foreground_color(col);
389}
390
391
392void AW_gc::set_background_color(int gc, AW_color color) {
393    unsigned long col;
394    if (color>=AW_DATA_BG) {
395        col = common->data_colors[0][color];
396    }else{
397        col = common->frame_colors[color];
398    }
399    common->gcs[gc]->set_background_color(col);
400}
401
402
403
404/**********************************************************************************************
405                                                COMMON
406**********************************************************************************************/
407void AW_get_common_extends_cb(AW_window *aww,AW_common *common) {
408    AWUSE(aww);
409    Window      root;
410    unsigned int width,height;
411    unsigned int depth, borderwidth;
412    XGetGeometry(common->display,common->window_id,
413                 &root,
414                 &common->screen_x_offset,      // xoffset
415                 &common->screen_y_offset,      // yoffset
416                 &width,
417                 &height,
418                 &borderwidth,          // border width
419                 &depth);               // depth of display
420
421    common->screen.t = 0;               // set clipping coordinates
422    common->screen.b = height;
423    common->screen.l = 0;
424    common->screen.r = width;
425}
426
427AW_common::AW_common(AW_window *aww, AW_area area,      Display *display_in,XID window_id_in,unsigned long *fcolors,unsigned int **dcolors)
428{
429    memset((char *)this,0,sizeof(AW_common));
430    root = aww->get_root();
431    window_id = window_id_in;
432    display = display_in;
433    frame_colors = fcolors;
434    data_colors = (unsigned long **)dcolors;
435    ngcs = 8;
436    gcs = (AW_GC_Xm **)malloc(sizeof(void *)*ngcs);
437    memset((char *)gcs,0,sizeof(void *)*ngcs);
438    aww->set_resize_callback(area,(AW_CB2)AW_get_common_extends_cb,(AW_CL)this,0);
439    AW_get_common_extends_cb(aww,this);
440}
441
442/**********************************************************************************************
443                                                DEVICE and GCS
444**********************************************************************************************/
445
446
447void            AW_device::push_clip_scale(void)
448{
449    AW_clip_scale_stack *stack = new AW_clip_scale_stack;
450    stack->next = clip_scale_stack;
451    clip_scale_stack = stack;
452    stack->scale = scale;
453    stack->xoffset = xoffset;
454    stack->yoffset = yoffset;
455    stack->top_font_overlap = top_font_overlap;
456    stack->bottom_font_overlap = bottom_font_overlap;
457    stack->left_font_overlap = left_font_overlap;
458    stack->right_font_overlap = right_font_overlap;
459    stack->clip_rect = clip_rect;
460}
461void            AW_device::pop_clip_scale(void){
462    if (!clip_scale_stack) {
463        AW_ERROR("To many pop_clip_scale on that device");
464        return;
465    }
466    scale = clip_scale_stack->scale;
467    xoffset = clip_scale_stack->xoffset;
468    yoffset = clip_scale_stack->yoffset;
469    clip_rect = clip_scale_stack->clip_rect;
470    top_font_overlap = clip_scale_stack->top_font_overlap;
471    bottom_font_overlap = clip_scale_stack->bottom_font_overlap;
472    left_font_overlap = clip_scale_stack->left_font_overlap;
473    right_font_overlap = clip_scale_stack->right_font_overlap;
474    AW_clip_scale_stack *oldstack = clip_scale_stack;
475    clip_scale_stack = clip_scale_stack->next;
476    delete oldstack;
477}
478
479void AW_device::get_area_size(AW_rectangle *rect) {     //get the extends from the class AW_device
480    *rect = common->screen;
481}
482
483void AW_device::get_area_size(AW_world *rect) { //get the extends from the class AW_device
484    rect->t = common->screen.t;
485    rect->b = common->screen.b;
486    rect->l = common->screen.l;
487    rect->r = common->screen.r;
488}
489
490void AW_device::_privat_reset()
491{
492    ;
493}
494
495void AW_device::reset(){
496    while (clip_scale_stack){
497        pop_clip_scale();
498    }
499    get_area_size(&clip_rect);
500    AW_matrix::reset();
501    _privat_reset();
502}
503
504AW_device::AW_device(class AW_common *commoni) : AW_gc(){
505    common = commoni;
506    clip_scale_stack = 0;
507    filter = (AW_bitset)-1;
508}
509
510AW_gc::AW_gc() : AW_clip(){
511    ;
512}
513/**********************************************************************************************
514                                                DEVICE and OUTPUT
515**********************************************************************************************/
516
517int AW_device::invisible(int gc, AW_pos x, AW_pos y, AW_bitset filteri, AW_CL clientdata1, AW_CL clientdata2) {
518    AWUSE(clientdata1);AWUSE(clientdata2);
519    AWUSE(gc);
520    AW_pos X,Y;                                                 // Transformed pos
521    if(filteri & filter) {
522        transform(x,y,X,Y);
523        if ( X > clip_rect.r) return 0;
524        if ( X < clip_rect.l) return 0;
525        if ( Y > clip_rect.b) return 0;
526        if ( Y < clip_rect.t) return 0;
527    }
528    return 1;
529}
530
531// PJ: ::zoomtext is defined in AW_xfigfont.cxx
532
533int AW_device::box(int gc, AW_pos x0,AW_pos y0,AW_pos width,AW_pos height, AW_bitset filteri, AW_CL cd1, AW_CL cd2)
534{
535    int erg = 0;
536    if (        !(filteri & filter) ) return 0;
537    erg |= line(gc,x0,y0,x0+width,y0,filteri,cd1,cd2);
538    erg |= line(gc,x0,y0,x0,y0+height,filteri,cd1,cd2);
539    erg |= line(gc,x0+width,y0+height,x0+width,y0+height,filteri,cd1,cd2);
540    erg |= line(gc,x0+width,y0+height,x0+width,y0+height,filteri,cd1,cd2);
541    return erg;
542}
543int AW_device::circle(int gc, AW_pos x0,AW_pos y0,AW_pos width,AW_pos height, AW_bitset filteri, AW_CL cd1, AW_CL cd2)
544{
545    int erg = 0;
546    if (        !(filteri & filter) ) return 0;
547    erg |= line(gc,x0,y0+height,x0+width,y0,filteri,cd1,cd2);
548    erg |= line(gc,x0,y0+height,x0-width,y0,filteri,cd1,cd2);
549    erg |= line(gc,x0,y0-height,x0+width,y0,filteri,cd1,cd2);
550    erg |= line(gc,x0,y0-height,x0-width,y0,filteri,cd1,cd2);
551    return erg;
552}
553int AW_device::filled_area(int gc, int npoints, AW_pos *points, AW_bitset filteri, AW_CL cd1, AW_CL cd2){
554    int erg = 0;
555    if (        !(filteri & filter) ) return 0;
556    npoints--;
557    erg |= line(gc,points[0],points[1],points[npoints*2],points[npoints*2+1],filteri,cd1,cd2);
558    while (     npoints>0) {
559        AW_pos x = *(points++);
560        AW_pos y = *(points++);
561        erg |= line(gc,x,y,points[0],points[1],filteri,cd1,cd2);
562        npoints--;
563    }
564    return erg;
565}
566
567
568void AW_device::clear(void){;}
569
570void AW_device::clear_part(AW_pos x, AW_pos y, AW_pos width, AW_pos height)
571{ AWUSE(x);AWUSE(y);AWUSE(width);AWUSE(height);}
572void 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)
573{
574    AWUSE(gc);AWUSE(string);AWUSE(x);AWUSE(y);AWUSE(filteri);AWUSE(cd1);AWUSE(cd2);AWUSE(alignment);
575}
576void 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 )
577{ AWUSE(src_x);AWUSE(src_y);AWUSE(width);AWUSE(height);AWUSE(dest_x);AWUSE(dest_y);}
578
579void AW_device::fast(void){;}
580void AW_device::slow(void){;}
581void AW_device::flush(void){;}
582
583
584
585const char * AW_device::open(const char *path)
586{
587    AW_ERROR ("This device dont allow 'open'");
588    AWUSE(path);
589    return 0;
590}
591
592void AW_device::close(void)
593{
594    AW_ERROR ("This device dont allow 'close'");
595}
596
597void AW_device::get_clicked_line(AW_clicked_line *ptr)
598{
599    AW_ERROR ("This device dont allow 'get_clicked_line'");
600    AWUSE(ptr);
601}
602void AW_device::get_clicked_text(AW_clicked_text *ptr){
603    AW_ERROR ("This device dont allow 'get_clicked_text'");
604    AWUSE(ptr);
605}
606
607void AW_device::get_size_information(AW_world *ptr){
608    AW_ERROR ("This device dont allow 'get_size_information'");
609    AWUSE(ptr);
610}
611
612
613
614
615int AW_device::cursor(int gc, AW_pos x0,AW_pos y0, AW_cursor_type type, AW_bitset filteri, AW_CL clientdata1, AW_CL clientdata2) {
616    register class AW_GC_Xm *gcm = AW_MAP_GC(gc);
617    register XFontStruct *xfs = &gcm->curfont;
618    AW_pos x1,x2,y1,y2;
619    AW_pos X0,Y0;                               // Transformed pos
620
621    //  cursor insert         cursor overwrite
622    //     (X0,Y0)           
623    //       /\               
624    //      /  \             
625    //      ----             
626    // (X1,Y1)(X2,Y2)         
627
628    if(filteri & filter) {
629        if( type == AW_cursor_insert ) {
630            transform(x0,y0,X0,Y0);
631
632            if (X0 > clip_rect.r) return 0;
633            if (X0 < clip_rect.l) return 0;
634            if (Y0+(AW_pos)(xfs->max_bounds.descent) < clip_rect.t) return 0;
635            if (Y0-(AW_pos)(xfs->max_bounds.ascent) > clip_rect.b) return 0;
636
637            x1 = x0-4;
638            y1 = y0+4;
639            x2 = x0+4;
640            y2 = y0+4;
641
642            line(gc,x1,y1,x0,y0,filteri,clientdata1, clientdata2);
643            line(gc,x2,y2,x0,y0,filteri,clientdata1, clientdata2);
644            line(gc,x1,y1,x2,y2,filteri,clientdata1, clientdata2);
645        }
646    }
647    return 1;
648}
649
650int AW_device::text_overlay( int gc, const char *opt_str, long opt_len, // either string or strlen != 0
651                             AW_pos x,AW_pos y, AW_pos alignment, AW_bitset filteri, AW_CL cduser, AW_CL cd1, AW_CL cd2, 
652                             AW_pos opt_ascent,AW_pos opt_descent,              // optional height (if == 0 take font height)
653                             int (*f)(AW_device *device, int gc, const char *opt_string, size_t opt_string_len,size_t start, size_t size,
654                                      AW_pos x,AW_pos y, AW_pos opt_ascent,AW_pos opt_descent,
655                                      AW_CL cduser, AW_CL cd1, AW_CL cd2))
656{
657    long        textlen;
658    class AW_GC_Xm *gcm = AW_MAP_GC(gc);
659    register XFontStruct *xfs = &gcm->curfont;
660    register short *size_per_char = common->gcs[gc]->width_of_chars;
661    register int        xi, yi;
662    register int        h;
663    int         start;
664    int         l;
665    int         c =0;
666    AW_pos              X0,Y0;                                  // Transformed pos
667    AW_BOOL             inside_clipping_left = AW_TRUE;         // clipping at the left edge of the screen is different
668    //  from clipping right of the left edge.
669    AW_BOOL             inside_clipping_right = AW_TRUE;
670
671    // es gibt 4 clipping Moeglichkeiten:
672    // 1. man will fuer den Fall clippen, dass man vom linken display-Rand aus druckt   => clipping rechts vom 1. Buchstaben
673    // 2. man will fuer den Fall clippen, dass man mitten im Bildschirm ist                     => clipping links vom 1. Buchstaben
674    // 3. man will fuer den Fall clippen, dass man mitten im Bildschirm ist                     => clipping links vom letzten Buchstaben
675    // 4. man will fuer den Fall clippen, dass man bis zum rechten display-Rand druckt  => clipping rechts vom letzten Buchstaben
676
677    if (!(filter & filteri)) return 0;
678
679    if (left_font_overlap || clip_rect.l == 0) {
680        inside_clipping_left = AW_FALSE;
681    }
682
683    if (right_font_overlap || clip_rect.r == common->screen.r) {
684        inside_clipping_right = AW_FALSE;
685    }
686
687    transform(x,y,X0,Y0);
688
689
690    if (top_font_overlap || clip_rect.t == 0) {                                                 // check clip border inside screen
691        if (Y0+(AW_pos)(xfs->max_bounds.descent) < clip_rect.t) return 0; // draw outside screen
692    }else {
693        if (Y0-(AW_pos)(xfs->max_bounds.ascent) < clip_rect.t) return 0; // dont cross the clip border
694    }
695
696    if (bottom_font_overlap || clip_rect.b == common->screen.b) {                               // check clip border inside screen drucken
697        if (Y0-(AW_pos)(xfs->max_bounds.ascent) > clip_rect.b) return 0;             // draw outside screen
698    }else {
699        if (Y0+(AW_pos)(xfs->max_bounds.descent)> clip_rect.b) return 0;             // dont cross the clip border
700    }
701
702    if (!opt_len) {
703        opt_len = textlen = strlen(opt_str);
704    }else{
705        textlen = opt_len;
706    }
707
708    if (alignment){
709        AW_pos width = get_string_size(gc,opt_str,textlen);
710        X0 = X0-alignment*width;
711    }
712    xi = AW_INT(X0);
713    yi = AW_INT(Y0);
714    if (X0 > clip_rect.r) return 0;                           // right of screen
715
716    l = (int)clip_rect.l;
717    if (xi + textlen*xfs->max_bounds.width < l) return 0;               // left of screen
718
719    start = 0;
720    if (xi < l) {                                                               // now clip left side
721        if (xfs->max_bounds.width == xfs->min_bounds.width) {           //  monospaced font
722            h = (l - xi)/xfs->max_bounds.width;
723            if (inside_clipping_left) {
724                if ( (l-xi)%xfs->max_bounds.width  >0 ) h += 1;
725            }
726            if (h >= textlen) return 0;
727            start = h;
728            xi += h*xfs->max_bounds.width;
729            textlen -= h;
730        }else {                                                         // non-monospaced font
731            for (h=0; xi < l; h++) {
732                if (!(c = opt_str[h])) return 0;
733                xi += size_per_char[c];
734            }
735            if (!inside_clipping_left) {
736                h-=1;
737                xi -= size_per_char[c];
738            }
739            start = h;
740            textlen -= h;
741        }
742    }
743
744    // now clipp right side
745    if (xfs->max_bounds.width == xfs->min_bounds.width) {                       // monospaced font
746        h = ((int)clip_rect.r - xi) / xfs->max_bounds.width;
747        if (h < textlen) {
748            if (inside_clipping_right) {
749                textlen = h;
750            }else{
751                textlen = h+1;
752            }
753        }
754    }else{                                                                      // non-monospaced font
755        l = (int)clip_rect.r - xi;
756        for (h = start; l >= 0 && textlen >=0 ; h++, textlen--) {
757            l -= size_per_char[opt_str[h]];
758        }
759        textlen = h - start;
760        if (inside_clipping_right && textlen  > 0 )
761            textlen -= 1;
762    }
763    X0=(AW_pos)xi;
764    rtransform(X0,Y0,x,y);
765    return f(this,gc,opt_str,opt_len, start ,(size_t)textlen, x,y, opt_ascent, opt_descent, cduser, cd1, cd2);
766}
767
768/**********************************************************************************************
769                                                DEVICE and ETC
770**********************************************************************************************/
771
772void AW_device::set_filter(AW_bitset filteri) { filter = filteri; }
Note: See TracBrowser for help on using the repository browser.