src/ldconfig.cc

changeset 557
04e140bdeb0b
child 600
209e3f1f7b2c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldconfig.cc	Fri Dec 13 20:01:49 2013 +0200
@@ -0,0 +1,194 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 Santeri Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "document.h"
+#include "ldconfig.h"
+#include "gui.h"
+#include "misc.h"
+#include "colors.h"
+
+// =============================================================================
+// Helper function for parseLDConfig
+// -----------------------------------------------------------------------------
+static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, str& val)
+{	int pos;
+
+	// Try find the token and get its position
+	if (!pars.findToken (pos, tag, 1))
+		return false;
+
+	// Get the token after it and store it into val
+	return pars.getToken (val, pos + 1);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void parseLDConfig()
+{	File* f = openLDrawFile ("LDConfig.ldr", false);
+
+	if (!f)
+	{	critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing: %1"),
+			strerror (errno)));
+		return;
+	}
+
+	// Read in the lines
+	for (str line : *f)
+	{	if (line.length() == 0 || line[0] != '0')
+			continue; // empty or illogical
+
+		line.remove ('\r');
+		line.remove ('\n');
+
+		// Parse the line
+		LDConfigParser pars (line, ' ');
+
+		int code = 0, alpha = 255;
+		str name, facename, edgename, valuestr;
+
+		// Check 0 !COLOUR, parse the name
+		if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (name, 2))
+			continue;
+
+		// Replace underscores in the name with spaces for readability
+		name.replace ("_", " ");
+
+		// Get the CODE tag
+		if (!parseLDConfigTag (pars, "CODE", valuestr))
+			continue;
+
+		if (!numeric (valuestr))
+			continue; // not a number
+
+		// Ensure that the code is within [0 - 511]
+		bool ok;
+		code = valuestr.toShort (&ok);
+
+		if (!ok || code < 0 || code >= 512)
+			continue;
+
+		// VALUE and EDGE tags
+		if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename))
+			continue;
+
+		// Ensure that our colors are correct
+		QColor faceColor (facename),
+			edgeColor (edgename);
+
+		if (!faceColor.isValid() || !edgeColor.isValid())
+			continue;
+
+		// Parse alpha if given.
+		if (parseLDConfigTag (pars, "ALPHA", valuestr))
+			alpha = clamp (valuestr.toInt(), 0, 255);
+
+		LDColor* col = new LDColor;
+		col->name = name;
+		col->faceColor = faceColor;
+		col->edgeColor = edgeColor;
+		col->hexcode = facename;
+		col->faceColor.setAlpha (alpha);
+		col->index = code;
+		setColor (code, col);
+	}
+
+	delete f;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+LDConfigParser::LDConfigParser (str inText, char sep)
+{	m_tokens = inText.split (sep, QString::SkipEmptyParts);
+	m_pos = -1;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::isAtBeginning()
+{	return m_pos == -1;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::isAtEnd()
+{	return m_pos == m_tokens.size() - 1;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::getToken (str& val, const int pos)
+{	if (pos >= m_tokens.size())
+		return false;
+
+	val = m_tokens[pos];
+	return true;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::getNextToken (str& val)
+{	return getToken (val, ++m_pos);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::peekNextToken (str& val)
+{	return getToken (val, m_pos + 1);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::findToken (int& result, char const* needle, int args)
+{	for (int i = 0; i < (m_tokens.size() - args); ++i)
+	{	if (m_tokens[i] == needle)
+		{	result = i;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDConfigParser::rewind()
+{	m_pos = -1;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDConfigParser::seek (int amount, bool rel)
+{	m_pos = (rel ? m_pos : 0) + amount;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+int LDConfigParser::getSize()
+{	return m_tokens.size();
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool LDConfigParser::tokenCompare (int inPos, const char* sOther)
+{	str tok;
+
+	if (!getToken (tok, inPos))
+		return false;
+
+	return (tok == sOther);
+}

mercurial