[Scummvm-cvs-logs] SF.net SVN: scummvm:[34354] scummvm/branches/gsoc2008-gui

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Fri Sep 5 16:48:48 CEST 2008


Revision: 34354
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34354&view=rev
Author:   Tanoku
Date:     2008-09-05 14:48:47 +0000 (Fri, 05 Sep 2008)

Log Message:
-----------
Fixed severe bottleneck in the XML Parser code.
Applied Max's patch for character drawing.
Added new FP squareroot function.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/common/xmlparser.cpp
    scummvm/branches/gsoc2008-gui/common/xmlparser.h
    scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp
    scummvm/branches/gsoc2008-gui/graphics/font.cpp
    scummvm/branches/gsoc2008-gui/gui/newgui.cpp
    scummvm/branches/gsoc2008-gui/gui/newgui.h

Modified: scummvm/branches/gsoc2008-gui/common/xmlparser.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/common/xmlparser.cpp	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/common/xmlparser.cpp	2008-09-05 14:48:47 UTC (rev 34354)
@@ -37,7 +37,8 @@
 bool XMLParser::parserError(const char *errorString, ...) {
 	_state = kParserError;
 
-	int pos = _pos;
+	int original_pos = _stream->pos();
+	int pos = original_pos;
 	int lineCount = 1;
 	int lineStart = 0;
 
@@ -46,18 +47,21 @@
 		lineCount = 0;
 	} else {
 		do {
-			if (_text[pos] == '\n' || _text[pos] == '\r') {
+			if (_char == '\n' || _char == '\r') {
 				lineCount++;
 		
 				if (lineStart == 0)
 					lineStart = MAX(pos + 1, _pos - 60);
 			}
-		} while (pos-- > 0);
+			
+			_stream->seek(-1, SEEK_CUR);
+
+		} while (_stream->pos() > 0);
 	}
 
 	char lineStr[70];
-	_text.stream()->seek(lineStart, SEEK_SET);
-	_text.stream()->readLine(lineStr, 70);
+	_stream->seek(original_pos - 35, SEEK_SET);
+	_stream->readLine(lineStr, 70);
 	
 	for (int i = 0; i < 70; ++i)
 		if (lineStr[i] == '\n')
@@ -70,7 +74,7 @@
 
 	printf("%s%s%s\n", startFull ? "" : "...", lineStr, endFull ? "" : "...");
 
-	int cursor = MIN(_pos - lineStart, 70);
+	int cursor = 35;
 
 	if (!startFull)
 		cursor += 3;
@@ -149,15 +153,20 @@
 	_token.clear();
 	char stringStart;
 
-	if (_text[_pos] == '"' || _text[_pos] == '\'') {
-		stringStart = _text[_pos++];
+	if (_char == '"' || _char == '\'') {
+		stringStart = _char;
+		_char = _stream->readByte();
 
-		while (_text[_pos] && _text[_pos] != stringStart)
-			_token += _text[_pos++];
+		while (_char && _char != stringStart) {
+			_token += _char;
+			_char = _stream->readByte();
+		}
 
-		if (_text[_pos++] == 0)
+		if (_char == 0)
 			return false;
 
+		_char = _stream->readByte();
+
 	} else if (!parseToken()) {
 		return false;
 	}
@@ -185,7 +194,7 @@
 
 bool XMLParser::parse() {
 
-	if (_text.ready() == false)
+	if (_stream == 0)
 		return parserError("XML stream not ready for reading.");
 		
 	if (_XMLkeys == 0)
@@ -202,8 +211,10 @@
 	_state = kParserNeedKey;
 	_pos = 0;
 	_activeKey.clear();
+
+	_char = _stream->readByte();
 	
-	while (_text[_pos] && _state != kParserError) {
+	while (_char && _state != kParserError) {
 		if (skipSpaces())
 			continue;
 
@@ -212,18 +223,18 @@
 
 		switch (_state) {
 			case kParserNeedKey:
-				if (_text[_pos++] != '<') {
+				if (_char != '<') {
 					parserError("Parser expecting key start.");
 					break;
 				}
 
-				if (_text[_pos] == 0) {
+				if ((_char = _stream->readByte()) == 0) {
 					parserError("Unexpected end of file.");
 					break;
 				}
 
-				if (_text[_pos] == '/' && _text[_pos + 1] != '*') {
-					_pos++;
+				if (_char == '/') { // FIXME: What if it's a comment start
+					_char = _stream->readByte();
 					activeClosure = true;
 				}
 
@@ -262,19 +273,25 @@
 
 					activeClosure = false;
 
-					if (_text[_pos++] != '>')
+					if (_char != '>')
 						parserError("Invalid syntax in key closure.");
 					else 
 						_state = kParserNeedKey;
 
+					_char = _stream->readByte();
 					break;
 				}
 
-				selfClosure = (_text[_pos] == '/');
+				selfClosure = false;
 
-				if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
+				if (_char == '/') { // FIXME: comment start?
+					selfClosure = true;
+					_char = _stream->readByte();
+				}
+
+				if (_char == '>') {
 					if (parseActiveKey(selfClosure)) {
-						_pos += selfClosure ? 2 : 1;
+						_char = _stream->readByte();
 						_state = kParserNeedKey;
 					}
 					break;
@@ -288,11 +305,12 @@
 				break;
 
 			case kParserNeedPropertyOperator:
-				if (_text[_pos++] != '=') 
+				if (_char != '=') 
 					parserError("Syntax error after key name.");
 				else  
 					_state = kParserNeedPropertyValue;
 
+				_char = _stream->readByte();
 				break;
 
 			case kParserNeedPropertyValue:

Modified: scummvm/branches/gsoc2008-gui/common/xmlparser.h
===================================================================
--- scummvm/branches/gsoc2008-gui/common/xmlparser.h	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/common/xmlparser.h	2008-09-05 14:48:47 UTC (rev 34354)
@@ -40,145 +40,12 @@
 
 namespace Common {
 	
-/***********************************************
- **** XMLParser.cpp/h -- Generic XML Parser ****
- ***********************************************
+/*
+	XMLParser.cpp/h -- Generic XML Parser
+	=====================================
 
-	This is a simple implementation of a generic parser which is able to
-	interpret a subset of the XML language.
-	
-	The XMLParser class is virtual, and must be derived into a child class,
-	called a Custom Parser Class, which will manage the parsed data for your
-	specific needs.
-	
-	Custom Parser Classes have two basic requirements:
-	They must inherit directly the XMLParser class, and they must define the
-	parsing layout of the XML file.
-	
-	Declaring the XML layout is done with the help of the CUSTOM_XML_PARSER()
-	macro: this macro must appear once inside the Custom Parser Class 
-	declaration, and takes a single parameter, the name of the Custom Parser
-	Class.
-	
-	The macro must be followed by the actual layout of the XML files to be 
-	parsed, and closed with the PARSER_END() macro. The layout of XML files
-	is defined by the use of 3 helper macros: XML_KEY(), KEY_END() and 
-	XML_PROP().
-	
-	Here's a sample of its usage:
-	
-	===========	===========	===========	===========	===========	===========
-	
-	CUSTOM_XML_PARSER(ThemeParser) {
-		XML_KEY(render_info)
-			XML_KEY(palette)
-				XML_KEY(color)
-					XML_PROP(name, true)
-					XML_PROP(rgb, true)
-				KEY_END()
-			KEY_END()
-
-			XML_KEY(fonts)
-				XML_KEY(font)
-					XML_PROP(id, true)
-					XML_PROP(type, true)
-					XML_PROP(color, true)
-				KEY_END()
-			KEY_END()
-
-			XML_KEY(defaults)
-				XML_PROP(stroke, false)
-				XML_PROP(shadow, false)
-				XML_PROP(factor, false)
-				XML_PROP(fg_color, false)
-				XML_PROP(bg_color, false)
-				XML_PROP(gradient_start, false)
-				XML_PROP(gradient_end, false)
-				XML_PROP(gradient_factor, false)
-				XML_PROP(fill, false)
-			KEY_END()
-		KEY_END()
-	} PARSER_END()
-			
-	===========	===========	===========	===========	===========	===========
-	
-	The XML_KEY() macro takes a single argument, the name of the expected key.
-	Inside the scope of each key, you may define properties for the given key
-	with the XML_PROP() macro, which takes as parameters the name of the 
-	property and whether it's optional or required. You might also define the 
-	contained children keys, using the XML_KEY() macro again.
-	The scope of a XML key is closed with the KEY_END() macro.
-	
-	Keys which may contain any kind of Property names may be defined with the
-	XML_PROP_ANY() macro instead of the XML_PROP() macro. This macro takes no
-	arguments.
-	
-	As an example, the following XML layout:
-	
-		XML_KEY(palette)
-			XML_KEY(color)
-				XML_PROP(name, true)
-				XML_PROP(rgb, true)
-				XML_PROP(optional_param, false)
-			KEY_END()
-		KEY_END()
-		
-	will expect to parse a syntax like this:
-	
-		<palette>
-			<color name = "red" rgb = "255, 0, 0" />
-			<color name = "blue" rgb = "0, 0, 255" optional_param = "565" />
-		</palette>
-		
-	Once a layout has been defined, everytime a XML node (that is, a key and
-	all its properties) has been parsed, a specific callback funcion is called,
-	which should take care of managing the parsed data for the node.
-	
-	Callback functions must be explicitly declared with the following syntax:
-	
-		bool parserCallback_KEYNAME(ParserNode *node);
-		
-	A callback function is needed for each key that can be parsed, since they
-	are called automatically; the function will receive a pointer to the XML
-	Node that has been parsed. This XML Node has the following properties:
-	
-		- It's assured to be expected in the layout of the XML file (i.e. 
-		  has the proper position and depth in the XML tree).
-		
-		- It's assured to contain all the required Properties that have 
-		  been declared in the XML layout.
-		
-		- It's assured to contain NO unexpected properties (i.e. properties
-		  which haven't been declared in the XML layout).
-		
-	Further validation of the Node's data may be performed inside the callback
-	function. Once the node has been validated and its data has been parsed/
-	managed, the callback function is expected to return true.
-	
-	If the data in the XML Node is corrupted or there was a problem when 
-	parsing it, the callback function is expected to return false or, 
-	preferably, to throw a parserError() using the following syntax:
-	
-		return parserError("There was a problem in key '%s'.", arg1, ...);
-	
-	Also, note that the XML parser doesn't take into account the actual order
-	of the keys and properties in the XML layout definition, only its layout 
-	and relationships.
-	
-	Lastly, when defining your own Custom XML Parser, further customization 
-	may be accomplished _optionally_ by overloading several virtual functions
-	of the XMLParser class.
-	
-	Check the API documentation of the following functions for more info:
-		
-		virtual bool closedKeyCallback(ParserNode *node);
-		virtual bool skipComments();
-		virtual bool isValidNameChar(char c);
-		virtual void cleanup();
-		
-	Check the sample implementation of the GUI::ThemeParser custom parser
-	for a working sample of a Custom XML Parser.
-		
+	External documentation available at:
+		http://www.smartlikearoboc.com/scummvm_doc/xmlparser_doc.html
 */
 			
 #define XML_KEY(keyName) {\
@@ -226,43 +93,6 @@
 	
 #define PARSER_END() layout.clear(); }
 
-class XMLStream {
-protected:
-	SeekableReadStream *_stream;
-	int _pos;
-
-public:
-	XMLStream() : _stream(0), _pos(0) {}
-
-	~XMLStream() {
-		delete _stream;
-	}
-
-	SeekableReadStream *stream() {
-		return _stream;
-	}
-
-	char operator [](int idx) {
-		assert(_stream && idx >= 0);
-
-		if (_pos + 1 != idx)
-			_stream->seek(idx, SEEK_SET);
-
-		_pos = idx;
-
-		return _stream->readByte();
-	}
-
-	void loadStream(SeekableReadStream *s) {
-		delete _stream;
-		_stream = s;
-	}
-
-	bool ready() {
-		return _stream != 0;
-	}
-};
-
 /**
  * The base XMLParser class implements generic functionality for parsing
  * XML-like files.
@@ -278,13 +108,14 @@
 	/**
 	 * Parser constructor.
 	 */
-	XMLParser() : _XMLkeys(0) {}
+	XMLParser() : _XMLkeys(0), _stream(0) {}
 
 	virtual ~XMLParser() {
 		while (!_activeKey.empty())
 			delete _activeKey.pop();
 
 		delete _XMLkeys;
+		delete _stream;
 
 		for (Common::List<XMLKeyLayout*>::iterator i = _layoutList.begin();
 			i != _layoutList.end(); ++i)
@@ -352,7 +183,7 @@
 		}
 
 		_fileName = filename;
-		_text.loadStream(f);
+		_stream = f;
 		return true;
 	}
 	
@@ -365,7 +196,7 @@
 		}
 		
 		_fileName = node.getName();
-		_text.loadStream(f);
+		_stream = f;
 		return true;
 	}
 
@@ -381,13 +212,13 @@
 	 *                   no longer needed by the parser.
 	 */
 	bool loadBuffer(const byte *buffer, uint32 size, bool disposable = false) {
-		_text.loadStream(new MemoryReadStream(buffer, size, disposable));
+		_stream = new MemoryReadStream(buffer, size, disposable);
 		_fileName = "Memory Stream";
 		return true;
 	}
 	
 	bool loadStream(MemoryReadStream *stream) {
-		_text.loadStream(stream);
+		_stream = stream;
 		_fileName = "Compressed File Stream";
 		return true;
 	}
@@ -492,11 +323,11 @@
 	 * Skips spaces/whitelines etc. Returns true if any spaces were skipped.
 	 */
 	bool skipSpaces() {
-		if (!isspace(_text[_pos]))
+		if (!isspace(_char))
 			return false;
 
-		while (_text[_pos] && isspace(_text[_pos]))
-			_pos++;
+		while (_char && isspace(_char))
+			_char = _stream->readByte();
 
 		return true;
 	}
@@ -508,14 +339,31 @@
 	 * or to change the commenting syntax.
 	 */
 	virtual bool skipComments() {
-		if (_text[_pos] == '/' && _text[_pos + 1] == '*') {
-			_pos += 2;
-			while (_text[_pos++]) {
-				if (_text[_pos - 2] == '*' && _text[_pos - 1] == '/')
+		char endComment1 = 0, endComment2 = 0;
+
+		if (_char == '/') {
+			_char = _stream->readByte();
+
+			if (_char != '*') {
+				_stream->seek(-1, SEEK_CUR);
+				_char = '/';
+				return false;
+			}
+			
+			_char = _stream->readByte();
+
+			while (_char) {
+				endComment1 = endComment2;
+				endComment2 = _char;
+				_char = _stream->readByte();
+
+				if (endComment1 == '*' && endComment2 == '/')
 					break;
-				if (_text[_pos] == 0)
+
+				if (_char == 0)
 					parserError("Comment has no closure.");
 			}
+			_char = _stream->readByte();
 			return true;
 		}
 
@@ -527,7 +375,7 @@
 	 * Overload this if you want to support keys with strange characters
 	 * in their name.
 	 */
-	virtual bool isValidNameChar(char c) {
+	virtual inline bool isValidNameChar(char c) {
 		return isalnum(c) || c == '_';
 	}
 
@@ -537,10 +385,13 @@
 	 */
 	bool parseToken() {
 		_token.clear();
-		while (isValidNameChar(_text[_pos]))
-			_token += _text[_pos++];
 
-		return isspace(_text[_pos]) != 0 || _text[_pos] == '>' || _text[_pos] == '=' || _text[_pos] == '/';
+		while (isValidNameChar(_char)) {
+			_token += _char;
+			_char = _stream->readByte();
+		}
+
+		return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
 	}
 
 	/**
@@ -599,7 +450,8 @@
 
 private:
 	int _pos; /** Current position on the XML buffer. */
-	XMLStream _text; /** Buffer with the text being parsed */
+	char _char;
+	SeekableReadStream *_stream;
 	Common::String _fileName;
 
 	ParserState _state; /** Internal state of the parser */

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp	2008-09-05 14:48:47 UTC (rev 34354)
@@ -36,7 +36,71 @@
 
 #define VECTOR_RENDERER_FAST_TRIANGLES
 
-/** HELPER MACROS for BRESENHAM's circle drawing algorithm **/
+const uint16 inv_sqrt_tbl[] = {
+	0x0000, 0x0100, 0x016A, 0x01BB, 0x0200, 0x023C, 0x0273, 0x02A5,
+	0x02D4, 0x0300, 0x0329, 0x0351, 0x0376, 0x039B, 0x03BD, 0x03DF,
+	0x0400, 0x041F, 0x043E, 0x045B, 0x0478, 0x0495, 0x04B0, 0x04CB,
+	0x04E6, 0x0500, 0x0519, 0x0532, 0x054A, 0x0562, 0x057A, 0x0591,
+	0x05A8, 0x05BE, 0x05D4, 0x05EA, 0x0600, 0x0615, 0x062A, 0x063E,
+	0x0653, 0x0667, 0x067B, 0x068E, 0x06A2, 0x06B5, 0x06C8, 0x06DB,
+	0x06ED, 0x0700, 0x0712, 0x0724, 0x0736, 0x0747, 0x0759, 0x076A,
+	0x077B, 0x078C, 0x079D, 0x07AE, 0x07BE, 0x07CF, 0x07DF, 0x07EF,
+	0x0800, 0x080F, 0x081F, 0x082F, 0x083F, 0x084E, 0x085D, 0x086D,
+	0x087C, 0x088B, 0x089A, 0x08A9, 0x08B7, 0x08C6, 0x08D4, 0x08E3,
+	0x08F1, 0x0900, 0x090E, 0x091C, 0x092A, 0x0938, 0x0946, 0x0953,
+	0x0961, 0x096F, 0x097C, 0x098A, 0x0997, 0x09A4, 0x09B2, 0x09BF,
+	0x09CC, 0x09D9, 0x09E6, 0x09F3, 0x0A00, 0x0A0C, 0x0A19, 0x0A26,
+	0x0A32, 0x0A3F, 0x0A4B, 0x0A58, 0x0A64, 0x0A70, 0x0A7C, 0x0A89,
+	0x0A95, 0x0AA1, 0x0AAD, 0x0AB9, 0x0AC5, 0x0AD1, 0x0ADC, 0x0AE8,
+	0x0AF4, 0x0B00, 0x0B0B, 0x0B17, 0x0B22, 0x0B2E, 0x0B39, 0x0B44,
+	0x0B50, 0x0B5B, 0x0B66, 0x0B72, 0x0B7D, 0x0B88, 0x0B93, 0x0B9E,
+	0x0BA9, 0x0BB4, 0x0BBF, 0x0BCA, 0x0BD5, 0x0BDF, 0x0BEA, 0x0BF5,
+	0x0C00, 0x0C0A, 0x0C15, 0x0C1F, 0x0C2A, 0x0C34, 0x0C3F, 0x0C49,
+	0x0C54, 0x0C5E, 0x0C68, 0x0C73, 0x0C7D, 0x0C87, 0x0C91, 0x0C9C,
+	0x0CA6, 0x0CB0, 0x0CBA, 0x0CC4, 0x0CCE, 0x0CD8, 0x0CE2, 0x0CEC,
+	0x0CF6, 0x0D00, 0x0D09, 0x0D13, 0x0D1D, 0x0D27, 0x0D30, 0x0D3A,
+	0x0D44, 0x0D4D, 0x0D57, 0x0D61, 0x0D6A, 0x0D74, 0x0D7D, 0x0D87,
+	0x0D90, 0x0D99, 0x0DA3, 0x0DAC, 0x0DB6, 0x0DBF, 0x0DC8, 0x0DD1,
+	0x0DDB, 0x0DE4, 0x0DED, 0x0DF6, 0x0E00, 0x0E09, 0x0E12, 0x0E1B,
+	0x0E24, 0x0E2D, 0x0E36, 0x0E3F, 0x0E48, 0x0E51, 0x0E5A, 0x0E63,
+	0x0E6C, 0x0E74, 0x0E7D, 0x0E86, 0x0E8F, 0x0E98, 0x0EA0, 0x0EA9,
+	0x0EB2, 0x0EBB, 0x0EC3, 0x0ECC, 0x0ED5, 0x0EDD, 0x0EE6, 0x0EEE,
+	0x0EF7, 0x0F00, 0x0F08, 0x0F11, 0x0F19, 0x0F21, 0x0F2A, 0x0F32,
+	0x0F3B, 0x0F43, 0x0F4C, 0x0F54, 0x0F5C, 0x0F65, 0x0F6D, 0x0F75,
+	0x0F7D, 0x0F86, 0x0F8E, 0x0F96, 0x0F9E, 0x0FA7, 0x0FAF, 0x0FB7,
+	0x0FBF, 0x0FC7, 0x0FCF, 0x0FD7, 0x0FDF, 0x0FE7, 0x0FEF, 0x0FF7,
+	0x1000
+};
+
+inline uint32 fp_sqroot(uint32 x) {
+    int bit;
+
+#if defined(__arm__)
+	__asm__ ("clz  %0, %1\nrsb  %0, %0, #31\n" : "=r"(bit) : "r" (x));
+#elif defined(__i386__)
+	__asm__("bsrl %1, %0" : "=r" (bit) : "r" (x));
+#else
+	unsigned int mask = 0x40000000;
+	bit = 30;
+	while (bit >= 0) {
+	    if (x & mask)
+			break;
+
+	    mask = (mask >> 1 | mask >> 2);
+	    bit -= 2;
+	}
+#endif
+	
+	bit -= 6 + (bit & 1);
+	return inv_sqrt_tbl[x >> bit] << (bit >> 1);
+}
+
+inline uint32 circleSqrt(int x) {
+	return (x > 255 ? fp_sqroot(x) : inv_sqrt_tbl[x]) ^ 0xFF;
+}
+
+
+/** HELPER MACROS for BESENHALM's circle drawing algorithm **/
 #define __BE_ALGORITHM() { \
 	if (f >= 0) { \
 		y--; \
@@ -111,7 +175,7 @@
 	blendPixelPtr(ptr4 + (y) + (px), color, a); \
 }
 
-#define __WU_ALGORITHM() { \
+/*#define __WU_ALGORITHM() { \
 	oldT = T; \
 	T = fp_sqroot(rsq - ((y * y) << 16)) ^ 0xFFFF; \
 	py += p; \
@@ -120,6 +184,16 @@
 	} \
 	a2 = (T >> 8); \
 	a1 = ~a2; \
+} */
+
+// optimized Wu's algorithm
+#define __WU_ALGORITHM() {\
+	py += p; \
+	oldT = T; \
+	T = circleSqrt(rsq - (y * y)); \
+	a2 = T; \
+	a1 = ~T; \
+	if (T < oldT) { x--; px -= p; } \
 }
 
 
@@ -138,30 +212,6 @@
 		return 0;
 	}
 }
-
-/** Fixed point SQUARE ROOT **/
-inline uint32 fp_sqroot(uint32 x) {
-	register uint32 root, remHI, remLO, testDIV, count;
-
-	root = 0;
-	remHI = 0;
-	remLO = x;
-	count = 23;
-
-	do {
-		remHI = (remHI << 2) | (remLO >> 30);
-		remLO <<= 2;
-		root <<= 1;
-		testDIV = (root << 1) + 1;
-
-		if (remHI >= testDIV) {
-			remHI -= testDIV;
-			root++;
-		}
-	} while (count--);
-
-	return root;
-}
      
 template <typename PixelType, typename PixelFormat>
 void VectorRendererSpec<PixelType, PixelFormat>::
@@ -1512,7 +1562,7 @@
 		x = r; y = 0; T = 0;
 		px = p * x; py = 0;
 		
-		while (x > y++) {
+		while (x > 1 + y++) {
 			__WU_ALGORITHM();
 
 			colorFill(ptr_tl - x - py, ptr_tr + x - py, color);

Modified: scummvm/branches/gsoc2008-gui/graphics/font.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/font.cpp	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/graphics/font.cpp	2008-09-05 14:48:47 UTC (rev 34354)
@@ -48,7 +48,29 @@
 	return desc.width[chr - desc.firstchar];
 }
 
-void NewFont::drawChar(Surface *dst, byte chr, int tx, int ty, uint32 color) const {
+
+template <int bytesPerPixel>
+void drawCharIntern(byte *ptr, uint pitch, const bitmap_t *src, int h, int minX, int maxX, const uint32 color) {
+	while (h-- > 0) {
+		const bitmap_t buffer = READ_UINT16(src);
+		src++;
+
+		int x = minX;
+		uint mask = 0x8000 >> minX;
+		for (; x < maxX; x++, mask >>= 1) {
+			if ((buffer & mask) != 0) {
+				if (bytesPerPixel == 1)
+					ptr[x] = color;
+				else if (bytesPerPixel == 2)
+					((uint16 *)ptr)[x] = color;
+			}
+		}
+		
+		ptr += pitch;
+	}
+}
+
+void NewFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const {
 	assert(dst != 0);
 
 	assert(desc.bits != 0 && desc.maxwidth <= 17);
@@ -80,25 +102,14 @@
 
 	const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
 
-	for (int y = 0; y < bbh; y++, ptr += dst->pitch) {
-		const bitmap_t buffer = READ_UINT16(tmp);
-		tmp++;
-		bitmap_t mask = 0x8000;
-		if (ty + desc.ascent - bby - bbh + y < 0 ||
-		    ty + desc.ascent - bby - bbh + y >= dst->h)
-			continue;
+	int y = MIN(bbh, ty + desc.ascent - bby);
+	tmp += bbh - y;
+	y -= MAX(0, ty + desc.ascent - bby - dst->h);
 
-		for (int x = 0; x < bbw; x++, mask >>= 1) {
-			if (tx + bbx + x < 0 || tx + bbx + x >= dst->w)
-				continue;
-			if ((buffer & mask) != 0) {
-				if (dst->bytesPerPixel == 1)
-					ptr[x] = color;
-				else if (dst->bytesPerPixel == 2)
-					((uint16 *)ptr)[x] = color;
-			}
-		}
-	}
+	if (dst->bytesPerPixel == 1)
+		drawCharIntern<1>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
+	else if (dst->bytesPerPixel == 2)
+		drawCharIntern<2>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
 }
 
 

Modified: scummvm/branches/gsoc2008-gui/gui/newgui.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/newgui.cpp	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/gui/newgui.cpp	2008-09-05 14:48:47 UTC (rev 34354)
@@ -106,7 +106,7 @@
 	delete _theme;
 }
 
-bool NewGui::loadNewTheme(const Common::String &filename, ThemeEngine::GraphicsMode gfx) {
+bool NewGui::loadNewTheme(Common::String filename, ThemeEngine::GraphicsMode gfx) {
 	if (_theme && filename == _theme->getThemeFileName() && gfx == _theme->getGraphicsMode())
 		return true;
 	
@@ -124,8 +124,6 @@
 	}
 
 	delete _theme;
-	_theme = 0;
-
 	_theme = new ThemeEngine(filename, gfx);
 
 	if (!_theme)

Modified: scummvm/branches/gsoc2008-gui/gui/newgui.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/newgui.h	2008-09-05 14:11:23 UTC (rev 34353)
+++ scummvm/branches/gsoc2008-gui/gui/newgui.h	2008-09-05 14:48:47 UTC (rev 34354)
@@ -78,7 +78,7 @@
 
 	bool isActive() const	{ return ! _dialogStack.empty(); }
 
-	bool loadNewTheme(const Common::String &file, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled);
+	bool loadNewTheme(Common::String file, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled);
 	Theme *theme() { return _theme; }
 	
 	ThemeEval *xmlEval() { return _theme->evaluator(); }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list