diff options
| author | Vicent Marti | 2008-06-18 00:15:21 +0000 | 
|---|---|---|
| committer | Vicent Marti | 2008-06-18 00:15:21 +0000 | 
| commit | 42036e7fd332a25cb902a220aa020e82cb0794ef (patch) | |
| tree | ec3300ec270aed74b7a510fee5b390aec7e4c695 | |
| parent | 6932c836cfb5f02565feb4700f42633ed5c84d68 (diff) | |
| download | scummvm-rg350-42036e7fd332a25cb902a220aa020e82cb0794ef.tar.gz scummvm-rg350-42036e7fd332a25cb902a220aa020e82cb0794ef.tar.bz2 scummvm-rg350-42036e7fd332a25cb902a220aa020e82cb0794ef.zip  | |
Expanded parser.
Added regex support for Common::String
Changed drawstep state saving.
svn-id: r32729
| -rw-r--r-- | common/str.cpp | 99 | ||||
| -rw-r--r-- | common/str.h | 17 | ||||
| -rw-r--r-- | graphics/VectorRenderer.cpp | 29 | ||||
| -rw-r--r-- | graphics/VectorRenderer.h | 19 | ||||
| -rw-r--r-- | gui/InterfaceManager.cpp | 12 | ||||
| -rw-r--r-- | gui/InterfaceManager.h | 9 | ||||
| -rw-r--r-- | gui/ThemeParser.cpp | 66 | ||||
| -rw-r--r-- | gui/ThemeParser.h | 9 | 
8 files changed, 213 insertions, 47 deletions
diff --git a/common/str.cpp b/common/str.cpp index ad48ef6087..e849cb042d 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -283,6 +283,105 @@ void String::toUppercase() {  		_str[i] = toupper(_str[i]);  } +bool String::regexMatch(const char *regex, bool skipSpaces) { +	int pos = 0; + +	if (regex[0] == '^') +		return regexMatchPos(1, regex, 1, skipSpaces); + +	do { +		if (regexMatchPos(pos, regex, 0, skipSpaces)) +			return true; +	} while (_str[pos++]); + +	return false; +} + +bool String::regexMatchCharacter(RegexMatchType type, char regexChar, char strChar) { +	switch (type) { +		case kRegexMatchAny: +			return true; + +		case kRegexMatchDigit: +			return isdigit(strChar) != 0; + +		case kRegexMatchSpace: +			return isspace(strChar) != 0; + +		case kRegexMatchAlphanum: +			return isalnum(strChar) != 0; + +		case kRegexMatchAlpha: +			return isalpha(strChar) != 0; + +		case kRegexMatchWord: +			return isalnum(strChar) != 0 || strChar == '_'; + +		case kRegexMatchCharacter: +			return regexChar == strChar; + +		default: +			return false; +	} +} + +bool String::regexMatchStar(RegexMatchType type, char regexChar, const char *regex, int regexPos, int strPos, bool skipSpaces) { + +	do { +		if (regexMatchPos(strPos, regex, regexPos, skipSpaces)) +			return true; +	} while (_str[strPos] && regexMatchCharacter(type, regexChar, _str[strPos++])); + +	return false; +} + +bool String::regexMatchPos(int strPos, const char *regex, int regexPos, bool skipSpaces) { +	RegexMatchType matchT = kRegexMatchCharacter; + +	if (skipSpaces) { +		while (isspace(_str[strPos])) +			strPos++; + +		while (isspace(regex[regexPos])) +			regexPos++; +	} + +	if (regex[regexPos] == '\0') +		return true; + +	if (regex[regexPos] == '.') +		matchT = kRegexMatchAny; +	else if (regex[regexPos] == '[') { +		String group; +		while (regex[regexPos - 1] != ']') +			group += regex[regexPos++]; + +		regexPos--; + +		if (group == "[digit]" || group == "[d]") +			matchT = kRegexMatchDigit; +		else if (group == "[space]" || group == "[s]") +			matchT = kRegexMatchSpace; +		else if (group == "[alnum]") +			matchT = kRegexMatchAlphanum; +		else if (group == "[alpha]") +			matchT = kRegexMatchAlpha; +		else if (group == "[word]") +			matchT = kRegexMatchWord; +	} + +	if (regex[regexPos + 1] == '*') +		return regexMatchStar(matchT, regex[regexPos], regex, regexPos + 2, strPos, skipSpaces); + +	if (regex[regexPos] == '$' && regex[regexPos + 1] == 0) +		return _str[strPos] == 0; + +	if (_str[strPos] && regexMatchCharacter(matchT, regex[regexPos], _str[strPos])) +		return regexMatchPos(strPos + 1, regex, regexPos + 1, skipSpaces); + +	return false; +} +  /**   * Ensure that enough storage is available to store at least new_len   * characters plus a null byte. In addition, if we currently share diff --git a/common/str.h b/common/str.h index a92ec34fff..2ea151ba96 100644 --- a/common/str.h +++ b/common/str.h @@ -165,6 +165,9 @@ public:  	uint hash() const; +	// Tanoku: Regular expression support for the String class +	bool regexMatch(const char *regex, bool skipSpaces = false); +  public:  	typedef char *        iterator;  	typedef const char *  const_iterator; @@ -189,6 +192,20 @@ protected:  	void ensureCapacity(uint32 new_len, bool keep_old);  	void incRefCount() const;  	void decRefCount(int *oldRefCount); + +	enum RegexMatchType { +		kRegexMatchAny, +		kRegexMatchDigit, +		kRegexMatchSpace, +		kRegexMatchAlphanum, +		kRegexMatchAlpha, +		kRegexMatchWord, +		kRegexMatchCharacter +	}; + +	bool regexMatchStar(RegexMatchType type, char regexChar, const char *regex, int regexPos, int strPos, bool skipSpaces); +	bool regexMatchCharacter(RegexMatchType type, char regexChar, char strChar); +	bool regexMatchPos(int strPos, const char *regex, int regexPos, bool skipSpaces);  };  // Append two strings to form a new (temp) string diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 0194231427..1f8ec3c397 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -53,35 +53,20 @@ VectorRenderer *createRenderer(int mode) {   ********************************************************************/  void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step) { -	if (step.flags & DrawStep::kStepCallbackOnly) { -		(this->*(step.drawingCall))(area, step); -		return; -	} - -	if (step.flags & DrawStep::kStepSetBG) +	if (step.bgColor.set)  		setBgColor(step.bgColor.r, step.bgColor.g, step.bgColor.b); -	if (step.flags & DrawStep::kStepSetFG) +	if (step.fgColor.set)  		setFgColor(step.fgColor.r, step.fgColor.g, step.fgColor.b); -	if (step.flags & DrawStep::kStepSetGradient) +	if (step.gradColor1.set && step.gradColor2.set)  		setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b,   						  step.gradColor2.r, step.gradColor2.g, step.gradColor2.b); -	if (step.flags & DrawStep::kStepSetShadow) -		shadowEnable(step.shadow); - -	if (step.flags & DrawStep::kStepSetGradientFactor) -		setGradientFactor(step.factor); - -	if (step.flags & DrawStep::kStepSetStroke) -		setStrokeWidth(step.stroke); - -	if (step.flags & DrawStep::kStepSetFillMode) -		setFillMode((FillMode)step.fillMode); -		 -	if (step.flags & DrawStep::kStepSettingsOnly) -		return; +	shadowEnable(step.shadow); +	setGradientFactor(step.factor); +	setStrokeWidth(step.stroke); +	setFillMode((FillMode)step.fillMode);  	(this->*(step.drawingCall))(area, step);	  } diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index b4c4bb656d..d989781d5c 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -40,10 +40,9 @@ class VectorRenderer;  struct DrawStep;  struct DrawStep { -	uint32 flags; /** Step flags, see DrawStepFlags */ -  	struct {  -		uint8 r, g, b;  +		uint8 r, g, b; +		bool set;  	}	  	fgColor, /** Foreground color */  	bgColor, /** backgroudn color */ @@ -68,18 +67,6 @@ struct DrawStep {  	uint32 scale; /** scale of all the coordinates in FIXED POINT with 16 bits mantissa */  	void (VectorRenderer::*drawingCall)(const Common::Rect &, const DrawStep &); /** Pointer to drawing function */ - -	enum DrawStepFlags { -		kStepCallbackOnly		= (1 << 0), -		kStepSettingsOnly		= (1 << 1), -		kStepSetBG				= (1 << 2), -		kStepSetFG				= (1 << 3), -		kStepSetGradient		= (1 << 4), -		kStepSetShadow			= (1 << 5), -		kStepSetGradientFactor	= (1 << 6), -		kStepSetStroke			= (1 << 7), -		kStepSetFillMode		= (1 << 8) -	};  };  VectorRenderer *createRenderer(int mode); @@ -403,6 +390,8 @@ public:  		drawBeveledSquare(x, y, w, h, step.extraData);  	} +	void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {} +  	/**  	 * Draws the specified draw step on the screen.  	 *  diff --git a/gui/InterfaceManager.cpp b/gui/InterfaceManager.cpp index ae52387502..dc2250a2bd 100644 --- a/gui/InterfaceManager.cpp +++ b/gui/InterfaceManager.cpp @@ -77,6 +77,11 @@ void InterfaceManager::setGraphicsMode(Graphics_Mode mode) {  	_vectorRenderer->setSurface(_screen);  } +void InterfaceManager::addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step) { +	_widgets[getDrawDataId(drawDataId)]->_steps.push_back(step); +} + +  bool InterfaceManager::init() {  	return false;  } @@ -96,7 +101,7 @@ void InterfaceManager::drawDD(DrawData type, const Common::Rect &r) {  	if (isWidgetCached(type, r)) {  		drawCached(type, r);  	} else { -		for (int i = 0; i < _widgets[type]->_stepCount; ++i) +		for (uint i = 0; i < _widgets[type]->_steps.size(); ++i)  			_vectorRenderer->drawStep(r, *_widgets[type]->_steps[i]);  	}  } @@ -171,7 +176,6 @@ int InterfaceManager::runGUI() {  	steps[0].gradColor2.b = 25;  	steps[0].fillMode = VectorRenderer::kFillGradient;  	steps[0].drawingCall = &VectorRenderer::drawCallback_FILLSURFACE; -	steps[0].flags = DrawStep::kStepSetGradient | DrawStep::kStepSetFillMode;  	steps[1].gradColor1.r = 206;  	steps[1].gradColor1.g = 121; @@ -182,7 +186,6 @@ int InterfaceManager::runGUI() {  	steps[1].radius = 8; // radius  	steps[1].fillArea = true;  	steps[1].drawingCall = &VectorRenderer::drawCallback_ROUNDSQ; -	steps[1].flags = DrawStep::kStepSetGradient;  	steps[1].scale = (1 << 16);  	steps[2].radius = 8; // radius @@ -194,13 +197,12 @@ int InterfaceManager::runGUI() {  	steps[2].w = 128;  	steps[2].h = 32;  	steps[2].drawingCall = &VectorRenderer::drawCallback_ROUNDSQ; -	steps[2].flags = DrawStep::kStepCallbackOnly;  	steps[2].scale = (1 << 16);  	steps[3].fgColor.r = 255;  	steps[3].fgColor.g = 255;  	steps[3].fgColor.b = 255; -	steps[3].flags = DrawStep::kStepSettingsOnly | DrawStep::kStepSetFG; +	steps[3].drawingCall = &VectorRenderer::drawCallback_VOID;  	Common::Rect area = Common::Rect(32, 32, 256, 256); diff --git a/gui/InterfaceManager.h b/gui/InterfaceManager.h index 7ab3f4c9db..f5efb105ec 100644 --- a/gui/InterfaceManager.h +++ b/gui/InterfaceManager.h @@ -167,6 +167,12 @@ public:  	void drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state = kStateEnabled) {}  	void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled); +	DrawData getDrawDataId(Common::String &name) { +		return (DrawData)0; +	} + +	void addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step); +  protected:  	template<typename PixelType> void screenInit(); @@ -209,8 +215,7 @@ struct WidgetDrawData {  	Common::Rect _realSize;  	bool _scaled; -	Graphics::DrawStep **_steps; -	int _stepCount; +	Common::Array<Graphics::DrawStep*> _steps;  	bool _cached;  	Graphics::Surface *_surfaceCache; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 267efba371..287805b0b6 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -29,7 +29,9 @@  #include "common/hashmap.h"  #include "common/hash-str.h" +#include "gui/InterfaceManager.h"  #include "gui/ThemeParser.h" +#include "graphics/VectorRenderer.h"  /** @@ -42,6 +44,8 @@  namespace GUI { +using namespace Graphics; +  void ThemeParser::debug_testEval() {  	static const char *debugConfigText =  		"</* lol this is just a moronic test */drawdata id = \"background_default\" cache = true>\n" @@ -50,6 +54,11 @@ void ThemeParser::debug_testEval() {  		"</ drawdata>/* lol this is just a simple test*/\n";  	_text = strdup(debugConfigText); + +	Common::String test = "12,  125, 125"; + +	printf("\n\nRegex result: %s.\n\n", test.regexMatch("^[d]*,[d]*,[d]*$", true) ? "Success." : "Fail"); +  	parse();  } @@ -59,8 +68,59 @@ void ThemeParser::parserError(const char *error_string) {  	printf("PARSER ERROR: %s\n", error_string);  } +Graphics::DrawStep *ThemeParser::newDrawStep() { + +	Graphics::DrawStep *step = new DrawStep; + +	step->fgColor.set = false; +	step->bgColor.set = false; +	step->gradColor1.set = false; +	step->gradColor2.set = false; + +	step->extraData = 0; +	step->factor = 1; +	step->fillArea = false; +	step->fillMode = Graphics::VectorRenderer::kFillDisabled; +	step->scale = (1 << 16); +	step->shadow = 0; +	step->stroke = 1; + +	return step; +} +  void ThemeParser::parserCallback_DRAWSTEP() { -	printf("Draw callback!\n"); +	ParserNode *stepNode = _activeKey.pop(); +	ParserNode *drawdataNode = _activeKey.pop(); + +	assert(stepNode->name == "drawstep"); +	assert(drawdataNode->name == "drawdata"); +	assert(drawdataNode->values.contains("id")); + +	Graphics::DrawStep *drawstep = newDrawStep(); + +	Common::String functionName = stepNode->values["func"];  + +	if (_drawFunctions.contains(functionName) == false) { +		parserError("Invalid drawing function in draw step."); +		_activeKey.push(drawdataNode); +		_activeKey.push(stepNode); +		return; +	}	 + +	drawstep->drawingCall = _drawFunctions[functionName]; + +	if (stepNode->values.contains("stroke")) { + +	} + +	if (functionName == "roundedsq") { + +	} + +	g_InterfaceManager.addDrawStep(drawdataNode->values["id"], drawstep); + +	_activeKey.push(drawdataNode); +	_activeKey.push(stepNode);  }  void ThemeParser::parserCallback_DRAWDATA() { @@ -78,8 +138,8 @@ void ThemeParser::parseActiveKey(bool closed) {  	// Don't you just love C++ syntax? Water clear.  	(this->*(_callbacks[_activeKey.top()->name]))(); -	for (Common::StringMap::const_iterator t = _activeKey.top()->values.begin(); t != _activeKey.top()->values.end(); ++t) -		printf("    Key %s = %s\n", t->_key.c_str(), t->_value.c_str()); +//	for (Common::StringMap::const_iterator t = _activeKey.top()->values.begin(); t != _activeKey.top()->values.end(); ++t) +//		printf("    Key %s = %s\n", t->_key.c_str(), t->_value.c_str());  	if (closed) {  		delete _activeKey.pop(); diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 956a6d1df2..c5ee55dbbf 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -34,6 +34,8 @@  #include "common/hash-str.h"  #include "common/stack.h" +#include "graphics/VectorRenderer.h" +  /**   *********************************************   ** Theme Description File format overview. ** @@ -302,10 +304,13 @@ func = "fill"  namespace GUI { +using namespace Graphics; +  class ThemeParser {  	static const int kParserMaxDepth = 4;  	typedef void (ThemeParser::*ParserCallback)(); +	typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const DrawStep &);  public:  	ThemeParser() { @@ -337,6 +342,8 @@ protected:  	void parseActiveKey(bool closed);  	void parserError(const char *errorString); +	Graphics::DrawStep *newDrawStep(); +  	inline bool skipSpaces() {  		if (!isspace(_text[_pos]))  			return false; @@ -395,7 +402,9 @@ protected:  	};  	Common::FixedStack<ParserNode*, kParserMaxDepth> _activeKey; +  	Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks; +	Common::HashMap<Common::String, DrawingFunctionCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _drawFunctions;  };  }  | 
