// License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2020 Intel Corporation. All Rights Reserved. #include #include #include #include "wrap.h" #include #include namespace utilities { namespace imgui { void trim_leading_spaces( std::string &remaining_paragraph ) { auto non_space_index = remaining_paragraph.find_first_not_of( ' ' ); if( non_space_index != std::string::npos ) { // Remove trailing spaces remaining_paragraph = remaining_paragraph.substr( non_space_index ); } } std::string wrap_paragraph( const std::string & paragraph, int wrap_pixels_width ) { float space_width = ImGui::CalcTextSize( " " ).x; // Calculate space width in pixels std::string wrapped_line; // The line that is wrapped in this iteration std::string wrapped_paragraph; // The output wrapped paragraph auto remaining_paragraph = paragraph; // Holds the remaining unwrapped part of the input paragraph // Handle a case when the paragraph starts with spaces trim_leading_spaces(remaining_paragraph); auto next_word = remaining_paragraph.substr( 0, remaining_paragraph.find( ' ' ) ); // The next word to add to the current line bool first_word = true; while( ! next_word.empty() ) { float next_x = 0.0f; // If this is the first word we try to place it first in line, // if not we concatenate it to the last word after adding a space if( ! first_word ) { next_x = ImGui::CalcTextSize( wrapped_line.c_str() ).x + space_width; } if( next_x + ImGui::CalcTextSize( next_word.c_str() ).x <= wrap_pixels_width ) { if( ! first_word ) wrapped_line += " "; // First word should not start with " " wrapped_line += next_word; } else { // Current line cannot feat new word so we wrap the line and // start building the new line wrapped_paragraph += wrapped_line; // copy line build by now if( ! first_word ) wrapped_paragraph += '\n'; // break the previous line if exist wrapped_line = next_word; // add next work to new line } first_word = false; // If we have more characters left other then the current word, prepare inputs for next // iteration, If not add the current line built so far to the output and finish current // line wrap. if( remaining_paragraph.size() > next_word.size() ) { remaining_paragraph = remaining_paragraph.substr( next_word.size() + 1 ); // Handle a case when the paragraph starts with spaces trim_leading_spaces(remaining_paragraph); next_word = remaining_paragraph.substr( 0, remaining_paragraph.find( ' ' ) ); // If no more words exist, copy the current wrapped line to output and stop if( next_word.empty() ) { wrapped_paragraph += wrapped_line; break; } } else { wrapped_paragraph += wrapped_line; break; } } return wrapped_paragraph; } std::string wrap( const std::string & text, int wrap_pixels_width ) { // Do not wrap if the wrap is smaller then 32 pixels (~2 characters on font 16) if( wrap_pixels_width < 32 ) return text; // Split text into paragraphs auto paragraphs_vector = rsutils::string::split( text, '\n' ); std::string wrapped_text; size_t line_number = 1; // Wrap each line according to the requested wrap width for( auto paragraph : paragraphs_vector ) { wrapped_text += wrap_paragraph( paragraph, wrap_pixels_width ); // Each paragraph except the last one ends with a new line if( line_number++ != paragraphs_vector.size() ) wrapped_text += '\n'; } return wrapped_text; } } // namespace imgui } // namespace utilities