home *** CD-ROM | disk | FTP | other *** search
/ M.u.C.S. Disc 2000 / MUCS2000.iso / anwend / qed453 / src / ausgabe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-29  |  21.4 KB  |  981 lines

  1. #include <support.h>
  2.  
  3. #include "global.h"
  4. #include "ausgabe.h"
  5. #include "memory.h"
  6. #include "options.h"
  7. #include "rsc.h"
  8. #include "window.h"
  9.  
  10. #define BLKANF        1
  11. #define BLKEND        2
  12. #define BLKFULL    4
  13.  
  14. /* lokale Variablen ********************************************************/
  15. static char    *text = NULL;
  16. static int    text_len = 0;
  17. #define MIN_TEXT_LEN    ((MAX_LINE_LEN+1) / 4)    /* Startlänge: 256 Bytes */
  18.  
  19. /*!! Muessen am Anfang jeder Routine gesetzt werden !!*/
  20. static bool    tab;
  21. static int    tab_size;
  22. static bool    umbrechen;
  23. static bool    show_end;
  24. static int    draw_mode;
  25. static bool    opt_draw;
  26.  
  27.  
  28. void set_drawmode(void)
  29. {
  30.     if (bg_color == WHITE)
  31.     {
  32.         /*
  33.          * Schnellere Ausgabe, da durch MD_REPLACE das Löschen der Zeile
  34.          * vor Ausgabe des Textes entfallen kann.
  35.          * Nur möglich, wenn als Hintergrundfarbe wei₧ gewählt ist!
  36.         */
  37.         opt_draw = TRUE;
  38.         draw_mode = MD_REPLACE;
  39.     }
  40.     else
  41.     {
  42.         /* 'langsame' Ausgabe bei nicht-wei₧em Hintergrund */
  43.         opt_draw = FALSE;
  44.         draw_mode = MD_TRANS;
  45.     }
  46.     vswr_mode(vdi_handle, draw_mode);
  47. }
  48.  
  49.  
  50. static void set_fill_color(int new)
  51. {
  52.     if (new != fill_color)
  53.     {
  54.         vsf_color(vdi_handle, new);
  55.         fill_color = new;
  56.     }
  57. }
  58.  
  59. /*
  60.  * Dynamischer Zeilenpuffer für die expandierte Zeile. MAX_LINE_LEN reicht
  61.  * nicht aus, wenn eine Zeile echte TABs enthält!
  62.  * Der angeforderte Puffer wird von line_to_str() benutzt.
  63. */
  64. static void adjust_text(TEXTP t_ptr)
  65. {
  66.     int    need;
  67.     
  68.     if (t_ptr->max_line == NULL)
  69.         need = -1;
  70.     else
  71.         need = t_ptr->max_line->exp_len;
  72.     if (text == NULL || need > text_len)
  73.     {
  74.         text_len = max(need, MIN_TEXT_LEN);
  75.         text = realloc(text, text_len + 1);
  76.     }
  77. }
  78.  
  79. /*
  80.  * Expandiert eine ganze Zeile zu einem String für die 
  81.  * Ausgabe mit v_gtext().
  82.  * Tab-Zeichen werden ggf. in mehrere CHR(32) gewandelt
  83.  * Die Stringlänge wird zurückgegeben.
  84. */
  85. int line_to_str(char *str, int anz)
  86. {
  87.     int    len, i, end;
  88.     char    c, *t;
  89.  
  90.     t = text;
  91. /*    str = TEXT(a);
  92.     if (anz == -1)
  93.         end = a->len;
  94.     else */
  95.         end = anz;
  96.     if (tab)
  97.     {
  98.         int    tabH;
  99.  
  100.         tabH = tab_size;
  101.         for (i = end, len = text_len; (--i)>=0; )
  102.         {
  103.             c = *str++;
  104.             if (c == '\t')
  105.             {
  106.                 len -= tabH;
  107.                 if (len < 0)
  108.                 {
  109.                     tabH += len;
  110.                     len = 0;
  111.                 }
  112.                 while (TRUE)
  113.                 {
  114.                     *t++ = ' ';    
  115.                     if ((--tabH) == 0) 
  116.                         break;
  117.                 }
  118.                 if (len == 0) 
  119.                     break;            /* Puffer voll */
  120.                 tabH = tab_size;
  121.             }
  122.             else if (c < min_ascii || c > max_ascii)
  123.             {
  124.                 *t++ = ' ';
  125.                 if ((--tabH) == 0) 
  126.                     tabH = tab_size;
  127.                 if ((--len) == 0) 
  128.                     break;        /* Puffer voll */
  129.             }
  130.             else
  131.             {
  132.                 *t++ = c;
  133.                 if ((--tabH) == 0)
  134.                     tabH = tab_size;
  135.                 if ((--len) == 0) 
  136.                     break;        /* Puffer voll */
  137.             }
  138.         }
  139.         len = text_len - len;
  140.         *t = EOS;
  141.     }
  142.     else
  143.     {
  144.         for (i = end, len = 0; (--i) >= 0 && (len < text_len); len++)
  145.         {
  146.             c = *str++;
  147.             if (c < min_ascii || c > max_ascii)
  148.                 *t++ = ' ';
  149.             else
  150.                 *t++ = c;
  151.         }
  152.         *t = EOS;
  153.     }
  154.     return(len);
  155. }
  156.  
  157. /* Liefert die interne Position */
  158. int inter_pos(int x, ZEILEP a, bool tab, int tab_size)
  159. {
  160.     int    len  = 0,
  161.             tabH = tab_size,
  162.              i    = 0;
  163.     char *str;
  164.  
  165.     if (!tab)
  166.         return min(x,a->len);
  167.     str = TEXT(a);
  168.     while(len < x && i < a->len)
  169.     {
  170.         if ((*str++) == '\t')
  171.         {
  172.             len += tabH;
  173.             tabH = tab_size;
  174.         }
  175.         else
  176.         {
  177.             len++;
  178.             if ((--tabH)==0)
  179.                 tabH = tab_size;
  180.         }
  181.         i++;
  182.     }
  183.     if (len > x)
  184.         i--;
  185.     return i;
  186. }
  187.  
  188. int bild_len(ZEILEP a, bool tab, int tab_size)
  189. {
  190.     return bild_pos(a->len,a,tab,tab_size);
  191. }
  192.  
  193. int bild_pos(int x, ZEILEP a, bool tab, int tab_size)
  194. {
  195.     int    len  = 0,
  196.             tabH = tab_size;
  197.     char    *str;
  198.  
  199.     if (!tab)
  200.         return min(x, a->len);
  201.     str = TEXT(a);
  202.     while ((--x)>=0)
  203.     {
  204.         if ((*str++) == '\t')
  205.         {
  206.             len += tabH;
  207.             tabH = tab_size;
  208.         }
  209.         else
  210.         {
  211.             len++;
  212.             if ((--tabH)==0)
  213.                 tabH = tab_size;
  214.         }
  215.     }
  216.     return len;
  217. }
  218.  
  219. /*----------------------------------------------------------------------------
  220.  * Cursor-Handling
  221. */
  222. int cursor_xpos(TEXTP t_ptr, int pos)
  223. {
  224.     int    len;
  225.     
  226.     if (font_prop)
  227.     {
  228.         int    pxy[8];
  229.         
  230.         tab = t_ptr->loc_opt->tab;
  231.         tab_size = t_ptr->loc_opt->tabsize;
  232.         adjust_text(t_ptr);
  233.         line_to_str(TEXT(t_ptr->cursor_line), pos);
  234.         vqt_extent(vdi_handle, text, pxy);
  235.         len = pxy[2] - pxy[0];
  236.     }
  237.     else
  238.         len = bild_pos(pos, t_ptr->cursor_line, t_ptr->loc_opt->tab, t_ptr->loc_opt->tabsize) * font_wcell;
  239.  
  240.     return len;
  241. }
  242.  
  243. static void _cursor(GRECT *r)
  244. {
  245.     int     pxy[4];
  246.  
  247.     pxy[0] = r->g_x;
  248.     pxy[1] = r->g_y;
  249.     pxy[2] = r->g_x + r->g_w - 1;
  250.     pxy[3] = r->g_y + r->g_h - 1;
  251.     set_fill_color(fg_color);
  252.     vswr_mode(vdi_handle, MD_XOR);
  253.     vr_recfl (vdi_handle, pxy);
  254.     vswr_mode(vdi_handle, draw_mode);
  255. }
  256.  
  257. void cursor(WINDOWP w, TEXTP t_ptr)
  258. {
  259.     int        pxy[8];
  260.     char        c[2];
  261.     GRECT        curs_rect, clip;
  262.     long        zeile;
  263.     bool        hidden;
  264.  
  265.     /* Position ermitteln */    
  266.     curs_rect.g_x = cursor_xpos(t_ptr, t_ptr->xpos) - ((int) w->doc.x * font_wcell) + w->work.g_x;
  267.  
  268.     zeile = t_ptr->ypos - w->doc.y;
  269.     curs_rect.g_y = (int) zeile * font_hcell + w->work.g_y;
  270.  
  271.     /* Cursor überhaupt sichtbar? */
  272.     if (curs_rect.g_x < w->work.g_x || curs_rect.g_x > (w->work.g_x + w->work.g_w - 1) ||
  273.          curs_rect.g_y < w->work.g_y || curs_rect.g_y > (w->work.g_y + w->work.g_h - 1) ||
  274.          (w->flags & WI_ICONIFIED))
  275.         return;
  276.  
  277.     /* Breite und Höhe ermitteln */    
  278.     if (overwrite)
  279.     {
  280.         if (font_prop)
  281.         {
  282.             c[0] = TEXT(t_ptr->cursor_line)[t_ptr->xpos];
  283.             c[1] = EOS;
  284.             vqt_extent(vdi_handle, c, pxy);
  285.             curs_rect.g_w = pxy[2] - pxy[0];
  286.             if (curs_rect.g_w == 0)
  287.                 curs_rect.g_w = 1;
  288.             curs_rect.g_h = pxy[7] - pxy[1];
  289.         }
  290.         else
  291.         {
  292.             curs_rect.g_w = font_wcell;
  293.             curs_rect.g_h = font_hcell;
  294.         }
  295.     }
  296.     else
  297.     {
  298.         curs_rect.g_w = 3;
  299.         curs_rect.g_h = font_hcell;
  300.     }
  301.  
  302.     /*
  303.      * Am Rand (oben/unten) darf der Cursor nicht überstehen, ansonsten
  304.      * 2 Pixel oben/unten.
  305.      */
  306.     if (zeile > 0)
  307.     {
  308.         curs_rect.g_y -= 2;
  309.         curs_rect.g_h += 2;
  310.     }
  311.     if (zeile < w->w_height-1)
  312.         curs_rect.g_h += 2;
  313.  
  314.     wind_update(BEG_UPDATE);
  315.     hidden = hide_mouse_if_needed(&curs_rect);
  316.  
  317.     if (rc_first(w->handle, &curs_rect, &clip))
  318.     {
  319.         do
  320.         {
  321.             set_clip(TRUE, &clip);
  322.             _cursor(&curs_rect);
  323.         }
  324.         while(rc_next(w->handle, &clip));
  325.     }
  326.     if (hidden)
  327.         show_mouse();
  328.     wind_update(END_UPDATE);
  329. }
  330.  
  331. static ZEILEP get_wline(TEXTP t_ptr, long y)
  332. {
  333.     ZEILEP    lauf;
  334.     long         i;
  335.  
  336.     if (y < 0 || y >= t_ptr->text.lines)
  337.         return NULL;
  338.     i = t_ptr->ypos;
  339.     lauf = t_ptr->cursor_line;
  340.     if (i > y)
  341.     {
  342.         i -= y;
  343.         while (TRUE)
  344.         {
  345.             VORG(lauf);
  346.             if ((--i)==0)
  347.                 break;
  348.         }
  349.     }
  350.     else if (i < y)
  351.     {
  352.         y -= i;
  353.         while (TRUE)
  354.         {
  355.             NEXT(lauf);
  356.             if ((--y)==0)
  357.                 break;
  358.         }
  359.     }
  360.     return (lauf);
  361. }
  362.  
  363. /*-----------------------------------------------------------------------------
  364.  * Fläche füllen.
  365.  *
  366.  * x ist Pixel-Koordinate
  367.  * y ist Pixel-Koordinate
  368.  * w ist die Breite in Pixel, die abgedeckt werden soll
  369. */
  370. void fill_area(int x, int y, int w, int h, int color)
  371. {
  372.     int    pxy[4];
  373.  
  374.     if (w <= 0) 
  375.         return;
  376.     pxy[0] = x;
  377.     pxy[1] = y;
  378.     pxy[2] = x + w - 1;
  379.     pxy[3] = y + h - 1;
  380.     set_fill_color(color);
  381.     vswr_mode(vdi_handle, MD_REPLACE);
  382.     vr_recfl(vdi_handle, pxy);
  383.     vswr_mode(vdi_handle, draw_mode);
  384. }
  385.  
  386. /*
  387.  * String mit v_gtext() ausgeben.
  388.  *
  389.  * x ist Pixel-Koordinate
  390.  * y ist Pixel-Koordinate
  391.  * w ist die Breite in Pixel, die abgedeckt werden soll
  392.  * return ende der Textausgabe
  393. */
  394. int out_s(int x, int y, int w, char *str)
  395. {
  396.     int    pxy[8], len;
  397.  
  398.     if (w <= 0)
  399.         return x;
  400.  
  401.     if (!opt_draw)
  402.         fill_area(x, y, w, font_hcell, bg_color);
  403.  
  404.     v_gtext(vdi_handle, x, y, str);
  405.     if (font_prop)
  406.     {
  407.         vqt_extent(vdi_handle, str, pxy);
  408.         len = pxy[2]-pxy[0];
  409.     }
  410.     else
  411.         len = (int) strlen(str) * font_wcell;
  412.  
  413.     if (len < w)
  414.     {
  415.         /* Text kürzer als Fenster breit: Rest löschen */
  416.         if (opt_draw)
  417.             fill_area(x + len, y, w, font_hcell, bg_color);
  418.         return x + len;
  419.     }
  420.     return x + w;
  421. }
  422.  
  423. /*
  424.  * String invers mit v_gtext ausgeben.
  425.  *
  426.  * x ist Pixel-Koordinate
  427.  * y ist Pixel-Koordinate
  428.  * w ist die Breite in Pixel, die abgedeckt werden soll
  429.  * return ende der Textausgabe
  430. */
  431. int out_sb(int x, int y, int w, char *str)
  432. {
  433.     int    pxy[8], len;
  434.  
  435.     if (w <= 0)
  436.         return x;
  437.  
  438. #if 0
  439.     /* Hintergrund füllen, da mit XOR drübergemalt wird */
  440.     fill_area(x, y, w, font_hcell, fg_color);
  441.  
  442.     vswr_mode(vdi_handle, MD_XOR);
  443.     v_gtext(vdi_handle, x, y, str);
  444.     vswr_mode(vdi_handle, draw_mode);
  445. #endif
  446.  
  447.     /* Hintergrund mit fg_color füllen und Text mit bg_color drübermalen */
  448.     fill_area(x, y, w, font_hcell, fg_color);
  449.  
  450.     vst_color(vdi_handle, bg_color);
  451.     if (opt_draw)
  452.         vswr_mode(vdi_handle, MD_TRANS);
  453.     v_gtext(vdi_handle, x, y, str);
  454.     if (opt_draw)
  455.         vswr_mode(vdi_handle, draw_mode);
  456.     vst_color(vdi_handle, fg_color);
  457.  
  458.     if (font_prop)
  459.     {
  460.         vqt_extent(vdi_handle, str, pxy);
  461.         len = pxy[2] - pxy[0];
  462.     }
  463.     else
  464.         len = (int) strlen(str) * font_wcell;
  465.     if (len > w)
  466.         return x + w;
  467.     return x + len;
  468. }
  469.  
  470. /*
  471.  * Absatzmarke zeichnen.
  472. */
  473. static void draw_cr(int x, int y, bool inv)
  474. {
  475.     int pxy[6], h, b;
  476.  
  477.     if (inv)
  478.         vsl_color (vdi_handle, bg_color);
  479.     else
  480.         vsl_color (vdi_handle, fg_color);
  481.     b = min(font_wcell, font_hcell);
  482.     h = b >> 1;
  483.     y += (font_hcell >> 1);
  484.     pxy[0] = x + b - 1;            /* oben rechts */
  485.     pxy[1] = y - h;
  486.     pxy[2] = x + b - 1;            /* mitte rechst */
  487.     pxy[3] = y;
  488.     pxy[4] = x;                        /* mitte links */
  489.     pxy[5] = y;
  490.     v_pline (vdi_handle, 3, pxy);
  491.     h = h >> 1;
  492.     pxy[0] = x + h;                /* schräg oben */
  493.     pxy[1] = y - h;
  494.     pxy[2] = x;                        /* mitte links */
  495.     pxy[3] = y;
  496.     pxy[4] = x + h;                /* schräg unten */
  497.     pxy[5] = y + h;
  498.     v_pline (vdi_handle, 3, pxy);
  499.     if (inv)
  500.         vsl_color(vdi_handle, fg_color);
  501.     else
  502.         vsl_color(vdi_handle, bg_color);
  503. }
  504.  
  505. /*
  506.  * String mit v_gtext() ausgeben.
  507.  *
  508.  * x ist Pixel-Koordinate
  509.  * y ist Pixel-Koordinate
  510.  * w ist die Breite in Pixel, die abgedeckt werden soll
  511.  * offset in Zeichen
  512. */
  513. static void str_out(int x, int y, int w, int offset, ZEILEP a)
  514. {
  515.     int    len, anz;
  516.     int    pxy[8];
  517.  
  518.     anz = line_to_str(TEXT(a), a->len);
  519.  
  520.     if (!opt_draw)
  521.         fill_area(x, y, w, font_hcell, bg_color);
  522.  
  523.     if (font_prop)
  524.     {
  525.         /* auf bei prop. wird um font_wcell gescrollt! */
  526.         offset *= font_wcell;
  527.         x -= offset;
  528.         w += offset;
  529.         v_gtext(vdi_handle, x, y, text);
  530.         vqt_extent(vdi_handle, text, pxy);
  531.         len = pxy[2] - pxy[0];
  532.         if (len < w)
  533.         {
  534.             /* Text kürzer als Fenster breit: Rest löschen */
  535.             if (opt_draw)
  536.                 fill_area(x+len, y, w-len, font_hcell, bg_color);
  537.  
  538.             if (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end))
  539.                 draw_cr(x+len, y, FALSE);
  540.         }
  541.     }
  542.     else
  543.     {
  544.         if (offset >= anz)
  545.         {
  546.             /* kein Text, ganze Zeile löschen */
  547.             if (opt_draw)
  548.                 fill_area(x, y, w, font_hcell, bg_color);
  549.  
  550.             if (offset == anz && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  551.                 draw_cr(x, y, FALSE);
  552.         }
  553.         else
  554.         {
  555.             anz -= offset;
  556.             len = anz * font_wcell;
  557.             if (w <= len)
  558.             {
  559.                 /* Zeile bis zum rechten Fensterrand */
  560.                 text[offset+w/font_wcell] = EOS;
  561.                 v_gtext(vdi_handle, x, y, text+offset);
  562.             }
  563.             else
  564.             {
  565.                 v_gtext(vdi_handle, x, y, text+offset);
  566.  
  567.                 /* Text kürzer als Fenster breit: Rest löschen */
  568.                 if (opt_draw)
  569.                     fill_area(x+len, y, w-len, font_hcell, bg_color);
  570.  
  571.                 if (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end))
  572.                     draw_cr(x + len, y, FALSE);
  573.             }
  574.         }
  575.     }
  576. }
  577.  
  578. /*
  579.  * String mit v_gtext() invers ausgeben.
  580.  *
  581.  * x ist Pixel-Koordinate
  582.  * y ist Pixel-Koordinate
  583.  * w ist die Breite in Pixel, die abgedeckt werden soll
  584.  * offset in Zeichen
  585.  * mode (BLKANF, BLKEND, BLKFULL)
  586. */
  587. static void str_out_b(int x, int y, int w, int offset, ZEILEP a, int mode, int x1, int x2)
  588. {
  589.     int    anz, anz1, anz2, len, len2, pxy[8], end;
  590.     char    h;
  591.  
  592.     anz = line_to_str(TEXT(a), a->len);
  593.     if (anz <= offset)        /* ganze Zeile ohne Text */
  594.     {
  595.         if (font_prop)
  596.         {
  597.             vqt_extent(vdi_handle,text,pxy);
  598.             end = x - (offset * font_wcell) + (pxy[2] - pxy[0]);
  599.         }
  600.         else
  601.             end = x - (offset * font_wcell) + anz * font_wcell;
  602.         if (mode == BLKFULL || mode == BLKANF)
  603.         {
  604.             fill_area(x, y, w, font_hcell, fg_color);
  605.             if (end >= x && end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  606.                 draw_cr(end, y, TRUE);
  607.         }
  608.         else
  609.         {
  610.             fill_area(x, y, w, font_hcell, bg_color);
  611.             if (end >= x && end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  612.                 draw_cr(end, y, FALSE);
  613.         }
  614.         return;
  615.     }
  616.     if (font_prop)
  617.     {
  618.         offset *= font_wcell;
  619.         x -= offset;
  620.         w += offset;
  621.         if (mode==BLKFULL)
  622.         /* Ganze Zeile einheitlich invers */
  623.         {
  624.             end = out_sb(x,y,w,text);
  625.             if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  626.                 draw_cr(end, y, TRUE);
  627.         }
  628.         else
  629.         /* Blockanfang oder -ende oder beides */
  630.         {
  631.             if (mode==BLKANF)
  632.             {
  633.                 anz1 = bild_pos(x1,a,tab,tab_size);
  634.                 h = text[anz1]; text[anz1] = EOS;
  635.                 vqt_extent(vdi_handle,text,pxy);
  636.                 len = pxy[2]-pxy[0];
  637.                 end = out_s(x,y,len,text);
  638.                 text[anz1] = h;
  639.                 end = out_sb(end,y,w-len,text+anz1);
  640.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  641.                     draw_cr(end, y, TRUE);
  642.             }
  643.             else if (mode==BLKEND)
  644.             {
  645.                 anz1 = bild_pos(x2,a,tab,tab_size);
  646.                 h = text[anz1]; text[anz1] = EOS;
  647.                 vqt_extent(vdi_handle,text,pxy);
  648.                 len = pxy[2]-pxy[0];
  649.                 end = out_sb(x,y,len,text);
  650.                 text[anz1] = h;
  651.                 end = out_s(end,y,w-len,text+anz1);
  652.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  653.                     draw_cr(end, y, FALSE);
  654.             }
  655.             else /* (mode==(BLKANF+BLKEND) */
  656.             {
  657.                 anz1 = bild_pos(x1,a,tab,tab_size);
  658.                 h = text[anz1]; text[anz1] = EOS;
  659.                 vqt_extent(vdi_handle,text,pxy);
  660.                 len = pxy[2]-pxy[0];
  661.                 end = out_s(x,y,len,text);
  662.                 text[anz1] = h;
  663.  
  664.                 anz2 = bild_pos(x2,a,tab,tab_size);
  665.                 h = text[anz2]; text[anz2] = EOS;
  666.                 vqt_extent(vdi_handle,text+anz1,pxy);
  667.                 len2 = pxy[2]-pxy[0];
  668.                 end = out_sb(end,y,len2,text+anz1);
  669.                 text[anz2] = h;
  670.  
  671.                 end = out_s(end,y,w-len-len2,text+anz2);
  672.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  673.                     draw_cr(end, y, FALSE);
  674.             }
  675.         }
  676.     }
  677.     else
  678.     {
  679.         char *ptr = text+offset;
  680.  
  681.         anz -= offset;
  682.         if (anz * font_wcell > w)
  683.         {
  684.             anz = w/font_wcell;
  685.             ptr[anz] = EOS;
  686.         }
  687.         if (mode == BLKFULL)
  688.         /* Ganze Zeile einheitlich invers */
  689.         {
  690.             end = out_sb(x,y,w,ptr);
  691.             if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  692.                 draw_cr(end, y, TRUE);
  693.         }
  694.         else
  695.         /* Blockanfang oder -ende oder beides */
  696.         {
  697.             if (mode==BLKANF)
  698.             {
  699.                 anz1 = bild_pos(x1,a,tab,tab_size)-offset;
  700.                 if (anz1<0) anz1 = 0;
  701.                 if (anz1>anz) anz1 = anz;
  702.                 h = ptr[anz1]; ptr[anz1] = EOS;
  703.                 len = anz1*font_wcell;
  704.                 end = out_s(x,y,len,ptr);
  705.                 ptr[anz1] = h;
  706.                 end = out_sb(end,y,w-len,ptr+anz1);
  707.  
  708.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  709.                     draw_cr(end,y, TRUE);
  710.             }
  711.             else if (mode==BLKEND)
  712.             {
  713.                 anz1 = bild_pos(x2,a,tab,tab_size)-offset;
  714.                 if (anz1<0) anz1 = 0;
  715.                 if (anz1>anz) anz1 = anz;
  716.                 h = ptr[anz1]; ptr[anz1] = EOS;
  717.                 len = anz1*font_wcell;
  718.                 end = out_sb(x,y,len,ptr);
  719.                 ptr[anz1] = h;
  720.                 end = out_s(end,y,w-len,ptr+anz1);
  721.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  722.                     draw_cr(end, y, FALSE);
  723.             }
  724.             else /* (mode==(BLKANF+BLKEND) */
  725.             {
  726.                 anz1 = bild_pos(x1,a,tab,tab_size)-offset;
  727.                 if (anz1<0) anz1 = 0;
  728.                 if (anz1>anz) anz1 = anz;
  729.                 h = ptr[anz1]; ptr[anz1] = EOS;
  730.                 len = anz1*font_wcell;
  731.                 end = out_s(x,y,len,ptr);
  732.                 ptr[anz1] = h;
  733.  
  734.                 anz2 = bild_pos(x2,a,tab,tab_size)-offset;
  735.                 if (anz2<0) anz2 = 0;
  736.                 if (anz2>anz) anz2 = anz;
  737.                 h = ptr[anz2]; ptr[anz2] = EOS;
  738.                 len2  = anz2*font_wcell - len;
  739.                 end = out_sb(end,y,len2,ptr+anz1);
  740.                 ptr[anz2] = h;
  741.  
  742.                 end = out_s(end,y,w-len-len2,ptr+anz2);
  743.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  744.                     draw_cr(end, y, FALSE);
  745.             }
  746.         }
  747.     }
  748. }
  749.  
  750. /* =========================================================== */
  751.  
  752. void line_out(WINDOWP window, TEXTP t_ptr, int wy)
  753. {
  754.     int        y;
  755.     ZEILEP    col;
  756.  
  757.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  758.     tab = t_ptr->loc_opt->tab;
  759.     tab_size = t_ptr->loc_opt->tabsize;
  760.     umbrechen = t_ptr->loc_opt->umbrechen;
  761.     show_end = t_ptr->loc_opt->show_end;
  762.     y = window->work.g_y+wy*font_hcell;
  763.     col = get_wline(t_ptr, window->doc.y+wy);
  764.     if (col != NULL)                                                /* Kommt vor */
  765.     {
  766.         if (t_ptr->block)
  767.         {
  768.             wy += (int) window->doc.y;
  769.             if (wy<t_ptr->z1 || wy>t_ptr->z2)
  770.                 str_out(window->work.g_x, y, window->work.g_w, (int)window->doc.x, col);
  771.             else
  772.             {
  773.                 int    mode = 0;
  774.  
  775.                 if (wy == t_ptr->z1)
  776.                     mode |= BLKANF;
  777.                 if (wy == t_ptr->z2)
  778.                     mode |= BLKEND;
  779.                 if (!mode)
  780.                     mode = BLKFULL;
  781.                 str_out_b(window->work.g_x, y, window->work.g_w,
  782.                          (int) window->doc.x, col, mode, t_ptr->x1, t_ptr->x2);
  783.             }
  784.         }
  785.         else
  786.             str_out(window->work.g_x, y, window->work.g_w, (int) window->doc.x, col);
  787.     }
  788.     else
  789.         fill_area(window->work.g_x, y, window->work.g_w, font_hcell, bg_color);
  790. }
  791.  
  792. void bild_out(WINDOWP window, TEXTP t_ptr)
  793. {
  794.     int        x, y, w;
  795.     ZEILEP    lauf;
  796.     int        min_col, max_col, max_y;
  797.     GRECT        c;
  798.  
  799.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  800.     tab = t_ptr->loc_opt->tab;
  801.     tab_size = t_ptr->loc_opt->tabsize;
  802.     umbrechen = t_ptr->loc_opt->umbrechen;
  803.     show_end = t_ptr->loc_opt->show_end;
  804.     x = window->work.g_x;
  805.     y = window->work.g_y;
  806.     w = window->work.g_w;
  807.  
  808.     if (window->class == CLASS_EDIT)                        /* Kopf ausgeben */
  809.         head_out(window, t_ptr);
  810.  
  811.     min_col = 0;
  812.     max_col = (int) min(window->w_height - 1, t_ptr->text.lines - window->doc.y-1);
  813.     max_y   = y + window->work.g_h-1;
  814.     if (get_clip(&c))                    /* nicht alles malen */
  815.     {
  816.         int y2 = c.g_y - y;
  817.  
  818.         min_col = max(min_col, y2/font_hcell);
  819.         max_col = min(max_col, (c.g_y + c.g_h - 1) / font_hcell);
  820.         max_y = min(max_y, c.g_y + c.g_h - 1);
  821.     }
  822.     y += (min_col * font_hcell);
  823.     lauf = get_wline(t_ptr, window->doc.y + min_col);
  824.     if (lauf != NULL)
  825.     {
  826.         int    xoffset, i;
  827.  
  828.         xoffset = (int) window->doc.x;
  829.         if (t_ptr->block)
  830.         {
  831.             long    y_r;
  832.  
  833.             y_r = window->doc.y+min_col;
  834.             for (i=min_col ; i<=max_col; y_r++,y+=font_hcell,NEXT(lauf),i++)
  835.             {
  836.                 /* Block nicht sichtbar */
  837.                 if (y_r < t_ptr->z1 || y_r > t_ptr->z2)
  838.                     str_out(x, y, w, xoffset, lauf);
  839.                 else
  840.                 {
  841.                     int mode = 0;
  842.  
  843.                     if (y_r == t_ptr->z1)
  844.                         mode |= BLKANF;
  845.                     if (y_r == t_ptr->z2)
  846.                         mode |= BLKEND;
  847.                     if (!mode)
  848.                         mode = BLKFULL;
  849.                     str_out_b(x, y, w, xoffset, lauf, mode, t_ptr->x1, t_ptr->x2);
  850.                 }
  851.             }
  852.         }
  853.         else
  854.         {
  855.             for (i=min_col ; i<=max_col; y+=font_hcell,NEXT(lauf),i++)
  856.                 str_out(x,y,w,xoffset,lauf);
  857.         }
  858.     }
  859.  
  860.     /* Fenster höher als Text lang ist -> Rest löschen */
  861.     if (y < max_y)
  862.         fill_area(x, y, w, (max_y - y + 1), bg_color);
  863. }
  864.  
  865. void bild_blkout(WINDOWP window, TEXTP t_ptr, long z1, long z2)
  866. /* Alle Textzeilen zwischen z1 und z2 werden neu ausgegeben */
  867. {
  868.     int        i, x, y, w, xoffset;
  869.     ZEILEP    lauf;
  870.     int        max_col;
  871.     long        lines, y_r;
  872.  
  873.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  874.     tab = t_ptr->loc_opt->tab;
  875.     tab_size = t_ptr->loc_opt->tabsize;
  876.     umbrechen = t_ptr->loc_opt->umbrechen;
  877.     show_end = t_ptr->loc_opt->show_end;
  878.     if (z1>z2)
  879.     {
  880.         lines = z1;
  881.         z1 = z2;
  882.         z2 = lines;
  883.     }
  884.     x          = window->work.g_x;
  885.     y           = window->work.g_y;
  886.     w          = window->work.g_w;
  887.     xoffset = (int) window->doc.x;
  888.     max_col = (int) min(window->w_height-1, t_ptr->text.lines-window->doc.y-1);
  889.     y_r      = window->doc.y;
  890.     lauf = get_wline(t_ptr, y_r);
  891.  
  892.     if (t_ptr->block)
  893.         for (i=0; i<=max_col; i++,y+=font_hcell,y_r++)
  894.         {
  895.             if (y_r>=z1 && y_r<=z2)
  896.             {
  897.                 if (y_r<t_ptr->z1 || y_r>t_ptr->z2)
  898.                     str_out(x,y,w,xoffset,lauf);
  899.                 else
  900.                 {
  901.                     int mode = 0;
  902.  
  903.                     if (y_r==t_ptr->z1) mode |= BLKANF;
  904.                     if (y_r==t_ptr->z2) mode |= BLKEND;
  905.                     if (!mode) mode = BLKFULL;
  906.                     str_out_b(x,y,w,xoffset,lauf,mode,t_ptr->x1,t_ptr->x2);
  907.                 }
  908.             }
  909.             NEXT(lauf);
  910.         }
  911.     else
  912.         for (i=0; i<=max_col; i++,y+=font_hcell,y_r++)
  913.         {
  914.             if (y_r>=z1 && y_r<=z2)
  915.                 str_out(x,y,w,xoffset,lauf);
  916.             NEXT(lauf);
  917.         }
  918. }
  919.  
  920.  
  921. /***************************************************************************/
  922.  
  923. void head_out(WINDOWP window, TEXTP t_ptr)
  924. {
  925.     char    head_str[WINSTRLEN];
  926.     int    len, head_len;
  927.  
  928.     if (t_ptr->info_str[0] != EOS)
  929.     {
  930.         strncpy(head_str, t_ptr->info_str, WINSTRLEN);
  931.         head_str[WINSTRLEN] = EOS;
  932.         head_len = (int) strlen(head_str);
  933.     }
  934.     else 
  935.     {
  936.         if (t_ptr->text.ending != binmode)
  937.         {
  938.             head_len = (int) strlen(rsc_string(HEADSTR));
  939.             strcpy(head_str, rsc_string(HEADSTR));
  940.             if (t_ptr->readonly)
  941.                 head_str[1] = '\x7F';
  942.     
  943.             switch (t_ptr->text.ending)
  944.             {
  945.                 case tos :
  946.                     break;
  947.                 case unix :
  948.                     head_str[2] = 'U';
  949.                     break;
  950.                 case apple :
  951.                     head_str[2] = 'A';
  952.                     break;
  953.                 default:
  954.                     head_str[2] = '?';
  955.             }
  956.  
  957.             ltoa(t_ptr->ypos+1, head_str + 8, 10);
  958.             head_str[strlen(head_str)] = ' ';
  959.             itoa(bild_pos(t_ptr->xpos,t_ptr->cursor_line,tab,tab_size)+1,head_str+18,10);
  960.             head_str[strlen(head_str)] = ' ';
  961.         }
  962.         else
  963.         {
  964.             long    p;
  965.             
  966.             head_len = (int) strlen(rsc_string(BHEADSTR));
  967.             strcpy(head_str, rsc_string(BHEADSTR));
  968.             if (t_ptr->readonly)
  969.                 head_str[1] = '\x7F';
  970.             p = t_ptr->ypos * t_ptr->text.max_line_len + t_ptr->xpos + 1;
  971.             ltoa(p, head_str + 24, 10);
  972.         }
  973.     }
  974.     len = window->work.g_w / gl_wchar;
  975.     if (len < head_len)
  976.         head_str[len] = EOS;
  977.     set_winfo(window, head_str);
  978. }
  979.  
  980. /***************************************************************************/
  981.