source: golgotha/src/i4/gui/text_scroll.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 5.7 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#ifdef _MANGLE_INC
10#include "gui/TEXT_~ZG.HH"
11#else
12#include "gui/text_scroll.hh"
13#endif
14#include "window/style.hh"
15#include "area/rectlist.hh"
16
17
18static inline int fmt_char(char c)
19{
20  if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
21    return 1;
22  return 0;
23}
24
25void i4_text_scroll_window_class::printf(char *fmt, ...)
26{
27  va_list ap;
28  va_start(ap, fmt);
29
30  while (*fmt)
31  {
32    if (*fmt=='%')
33    {
34      char *fmt_end=fmt;
35      while (!fmt_char(*fmt_end) && *fmt_end) fmt_end++;
36      char f[10], out[500];
37      memcpy(f, fmt, fmt_end-fmt+1);
38      f[fmt_end-fmt+1]=0;
39      out[0]=0;
40
41      switch (*fmt_end)
42      {
43        case 's' :
44        {
45          char *str=va_arg(ap,char *);
46          output_string(str);
47        } break;         
48
49        case 'd' :
50        case 'i' :
51        case 'x' :
52        case 'X' :
53        case 'c' :
54        case 'o' :
55        {
56          ::sprintf(out,f,va_arg(ap,int));
57          output_string(out);
58        } break;
59
60        case 'f' :
61        case 'g' :
62          ::sprintf(out,f,va_arg(ap,double));
63          output_string(out);
64          break;
65
66        default :
67          ::sprintf(out,f,va_arg(ap,void *));
68          output_string(out);
69          break;
70      }
71      fmt=fmt_end;
72      if (*fmt)
73        fmt++;
74    }
75    else
76    {
77      output_char(*fmt);
78      fmt++;
79    }
80  }
81  va_end(ap);
82}
83
84
85
86i4_text_scroll_window_class::i4_text_scroll_window_class(i4_graphical_style_class *style,
87                                                         i4_color text_foreground,
88                                                         i4_color text_background,
89                                                         w16 width, w16 height)    // in pixels
90  : i4_parent_window_class(width, height),
91    style(style),
92    fore(text_foreground),
93    back(text_background)
94{
95  i4_font_class *fnt=style->font_hint->normal_font;
96
97  term_height=height/fnt->largest_height();
98  term_size=(width/fnt->largest_width() + 1) * term_height;
99
100  if (!term_size)
101    term_size=512;
102
103  term_out=(i4_char *)i4_malloc(term_size, "terminal chars");
104
105  draw_start=term_out;
106  line_height=fnt->largest_height()+1;
107  *term_out=0;
108  dx=dy=tdx=tdy=0;
109  need_clear=i4_T;
110  used_size = 0;
111}
112
113void i4_text_scroll_window_class::skip_first_line()
114{
115  i4_font_class *fnt=style->font_hint->normal_font;
116  w32 x=0, wd=width(), count=0;
117  i4_char *s=term_out;
118   
119  while (s->value() && x<wd)
120  {
121    if (s->value()=='\n')
122      x=wd;
123    else
124      x+=fnt->width(*s);
125    count++;
126    s++;
127  }
128  memmove(term_out, s, used_size-count+1);
129  used_size-=count;
130}
131
132void i4_text_scroll_window_class::output_string(char *string)
133{
134  while (*string)
135  {
136    output_char( (i4_char)(*string));
137    string++;
138  }
139}
140
141void i4_text_scroll_window_class::output_char(const i4_char &ch)
142{
143  sw32 i;
144  i4_font_class *fnt=style->font_hint->normal_font;
145
146  if (used_size+2>term_size)
147  {
148    term_size+=100;
149    i4_char *old_spot=term_out;
150    term_out=(i4_char *)i4_realloc(term_out, term_size, "terminal chars");
151    dx=dy=0;
152    draw_start=term_out;       
153    need_clear=i4_T;   
154  }
155
156  if (!redraw_flag)
157    request_redraw();
158
159  tdx+=fnt->width(ch);
160  if (tdx>=width() || ch=='\n')
161  {
162    tdx=0;
163    tdy+=line_height;
164    if (tdy+line_height>height())
165    {
166      skip_first_line();
167      tdy-=line_height;
168      dx=dy=0;
169      draw_start=term_out;       
170      need_clear=i4_T;
171    }
172  }
173
174  term_out[used_size++]=ch; 
175  term_out[used_size]=0;
176}
177
178void i4_text_scroll_window_class::clear()
179{
180  draw_start=term_out;
181  *term_out=0;
182  dx=dy=tdx=tdy=0;
183  need_clear=i4_T;
184  used_size = 0;
185  request_redraw(i4_F);
186}
187
188void i4_text_scroll_window_class::resize(w16 new_width, w16 new_height)
189{
190  i4_font_class *fnt=style->font_hint->normal_font;
191  term_height=new_height/fnt->largest_height();
192 
193  int new_size=(new_width/fnt->largest_width() + 1) * term_height;
194  if (new_size>term_size)
195  {
196    term_size=new_size;
197
198    if (!term_size)
199      term_size=512;
200
201    if (term_out)
202      term_out=(i4_char *)i4_realloc(term_out, term_size, "terminal chars");
203    else
204    {
205      term_out=(i4_char *)i4_malloc(term_size, "terminal chars");
206      term_out[0]=0;
207    }
208  }
209
210  dx=dy=tdx=tdy=0;
211  used_size = 0;
212
213  i4_parent_window_class::resize(new_width, new_height);
214}
215
216
217void i4_text_scroll_window_class::parent_draw(i4_draw_context_class &context)
218{
219  i4_font_class *fnt=style->font_hint->normal_font;
220
221  if (!undrawn_area.empty())
222  {
223    draw_start=term_out;
224    dx=dy=0;
225    need_clear=i4_T;
226  }
227   
228  if (need_clear)
229  {
230    if (back==style->color_hint->neutral())
231      style->deco_neutral_fill(local_image, 0,0, width()-1, height()-1, context);
232    else
233      local_image->clear(back, context);
234
235    need_clear=i4_F;
236  }
237  fnt->set_color(fore);
238
239  while (draw_start->value())
240  {
241    if (draw_start->value()=='\n')
242      dx=width()+1;
243    else
244    {
245      fnt->put_character(local_image, dx,dy, *draw_start, context);
246      dx+=fnt->width(*draw_start);
247    }
248
249    if (dx>=width())
250    {
251      dx=0;
252      dy+=fnt->largest_height();
253    }
254
255    draw_start++; 
256  }
257  tdx=dx;
258  tdy=dy;
259  i4_parent_window_class::parent_draw(context);
260}
261
262i4_bool i4_text_scroll_window_class::need_redraw()
263{
264  if (draw_start->value())
265    return i4_T;
266  else
267    return i4_parent_window_class::need_redraw();
268}     
Note: See TracBrowser for help on using the repository browser.