21 u_int16 label::cursor_blink_cycle = 75;
23 #define LINE_LENGTH(line) (line.pos_x + line.offset_x/screen::scale())
44 cursor_cur_blink_ = 0;
75 my_old_cursor_ = my_cursor_;
79 my_cursor_.idx = my_text_.length ();
95 int size = new_text_.length ();
96 if (size == 2 && (
u_int8) new_text_[0] >= 0xE0)
return;
97 if (size == 1 && (
u_int8) new_text_[0] >= 0x80)
return;
99 my_old_cursor_ = my_cursor_;
101 if (my_old_cursor_.idx == my_text_.length ())
103 my_text_ += new_text_;
104 my_cursor_.idx = my_text_.length ();
106 else my_text_.insert (my_cursor_.idx, new_text_);
130 if (my_text_.empty())
143 memset(&my_cursor_, 0,
sizeof my_cursor_);
150 memset(&tmp, 0,
sizeof tmp);
153 my_vect_.push_back (tmp);
168 if (my_font_ == NULL)
return;
175 draw_string (!erase_all);
179 build_form_auto_height ();
181 draw_string (!erase_all);
185 build_form_auto_size ();
209 moveable_cursor_ = b;
219 u_int16 j, word_length, word_length_pix, start_idx;
226 line_tmp.idx_beg = my_vect_[my_old_cursor_.line].idx_beg;
228 line_tmp.offset_x = 0;
231 start_idx = line_tmp.idx_beg;
234 vector <Sline_text>::iterator ii = my_vect_.begin ();
236 while (i != my_old_cursor_.line) { i++; ii++; }
237 my_vect_.erase (ii, my_vect_.end ());
241 while (start_idx < my_text_.length () )
244 if (my_text_[start_idx] ==
'\n')
247 line_tmp.idx_end = start_idx;
250 my_vect_.push_back (line_tmp);
254 line_tmp.offset_x = 0;
255 line_tmp.idx_beg = ++start_idx;
259 else if (my_text_[start_idx] ==
' ')
261 if ((*my_font_) [
' '].
length () + LINE_LENGTH(line_tmp) >
length ())
263 line_tmp.idx_end = start_idx;
266 my_vect_.push_back (line_tmp);
270 line_tmp.offset_x = 0;
271 line_tmp.idx_beg = ++start_idx;
277 line_tmp.pos_x += (*my_font_) [
' '].length ();
278 if (prev_c != 0) line_tmp.offset_x += my_font_->kerning(prev_c,
' ');
288 switch (find_word (start_idx, word_length, word_length_pix, word_offset_x, prev_c, LINE_LENGTH(line_tmp)))
291 line_tmp.pos_x += word_length_pix;
292 line_tmp.offset_x += word_offset_x;
303 (my_vect_.size () - start_line_) * my_font_->height (),
304 length () - LINE_LENGTH(line_tmp),
307 line_tmp.idx_end = (start_idx - word_length) - 1;
308 my_vect_.push_back (line_tmp);
310 line_tmp.pos_x = word_length_pix;
311 line_tmp.offset_x = word_offset_x;
312 line_tmp.idx_beg = start_idx - word_length;
318 j = start_idx - word_length;
319 while (j < start_idx)
322 if (line_tmp.pos_x + (*my_font_) [c].length () >
length ())
324 line_tmp.idx_end = j - 1;
325 my_vect_.push_back (line_tmp);
328 line_tmp.offset_x = 0;
329 line_tmp.idx_beg = j;
331 line_tmp.pos_x += (*my_font_) [c].length ();
332 if (prev_c != 0) line_tmp.offset_x += my_font_->kerning(prev_c, c);
343 line_tmp.idx_end = start_idx - 1;
344 my_vect_.push_back (line_tmp);
348 void label::build_form_auto_height ()
355 u_int16 new_size = my_vect_.size () * my_font_->height ();
357 if (new_size !=
height ())
361 draw (0, 0, 0, 0,
length (), my_old_cursor_.pos_y + my_font_->height (), NULL, &tmp);
363 tmp.draw (0, 0, NULL,
this);
368 void label::build_form_auto_size ()
379 line_tmp.offset_x = 0;
380 line_tmp.idx_beg = 0;
385 while ( i < my_text_.size ())
387 if (my_text_[i] ==
'\n')
389 if (line_tmp.pos_x + LINE_LENGTH(line_tmp) > max_length)
391 max_length = LINE_LENGTH(line_tmp);
393 line_tmp.idx_end = i;
394 my_vect_.push_back (line_tmp);
396 line_tmp.idx_beg = i+1;
398 line_tmp.offset_x = 0;
405 line_tmp.pos_x += (*my_font_) [c].length ();
406 if (prev_c != 0) line_tmp.offset_x += my_font_->kerning(prev_c, c);
412 if (LINE_LENGTH(line_tmp) > max_length)
414 max_length = LINE_LENGTH(line_tmp);
418 line_tmp.idx_end = i-1;
419 my_vect_.push_back (line_tmp);
422 image::resize (max_length, my_vect_.size () * my_font_->height ());
425 void label::fit_text_width()
428 for (vector<Sline_text>::iterator i = my_vect_.begin(); i != my_vect_.end(); i++)
430 if (LINE_LENGTH((*i)) > new_size)
432 new_size = LINE_LENGTH((*i));
442 void label::clean_surface (
const bool erase_all)
446 if ( my_cursor_.idx != my_text_.length ())
449 fillrect ( my_old_cursor_.pos_x, my_old_cursor_.pos_y,
length () - my_old_cursor_.pos_x,
452 fillrect (0, my_old_cursor_.pos_y + my_font_->height (),
length (),
481 while (index < my_text_.length () && my_text_[index] !=
' ' && my_text_[index] !=
'\n')
484 wlengthpix += (*my_font_) [c].length ();
485 if (last_letter != 0) woffset += my_font_->kerning(last_letter, c);
491 wlength = index - wlength;
502 void label::update_cursor ()
508 cursor_cur_blink_ = cursor_blink_cycle;
511 while (!b && my_cursor_.line < my_vect_.size () )
513 if (my_cursor_.idx >= my_vect_[my_cursor_.line].idx_beg &&
514 my_cursor_.idx <= my_vect_[my_cursor_.line].idx_end ) b =
true;
515 else if (my_cursor_.idx > my_vect_[my_cursor_.line].idx_end)
517 if (my_cursor_.line == my_vect_.size () - 1) b =
true;
518 else my_cursor_.line++;
520 else if (my_cursor_.idx < my_vect_[my_cursor_.line].idx_beg)
527 my_cursor_.pos_x = 0;
528 my_cursor_.offset_x = 0;
531 u_int16 j = my_vect_[my_cursor_.line].idx_beg;
532 while (j < my_cursor_.idx) {
534 my_cursor_.pos_x+= (*my_font_) [c].length ();
535 if (prev_c != 0) my_cursor_.offset_x += my_font_->kerning(prev_c, c);
541 my_cursor_.pos_y = (my_cursor_.line - start_line_) * my_font_->height ();
547 void label::draw_string (
const bool at_cursor)
556 clean_surface (!at_cursor);
560 tmp_start_line = my_old_cursor_.line;
561 tx = my_old_cursor_.pos_x;
562 ox = my_cursor_.offset_x;
563 idx_cur_line = my_old_cursor_.idx;
564 ty = (tmp_start_line - start_line_) * my_font_->height ();
568 tmp_start_line = start_line_;
569 idx_cur_line = my_vect_[tmp_start_line].idx_beg;
573 for (j = idx_cur_line;
574 j < my_vect_[tmp_start_line].idx_end + 1 ;
578 if (c !=
'\n' && my_font_->in_table (c))
580 if (prev_c != 0) ox += my_font_->kerning(prev_c, c);
582 (*my_font_) [c].draw (tx, ty, NULL,
this);
583 tx += (*my_font_) [c].length ();
588 ty += my_font_->height ();
593 while (tmp_start_line < my_vect_.size ())
597 for (j = my_vect_[tmp_start_line].idx_beg;
598 j < my_vect_[tmp_start_line].idx_end + 1 ;
602 if (my_font_->in_table (c))
604 if (prev_c != 0) ox += my_font_->kerning(prev_c, c);
606 (*my_font_) [c].draw (tx, ty, NULL,
this);
607 tx += (*my_font_) [c].length ();
612 ty += my_font_->height ();
623 if (cursor_cur_blink_ == cursor_blink_cycle)
628 cursor_cur_blink_ = 0;
629 }
else if (cursor_cur_blink_ == (cursor_blink_cycle >> 1))
638 void label::cursor_draw ()
643 if (last_letter (idx) || my_text_[idx] ==
'\n')
644 my_font_->cursor->
draw (my_cursor_.pos_x, my_cursor_.pos_y,NULL,
this);
646 my_font_->cursor->
draw (my_cursor_.pos_x, my_cursor_.pos_y,0, 0,
647 (*my_font_) [ucd (idx)].
length (),
648 my_font_->height (), NULL,
this);
651 void label::cursor_undraw ()
656 if (last_letter (idx) || my_text_[idx] ==
'\n')
658 fillrect(my_cursor_.pos_x, my_cursor_.pos_y,
659 my_font_->cursor->
length () ,
660 my_font_->cursor->
height(),
663 else (*my_font_) [ucd (idx)].draw (my_cursor_.pos_x, my_cursor_.pos_y, NULL,
this);
666 bool label::last_letter (
u_int16 idx)
668 if ((
u_int8) my_text_[idx] == 0xEF)
return my_text_.length () - idx == 2;
669 if ((
u_int8) my_text_[idx] == 0xC3)
return my_text_.length () - idx == 1;
670 return my_cursor_.idx == my_text_.length ();
692 void label::cursor_next ()
694 if (!moveable_cursor_)
return;
695 if (my_cursor_.idx < my_text_.length ())
699 if (my_cursor_.idx < my_text_.length () - 2 && (
u_int8) my_text_[my_cursor_.idx+1] == 0xEF) count = 3;
700 else if (my_cursor_.idx < my_text_.length () - 1 && (
u_int8) my_text_[my_cursor_.idx+1] == 0xC3) count = 2;
703 my_cursor_.idx += count;
709 void label::cursor_previous ()
711 if (!moveable_cursor_)
return;
712 if (my_cursor_.idx > 0)
716 if (my_cursor_.idx > 2 && (
u_int8) my_text_[my_cursor_.idx-3] == 0xEF) count = 3;
717 else if (my_cursor_.idx > 1 && (
u_int8) my_text_[my_cursor_.idx-2] == 0xC3) count = 2;
720 my_cursor_.idx -= count;
733 return my_text_.c_str ();
739 const u_int8 c = text.at(i);
740 if (c < 0x80)
return c;
744 const u_int8 c1 = text.at(++i);
745 return ((
u_int16) (c & 0x1f) << 6)
749 const u_int8 c1 = text.at(++i);
750 const u_int8 c2 = text.at(++i);
751 return ((
u_int16) (c & 0x0f) << 12)