[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>, &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