//------------------------------------------------- // truncate_wrap //------------------------------------------------- void truncate_wrap() { char32_t elipsis = 0x2026; // for now, lets assume that we're only truncating the last character UInt32 truncate_position = m_current_line.character_count() - 1; var truncate_char = m_current_line.character(truncate_position); // copy style information char_style style = truncate_char.style; // copy source information source_info source; source.start = truncate_char.source.start + truncate_char.source.span; source.span = 0; // figure out how wide an elipsis is float elipsis_width = get_char_width(elipsis, style.size); // where should we really truncate from? while (truncate_position > 0 && m_current_line.character(truncate_position).xoffset + elipsis_width > width()) { truncate_position--; } // truncate!!! m_current_line.truncate(truncate_position); // and append the elipsis m_current_line.add_character(elipsis, style, source); // take note that we are truncating; supress new characters m_truncating = true; }
// methods //------------------------------------------------- // line::add_character //------------------------------------------------- public void add_character(text_layout layout, char32_t ch, char_style style, source_info source) { // get the width of this character float chwidth = layout.get_char_width(ch, style.size); // append the positioned character m_characters.emplace_back(new positioned_char() { character = ch, style = style, source = source, xoffset = m_width, xwidth = chwidth }); m_width += chwidth; // we might be bigger m_height = std.max(m_height, style.size * layout.yscale()); }
// methods //------------------------------------------------- // line::add_character //------------------------------------------------- public void add_character(char32_t ch, char_style style, source_info source) { // get the width of this character float chwidth = m_layout.get_char_width(ch, style.size); // create the positioned character positioned_char positioned_char; positioned_char.character = ch; positioned_char.xoffset = m_width; positioned_char.xwidth = chwidth; positioned_char.style = style; positioned_char.source = source; // append the character m_characters.push_back(positioned_char); m_width += chwidth; // we might be bigger m_height = Math.Max(m_height, style.size * m_layout.yscale()); }
// methods //------------------------------------------------- // add_text //------------------------------------------------- void add_text(string text, char_style style) { UInt32 position = 0; UInt32 text_length = (UInt32)text.Length; while (position < text_length) { // adding a character - we might change the width invalidate_calculated_actual_width(); // do we need to create a new line? if (m_current_line == null) { // get the current character char schar; //char32_t schar; int scharcount = unicode_global.uchar_from_utf8(out schar, text.Substring((int)position), (int)(text_length - position)); // &text[position] if (scharcount < 0) { break; } // if the line starts with a tab character, center it regardless text_justify line_justify = justify(); if (schar == '\t') { position += (UInt32)scharcount; line_justify = text_justify.CENTER; } // start a new line start_new_line(line_justify, style.size); } { // get the current character char ch; //char32_t ch; int scharcount = unicode_global.uchar_from_utf8(out ch, text.Substring((int)position), (int)(text_length - position)); // &text[position], text_length - position); if (scharcount < 0) { break; } position += (UInt32)scharcount; // set up source information source_info source; source.start = m_text_position; source.span = (UInt32)scharcount; m_text_position += (UInt32)scharcount; // is this an endline? if (ch == '\n') { // first, start a line if we have not already if (m_current_line == null) { start_new_line(text_justify.LEFT, style.size); } // and then close up the current line m_current_line = null; } else if (!m_truncating) { // if we hit a space, remember the location and width *without* the space if (is_space_character(ch)) { m_last_break = m_current_line.character_count(); } // append the character m_current_line.add_character(ch, style, source); // do we have to wrap? if (wrap() != word_wrapping.NEVER && m_current_line.width() > m_width) { switch (wrap()) { case word_wrapping.TRUNCATE: truncate_wrap(); break; case word_wrapping.WORD: word_wrap(); break; default: fatalerror("invalid word wrapping value"); break; } } else { // we didn't wrap - if we hit any non-space breakable character, remember the location and width // *with* the breakable character if (ch != ' ' && is_breakable_char(ch)) { m_last_break = m_current_line.character_count(); } } } } } }
//------------------------------------------------- // add_text //------------------------------------------------- void add_text(string text, text_justify line_justify, char_style style) { while (!text.empty()) { // adding a character - we might change the width invalidate_calculated_actual_width(); // do we need to create a new line? if (m_current_line == null) { start_new_line(style.size); } m_current_line.set_justification(line_justify); // get the current character char ch; //char32_t ch; int scharcount = uchar_from_utf8(out ch, text); if (scharcount < 0) { break; } text = text.remove_prefix_((size_t)scharcount); // set up source information source_info source = new source_info() { start = 0, span = 0 }; source.start = m_text_position; source.span = (size_t)scharcount; m_text_position += (size_t)scharcount; // is this an endline? if (ch == '\n') { // close up the current line m_current_line.align_text(this); m_current_line = null; } else if (!m_truncating) { // if we hit a space, remember the location and width *without* the space bool is_space = is_space_character(ch); if (is_space) { m_last_break = m_current_line.character_count(); } // append the character m_current_line.add_character(this, ch, style, source); // do we have to wrap? if ((wrap() != word_wrapping.NEVER) && (m_current_line.width() > m_width)) { switch (wrap()) { case word_wrapping.TRUNCATE: truncate_wrap(); break; case word_wrapping.WORD: word_wrap(); break; case word_wrapping.NEVER: // can't happen due to if condition, but compile warns about it break; } } else { // we didn't wrap - if we hit any non-space breakable character, // remember the location and width *with* the breakable character if (!is_space && is_breakable_char(ch)) { m_last_break = m_current_line.character_count(); } } } } }