text_scroll.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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. #ifdef _MANGLE_INC
  9. #include "gui/TEXT_~ZG.HH"
  10. #else
  11. #include "gui/text_scroll.hh"
  12. #endif
  13. #include "window/style.hh"
  14. #include "area/rectlist.hh"
  15. static inline int fmt_char(char c)
  16. {
  17. if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
  18. return 1;
  19. return 0;
  20. }
  21. void i4_text_scroll_window_class::printf(char *fmt, ...)
  22. {
  23. va_list ap;
  24. va_start(ap, fmt);
  25. while (*fmt)
  26. {
  27. if (*fmt=='%')
  28. {
  29. char *fmt_end=fmt;
  30. while (!fmt_char(*fmt_end) && *fmt_end) fmt_end++;
  31. char f[10], out[500];
  32. memcpy(f, fmt, fmt_end-fmt+1);
  33. f[fmt_end-fmt+1]=0;
  34. out[0]=0;
  35. switch (*fmt_end)
  36. {
  37. case 's' :
  38. {
  39. char *str=va_arg(ap,char *);
  40. output_string(str);
  41. } break;
  42. case 'd' :
  43. case 'i' :
  44. case 'x' :
  45. case 'X' :
  46. case 'c' :
  47. case 'o' :
  48. {
  49. ::sprintf(out,f,va_arg(ap,int));
  50. output_string(out);
  51. } break;
  52. case 'f' :
  53. case 'g' :
  54. ::sprintf(out,f,va_arg(ap,double));
  55. output_string(out);
  56. break;
  57. default :
  58. ::sprintf(out,f,va_arg(ap,void *));
  59. output_string(out);
  60. break;
  61. }
  62. fmt=fmt_end;
  63. if (*fmt)
  64. fmt++;
  65. }
  66. else
  67. {
  68. output_char(*fmt);
  69. fmt++;
  70. }
  71. }
  72. va_end(ap);
  73. }
  74. i4_text_scroll_window_class::i4_text_scroll_window_class(i4_graphical_style_class *style,
  75. i4_color text_foreground,
  76. i4_color text_background,
  77. w16 width, w16 height) // in pixels
  78. : i4_parent_window_class(width, height),
  79. style(style),
  80. fore(text_foreground),
  81. back(text_background)
  82. {
  83. i4_font_class *fnt=style->font_hint->normal_font;
  84. term_height=height/fnt->largest_height();
  85. term_size=(width/fnt->largest_width() + 1) * term_height;
  86. if (!term_size)
  87. term_size=512;
  88. term_out=(i4_char *)i4_malloc(term_size, "terminal chars");
  89. draw_start=term_out;
  90. line_height=fnt->largest_height()+1;
  91. *term_out=0;
  92. dx=dy=tdx=tdy=0;
  93. need_clear=i4_T;
  94. used_size = 0;
  95. }
  96. void i4_text_scroll_window_class::skip_first_line()
  97. {
  98. i4_font_class *fnt=style->font_hint->normal_font;
  99. w32 x=0, wd=width(), count=0;
  100. i4_char *s=term_out;
  101. while (s->value() && x<wd)
  102. {
  103. if (s->value()=='\n')
  104. x=wd;
  105. else
  106. x+=fnt->width(*s);
  107. count++;
  108. s++;
  109. }
  110. memmove(term_out, s, used_size-count+1);
  111. used_size-=count;
  112. }
  113. void i4_text_scroll_window_class::output_string(char *string)
  114. {
  115. while (*string)
  116. {
  117. output_char( (i4_char)(*string));
  118. string++;
  119. }
  120. }
  121. void i4_text_scroll_window_class::output_char(const i4_char &ch)
  122. {
  123. sw32 i;
  124. i4_font_class *fnt=style->font_hint->normal_font;
  125. if (used_size+2>term_size)
  126. {
  127. term_size+=100;
  128. i4_char *old_spot=term_out;
  129. term_out=(i4_char *)i4_realloc(term_out, term_size, "terminal chars");
  130. dx=dy=0;
  131. draw_start=term_out;
  132. need_clear=i4_T;
  133. }
  134. if (!redraw_flag)
  135. request_redraw();
  136. tdx+=fnt->width(ch);
  137. if (tdx>=width() || ch=='\n')
  138. {
  139. tdx=0;
  140. tdy+=line_height;
  141. if (tdy+line_height>height())
  142. {
  143. skip_first_line();
  144. tdy-=line_height;
  145. dx=dy=0;
  146. draw_start=term_out;
  147. need_clear=i4_T;
  148. }
  149. }
  150. term_out[used_size++]=ch;
  151. term_out[used_size]=0;
  152. }
  153. void i4_text_scroll_window_class::clear()
  154. {
  155. draw_start=term_out;
  156. *term_out=0;
  157. dx=dy=tdx=tdy=0;
  158. need_clear=i4_T;
  159. used_size = 0;
  160. request_redraw(i4_F);
  161. }
  162. void i4_text_scroll_window_class::resize(w16 new_width, w16 new_height)
  163. {
  164. i4_font_class *fnt=style->font_hint->normal_font;
  165. term_height=new_height/fnt->largest_height();
  166. int new_size=(new_width/fnt->largest_width() + 1) * term_height;
  167. if (new_size>term_size)
  168. {
  169. term_size=new_size;
  170. if (!term_size)
  171. term_size=512;
  172. if (term_out)
  173. term_out=(i4_char *)i4_realloc(term_out, term_size, "terminal chars");
  174. else
  175. {
  176. term_out=(i4_char *)i4_malloc(term_size, "terminal chars");
  177. term_out[0]=0;
  178. }
  179. }
  180. dx=dy=tdx=tdy=0;
  181. used_size = 0;
  182. i4_parent_window_class::resize(new_width, new_height);
  183. }
  184. void i4_text_scroll_window_class::parent_draw(i4_draw_context_class &context)
  185. {
  186. i4_font_class *fnt=style->font_hint->normal_font;
  187. if (!undrawn_area.empty())
  188. {
  189. draw_start=term_out;
  190. dx=dy=0;
  191. need_clear=i4_T;
  192. }
  193. if (need_clear)
  194. {
  195. if (back==style->color_hint->neutral())
  196. style->deco_neutral_fill(local_image, 0,0, width()-1, height()-1, context);
  197. else
  198. local_image->clear(back, context);
  199. need_clear=i4_F;
  200. }
  201. fnt->set_color(fore);
  202. while (draw_start->value())
  203. {
  204. if (draw_start->value()=='\n')
  205. dx=width()+1;
  206. else
  207. {
  208. fnt->put_character(local_image, dx,dy, *draw_start, context);
  209. dx+=fnt->width(*draw_start);
  210. }
  211. if (dx>=width())
  212. {
  213. dx=0;
  214. dy+=fnt->largest_height();
  215. }
  216. draw_start++;
  217. }
  218. tdx=dx;
  219. tdy=dy;
  220. i4_parent_window_class::parent_draw(context);
  221. }
  222. i4_bool i4_text_scroll_window_class::need_redraw()
  223. {
  224. if (draw_start->value())
  225. return i4_T;
  226. else
  227. return i4_parent_window_class::need_redraw();
  228. }