/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/grtext/textaux.cpp $ * $Revision: 6 $ * $Date: 5/19/99 10:00p $ * $Author: Jeff $ * * Auxillary Text functions (helper function, not necessarily belonging to grtext) * * $Log: /DescentIII/Main/grtext/textaux.cpp $ * * 6 5/19/99 10:00p Jeff * fixed word-wrap not to wrap words that are bigger than the line * * 5 11/03/98 7:04p Samir * made Grtext_spacing global so word wrapper could access it. * * 4 11/03/98 3:12p Jeff * fixed wordwrap so it doesn't modify source buffer * * 3 7/14/98 2:47p Jeff * added textaux_ClipString * * 2 7/14/98 11:53a Samir * moved textaux to it's own libtary again. * * 1 7/13/98 4:41p Samir * * 2 7/11/98 9:14p Jeff * initial creation (moved from TelCom) * * $NoKeywords: $ */ #include #include #include "grtext.h" // textaux_WordWrap // // Given a buffer of text, and an empty buffer of same size // it will break the source buffer up into lines (seperated by /n) of size width or smaller (in pixels). // All /n within the source buffer are preserved. Source buffer is also not changed. void textaux_WordWrap(const char *src, char *dest, int width, int font) { // make sure we are kosher with the values past in if ((!src) || (!dest)) return; if (src[0] == '\0') return; char *last_word; // points to the character after the last complete word char *start_line; // points to the starting char of the line // char *destpos; //points to the current position of the dest buffer int curr_width; // current width int index; // index into source string bool done = false; // if we are done adjusting for word-wrap // copy the source buffer into the destination buffer, where all work will go strcpy(dest, src); // initialize vars last_word = start_line = dest; curr_width = 0; index = 0; int num_words_on_line = 0; while (!done) { curr_width = 0; index = 0; num_words_on_line = 0; while (curr_width <= width || num_words_on_line == 0) { switch (start_line[index]) { case '\0': // we are done with everything done = true; case '\n': // we are done with this line curr_width = width + 1; case ' ': // update last_word last_word = &start_line[index]; num_words_on_line++; break; } if ((start_line[index] != '\0') && (start_line[index] != '\n')) curr_width += (grfont_GetCharWidth(font, start_line[index]) + Grtext_spacing); index++; } // put a newline char if (!done) { last_word[0] = '\n'; } // copy from start_line->last_word into the dest buffer start_line += (last_word - start_line + 1); last_word = start_line; } } // textaux_CopyTextLine // // This function goes hand-in-hand with textaux_WordWrap(). Given a buffer of data it will fill in // the dest buffer until it hits a /n or /0. It returns a pointer to the start position of the next line, // or NULL if it's done with the buffer (it hit a /0). const char *textaux_CopyTextLine(const char *src, char *dest) { // make sure src and dest are allocated if (!src) { if (dest) dest[0] = '\0'; return nullptr; } if (!dest) return nullptr; // see if we are at the end of the src if (src[0] == '\0') { dest[0] = '\0'; return nullptr; } int i; i = 0; // find the end while ((src[i] != '\n') && (src[i] != '\0')) i++; if (src[i] == '\0') { // no more lines left after this strncpy(dest, src, i); dest[i] = '\0'; return nullptr; } else { // we hit a newline char strncpy(dest, src, i); dest[i] = '\0'; i++; return &src[i]; } } // textaux_ClipString // Given a width (in pixels), and a string, this function will truncate the string // to at most width pixels. If the end parameter is not 0, then that char is attached to // the end of the string if it has to clip(the char's width is taken into consideration). // It is based off the current font. if horizont_ratio is given it is used to correct for // possible different sized hud fonts. For instance, if this string is going to be printed on // the hud, then you should always pass (DEFAULT_HUD_WIDTH/((float)*Game_window_w)) as the // horizont_ratio paramter. void textaux_ClipString(int width, char *string, float horizont_ratio, char end) { if (!string) return; float ratio = horizont_ratio; int string_length = strlen(string); char arrow_string[2]; int arrow_length = 0; if (end) { snprintf(arrow_string, sizeof(arrow_string), "%c", end); arrow_length = (int)(ratio * ((float)grtext_GetTextLineWidth(arrow_string))); } if (width < arrow_length) { // Nothing can fit strcpy(string, ""); return; } // adjust width based on the arrow width -= arrow_length; int size = 0; char save = string[0]; while (size < string_length) { string[size] = '\0'; if ((((float)grtext_GetTextLineWidth(string)) * ratio) >= width) { // We have to clip size--; if (end) { string[size] = end; string[size + 1] = '\0'; } return; } // replace the char and move to the next string[size] = save; size++; save = string[size]; } // The string didn't need to be clipped }