[Scummvm-cvs-logs] CVS: scummvm/scumm/smush smush_font.cpp,1.11,1.12 smush_font.h,1.6,1.7 smush_player.cpp,1.25,1.26

Max Horn fingolfin at users.sourceforge.net
Sat Jun 7 17:40:02 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm/smush
In directory sc8-pr-cvs1:/tmp/cvs-serv22126

Modified Files:
	smush_font.cpp smush_font.h smush_player.cpp 
Log Message:
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)

Index: smush_font.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- smush_font.cpp	7 Jun 2003 23:12:46 -0000	1.11
+++ smush_font.cpp	8 Jun 2003 00:39:08 -0000	1.12
@@ -33,6 +33,7 @@
 }
 
 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::getStringHeight(const char *str) {
+	assert(str);
 	if (!_loaded) {
 		warning("SmushFont::getStringHeight() Font is not loaded");
 		return 0;
@@ -134,30 +136,6 @@
 	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 @@
 	}
 }
 
+#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,138 +168,116 @@
 	}
 }
 
-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]);
+			*(words[i]-1) = ' ';	// Convert 0 byte back to space
+			i++;
 		}
 
 		substrings[line_count] = substr;
 		substr_widths[line_count++] = substr_width;
-		if (substr_width > max_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;
-	int x = xmin + width / 2 + offset - dst_width / 2;
+	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);
 }
 
-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);
+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);
 
-	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, ' ');
+	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]);
+			*(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;
 	}
@@ -329,86 +288,72 @@
 	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);
 }

Index: smush_font.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- smush_font.h	7 Jun 2003 00:33:46 -0000	1.6
+++ smush_font.h	8 Jun 2003 00:39:08 -0000	1.7
@@ -43,10 +43,10 @@
 	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

Index: smush_player.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_player.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- smush_player.cpp	7 Jun 2003 22:57:27 -0000	1.25
+++ smush_player.cpp	8 Jun 2003 00:39:08 -0000	1.26
@@ -484,7 +484,7 @@
 	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 @@
 			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);





More information about the Scummvm-git-logs mailing list