mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
cleanup; got rid of the split function and rather work in place (so instead of allocating dozens of small goblets of memory, we only need to duplicate the string once); fixed some text positioning bugs (but again, to get a real accurate implementation, I'll need to study screen shots of the Dig/FT/COMI videos and compare them to our results)
svn-id: r8388
This commit is contained in:
+123
-178
@@ -33,6 +33,7 @@ SmushFont::SmushFont(bool use_original_colors, bool new_colors) :
|
||||
}
|
||||
|
||||
int SmushFont::getStringWidth(const char *str) {
|
||||
assert(str);
|
||||
if (!_loaded) {
|
||||
warning("SmushFont::getStringWidth() Font is not loaded");
|
||||
return 0;
|
||||
@@ -46,6 +47,7 @@ int SmushFont::getStringWidth(const char *str) {
|
||||
}
|
||||
|
||||
int SmushFont::getStringHeight(const char *str) {
|
||||
assert(str);
|
||||
if (!_loaded) {
|
||||
warning("SmushFont::getStringHeight() Font is not loaded");
|
||||
return 0;
|
||||
@@ -134,30 +136,6 @@ int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) {
|
||||
return w + 1;
|
||||
}
|
||||
|
||||
static char **split(const char *str, char sep) {
|
||||
char **ret = new char *[62];
|
||||
int n = 0;
|
||||
const char *i = str;
|
||||
char *j = strchr(i, sep);
|
||||
|
||||
while (j != NULL) {
|
||||
assert(n < 60);
|
||||
ret[n] = new char[j - i + 1];
|
||||
memcpy(ret[n], i, j - i);
|
||||
ret[n++][j - i] = 0;
|
||||
i = j + 1;
|
||||
j = strchr(i, sep);
|
||||
}
|
||||
|
||||
int len = strlen(i);
|
||||
ret[n] = new char[len + 1];
|
||||
memcpy(ret[n], i, len);
|
||||
ret[n++][len] = 0;
|
||||
ret[n] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SmushFont::drawSubstring(const char *str, byte *buffer, int dst_width, int x, int y) {
|
||||
for (int i = 0; str[i] != 0; i++) {
|
||||
if ((byte)str[i] >= 0x80 && _vm->_CJKMode) {
|
||||
@@ -168,6 +146,9 @@ void SmushFont::drawSubstring(const char *str, byte *buffer, int dst_width, int
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_WORDS 60
|
||||
|
||||
|
||||
void SmushFont::drawStringAbsolute(const char *str, byte *buffer, int dst_width, int x, int y) {
|
||||
debug(9, "SmushFont::drawStringAbsolute(%s, %d, %d)", str, x, y);
|
||||
|
||||
@@ -187,137 +168,115 @@ void SmushFont::drawStringAbsolute(const char *str, byte *buffer, int dst_width,
|
||||
}
|
||||
}
|
||||
|
||||
void SmushFont::drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset) {
|
||||
debug(9, "SmushFont::drawStringCentered(%s, %d, %d)", str, xmin, y);
|
||||
void SmushFont::drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
|
||||
debug(9, "SmushFont::drawStringCentered(%s, %d, %d, %d, %d)", str, x, y, left, right);
|
||||
|
||||
char *z = strchr(str, '\n');
|
||||
if (z != 0) {
|
||||
// FIXME: this is actually evil, because it silently modifes the
|
||||
// string 'str' passed to us, despite it being declared const.
|
||||
warning("drawStringCentered: got input string containing \\n");
|
||||
*z = 0;
|
||||
}
|
||||
char **words = split(str, ' ');
|
||||
const int width = right - left;
|
||||
char *s = strdup(str);
|
||||
char *words[MAX_WORDS];
|
||||
int word_count = 0;
|
||||
|
||||
while (words[word_count])
|
||||
word_count++;
|
||||
char *tmp = s;
|
||||
while (tmp) {
|
||||
assert(word_count < MAX_WORDS);
|
||||
words[word_count++] = tmp;
|
||||
tmp = strpbrk(tmp, " \t\r\n");
|
||||
if (tmp == 0)
|
||||
break;
|
||||
*tmp++ = 0;
|
||||
}
|
||||
|
||||
int i = 0, max_width = 0, height = 0, line_count = 0;
|
||||
|
||||
char **substrings = new char *[word_count];
|
||||
int *substr_widths = new int[word_count];
|
||||
int space_width = getCharWidth(' ');
|
||||
char *substrings[MAX_WORDS];
|
||||
int substr_widths[MAX_WORDS];
|
||||
const int space_width = getCharWidth(' ');
|
||||
|
||||
i = 0;
|
||||
while (i < word_count) {
|
||||
int substr_width = getStringWidth(words[i]);
|
||||
char *substr = new char[1000];
|
||||
strcpy(substr, words[i]);
|
||||
int j = i + 1;
|
||||
char *substr = words[i++];
|
||||
int substr_width = getStringWidth(substr);
|
||||
|
||||
while (j < word_count) {
|
||||
int word_width = getStringWidth(words[j]);
|
||||
while (i < word_count) {
|
||||
int word_width = getStringWidth(words[i]);
|
||||
if ((substr_width + space_width + word_width) >= width)
|
||||
break;
|
||||
substr_width += word_width + space_width;
|
||||
j++;
|
||||
}
|
||||
|
||||
for (int k = i + 1; k < j; k++) {
|
||||
strcat(substr, " ");
|
||||
strcat(substr, words[k]);
|
||||
}
|
||||
|
||||
substrings[line_count] = substr;
|
||||
substr_widths[line_count++] = substr_width;
|
||||
if (substr_width > max_width)
|
||||
max_width = substr_width;
|
||||
i = j;
|
||||
height += getStringHeight(substr);
|
||||
}
|
||||
|
||||
for (i = 0; i < word_count; i++) {
|
||||
delete[] words[i];
|
||||
}
|
||||
delete[] words;
|
||||
|
||||
if (y > dst_height - height) {
|
||||
y = dst_height - height;
|
||||
}
|
||||
|
||||
max_width = (max_width + 1) >> 1;
|
||||
int x = xmin + width / 2 + offset - dst_width / 2;
|
||||
|
||||
if (x < max_width)
|
||||
x = max_width;
|
||||
if (x > dst_width - max_width)
|
||||
x = dst_width - max_width;
|
||||
|
||||
for (i = 0; i < line_count; i++) {
|
||||
drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
|
||||
y += getStringHeight(substrings[i]);
|
||||
delete[] substrings[i];
|
||||
}
|
||||
|
||||
delete[] substr_widths;
|
||||
delete[] substrings;
|
||||
}
|
||||
|
||||
void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) {
|
||||
debug(9, "SmushFont::drawStringWrap(%s, %d, %d)", str, x, y);
|
||||
|
||||
char *z = strchr(str, '\n');
|
||||
if (z != 0) {
|
||||
// FIXME: this is actually evil, because it silently modifes the
|
||||
// string 'str' passed to us, despite it being declared const.
|
||||
warning("drawStringWrap: got input string containing \\n");
|
||||
*z = 0;
|
||||
}
|
||||
char **words = split(str, ' ');
|
||||
int word_count = 0;
|
||||
|
||||
while (words[word_count])
|
||||
word_count++;
|
||||
|
||||
int i = 0, max_width = 0, height = 0, line_count = 0;
|
||||
|
||||
char **substrings = new char *[word_count];
|
||||
int *substr_widths = new int[word_count];
|
||||
int space_width = getCharWidth(' ');
|
||||
|
||||
i = 0;
|
||||
while (i < word_count) {
|
||||
int substr_width = getStringWidth(words[i]);
|
||||
char *substr = new char[1000];
|
||||
strcpy(substr, words[i]);
|
||||
int j = i + 1;
|
||||
|
||||
while (j < word_count) {
|
||||
int word_width = getStringWidth(words[j]);
|
||||
if ((substr_width + space_width + word_width) >= width)
|
||||
break;
|
||||
substr_width += word_width + space_width;
|
||||
j++;
|
||||
}
|
||||
|
||||
for (int k = i + 1; k < j; k++) {
|
||||
strcat(substr, " ");
|
||||
strcat(substr, words[k]);
|
||||
*(words[i]-1) = ' '; // Convert 0 byte back to space
|
||||
i++;
|
||||
}
|
||||
|
||||
substrings[line_count] = substr;
|
||||
substr_widths[line_count++] = substr_width;
|
||||
if (max_width < substr_width)
|
||||
max_width = substr_width;
|
||||
i = j;
|
||||
height += getStringHeight(substr);
|
||||
}
|
||||
|
||||
for (i = 0; i < word_count; i++) {
|
||||
delete[] words[i];
|
||||
if (y > dst_height - height) {
|
||||
y = dst_height - height;
|
||||
}
|
||||
|
||||
max_width = (max_width + 1) >> 1;
|
||||
x = left + width / 2;
|
||||
|
||||
if (x < left + max_width)
|
||||
x = left + max_width;
|
||||
if (x > right - max_width)
|
||||
x = right - max_width;
|
||||
|
||||
for (i = 0; i < line_count; i++) {
|
||||
drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
|
||||
y += getStringHeight(substrings[i]);
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
|
||||
debug(9, "SmushFont::drawStringWrap(%s, %d, %d, %d, %d)", str, x, y, left, right);
|
||||
|
||||
const int width = right - left;
|
||||
char *s = strdup(str);
|
||||
char *words[MAX_WORDS];
|
||||
int word_count = 0;
|
||||
|
||||
char *tmp = s;
|
||||
while (tmp) {
|
||||
assert(word_count < MAX_WORDS);
|
||||
words[word_count++] = tmp;
|
||||
tmp = strpbrk(tmp, " \t\r\n");
|
||||
if (tmp == 0)
|
||||
break;
|
||||
*tmp++ = 0;
|
||||
}
|
||||
|
||||
int i = 0, max_width = 0, height = 0, line_count = 0;
|
||||
|
||||
char *substrings[MAX_WORDS];
|
||||
int substr_widths[MAX_WORDS];
|
||||
const int space_width = getCharWidth(' ');
|
||||
|
||||
i = 0;
|
||||
while (i < word_count) {
|
||||
char *substr = words[i++];
|
||||
int substr_width = getStringWidth(substr);
|
||||
|
||||
while (i < word_count) {
|
||||
int word_width = getStringWidth(words[i]);
|
||||
if ((substr_width + space_width + word_width) >= width)
|
||||
break;
|
||||
substr_width += word_width + space_width;
|
||||
*(words[i]-1) = ' '; // Convert 0 byte back to space
|
||||
i++;
|
||||
}
|
||||
|
||||
substrings[line_count] = substr;
|
||||
substr_widths[line_count++] = substr_width;
|
||||
if (max_width < substr_width)
|
||||
max_width = substr_width;
|
||||
height += getStringHeight(substr);
|
||||
}
|
||||
delete[] words;
|
||||
|
||||
if (y > dst_height - height) {
|
||||
y = dst_height - height;
|
||||
@@ -329,86 +288,72 @@ void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int
|
||||
for (i = 0; i < line_count; i++) {
|
||||
drawSubstring(substrings[i], buffer, dst_width, x, y);
|
||||
y += getStringHeight(substrings[i]);
|
||||
delete[] substrings[i];
|
||||
}
|
||||
|
||||
delete[] substr_widths;
|
||||
delete[] substrings;
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
void SmushFont::drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) {
|
||||
debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d)", str, x, y);
|
||||
void SmushFont::drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
|
||||
debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d, %d, %d)", str, x, y, left, right);
|
||||
|
||||
char *z = strchr(str, '\n');
|
||||
if (z != 0) {
|
||||
// FIXME: this is actually evil, because it silently modifes the
|
||||
// string 'str' passed to us, despite it being declared const.
|
||||
warning("drawStringWrapCentered: got input string containing \\n");
|
||||
*z = 0;
|
||||
}
|
||||
char **words = split(str, ' ');
|
||||
const int width = right - left;
|
||||
char *s = strdup(str);
|
||||
char *words[MAX_WORDS];
|
||||
int word_count = 0;
|
||||
|
||||
while (words[word_count])
|
||||
word_count++;
|
||||
char *tmp = s;
|
||||
while (tmp) {
|
||||
assert(word_count < MAX_WORDS);
|
||||
words[word_count++] = tmp;
|
||||
tmp = strpbrk(tmp, " \t\r\n");
|
||||
if (tmp == 0)
|
||||
break;
|
||||
*tmp++ = 0;
|
||||
}
|
||||
|
||||
int i = 0, max_width = 0, height = 0, line_count = 0;
|
||||
|
||||
char **substrings = new char *[word_count];
|
||||
int *substr_widths = new int[word_count];
|
||||
int space_width = getCharWidth(' ');
|
||||
char *substrings[MAX_WORDS];
|
||||
int substr_widths[MAX_WORDS];
|
||||
const int space_width = getCharWidth(' ');
|
||||
|
||||
i = 0;
|
||||
width = MIN(width, dst_width);
|
||||
while (i < word_count) {
|
||||
int substr_width = getStringWidth(words[i]);
|
||||
char *substr = new char[1000];
|
||||
strcpy(substr, words[i]);
|
||||
int j = i + 1;
|
||||
char *substr = words[i++];
|
||||
int substr_width = getStringWidth(substr);
|
||||
|
||||
while (j < word_count) {
|
||||
int word_width = getStringWidth(words[j]);
|
||||
while (i < word_count) {
|
||||
int word_width = getStringWidth(words[i]);
|
||||
if ((substr_width + space_width + word_width) >= width)
|
||||
break;
|
||||
substr_width += word_width + space_width;
|
||||
j++;
|
||||
}
|
||||
|
||||
for (int k = i + 1; k < j; k++) {
|
||||
strcat(substr, " ");
|
||||
strcat(substr, words[k]);
|
||||
*(words[i]-1) = ' '; // Convert 0 byte back to space
|
||||
i++;
|
||||
}
|
||||
|
||||
substrings[line_count] = substr;
|
||||
substr_widths[line_count++] = substr_width;
|
||||
if (max_width < substr_width)
|
||||
max_width = substr_width;
|
||||
i = j;
|
||||
height += getStringHeight(substr);
|
||||
}
|
||||
|
||||
for (i = 0; i < word_count; i++) {
|
||||
delete[] words[i];
|
||||
}
|
||||
delete[] words;
|
||||
|
||||
if (y > dst_height - height) {
|
||||
y = dst_height - height;
|
||||
}
|
||||
|
||||
max_width = (max_width + 1) >> 1;
|
||||
x = left + width / 2;
|
||||
|
||||
if (x < max_width)
|
||||
x = max_width;
|
||||
if (x > dst_width - max_width)
|
||||
x = dst_width - max_width;
|
||||
if (x < left + max_width)
|
||||
x = left + max_width;
|
||||
if (x > right - max_width)
|
||||
x = right - max_width;
|
||||
|
||||
for (i = 0; i < line_count; i++) {
|
||||
drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
|
||||
y += getStringHeight(substrings[i]);
|
||||
delete[] substrings[i];
|
||||
}
|
||||
|
||||
delete[] substr_widths;
|
||||
delete[] substrings;
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ public:
|
||||
SmushFont(bool use_original_colors, bool new_colors);
|
||||
|
||||
void setColor(byte c) { _color = c; }
|
||||
void drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset);
|
||||
void drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width);
|
||||
void drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width);
|
||||
void drawStringAbsolute(const char *str, byte *buffer, int dst_width, int x, int y);
|
||||
void drawStringAbsolute (const char *str, byte *buffer, int dst_width, int x, int y);
|
||||
void drawStringCentered (const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
|
||||
void drawStringWrap (const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
|
||||
void drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -484,7 +484,7 @@ void SmushPlayer::handleTextResource(Chunk &b) {
|
||||
int flags = b.getShort();
|
||||
int left = b.getShort();
|
||||
int top = b.getShort();
|
||||
int width = b.getShort();
|
||||
int right = b.getShort();
|
||||
/*int32 height =*/ b.getShort();
|
||||
/*int32 unk2 =*/ b.getWord();
|
||||
|
||||
@@ -561,13 +561,13 @@ void SmushPlayer::handleTextResource(Chunk &b) {
|
||||
sf->drawStringAbsolute(str, _data, _width, pos_x, pos_y);
|
||||
break;
|
||||
case 1:
|
||||
sf->drawStringCentered(str, _data, _width, _height, MAX(pos_y, top), left, width, pos_x);
|
||||
sf->drawStringCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
|
||||
break;
|
||||
case 8:
|
||||
sf->drawStringWrap(str, _data, _width, _height, pos_x, MAX(pos_y, top), width);
|
||||
sf->drawStringWrap(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
|
||||
break;
|
||||
case 9:
|
||||
sf->drawStringWrapCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), width);
|
||||
sf->drawStringWrapCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
|
||||
break;
|
||||
default:
|
||||
warning("SmushPlayer::handleTextResource. Not handled flags: %d", flags);
|
||||
|
||||
Reference in New Issue
Block a user