[fondue-commits] [SCM] Fondue Font Editor branch, master, updated. b4b0fcfdc1ccc77c9ee183fbbb62c08262304f62

Eugeniy Meshcheryakov eugen at debian.org
Sat Aug 18 16:45:14 UTC 2007


The branch, master has been updated
       via  b4b0fcfdc1ccc77c9ee183fbbb62c08262304f62 (commit)
       via  8791b68b6b17c173d90b6a53e9b7ba740a52aa27 (commit)
       via  619d5173bd58c257a8f6322b1deedaa508774de1 (commit)
       via  5d6a33d68a2131ef62a3a64f11fc4186dc9d2e1a (commit)
       via  94fd78405f9616d630ff1d07515107ee11d1d7ac (commit)
      from  6a65065ee0b35eaa5fbef22b9b5691e18755f3c4 (commit)


- Log -----------------------------------------------------------------
commit b4b0fcfdc1ccc77c9ee183fbbb62c08262304f62
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sat Aug 18 18:45:03 2007 +0200

    add truetype instructions compiller

commit 8791b68b6b17c173d90b6a53e9b7ba740a52aa27
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sat Aug 18 18:42:38 2007 +0200

    include <QtEndian> instead of <QtCore>

commit 619d5173bd58c257a8f6322b1deedaa508774de1
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sat Aug 18 04:02:23 2007 +0200

    fix description for [N]ROUND instructions
    they accept two bits as color argument, not one

commit 5d6a33d68a2131ef62a3a64f11fc4186dc9d2e1a
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sat Aug 18 03:24:09 2007 +0200

    truncate file before saving

commit 94fd78405f9616d630ff1d07515107ee11d1d7ac
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sat Aug 18 02:53:42 2007 +0200

    add -Wwrite-strings option

-----------------------------------------------------------------------

Summary of changes:
 Makefile.am                                  |    2 +-
 data/instructions.xml                        |    6 +-
 gui/mainwindow.cxx                           |    2 +-
 gui/instnames.xsl => nongui/encodertable.xsl |   22 ++-
 nongui/nongui.rules                          |   16 +-
 nongui/ttfdecode.cxx                         |    2 +-
 nongui/ttfencode.cxx                         |  398 ++++++++++++++++++++++++++
 nongui/ttfencode.h                           |   69 +++++
 8 files changed, 501 insertions(+), 16 deletions(-)
 copy gui/instnames.xsl => nongui/encodertable.xsl (70%)
 create mode 100644 nongui/ttfencode.cxx
 create mode 100644 nongui/ttfencode.h

diff --git a/Makefile.am b/Makefile.am
index 2250fb9..6f3e84f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-AM_CXXFLAGS = -Wall -Wextra -pedantic -Wno-long-long
+AM_CXXFLAGS = -Wall -Wextra -pedantic -Wno-long-long -Wwrite-strings
 AM_LDFLAGS = -Wl,--as-needed
 SUFFIXES = .moc.cxx .tbl.cxx .xsl
 
diff --git a/data/instructions.xml b/data/instructions.xml
index 4bf8045..36a97d5 100644
--- a/data/instructions.xml
+++ b/data/instructions.xml
@@ -109,10 +109,8 @@
     <instruction name="NEG" value="101"/>
     <instruction name="FLOOR" value="102"/>
     <instruction name="CEILING" value="103"/>
-    <instruction name="ROUND" value="104" argbits="1" argtype="NROUND"/>
-    <hole size="2" offset="106"/>
-    <instruction name="NROUND" value="108" argbits="1" argtype="NROUND"/>
-    <hole size="2" offset="110"/>
+    <instruction name="ROUND" value="104" argbits="2" argtype="NROUND"/>
+    <instruction name="NROUND" value="108" argbits="2" argtype="NROUND"/>
     <instruction name="WCVTF" value="112"/>
     <instruction name="DELTAP2" value="113"/>
     <instruction name="DELTAP3" value="114"/>
diff --git a/gui/mainwindow.cxx b/gui/mainwindow.cxx
index 92b7998..65cf8b3 100644
--- a/gui/mainwindow.cxx
+++ b/gui/mainwindow.cxx
@@ -213,7 +213,7 @@ bool MainWindow::saveFile(const QString &fileName)
 	Q_ASSERT(m_doc);
 
 	QFile file(fileName);
-	if (!file.open(QIODevice::WriteOnly)) {
+	if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
 		QMessageBox::warning(this, "Fondue", QString("Cannot write file %1:\n%2")
 				.arg(fileName)
 				.arg(file.errorString()));
diff --git a/gui/instnames.xsl b/nongui/encodertable.xsl
similarity index 70%
copy from gui/instnames.xsl
copy to nongui/encodertable.xsl
index e4ed3cb..c0edb11 100644
--- a/gui/instnames.xsl
+++ b/nongui/encodertable.xsl
@@ -19,22 +19,34 @@
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
     <xsl:template match="/">
-	<xsl:text><![CDATA[#include "ttihighlighter.h"
+	<xsl:text><![CDATA[#include "ttfencode.h"
 
-const char * const TTIHighlighter::instructions[] = {
+const TTInstructionsEncoder::EncoderTableEntry TTInstructionsEncoder::encoderTable[] = {
 ]]></xsl:text>
 	<xsl:apply-templates select="//instruction"/>
-	<xsl:text><![CDATA[	0,
+	<xsl:text><![CDATA[	{0, 0, 0},
 };
 ]]></xsl:text>
     </xsl:template>
 
     <xsl:template match="//instruction">
-	<xsl:text>	"</xsl:text>
+	<xsl:text>	{"</xsl:text>
 	<xsl:value-of select="@name"/>
-	<xsl:text>",
+	<xsl:text>", </xsl:text>
+	<xsl:value-of select="@value"/>
+	<xsl:text>, &#x26;TTInstructionsEncoder::encode</xsl:text>
+	<xsl:choose>
+	    <xsl:when test="@argtype">
+		<xsl:value-of select="@argtype"/>
+	    </xsl:when>
+	    <xsl:otherwise>
+		<xsl:text>NoParams</xsl:text>
+	    </xsl:otherwise>
+	</xsl:choose>
+	<xsl:text>},
 </xsl:text>
     </xsl:template>
+
 </xsl:stylesheet>
 
 <!--
diff --git a/nongui/nongui.rules b/nongui/nongui.rules
index 0370eaf..d4a656b 100644
--- a/nongui/nongui.rules
+++ b/nongui/nongui.rules
@@ -4,16 +4,21 @@ libfonduenongui_a_SOURCES =		\
 	nongui/ttfdecode.cxx		\
 	nongui/fontdocumentreader.cxx	\
 	nongui/fontdocumentwriter.cxx	\
-	nongui/fontdocument.cxx
+	nongui/fontdocument.cxx		\
+	nongui/ttfencode.cxx
 
 nodist_libfonduenongui_a_SOURCES = 	\
 	nongui/decodertable.tbl.cxx	\
 	nongui/glyph.moc.cxx		\
-	nongui/fontdocument.moc.cxx
+	nongui/fontdocument.moc.cxx	\
+	nongui/encodertable.tbl.cxx
 
 nongui/decodertable.tbl.cxx: data/instructions.xml
 nongui/decodertable.tbl.cxx: DATAFILE=$(srcdir)/data/instructions.xml
 
+nongui/encodertable.tbl.cxx: data/instructions.xml
+nongui/encodertable.tbl.cxx: DATAFILE=$(srcdir)/data/instructions.xml
+
 libfonduenongui_a_CPPFLAGS = $(QtCore_CFLAGS) $(QtXml_CFLAGS)
 
 CLEANFILES += nongui/*.tbl.cxx nongui/*.moc.cxx
@@ -29,8 +34,11 @@ noinst_HEADERS +=			\
 	nongui/fontdocumentwriter.h	\
 	nongui/cvtentry.h		\
 	nongui/lookup.h			\
-	nongui/script.h
+	nongui/script.h			\
+	nongui/ttfencode.h
 
-EXTRA_DIST += nongui/decodertable.xsl
+EXTRA_DIST +=			\
+	nongui/decodertable.xsl	\
+	nongui/encodertable.xsl
 
 ## vim:ft=automake
diff --git a/nongui/ttfdecode.cxx b/nongui/ttfdecode.cxx
index 5ac8fef..24af011 100644
--- a/nongui/ttfdecode.cxx
+++ b/nongui/ttfdecode.cxx
@@ -16,7 +16,7 @@
  */
 #include <QByteArray>
 #include <QDataStream>
-#include <QtCore>
+#include <QtEndian>
 #include <QDebug>
 
 #include "ttfdecode.h"
diff --git a/nongui/ttfencode.cxx b/nongui/ttfencode.cxx
new file mode 100644
index 0000000..2f84abf
--- /dev/null
+++ b/nongui/ttfencode.cxx
@@ -0,0 +1,398 @@
+/* Copyright (C) 2007 Євгеній Мещеряков <eugen at debian.org>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include "ttfencode.h"
+#include <QIODevice>
+#include <QString>
+#include <QRegExp>
+#include <QDebug>
+#include <QtEndian>
+
+TTInstructionsEncoder::TTInstructionsEncoder(const QString &input) :
+	m_status(NoError), m_input(input), inputOffset(0)
+{
+
+}
+
+bool TTInstructionsEncoder::encode(QIODevice *output)
+{
+	Q_ASSERT(output);
+
+	m_output = output;
+	for (QString token = nextToken(); !token.isEmpty(); token = nextToken()) {
+		bool found = false;;
+		for (int i = 0; encoderTable[i].name; i++) {
+			if (!token.compare(encoderTable[i].name, Qt::CaseInsensitive)) {
+				found = true;
+				bool res = (this->*encoderTable[i].f)(encoderTable[i].base);
+				if (!res) {
+					m_status = SyntaxError;
+					return false;
+				}
+			}
+		}
+		if (!found) {
+			m_status = SyntaxError;
+			return false;
+		}
+	}
+	return true;
+}
+
+QString TTInstructionsEncoder::readToken()
+{
+	while (inputOffset < m_input.size()) {
+		/* find where next token may start */
+		int nextToken = m_input.indexOf(QRegExp("\\S"), inputOffset);
+		if (nextToken == -1)
+			return 0;
+
+		inputOffset = nextToken;
+		if (m_input[inputOffset] == QChar('#')) {
+			// comment, skip to the end of the line
+			int endOfLine = m_input.indexOf("\n", inputOffset);
+			if (endOfLine == -1)
+				return 0;
+			inputOffset = endOfLine + 1;
+		}
+		else {
+			/* some "word" or one of [], */
+			QRegExp rx("([^[\\],][^[\\],\\s]*|[[\\],])");
+			int pos = rx.indexIn(m_input, inputOffset);
+			if (pos == -1)
+				return 0;
+			QString token = rx.cap(1);
+			inputOffset = pos + token.size();
+			qDebug() << "Token:" << token;
+			return token;
+		}
+	}
+	return 0;
+}
+
+void TTInstructionsEncoder::putToken(const QString &token)
+{
+	Q_ASSERT(savedToken.isEmpty());
+
+	qDebug() << "Push:" << token;
+	savedToken = token;
+}
+
+QString TTInstructionsEncoder::nextToken()
+{
+	if (!savedToken.isEmpty()) {
+		QString ret = savedToken;
+		savedToken.clear();
+		qDebug() << "Saved token:" << ret;
+		return ret;
+	}
+	return readToken();
+}
+
+bool TTInstructionsEncoder::encodeNoParams(quint8 base)
+{
+	QString token = nextToken();
+	if (token == "[") {
+		token = nextToken();
+		if (token != "]") {
+			m_status = SyntaxError;
+			return false;
+		}
+	}
+	else
+		putToken(token);
+
+	return m_output->putChar(base);
+}
+
+// TODO add support for syntax like MD[1]
+bool TTInstructionsEncoder::encodeOneParam(quint8 base, const char *iftrue, const char *iffalse)
+{
+	QString token = nextToken();
+
+	if (token != "[") {
+		m_status = SyntaxError;
+		return false;
+	}
+	token = nextToken();
+	quint8 diff;
+	if (!token.compare(iftrue, Qt::CaseInsensitive))
+		diff = 1;
+	else if (!token.compare(iffalse, Qt::CaseInsensitive))
+		diff = 0;
+	else {
+		m_status = SyntaxError;
+		return false;
+	}
+	token = nextToken();
+	if (token != "]") {
+		m_status = SyntaxError;
+		return false;
+	}
+	return m_output->putChar(base + diff);
+}
+
+bool TTInstructionsEncoder::encodeIUP(quint8 base)
+{
+	return encodeOneParam(base, "x-axis", "y-axis");
+}
+
+bool TTInstructionsEncoder::encodeSDPVTL(quint8 base)
+{
+	return encodeOneParam(base, "orthog", "parallel");
+}
+
+bool TTInstructionsEncoder::encodeMDAP(quint8 base)
+{
+	return encodeOneParam(base, "rnd", "no-rnd");
+}
+
+bool TTInstructionsEncoder::encodeSHC(quint8 base)
+{
+	return encodeOneParam(base, "rp1", "rp2");
+}
+
+bool TTInstructionsEncoder::encodeMSIRP(quint8 base)
+{
+	return encodeOneParam(base, "rp0", "no-rp0");
+}
+
+template <typename T> 
+static inline T safeToBigEndian(T value) {
+	return qToBigEndian<T>(value);
+}
+
+template <>
+inline quint8 safeToBigEndian(quint8 value) {
+	return value;
+}
+
+template <typename T>
+bool TTInstructionsEncoder::encodeNPUSHX(quint8 base)
+{
+	QList<int> values;
+	QString token = nextToken();
+	if (token == "[") {
+		token = nextToken();
+		if (token == "]")
+			token = nextToken();
+		else {
+			m_status = SyntaxError;
+			return false;
+		}
+	}
+	
+	for (;;) {
+		bool ok;
+		int v = token.toInt(&ok, 0); // TODO support other formats
+		if (!ok) {
+			putToken(token);
+			break;
+		}
+		values << v; // TODO maybe check for accepted values
+		token = nextToken();
+	}
+
+	if (values.size() < 1) {
+		m_status = SyntaxError;
+		return false; // FIXME is this really needed?
+	}
+	if (values.size() > 0xff) {
+		m_status = SyntaxError;
+		return false; // TODO reason?
+	}
+
+	bool ret = m_output->putChar(base) && m_output->putChar((quint8)values.size());
+	if (ret) {
+		foreach (int i, values) {
+			T val = safeToBigEndian((T)i);
+			ret = (m_output->write((const char *)&val, sizeof(val)) == sizeof(val));
+			if (!ret) {
+				m_status = IOError;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
+bool TTInstructionsEncoder::encodeNPUSHB(quint8 base)
+{
+	return encodeNPUSHX<quint8>(base);
+}
+
+bool TTInstructionsEncoder::encodeNPUSHW(quint8 base)
+{
+	return encodeNPUSHX<quint16>(base);
+}
+
+bool TTInstructionsEncoder::encodeGC(quint8 base)
+{
+	return encodeOneParam(base, "orig", "cur");
+}
+
+bool TTInstructionsEncoder::encodeMD(quint8 base)
+{
+	return encodeOneParam(base, "grid", "orig");
+}
+
+static int stringToColor(const QString &s)
+{
+	if (!s.compare("grey", Qt::CaseInsensitive))
+		return 0;
+	if (!s.compare("white", Qt::CaseInsensitive))
+		return 1;
+	if (!s.compare("black", Qt::CaseInsensitive))
+		return 2;
+	return -1;
+}
+
+bool TTInstructionsEncoder::encodeNROUND(quint8 base)
+{
+	QString token = nextToken();
+	if (token != "[") {
+		m_status = SyntaxError;
+		return false;
+	}
+	token = nextToken();
+	int color = stringToColor(token);
+	if (color == -1) {
+		m_status = SyntaxError;
+		return false;
+	}
+	token = nextToken();
+	if (token != "]") {
+		m_status = SyntaxError;
+		return false;
+	}
+	return m_output->putChar(base + (quint8)color);
+}
+
+template <typename T>
+bool TTInstructionsEncoder::encodePUSHX(quint8 base)
+{
+	QList<int> values;
+	QString token = nextToken();
+	if (token == "[") {
+		token = nextToken();
+		if (token == "]")
+			token = nextToken();
+		else {
+			m_status = SyntaxError;
+			return false;
+		}
+	}
+	
+	for (;;) {
+		bool ok;
+		int v = token.toInt(&ok, 0); // TODO support other formats
+		if (!ok) {
+			putToken(token);
+			break;
+		}
+		values << v; // TODO maybe check for accepted values
+		token = nextToken();
+	}
+
+	if (values.size() < 1) {
+		m_status = SyntaxError;
+		return false;
+	}
+	if (values.size() > 0x08) {
+		m_status = SyntaxError;
+		return false;
+	}
+
+	bool ret = m_output->putChar(base + (quint8)values.size() - 1);
+	if (ret) {
+		foreach (int i, values) {
+			T val = safeToBigEndian((T)i);
+			ret = (m_output->write((const char *)&val, sizeof(val)) == sizeof(val));
+			if (!ret) {
+				m_status = IOError;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
+bool TTInstructionsEncoder::encodePUSHB(quint8 base)
+{
+	return encodePUSHX<quint8>(base);
+}
+
+bool TTInstructionsEncoder::encodePUSHW(quint8 base)
+{
+	return encodePUSHX<quint16>(base);
+}
+
+bool TTInstructionsEncoder::encodeMDRP(quint8 base)
+{
+	quint8 off = 0;
+
+	QString token = nextToken();
+	if (token != "[") {
+		m_status = SyntaxError;
+		return false;
+	}
+	token = nextToken();
+
+	if (!token.compare("rp0", Qt::CaseInsensitive)) {
+		off |= 0x10;
+		token = nextToken();
+		if (token != ",") {
+			m_status = SyntaxError;
+			return false;
+		}
+		token = nextToken();
+	}
+
+	if (!token.compare("min", Qt::CaseInsensitive)) {
+		off |= 0x08;
+		token = nextToken();
+		if (token != ",") {
+			m_status = SyntaxError;
+			return false;
+		}
+		token = nextToken();
+	}
+
+	if (!token.compare("rnd", Qt::CaseInsensitive)) {
+		off |= 0x04;
+		token = nextToken();
+		if (token != ",") {
+			m_status = SyntaxError;
+			return false;
+		}
+		token = nextToken();
+	}
+
+	int color = stringToColor(token);
+	if (color == -1) {
+		m_status = SyntaxError;
+		return false;
+	}
+	off |= color;
+
+	token = nextToken();
+	if (token != "]") {
+		m_status = SyntaxError;
+		return false;
+	}
+
+	return m_output->putChar(base + off);
+}
diff --git a/nongui/ttfencode.h b/nongui/ttfencode.h
new file mode 100644
index 0000000..a70d457
--- /dev/null
+++ b/nongui/ttfencode.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 2007 Євгеній Мещеряков <eugen at debian.org>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef TTFENCODE_H
+#define TTFENCODE_H
+#include <QString>
+
+class QIODevice;
+
+class TTInstructionsEncoder {
+public:
+	enum Status {NoError, SyntaxError, IOError};
+	TTInstructionsEncoder(const QString &input);
+	bool encode(QIODevice *output);
+	Status status() const {return m_status;}
+private:
+	Status m_status;
+	QString m_input;
+	QIODevice *m_output;
+	int inputOffset;
+	QString savedToken;
+
+	QString readToken();
+	QString nextToken();
+	void putToken(const QString &token);
+
+	typedef bool (EncoderFunc)(quint8 base);
+
+	EncoderFunc encodeNoParams;
+	EncoderFunc encodeIUP;
+	EncoderFunc encodeSDPVTL;
+	EncoderFunc encodeMDAP;
+	EncoderFunc encodeSHC;
+	EncoderFunc encodeMSIRP;
+	EncoderFunc encodeNPUSHB;
+	EncoderFunc encodeNPUSHW;
+	EncoderFunc encodeGC;
+	EncoderFunc encodeMD;
+	EncoderFunc encodeNROUND;
+	EncoderFunc encodePUSHB;
+	EncoderFunc encodePUSHW;
+	EncoderFunc encodeMDRP;
+
+	bool encodeOneParam(quint8 base, const char *iftrue, const char *iffalse);
+	template <typename T> bool encodeNPUSHX(quint8 base);
+	template <typename T> bool encodePUSHX(quint8 base);
+
+	struct EncoderTableEntry {
+		const char *name;
+		quint8 base;
+		EncoderFunc (TTInstructionsEncoder::*f);
+	};
+	static const EncoderTableEntry encoderTable[];
+};
+
+#endif

-- 
Fondue Font Editor



More information about the fondue-commits mailing list