Common/font/fonts.cpp
// Break up the text into lines
Break up the text into lines
Break up the text into lines
size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines) {
     if (game.options[OPT_BASESCRIPTAPI] < $Your current version$)
    wii -= 1;
    lines.Reset();
    unescape_script_string(todis, lines.LineBuf);
    char *theline = &lines.LineBuf.front();
    char *scan_ptr = theline;
    char *prev_ptr = theline;
    char *last_whitespace = nullptr;
    while (1) {
        char *split_at = nullptr;
        if (*scan_ptr == 0) {
             end of the text, add the last line if necessary
            if (scan_ptr > theline) {
                lines.Add(theline);
            }
            break;
        }
        if (*scan_ptr == ' ')
            last_whitespace = scan_ptr;
         force end of line with the \n character
        if (*scan_ptr == '\n') {
            split_at = scan_ptr;
         otherwise, see if we are too wide
        } else {
             temporarily terminate the line in the *next* char and test its width
            char *next_ptr = scan_ptr;
            ugetx(&next_ptr);
            const int next_chwas = ugetc(next_ptr);
            *next_ptr = 0;
            if (get_text_width_outlined(theline, fonnt) > wii) {
                 line is too wide, order the split
                if (last_whitespace)
                     revert to the last whitespace
                    split_at = last_whitespace;
                else
                     single very wide word, display as much as possible
                    split_at = prev_ptr;
            }
             restore the character that was there before
            usetc(next_ptr, next_chwas);
        }
        if (split_at == nullptr) {
            prev_ptr = scan_ptr;
            ugetx(&scan_ptr);
        } else {
             check if even one char cannot fit...
            if (split_at == theline && !((*theline == ' ') || (*theline == '\n'))) {
               cannot split with current width restriction
              lines.Reset();
              break;
            }
             add this line; do the temporary terminator trick again
            const int next_chwas = *split_at;
            *split_at = 0;
            lines.Add(theline);
            usetc(split_at, next_chwas);
             check if too many lines
            if (lines.Count() >= max_lines) {
                lines[lines.Count() - 1].Append("...");
                break;
            }
             the next line starts from the split point
            theline = split_at;
             skip the space or new line that caused the line break
            if ((*theline == ' ') || (*theline == '\n'))
                theline++;
            scan_ptr = theline;
            prev_ptr = theline;
            last_whitespace = nullptr;
        }
    }
    return lines.Count();
}
size_t split_lines ( const char * todis , SplitLines & lines , int wii , int fonnt , size_t max_lines ) { wii -= 1 ; lines . Reset ( ) ; unescape_script_string ( todis , lines . LineBuf ) ; char * theline = & lines . LineBuf . front ( ) ; char * scan_ptr = theline ; char * prev_ptr = theline ; char * last_whitespace = nullptr ; while ( 1 ) { char * split_at = nullptr ; if ( * scan_ptr == 0 ) { if ( scan_ptr > theline ) { lines . Add ( theline ) ; } break ; } if ( * scan_ptr == ' ' ) last_whitespace = scan_ptr ; if ( * scan_ptr == ' \n ' ) { split_at = scan_ptr ; } else { char * next_ptr = scan_ptr ; ugetx ( & next_ptr ) ; const int next_chwas = ugetc ( next_ptr ) ; * next_ptr = 0 ; if ( get_text_width_outlined ( theline , fonnt ) > wii ) { if ( last_whitespace ) split_at = last_whitespace ; else split_at = prev_ptr ; } usetc ( next_ptr , next_chwas ) ; } if ( split_at == nullptr ) { prev_ptr = scan_ptr ; ugetx ( & scan_ptr ) ; } else { if ( split_at == theline && ! ( ( * theline == ' ' ) || ( * theline == ' \n ' ) ) ) { lines . Reset ( ) ; break ; } const int next_chwas = * split_at ; * split_at = 0 ; lines . Add ( theline ) ; usetc ( split_at , next_chwas ) ; if ( lines . Count ( ) >= max_lines ) { lines [ lines . Count ( ) - 1 ] . Append ( " " ) ; break ; } theline = split_at ; if ( ( * theline == ' ' ) || ( * theline == ' \n ' ) ) theline ++ ; scan_ptr = theline ; prev_ptr = theline ; last_whitespace = nullptr ; } } return lines . Count ( ) ; }
Break up the text into lines
Break up the text into lines
// NOTE: following hack accomodates for the legacy math mistake in split_lines. // It's hard to tell how cruicial it is for the game looks, so research may be needed. // TODO: IMHO this should rely not on game format, but script API level, because it // defines necessary adjustments to game scripts. If you want to fix this, find a way to // pass this flag here all the way from game.options[OPT_BASESCRIPTAPI] (or game format). // // if (game.options[OPT_BASESCRIPTAPI] < $Your current version$) // end of the text, add the last line if necessary // force end of line with the \n character // otherwise, see if we are too wide // temporarily terminate the line in the *next* char and test its width // line is too wide, order the split // revert to the last whitespace // single very wide word, display as much as possible // restore the character that was there before // check if even one char cannot fit... // cannot split with current width restriction // add this line; do the temporary terminator trick again // check if too many lines // the next line starts from the split point // skip the space or new line that caused the line break