Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/gumps/Book_gump.cc b/gumps/Book_gump.cc
- index 3e7da65bb..daed28bad 100644
- --- a/gumps/Book_gump.cc
- +++ b/gumps/Book_gump.cc
- @@ -40,7 +40,7 @@ void Book_gump::paint() {
- // Paint the gump itself.
- paint_shape(x, y);
- // Paint left page.
- - curend = paint_page(TileRect(36, 10, 122, 130), curtop);
- + curend = paint_page(TileRect(35, 8, 125, 132), curtop);
- // Paint right page.
- - curend = paint_page(TileRect(174, 10, 122, 130), curend);
- + curend = paint_page(TileRect(173, 8, 125, 132), curend);
- }
- diff --git a/gumps/Scroll_gump.cc b/gumps/Scroll_gump.cc
- index 533f4f49b..f66837026 100644
- --- a/gumps/Scroll_gump.cc
- +++ b/gumps/Scroll_gump.cc
- @@ -39,5 +39,5 @@ Scroll_gump::Scroll_gump(int fnt, int gump)
- void Scroll_gump::paint() {
- // Paint the gump itself.
- paint_shape(x, y);
- - curend = paint_page(TileRect(52, 30, 142, 118), curtop);
- + curend = paint_page(TileRect(51, 31, 142, 118), curtop);
- }
- diff --git a/gumps/Text_gump.cc b/gumps/Text_gump.cc
- index 5feb93b07..5f3032c26 100644
- --- a/gumps/Text_gump.cc
- +++ b/gumps/Text_gump.cc
- @@ -21,10 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- #endif
- #include "Text_gump.h"
- -
- +#include "game.h"
- #include "gamewin.h"
- #include <cstring>
- +#include <string>
- using std::strchr;
- @@ -33,21 +34,18 @@ using std::strchr;
- */
- void Text_gump::add_text(const char* str) {
- - const int slen = strlen(str); // Length of new text.
- - // Allocate new space.
- - char* newtext = new char[textlen + (textlen != 0) + slen + 1];
- - if (textlen) { // Copy over old.
- - strcpy(newtext, text);
- - // Add new line if not starting a new page and if first char of new
- - // string is not a new line
- + std::string newtext;
- + if (textlen) {
- + newtext = text;
- if (newtext[textlen - 1] != '*') {
- - newtext[textlen++] = '~';
- + newtext += '~';
- }
- }
- - strcpy(newtext + textlen, str); // Append new.
- + newtext += str;
- delete[] text;
- - text = newtext;
- - textlen += slen;
- + text = new char[newtext.length() + 1];
- + strcpy(text, newtext.c_str());
- + textlen = newtext.length();
- }
- /*
- @@ -56,50 +54,185 @@ void Text_gump::add_text(const char* str) {
- * Output: Index past end of displayed page.
- */
- -int Text_gump::paint_page(
- - const TileRect& box, // Display box rel. to gump.
- - int start // Starting offset into text.
- -) {
- - const int vlead = 1; // Extra inter-line spacing.
- +int Text_gump::paint_page(const TileRect& box, int start) {
- int ypos = 0;
- + const int vlead = 1;
- const int textheight = sman->get_text_height(font) + vlead;
- char* str = text + start;
- - while (*str && *str != '*' && ypos + textheight <= box.h) {
- - if (*str == '~') { // Empty paragraph?
- - ypos += textheight;
- - str++;
- - continue;
- + curend = start; // Initialize curend to the starting position
- +
- + char* lineBreak = nullptr;
- + char* pageBreakStar = nullptr;
- + char* extraBreak = nullptr;
- + char* epage = nullptr; // page break marker
- + char* eol = nullptr; // end-of-line marker
- +
- + while (*str && ypos + textheight <= box.h) {
- + // Find the first tilde (line break marker)
- + lineBreak = strchr(str, '~');
- + // Update markers based on current position
- + pageBreakStar = strchr(str, '*');
- +
- + if (GAME_SI) {
- + extraBreak = strstr(str, "~~~");
- + }
- + if (GAME_BG) {
- + extraBreak = strstr(str, " ~~");
- + if (extraBreak) {
- + // If " ~~" is preceded by "~~", ignore it.
- + if (extraBreak - text >= 2 && *(extraBreak - 2) == '~'
- + && *(extraBreak - 1) == '~') {
- + extraBreak = nullptr;
- + }
- + }
- }
- - // Look for page break.
- - char* epage = strchr(str, '*');
- - // Look for line break.
- - char* eol = strchr(str, '~');
- - if (epage && (!eol || eol > epage)) {
- - eol = epage;
- +
- + // if extraBreak is found and it occurs at the same position
- + // as the first tilde, use it as page break.
- + if (extraBreak && lineBreak
- + && ((GAME_SI && extraBreak == lineBreak)
- + || (GAME_BG && extraBreak + 1 == lineBreak))) {
- + epage = extraBreak;
- + eol = extraBreak;
- + } else if (pageBreakStar && (!lineBreak || pageBreakStar < lineBreak)) {
- + epage = pageBreakStar;
- + eol = pageBreakStar;
- + } else {
- + eol = lineBreak;
- + epage = nullptr; // no page break marker
- }
- - if (!eol) { // No end found?
- +
- + if (!eol) {
- + // No marker found: paint until the end of text.
- eol = text + textlen;
- }
- - const char eolchr = *eol; // Save char. at EOL.
- - *eol = 0;
- - const int endoff = sman->paint_text_box(
- - font, str, x + box.x, y + box.y + ypos, box.w, box.h - ypos,
- - vlead);
- - *eol = eolchr; // Restore char.
- - if (endoff > 0) { // All painted?
- - // Value returned is height.
- - str = eol + (eolchr == '~');
- +
- + // Temporarily null-terminate at eol for painting.
- + const char eolchr = *eol;
- + *eol = '\0';
- +
- + int endoff = sman->paint_text_box(
- + font, str, x + box.x, y + box.y + ypos, box.w, box.h - ypos,
- + vlead);
- + // Restore the character at eol.
- + *eol = eolchr;
- +
- + if (endoff > 0) {
- + // Check for a page‑break marker
- + if (epage) {
- + // Handle extraBreak marker (e.g. "~~~" or " ~~")
- + if (extraBreak && epage == extraBreak) {
- + if (GAME_SI && start == 0 && ypos == 0) {
- + // If it's the first line of the entire text, ignore the
- + // extraBreak
- + eol = extraBreak + 1;
- + str = eol;
- + curend = str - text;
- + ypos += endoff;
- + continue;
- + }
- + // Calculate vertical space remaining after the current
- + // block has been painted.
- + int remaining = box.h - (ypos + endoff);
- +
- + // Require room for at least two extra full line.
- + if (remaining >= 2 * textheight) {
- + // Reserve two extra line for spacing; the rest is
- + // available for the next text chunk.
- + int available = remaining - (2 * textheight);
- + if (available < 0) {
- + available = 0;
- + }
- +
- + // Use existing markers to find earliest upcoming marker
- + const char* earliest
- + = text + textlen; // default: measure to
- + // end-of-text
- +
- + if (pageBreakStar > eol + 3
- + && pageBreakStar < earliest) {
- + earliest = pageBreakStar;
- + }
- + if (extraBreak > eol + 3 && extraBreak < earliest) {
- + earliest = extraBreak;
- + }
- +
- + // Temporarily replace the character at 'earliest' with
- + // '\0' to isolate the next chunk.
- + char saved = *earliest;
- +
- + // PEEK MEASUREMENT:
- + // To avoid drawing on top of already painted text, we
- + // use an off-screen y coordinate (e.g. -1000).
- + int peekHeight = sman->paint_text_box(
- + font,
- + eol + 3, // start after extraBreak marker
- + x + box.x,
- + -1000, // off-screen y coordinate for
- + // measurement only
- + box.w, available, vlead);
- + // Restore the character we replaced.
- + *((char*)earliest) = saved;
- +
- + if (peekHeight > 0
- + && peekHeight
- + <= available + 5) // Add a tolerance
- + // of 5 pixels
- + {
- + // The entire upcoming text fits in the available
- + // space. Consume the extraBreak marker and add an
- + // extra line spacing.
- + eol += 1; // skip extraBreak marker ("~~~" or "
- + // ~~")
- + ypos += endoff; // update vertical offset
- + str = eol; // continue painting after the marker
- + curend = str - text; // Update curend
- + continue; // next iteration: the peeked block
- + // will be painted on this page only
- + } else {
- + // The upcoming block does not fully fit;
- + // consume the marker and break so that it will be
- + // painted on the next page.
- + eol += 3;
- + str = eol;
- + curend = str - text; // Update curend
- + break;
- + }
- + }
- + }
- + } else if (eolchr == '~' || (lineBreak && lineBreak == eol)) {
- + // Normal handling for a tilde line break.
- + eol++;
- + }
- +
- + // After handling markers (or if none applied), update the text
- + // pointer and vertical offset.
- ypos += endoff;
- - } else { // Out of room.
- + str = eol;
- + curend = str - text; // Update curend
- +
- + // Skip any leading space at the beginning of a new line.
- + if (*str == ' ') {
- + str++;
- + }
- + } else {
- + // Out of room or partial paint -> back up
- str += -endoff;
- + curend = str - text; // Update curend
- break;
- }
- }
- - if (*str == '*') { // Saw end of page?
- - str++;
- +
- + // After the loop, check for markers at current position
- + if (GAME_SI && extraBreak && extraBreak == str) {
- + str += 3; // skip "~~~"
- + } else if (pageBreakStar && pageBreakStar == str) {
- + str++; // skip "*"
- }
- - gwin->set_painted(); // Force blit.
- - return str - text; // Return offset past end.
- +
- + curend = str - text; // Update curend one last time after the loop
- + gwin->set_painted();
- + return str - text;
- }
- /*
- @@ -113,6 +246,12 @@ int Text_gump::show_next_page() {
- return 0; // That's all, folks.
- }
- curtop = curend; // Start next page or pair of pages.
- - paint(); // Paint. This updates curend.
- +
- + // Skip any leading tildes at the beginning of the new page.
- + while (curtop < textlen && text[curtop] == '~') {
- + curtop++;
- + }
- +
- + paint(); // Paint. This updates curend.
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement