Index: scumm/nut_renderer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.cpp,v
retrieving revision 1.57
diff -u -r1.57 nut_renderer.cpp
--- scumm/nut_renderer.cpp	15 May 2005 10:40:27 -0000	1.57
+++ scumm/nut_renderer.cpp	16 Jun 2005 17:45:06 -0000
@@ -44,74 +44,42 @@
 	}
 }
 
-int32 NutRenderer::decodeCodec44(byte *dst, const byte *src, uint32 length) {
-	byte val;
-	uint16 size_line, num;
-	int16 decoded_length = 0;
-
-	do {
-		size_line = READ_LE_UINT16(src);
-		src += 2;
-		length -= 2;
-
-		while (size_line != 0) {
-			num = *src++;
-			val = *src++;
-			memset(dst, val, num);
-			dst += num;
-			decoded_length += num;
-			length -= 2;
-			size_line -= 2;
-			if (size_line != 0) {
-				num = READ_LE_UINT16(src) + 1;
-				src += 2;
-				memcpy(dst, src, num);
-				dst += num;
-				decoded_length += num;
-				src += num;
-				length -= num + 2;
-				size_line -= num + 2;
-			}
-		}
-		dst--;
-		decoded_length--;
+static uint8 *fobj_end = 0;
+static uint8 *dst_end = 0;
 
-	} while (length > 1);
-	return decoded_length;
-}
+void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
 
-static int32 codec1(byte *dst, byte *src, int height) {
-	byte val, code;
-	int32 length, decoded_length = 0;
-	int h = height, size_line;
-
-	for (h = 0; h < height; h++) {
-		size_line = READ_LE_UINT16(src);
-		src += 2;
-		while (size_line > 0) {
-			code = *src++;
-			size_line--;
-			length = (code >> 1) + 1;
-			if (code & 1) {
-				val = *src++;
-				size_line--;
-				if (val)
-					memset(dst, val, length);
-				dst += length;
-				decoded_length += length;
-			} else {
-				size_line -= length;
-				while (length--) {
-					val = *src++;
-					if (val)
-						*dst = val;
-					dst++;
-					decoded_length++;
-				}
+static void smush_decode_codec21(byte *dst, const byte *src, int width, int height, int pitch) {
+	while (height--) {
+		uint8 *dstPtrNext = dst + pitch;
+		assert(src + 2 <= fobj_end);
+		const uint8 *srcPtrNext = src + 2 + READ_LE_UINT16(src); src += 2;
+		int len = width;
+		do {
+			assert(src + 2 <= fobj_end);
+			int offs = READ_LE_UINT16(src); src += 2;
+			dst += offs;
+			len -= offs;
+			if (len <= 0) {
+				break;
 			}
-		}
+			assert(src + 2 <= fobj_end);
+			int w = READ_LE_UINT16(src) + 1; src += 2;
+			len -= w;
+			if (len < 0) {
+				w += len;
+			}
+			// the original codec44 handles this part slightly differently (this is the only difference with codec21) :
+			//  src bytes equal to 255 are replaced by 0 in dst
+			//  src bytes equal to 1 are replaced by a color passed as an argument in the original function
+			//  other src bytes values are copied as-is
+			assert(dst + w <= dst_end);
+			assert(src + w <= fobj_end);
+			memcpy(dst, src, w); dst += w; src += w;
+		} while (len > 0);
+		dst = dstPtrNext;
+		src = srcPtrNext;
 	}
-	return decoded_length;
 }
 
 bool NutRenderer::loadFont(const char *filename) {
@@ -145,51 +113,43 @@
 
 	_numChars = READ_LE_UINT16(dataSrc + 10);
 	uint32 offset = 0;
-	int32 decoded_length;
-
 	for (int l = 0; l < _numChars; l++) {
 		offset += READ_BE_UINT32(dataSrc + offset + 4) + 8;
-		if (READ_BE_UINT32(dataSrc + offset) == 'FRME') {
-			offset += 8;
-
-			if (READ_BE_UINT32(dataSrc + offset) == 'FOBJ') {
-				int codec = READ_LE_UINT16(dataSrc + offset + 8);
-				_chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
-				_chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
-				_chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
-				_chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
-				_chars[l].src = new byte[(_chars[l].width + 2) * _chars[l].height + 1000];
-
-				// If characters have transparency, then bytes just get skipped and
-				// so there may appear some garbage. That's why we have to fill it
-				// with zeroes first.
-				memset(_chars[l].src, 0, (_chars[l].width + 2) * _chars[l].height + 1000);
-				if ((codec == 44) || (codec == 21)) 
-					decoded_length = decodeCodec44(_chars[l].src, dataSrc + offset + 22, READ_BE_UINT32(dataSrc + offset + 4) - 14);
-				else if (codec == 1) {
-					decoded_length = codec1(_chars[l].src, dataSrc + offset + 22, _chars[l].height);
-				} else
-					error("NutRenderer::loadFont: unknown codec: %d", codec);
-
-				// FIXME: This is used to work around wrong font file format in Russian 
-				// version of FT. Font files there contain wrong information about
-				// glyphs width. See patch #823031.
-				if (_vm->_language == Common::RU_RUS) {
-					// try to rely on length of returned data
-				  	if (l > 127)
-						_chars[l].width = decoded_length / _chars[l].height;
-					// but even this not always works
-					if (l == 134 && !strcmp(filename, "titlfnt.nut"))
-						_chars[l].width--;
-				}
-			} else {
-				warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
-				break;
-			}
-		} else {
+		if (READ_BE_UINT32(dataSrc + offset) != 'FRME') {
 			warning("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);
 			break;
 		}
+		offset += 8;
+		if (READ_BE_UINT32(dataSrc + offset) != 'FOBJ') {
+			warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
+			break;
+		}
+		int codec = READ_LE_UINT16(dataSrc + offset + 8);
+		_chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
+		_chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
+		_chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
+		_chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
+		const int srcSize = _chars[l].width * _chars[l].height;
+		_chars[l].src = new byte[srcSize];
+		// If characters have transparency, then bytes just get skipped and
+		// so there may appear some garbage. That's why we have to fill it
+		// with zeroes first.
+		memset(_chars[l].src, 0, srcSize);
+		
+		const uint8 *fobjptr = dataSrc + offset + 22;
+		fobj_end = dataSrc + offset + 22 + READ_BE_UINT32(dataSrc + offset + 4) - 14;
+		dst_end = _chars[l].src + srcSize;
+		switch (codec) {
+		case 1:
+			smush_decode_codec1(_chars[l].src, fobjptr, 0, 0, _chars[l].width, _chars[l].height, _chars[l].width);
+			break;
+		case 21:
+		case 44:
+			smush_decode_codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
+			break;
+		default:
+			error("NutRenderer::loadFont: unknown codec: %d", codec);
+		}
 	}
 
 	free(dataSrc);
@@ -227,38 +187,6 @@
 	return _chars[c].height;
 }
 
-int NutRenderer::getCharOffsX(byte c) const {
-	if (!_loaded) {
-		warning("NutRenderer::getCharOffsX() Font is not loaded");
-		return 0;
-	}
-
-	if (c >= 0x80 && _vm->_useCJKMode) {
-		return 0;
-	}
-
-	if (c >= _numChars)
-		error("invalid character in NutRenderer::getCharOffsX : %d (%d)", c, _numChars);
-
-	return _chars[c].xoffs;
-}
-
-int NutRenderer::getCharOffsY(byte c) const {
-	if (!_loaded) {
-		warning("NutRenderer::getCharOffsY() Font is not loaded");
-		return 0;
-	}
-
-	if (c >= 0x80 && _vm->_useCJKMode) {
-		return 0;
-	}
-
-	if (c >= _numChars)
-		error("invalid character in NutRenderer::getCharOffsY : %d (%d)", c, _numChars);
-
-	return _chars[c].yoffs;
-}
-
 void NutRenderer::drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow) {
 	if (!_loaded) {
 		warning("NutRenderer::drawShadowChar() Font is not loaded");
Index: scumm/nut_renderer.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.h,v
retrieving revision 1.22
diff -u -r1.22 nut_renderer.h
--- scumm/nut_renderer.h	1 Jan 2005 16:09:14 -0000	1.22
+++ scumm/nut_renderer.h	16 Jun 2005 17:45:06 -0000
@@ -42,8 +42,6 @@
 		byte *src;
 	} _chars[256];
 
-	int32 decodeCodec44(byte *dst, const byte *src, uint32 length);
-
 	void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
 	void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
 
@@ -59,9 +57,6 @@
 
 	int getCharWidth(byte c) const;
 	int getCharHeight(byte c) const;
-
-	int getCharOffsX(byte c) const;
-	int getCharOffsY(byte c) const;
 };
 
 } // End of namespace Scumm
Index: scumm/smush/codec1.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/codec1.cpp,v
retrieving revision 1.15
diff -u -r1.15 codec1.cpp
--- scumm/smush/codec1.cpp	1 Jan 2005 16:09:18 -0000	1.15
+++ scumm/smush/codec1.cpp	16 Jun 2005 17:45:06 -0000
@@ -24,12 +24,12 @@
 
 namespace Scumm {
 
-void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth) {
+void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {
 	byte val, code;
 	int32 length;
 	int h = height, size_line;
 
-	dst += top * dstWidth;
+	dst += top * pitch;
 	for (h = 0; h < height; h++) {
 		size_line = READ_LE_UINT16(src);
 		src += 2;
@@ -54,7 +54,7 @@
 				}
 			}
 		}
-		dst += dstWidth - left - width;
+		dst += pitch - left - width;
 	}
 }
 
Index: scumm/smush/smush_player.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_player.cpp,v
retrieving revision 1.165
diff -u -r1.165 smush_player.cpp
--- scumm/smush/smush_player.cpp	11 Jun 2005 15:46:00 -0000	1.165
+++ scumm/smush/smush_player.cpp	16 Jun 2005 17:45:06 -0000
@@ -724,7 +724,7 @@
 	setDirtyColors(0, 255);
 }
 
-void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth);
+void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
 
 #ifdef USE_ZLIB
 void SmushPlayer::handleZlibFrameObject(Chunk &b) {
@@ -781,7 +781,7 @@
 	switch (codec) {
 	case 1:
 	case 3:
-		smush_decode_codec1(_dst, fobjBuffer + 14, left, top, height, width, _vm->_screenWidth);
+		smush_decode_codec1(_dst, fobjBuffer + 14, left, top, width, height, _vm->_screenWidth);
 		break;
 	case 37:
 		_codec37.decode(_dst, fobjBuffer + 14);
@@ -855,7 +855,7 @@
 	switch (codec) {
 	case 1:
 	case 3:
-		smush_decode_codec1(_dst, chunk_buffer, left, top, height, width, _vm->_screenWidth);
+		smush_decode_codec1(_dst, chunk_buffer, left, top, width, height, _vm->_screenWidth);
 		break;
 	case 37:
 		_codec37.decode(_dst, chunk_buffer);
