1 /*
2 Copyright (C) 2000-2013 The Exult Team
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <cstring>
24
25 #include "gamewin.h"
26 #include "Text_gump.h"
27
28 using std::strchr;
29 using std::strcpy;
30 using std::strlen;
31
32 /*
33 * Add to the text, starting a newline.
34 */
35
add_text(const char * str)36 void Text_gump::add_text(
37 const char *str
38 ) {
39 int slen = strlen(str); // Length of new text.
40 // Allocate new space.
41 char *newtext = new char[textlen + (textlen != 0) + slen + 1];
42 if (textlen) { // Copy over old.
43 strcpy(newtext, text);
44 // Add new line if not starting a new page and if first char of new string is
45 // not a new line
46 if (newtext[textlen - 1] != '*') newtext[textlen++] = '~';
47 }
48 strcpy(newtext + textlen, str); // Append new.
49 delete [] text;
50 text = newtext;
51 textlen += slen;
52 }
53
54 /*
55 * Paint a page and find where its text ends.
56 *
57 * Output: Index past end of displayed page.
58 */
59
paint_page(TileRect const & box,int start)60 int Text_gump::paint_page(
61 TileRect const &box, // Display box rel. to gump.
62 int start // Starting offset into text.
63 ) {
64 const int vlead = 1; // Extra inter-line spacing.
65 int ypos = 0;
66 int textheight = sman->get_text_height(font) + vlead;
67 char *str = text + start;
68 while (*str && *str != '*' && ypos + textheight <= box.h) {
69 if (*str == '~') { // Empty paragraph?
70 ypos += textheight;
71 str++;
72 continue;
73 }
74 // Look for page break.
75 char *epage = strchr(str, '*');
76 // Look for line break.
77 char *eol = strchr(str, '~');
78 if (epage && (!eol || eol > epage))
79 eol = epage;
80 if (!eol) // No end found?
81 eol = text + textlen;
82 char eolchr = *eol; // Save char. at EOL.
83 *eol = 0;
84 int endoff = sman->paint_text_box(font, str, x + box.x,
85 y + box.y + ypos, box.w, box.h - ypos, vlead);
86 *eol = eolchr; // Restore char.
87 if (endoff > 0) { // All painted?
88 // Value returned is height.
89 str = eol + (eolchr == '~');
90 ypos += endoff;
91 } else { // Out of room.
92 str += -endoff;
93 break;
94 }
95 }
96 if (*str == '*') // Saw end of page?
97 str++;
98 gwin->set_painted(); // Force blit.
99 return str - text; // Return offset past end.
100 }
101
102 /*
103 * Show next page(s) of book or scroll.
104 *
105 * Output: 0 if already at end.
106 */
107
show_next_page()108 int Text_gump::show_next_page(
109 ) {
110 if (curend >= textlen)
111 return 0; // That's all, folks.
112 curtop = curend; // Start next page or pair of pages.
113 paint(); // Paint. This updates curend.
114 return 1;
115 }
116