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

Eugeniy Meshcheryakov eugen at debian.org
Fri Dec 14 15:46:17 UTC 2007


The branch, master has been updated
       via  dc39790d9056b7c7647137566c4f3bfba317f2b1 (commit)
       via  3966e4b47a993daa5314e8c2c46f59f39e4ae9d0 (commit)
       via  73aa3b1e6f4efc82d47001b69f1591ab02eb9581 (commit)
       via  63aa77ca61e5ea16a061485094a27e146fded26f (commit)
       via  68d4043a9e098acf1025495be9ebb0f8dda36d16 (commit)
       via  e4dc0fb96ea0abefa6405cd1abfc8a367550180c (commit)
       via  2b9c14155045729dc4cc8d6fe0db0d1cbcd411bf (commit)
       via  04e13ea1919ad4aca8d79c075e6fa1e1b61526fd (commit)
       via  ee35c4b102772a9492d2f37493a5fd57b983932f (commit)
       via  f9e16d957e35071e9fd0e43717a5a12710a73b15 (commit)
       via  410feaaeae372aaf309feda371de523f36283200 (commit)
       via  a1cdf069b7f1da80154a298d1806db301355dfae (commit)
       via  94475a450663ee37f568f8d7fdf332b1c2276443 (commit)
       via  cf810c03b9435e55738547bca4722fbc5b3d38e4 (commit)
       via  1b5e33135dc626aa7780ae7eb228fb72aa3ba552 (commit)
       via  35d0002dc35f32b12905562a9fb44e1fa15d945d (commit)
       via  708913064cffe2b6f900d84123a1403a613d2e64 (commit)
       via  2c105c4aec27b8bff9382c96926876acdab37111 (commit)
       via  babfdeee7aa83e506dcf864c2ce473546265918f (commit)
       via  a1fe7b2266daf4ffa91992f59a22176b8fc444af (commit)
       via  8b85da97b016ee0865eec9d34e5488855f41a666 (commit)
       via  563eb52825b745787e2acaee2e68827d5635255b (commit)
       via  e3a03a68dd2d9b29ef41b57fd6695aabbe10333a (commit)
       via  f73a45e6612bfc9762bf2bc8575f7ba4ee958879 (commit)
       via  6139dfb9f9b9f877df6794243add5a0f7b8beb0a (commit)
       via  3f80bc320cf53aa01f908d7d2ae35f2ee1df260c (commit)
      from  586b64ac89e9a0dd619ef83c8955b3c6e81fa745 (commit)


- Shortlog ------------------------------------------------------------
dc39790 add RelaxNG schema
3966e4b add QtScript testing program (src/script)
73aa3b1 add QtScript support
63aa77c do not emit lookups, anchors, strings, kerning classes and substitutions - NIY
68d4043 cleanup #include's
e4dc0fb remove Lookup and Script classes (NIY)
2b9c141 make some more functions const
04e13ea rm FontDocument::changeUnicodeValue()
ee35c4b FontDocument::hasUnicodeGlyph() -> public slot
f9e16d9 remove FontDocument::changeInstructions()
410feaa allow invalid values FontDocument::addGlyph()'s argument (for QtScript)
a1cdf06 FontDocument::removeGlyphs() -> public slot
94475a4 make slots from FontDocument::getGlyph(), FontDocument::hasGlyph(), FontDocument::addGlyph()
cf810c0 use Glyph::setGlyphName() for renaming glyphs
1b5e331 add properties 'glyphs' and 'cvt'
35d0002 fix typo in property name s/setHorizAdvX/horizAdvX/
7089130 initialize horiz_adv_x
2c105c4 fix prototype for Glyph::outlineChanged() signal
babfdee reset changed attribute on glyphs after loading from file
a1fe7b2 set changed flag for class Glyph when needed
8b85da9 remove Glyph* argument from class Glyph signals
563eb52 unset attribute Qt::WA_QuitOnClose on GlyphEditWidget
e3a03a6 unset attribute Qt::WA_QuitOnClose on all dialogs, otherwise application will not exit (probably bug in Qt)
f73a45e remove documentClosed() signal
6139dfb add properties "changed" and "glyphName" to class Glyph
3f80bc3 declare properties of class Glyph

Summary of changes:
 Makefile.am                   |    5 +-
 configure.ac                  |    1 +
 gui/cvteditor.cxx             |    3 +
 gui/documentinfoeditor.cxx    |    3 +
 gui/glyphcell.cxx             |    1 +
 gui/glypheditwidget.cxx       |    4 +-
 gui/glyphgraphics.cxx         |   11 +-
 gui/glyphgraphics.h           |    2 +-
 gui/glyphpropertieseditor.cxx |    3 +
 gui/glyphsmodel.cxx           |   15 +--
 gui/mainwindow.cxx            |    8 +-
 gui/mainwindow.h              |    1 -
 gui/maxpeditor.cxx            |    3 +
 gui/ttieditor.cxx             |    3 +
 nongui/fontdocument.cxx       |   93 +++++++--------
 nongui/fontdocument.h         |   38 +++---
 nongui/fontdocumentreader.cxx |  124 +-------------------
 nongui/fontdocumentreader.h   |    5 -
 nongui/fontdocumentwriter.cxx |   37 +------
 nongui/fontdocumentwriter.h   |    1 -
 nongui/glyph.cxx              |  111 +++++++++++++++--
 nongui/glyph.h                |   30 ++++-
 nongui/lookup.h               |   43 -------
 nongui/nongui.rules           |    2 -
 nongui/script.h               |   34 ------
 nongui/ttfwriter.cxx          |    9 +-
 qscript/constructors.cxx      |   74 ++++++++++++
 qscript/constructors.h        |   24 ++++
 qscript/fontio.cxx            |  101 ++++++++++++++++
 qscript/fontio.h              |   28 +++++
 qscript/qscript.rules         |   20 +++
 qscript/scriptconsole.cxx     |  109 +++++++++++++++++
 qscript/scriptconsole.h       |   44 +++++++
 schema/fondue-font.rng        |  264 +++++++++++++++++++++++++++++++++++++++++
 scripts/conv.rb               |   15 ++-
 src/script.cxx                |   33 +++++
 src/src.rules                 |    6 +
 37 files changed, 947 insertions(+), 361 deletions(-)
-----------------------------------------------------------------------
Details of changes:

commit dc39790d9056b7c7647137566c4f3bfba317f2b1
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Dec 14 16:45:34 2007 +0100

    add RelaxNG schema

diff --git a/Makefile.am b/Makefile.am
index 4eee1b5..0e9d6b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ include ruby/ruby.rules
 include scripts/scripts.rules
 include qscript/qscript.rules
 
-EXTRA_DIST += data/instructions.xml
+EXTRA_DIST += data/instructions.xml schema/fondue-font.rng
 
 .h.moc.cxx:
 	$(MOC) $< -o $@
diff --git a/schema/fondue-font.rng b/schema/fondue-font.rng
new file mode 100644
index 0000000..4862525
--- /dev/null
+++ b/schema/fondue-font.rng
@@ -0,0 +1,264 @@
+<?xml version="1.0"?>
+
+<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0"
+    ns="http://people.debian.org/~eugen/fondue/2007"
+    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+    <rng:start>
+	<rng:ref name="font"/>
+    </rng:start>
+
+    <rng:define name="font">
+	<rng:element name="font">
+	    <rng:attribute name="version"/>
+	    <rng:optional>
+		<rng:attribute name="font-version"/>
+	    </rng:optional>
+	    <rng:interleave>
+		<rng:ref name="font-face"/>
+		<rng:optional>
+		    <rng:ref name="copyright"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="comment"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="prep"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="fpgm"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="cvt"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="maxp"/>
+		</rng:optional>
+		<rng:ref name="glyphs"/>
+	    </rng:interleave>
+	</rng:element>
+    </rng:define>
+
+    <!-- TODO split metrics and names -->
+    <rng:define name="font-face">
+	<rng:element name="font-face">
+	    <rng:optional>
+		<rng:attribute name="font-name"/>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="font-family"/>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="font-weight"/>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="italic-angle">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="underline-position">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="underline-thickness">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="ascent">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="descent">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="panose"/>
+	    </rng:optional>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="copyright">
+	<rng:element name="copyright">
+	    <rng:text/>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="prep">
+	<rng:element name="prep">
+	    <rng:ref name="tti"/>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="fpgm">
+	<rng:element name="fpgm">
+	    <rng:ref name="tti"/>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="cvt">
+	<rng:element name="cvt">
+	    <rng:zeroOrMore>
+		<rng:ref name="cv"/>
+	    </rng:zeroOrMore>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="maxp">
+	<rng:element name="maxp">
+	    <rng:optional>
+		<rng:attribute name="zones">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="twilight">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="storage">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="funcs">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="instrs">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="stack">
+		    <rng:data type="integer"/>
+		</rng:attribute>
+	    </rng:optional>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="glyphs">
+	<rng:element name="glyphs">
+	    <rng:zeroOrMore>
+		<rng:ref name="glyph"/>
+	    </rng:zeroOrMore>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="tti">
+	<rng:element name="tti">
+	    <rng:text/>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="cv">
+	<rng:element name="cv">
+	    <rng:attribute name="v"/>
+	    <rng:optional>
+		<rng:attribute name="name"/>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="comm"/>
+	    </rng:optional>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="glyph">
+	<rng:element name="glyph">
+	    <rng:attribute name="glyph-name"/>
+	    <rng:optional>
+		<rng:attribute name="horiz-adv-x">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="u"/>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="color"/>
+	    </rng:optional>
+	    <rng:interleave>
+		<rng:optional>
+		    <rng:ref name="tti"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="content"/>
+		</rng:optional>
+		<rng:optional>
+		    <rng:ref name="comment"/>
+		</rng:optional>
+	    </rng:interleave>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="content">
+	<rng:element name="content">
+	    <rng:oneOrMore>
+		<rng:choice>
+		    <rng:ref name="contour"/>
+		    <rng:ref name="ref"/>
+		</rng:choice>
+	    </rng:oneOrMore>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="contour">
+	<rng:element name="contour">
+	    <rng:optional>
+		<rng:attribute name="open">
+		    <rng:value type="integer">1</rng:value>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:oneOrMore>
+		<rng:ref name="pt"/>
+	    </rng:oneOrMore>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="ref">
+	<rng:element name="ref">
+	    <rng:attribute name="g"/>
+	    <rng:optional>
+		<rng:attribute name="x">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	    <rng:optional>
+		<rng:attribute name="y">
+		    <rng:data type="double"/>
+		</rng:attribute>
+	    </rng:optional>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="pt">
+	<rng:element name="pt">
+	    <rng:attribute name="x">
+		<rng:data type="double"/>
+	    </rng:attribute>
+	    <rng:attribute name="y">
+		<rng:data type="double"/>
+	    </rng:attribute>
+	    <rng:optional>
+		<rng:attribute name="on">
+		    <rng:value type="string">no</rng:value>
+		</rng:attribute>
+	    </rng:optional>
+	</rng:element>
+    </rng:define>
+
+    <rng:define name="comment">
+	<rng:element name="comment">
+	    <rng:text/>
+	</rng:element>
+    </rng:define>
+</rng:grammar>
+
+<!--
+vim:sw=4
+-->

commit 3966e4b47a993daa5314e8c2c46f59f39e4ae9d0
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Dec 14 16:41:10 2007 +0100

    add QtScript testing program (src/script)

diff --git a/gui/documentinfoeditor.h b/src/script.cxx
similarity index 73%
copy from gui/documentinfoeditor.h
copy to src/script.cxx
index a73f4c2..2ca51f0 100644
--- a/gui/documentinfoeditor.h
+++ b/src/script.cxx
@@ -14,17 +14,20 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
-#ifndef DOCUMENTINFOEDITOR_H
-#define DOCUMENTINFOEDITOR_H
-#include <QDialog>
+#include <QApplication>
+#include <QtScript>
+#include <QString>
+#include "scriptconsole.h"
 
-class QAbstractItemModel;
-
-class DocumentInfoEditor : public QDialog
+int main(int  argc, char **argv)
 {
-	Q_OBJECT
-public:
-	DocumentInfoEditor(QAbstractItemModel *model, QWidget *parent = 0);
-};
+	QApplication app(argc, argv);
+
+	ScriptConsole *con = new ScriptConsole;
+
+	con->setWindowTitle("Script Console");
+	con->resize(640, 480);
+	con->show();
 
-#endif
+	return app.exec();
+}
diff --git a/src/src.rules b/src/src.rules
index 37b4901..15d6564 100644
--- a/src/src.rules
+++ b/src/src.rules
@@ -12,4 +12,10 @@ src_fondue_SOURCES = src/main.cxx
 src_fondue_CPPFLAGS = $(QtCore_CFLAGS) $(QtGui_CFLAGS) $(QtXml_CFLAGS)
 src_fondue_LDADD = libfonduegui.a libfonduenongui.a $(QtCore_LIBS) $(QtGui_LIBS) $(QtXml_LIBS)
 
+bin_PROGRAMS += src/script
+
+src_script_SOURCES = src/script.cxx
+src_script_CPPFLAGS = $(QtCore_CFLAGS) $(QtXml_CFLAGS) $(QtGui_CFLAGS) $(QtScript_CFLAGS)
+src_script_LDADD = libfondueqscript.a libfonduenongui.a $(QtCore_LIBS) $(QtGui_LIBS) $(QtXml_LIBS) $(QtScript_LIBS)
+
 ## vim:ft=automake

commit 73aa3b1e6f4efc82d47001b69f1591ab02eb9581
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Dec 14 16:39:42 2007 +0100

    add QtScript support

diff --git a/Makefile.am b/Makefile.am
index f0191e4..4eee1b5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,6 +13,7 @@ include nongui/nongui.rules
 include gui/gui.rules
 include ruby/ruby.rules
 include scripts/scripts.rules
+include qscript/qscript.rules
 
 EXTRA_DIST += data/instructions.xml
 
@@ -25,4 +26,4 @@ EXTRA_DIST += data/instructions.xml
 .awk.awked.cxx:
 	$(AWK) -f $< $(DATAFILE) > $@
 
-INCLUDES = -I$(srcdir)/src -I$(srcdir)/ruby -I$(srcdir)/gui -I$(srcdir)/nongui
+INCLUDES = -I$(srcdir)/src -I$(srcdir)/ruby -I$(srcdir)/gui -I$(srcdir)/nongui -I$(srcdir)/qscript
diff --git a/configure.ac b/configure.ac
index 41aed3d..c2464b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,7 @@ AM_CONDITIONAL([RUBY_SUPPORT], [test x$enable_ruby = xtrue])
 PKG_CHECK_MODULES([QtCore], [QtCore >= 4.3])
 PKG_CHECK_MODULES([QtGui], [QtGui >= 4.3])
 PKG_CHECK_MODULES([QtXml], [QtXml >= 4.3])
+PKG_CHECK_MODULES([QtScript], [QtScript >= 4.3])
 
 AC_ARG_VAR([MOC], [Meta object compiler command])
 if test -z "$MOC"
diff --git a/qscript/constructors.cxx b/qscript/constructors.cxx
new file mode 100644
index 0000000..2aa19a2
--- /dev/null
+++ b/qscript/constructors.cxx
@@ -0,0 +1,74 @@
+/* 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 "constructors.h"
+#include "fontdocument.h"
+#include "glyph.h"
+#include <QtScript>
+#include "fontio.h"
+
+Q_SCRIPT_DECLARE_QMETAOBJECT(FontDocument, QObject*)
+Q_SCRIPT_DECLARE_QMETAOBJECT(Glyph, QString)
+
+Q_DECLARE_METATYPE(FontDocument *)
+
+static QScriptValue cvtEntryToScriptValue(QScriptEngine *engine, const CVTEntry &ent)
+{
+	QScriptValue obj = engine->newObject();
+	obj.setProperty("value", QScriptValue(engine, ent.value()));
+	obj.setProperty("variableName", QScriptValue(engine, ent.variableName()));
+	obj.setProperty("comment", QScriptValue(engine, ent.comment()));
+	return obj;
+}
+
+static void cvtEntryFromScriptValue(const QScriptValue &obj, CVTEntry &ent)
+{
+	ent.setValue(obj.property("value").toInt32());
+	ent.setVariableName(obj.property("variableName").toString());
+	ent.setComment(obj.property("comment").toString());
+}
+
+static QScriptValue glyphToScriptValue(QScriptEngine *engine, Glyph * const &glyph)
+{
+	QScriptValue obj = engine->newQObject(glyph, QScriptEngine::AutoOwnership);
+	return obj;
+}
+
+static void glyphFromScriptValue(const QScriptValue &obj, Glyph *&glyph)
+{
+	glyph = qobject_cast<Glyph *>(qscriptvalue_cast<QObject *>(obj));
+}
+
+void initScripting(QScriptEngine *engine)
+{
+	QScriptValue global = engine->globalObject();
+
+	qRegisterMetaType<FontDocument*>();
+	qRegisterMetaType<Glyph*>();
+
+	global.setProperty("FontDocument", engine->scriptValueFromQMetaObject<FontDocument>());
+	global.setProperty("Glyph", engine->scriptValueFromQMetaObject<Glyph>());
+	engine->setDefaultPrototype(qRegisterMetaType<Glyph*>(), engine->scriptValueFromQMetaObject<Glyph>());
+
+	global.setProperty("loadFont", engine->newFunction(loadFont, 1));
+	global.setProperty("saveFont", engine->newFunction(saveFont, 2));
+	global.setProperty("exportFontToTTF", engine->newFunction(exportFontToTTF, 2));
+
+	qScriptRegisterMetaType<Glyph *>(engine, glyphToScriptValue, glyphFromScriptValue);
+	qScriptRegisterSequenceMetaType<QList<Glyph *> >(engine);
+	qScriptRegisterMetaType<CVTEntry>(engine, cvtEntryToScriptValue, cvtEntryFromScriptValue);
+	qScriptRegisterSequenceMetaType<QVector<CVTEntry> >(engine);
+}
diff --git a/ruby/ruby_bindings.h b/qscript/constructors.h
similarity index 88%
copy from ruby/ruby_bindings.h
copy to qscript/constructors.h
index 3be9ec2..c17d992 100644
--- a/ruby/ruby_bindings.h
+++ b/qscript/constructors.h
@@ -14,9 +14,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
-#ifndef RUBY_BINDINGS_H
-#define RUBY_BINDINGS_H
+#ifndef CONSTRUCTORS_H
+#define CONSTRUCTORS_H
 
-void addRubyBindings();
+class QScriptEngine;
+
+void initScripting(QScriptEngine *engine);
 
 #endif
diff --git a/qscript/fontio.cxx b/qscript/fontio.cxx
new file mode 100644
index 0000000..3bde02c
--- /dev/null
+++ b/qscript/fontio.cxx
@@ -0,0 +1,101 @@
+/* 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 "fontio.h"
+#include "fontdocument.h"
+#include "fontdocumentreader.h"
+#include "fontdocumentwriter.h"
+#include "ttfwriter.h"
+
+Q_DECLARE_METATYPE(FontDocument*)
+
+QScriptValue loadFont(QScriptContext *context, QScriptEngine *engine)
+{
+	if (context->argumentCount() < 1)
+		return context->throwError("loadFont requires an argument");
+	QString fileName = context->argument(0).toString();
+	QFile file(fileName);
+	if (!file.open(QFile::ReadOnly))
+		return context->throwError(QString("Cannot read file %1: %2")
+				.arg(fileName)
+				.arg(file.errorString()));
+
+	FontDocument *doc = new FontDocument;
+	FontDocumentReader reader(doc);
+
+	reader.read(&file);
+
+	file.close();
+
+	if (reader.hasError()) {
+		delete doc;
+		return context->throwError(QString("Cannot read file %1: %2")
+				.arg(fileName)
+				.arg(reader.errorString()));
+	}
+
+	return engine->newQObject(doc, QScriptEngine::AutoOwnership);
+}
+
+QScriptValue saveFont(QScriptContext *context, QScriptEngine *engine)
+{
+	if (context->argumentCount() < 2)
+		return context->throwError("saveFont requires two arguments");
+	FontDocument *doc = qscriptvalue_cast<FontDocument *>(context->argument(0));
+	if (!doc)
+		return context->throwError("First argument should be a FontDocument");
+
+	QString fileName = context->argument(1).toString();
+
+	QFile file(fileName);
+	if (!file.open(QFile::WriteOnly | QFile::Truncate))
+		return context->throwError(QString("Cannot write file %1: %2")
+				.arg(fileName)
+				.arg(file.errorString()));
+
+	FontDocumentWriter writer(doc);
+
+	writer.write(&file);
+
+	file.close();
+
+	return engine->undefinedValue();
+}
+
+QScriptValue exportFontToTTF(QScriptContext *context, QScriptEngine *engine)
+{
+	if (context->argumentCount() < 2)
+		return context->throwError("exportFontToTTF requires two arguments");
+	FontDocument *doc = qscriptvalue_cast<FontDocument *>(context->argument(0));
+	if (!doc)
+		return context->throwError("First argument should be a Fontdocument");
+
+	QString fileName = context->argument(1).toString();
+
+	QFile file(fileName);
+
+	if (!file.open(QFile::WriteOnly | QFile::Truncate))
+		return context->throwError(QString("Cannot write file %1: %2")
+				.arg(fileName)
+				.arg(file.errorString()));
+
+	TTFWriter writer(doc);
+	if (!writer.write(&file))
+		return context->throwError(QString("Cannot export to TrueType."));
+	file.close();
+
+	return engine->undefinedValue();
+}
diff --git a/gui/colorcombobox.h b/qscript/fontio.h
similarity index 64%
copy from gui/colorcombobox.h
copy to qscript/fontio.h
index c1f3d66..62e2922 100644
--- a/gui/colorcombobox.h
+++ b/qscript/fontio.h
@@ -14,19 +14,15 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
-#ifndef COLORCOMBOBOX_H
-#define COLORCOMBOBOX_H
-#include <QComboBox>
+#ifndef FONTIO_H
+#define FONTIO_H
+#include <QtScript>
 
-class QColor;
-
-class ColorComboBox : public QComboBox {
-	Q_OBJECT
-	Q_PROPERTY(QColor color READ color WRITE setColor USER true)
-public:
-	ColorComboBox(QWidget *parent = 0);
-	QColor color() const;
-	void setColor(QColor c);
-};
+// loadFont(filename : String) : FontDocument
+QScriptValue loadFont(QScriptContext *context, QScriptEngine *engine);
+// saveFont(doc : FontDocument, filename : String) : Undefined
+QScriptValue saveFont(QScriptContext *context, QScriptEngine *engine);
+// exportFontToTTF(doc : FontDocument, filename : String) : Undefined
+QScriptValue exportFontToTTF(QScriptContext *context, QScriptEngine *engine);
 
 #endif
diff --git a/qscript/qscript.rules b/qscript/qscript.rules
new file mode 100644
index 0000000..7233002
--- /dev/null
+++ b/qscript/qscript.rules
@@ -0,0 +1,20 @@
+noinst_LIBRARIES += libfondueqscript.a
+
+libfondueqscript_a_SOURCES =		\
+	qscript/constructors.cxx	\
+	qscript/scriptconsole.cxx	\
+	qscript/fontio.cxx
+
+nodist_libfondueqscript_a_SOURCES =	\
+	qscript/scriptconsole.moc.cxx
+
+libfondueqscript_a_CPPFLAGS = $(QtCore_CFLAGS) $(QtGui_CFLAGS) $(QtXml_CFLAGS) $(QtScript_CFLAGS)
+
+CLEANFILES += qscript/*.moc.cxx
+
+noinst_HEADERS +=		\
+	qscript/constructors.h	\
+	qscript/scriptconsole.h	\
+	qscript/fontio.h
+
+## vim:ft=automake
diff --git a/qscript/scriptconsole.cxx b/qscript/scriptconsole.cxx
new file mode 100644
index 0000000..b712cfb
--- /dev/null
+++ b/qscript/scriptconsole.cxx
@@ -0,0 +1,109 @@
+/* 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 "scriptconsole.h"
+#include <QSplitter>
+#include <QTextEdit>
+#include <QVBoxLayout>
+#include <QKeyEvent>
+#include <QPushButton>
+#include <QHBoxLayout>
+#include <QScriptEngine>
+#include "constructors.h"
+#include "fontdocument.h"
+
+static QScriptValue printFunction(QScriptContext *context, QScriptEngine *engine);
+
+ScriptConsole::ScriptConsole(QWidget *parent) :
+	QWidget(parent)
+{
+	QVBoxLayout *vbox = new QVBoxLayout;
+
+	QSplitter *splitter = new QSplitter(Qt::Vertical);
+	m_displayArea = new QTextEdit;
+	m_displayArea->setReadOnly(true);
+	m_inputArea = new QTextEdit;
+	m_inputArea->setAcceptRichText(false);
+
+	splitter->addWidget(m_displayArea);
+	splitter->addWidget(m_inputArea);
+
+	vbox->addWidget(splitter);
+
+	QPushButton *execButton = new QPushButton("E&xecute");
+	QHBoxLayout *hbox = new QHBoxLayout;
+	hbox->addStretch();
+	hbox->addWidget(execButton);
+	vbox->addLayout(hbox);
+	setLayout(vbox);
+
+	connect(execButton, SIGNAL(clicked(bool)), this, SLOT(tryExecute()));
+
+	m_scriptEngine = new QScriptEngine(this);
+	m_scriptEngine->globalObject().setProperty("print",
+			m_scriptEngine->newFunction(printFunction));
+	initScripting(m_scriptEngine);
+
+	userTextFormat.setFontWeight(QFont::DemiBold);
+	errorTextFormat.setForeground(Qt::red);
+}
+
+void ScriptConsole::tryExecute()
+{
+	QString text = m_inputArea->toPlainText();
+
+	if (!text.isEmpty() && m_scriptEngine->canEvaluate(text)) {
+		QTextCursor cursor = m_displayArea->textCursor();
+		if (cursor.hasSelection()) {
+			cursor.clearSelection();
+			m_displayArea->setTextCursor(cursor);
+		}
+		m_displayArea->setCurrentCharFormat(userTextFormat);
+		m_displayArea->append(text);
+		m_displayArea->setCurrentCharFormat(outputTextFormat);
+		m_inputArea->clear();
+		QScriptValue result = m_scriptEngine->evaluate(text);
+
+		if (m_scriptEngine->hasUncaughtException()) {
+			m_displayArea->setCurrentCharFormat(errorTextFormat);
+			m_displayArea->append(result.toString());
+			m_displayArea->setCurrentCharFormat(outputTextFormat);
+		}
+	}
+}
+
+void ScriptConsole::printOutputText(const QString &s)
+{
+	m_displayArea->append(s);
+}
+
+static QScriptValue printFunction(QScriptContext *context, QScriptEngine *engine)
+{
+	QString printString;
+
+	for (int i = 0; i < context->argumentCount(); i++) {
+		printString.append(context->argument(i).toString());
+		if (i < context->argumentCount() - 1)
+			printString.append(" ");
+	}
+	qDebug(qPrintable(printString));
+
+	ScriptConsole *console = qobject_cast<ScriptConsole *>(engine->parent());
+	if (console)
+		console->printOutputText(printString);
+
+	return engine->undefinedValue();
+}
diff --git a/gui/ttieditor.h b/qscript/scriptconsole.h
similarity index 65%
copy from gui/ttieditor.h
copy to qscript/scriptconsole.h
index e465d58..069daf2 100644
--- a/gui/ttieditor.h
+++ b/qscript/scriptconsole.h
@@ -14,31 +14,31 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
-#ifndef TTIEDITOR_H
-#define TTIEDITOR_H
-#include <QDialog>
+#ifndef SCRIPTCONSOLE_H
+#define SCRIPTCONSOLE_H
+#include <QWidget>
+#include <QTextCharFormat>
+#include "fontdocument.h"
 
-class QAbstractItemModel;
-class QModelIndex;
-class QAbstractButton;
-class QDataWidgetMapper;
-class QDialogButtonBox;
 class QTextEdit;
+class QScriptEngine;
 
-class TTIEditor : public QDialog
-{
+class ScriptConsole : public QWidget {
 	Q_OBJECT
 public:
-	TTIEditor(QAbstractItemModel *model, const QModelIndex &item, QWidget *parent = 0);
-
+	ScriptConsole(QWidget *parent = 0);
+	void printOutputText(const QString &s);
 public slots:
-	void accept();
-	void buttonClicked(QAbstractButton *button);
-	void checkInstructions();
+	void tryExecute();
 private:
-	QDataWidgetMapper *mapper;
-	QDialogButtonBox *buttons;
-	QTextEdit *textEditor;
+	QTextEdit *m_displayArea;
+	QTextEdit *m_inputArea;
+
+	QScriptEngine *m_scriptEngine;
+
+	QTextCharFormat userTextFormat;
+	QTextCharFormat errorTextFormat;
+	QTextCharFormat outputTextFormat;
 };
 
 #endif

commit 63aa77ca61e5ea16a061485094a27e146fded26f
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Dec 14 16:32:21 2007 +0100

    do not emit lookups, anchors, strings, kerning classes and substitutions - NIY

diff --git a/scripts/conv.rb b/scripts/conv.rb
index b336e93..01c0eea 100755
--- a/scripts/conv.rb
+++ b/scripts/conv.rb
@@ -86,11 +86,13 @@ def read_file(f, doc)
 	end
       elsif tag == 'Lookup'
 	if (!lookupstbl)
-	  doc.root << lookupstbl = XML::Node.new("lookups")
+	  #XXX doc.root << lookupstbl = XML::Node.new("lookups")
+	  lookupstbl = XML::Node.new("lookups")
 	end
 	lookupstbl << decode_lookup(value)
       elsif tag == 'AnchorClass2'
-	doc.root << anchors = XML::Node.new("anchors")
+	# XXX doc.root << anchors = XML::Node.new("anchors")
+	anchors = XML::Node.new("anchors")
 	value.scan(/"([^"]*)"\s*"([^"]*)"/) do |mark|
 	  anchors << anchor = XML::Node.new("anchor")
 	  anchor["name"] = decode_ff_utf7(mark[0])
@@ -98,7 +100,8 @@ def read_file(f, doc)
 	end
       elsif tag == 'LangName'
 	_, langnum, content = value.match(/^\s*([\w]+)\s*(.*)$/).to_a
-	doc.root << ttfstrings = XML::Node.new("strings")
+	# XXX doc.root << ttfstrings = XML::Node.new("strings")
+	ttfstrings = XML::Node.new("strings")
 	ttfstrings["langid"] = langnum # FIXME use ISO names here
 	strid = 0
 	content.scan(/"([^"]*)"/) do |s|
@@ -112,9 +115,11 @@ def read_file(f, doc)
 	# skip them
 	(value.to_i - 1).times do f.readline end
       elsif tag == 'KernClass2'
-	doc.root << decode_kernclass(value, f);
+	# XXX doc.root << decode_kernclass(value, f);
+	decode_kernclass(value, f);
       elsif tag == 'ChainSub2'
-	doc.root << decode_chainsub(value, f)
+	decode_chainsub(value, f)
+	# XXX doc.root << decode_chainsub(value, f)
       end
     end
   end

commit 68d4043a9e098acf1025495be9ebb0f8dda36d16
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Dec 14 16:31:01 2007 +0100

    cleanup #include's

diff --git a/gui/glyphcell.cxx b/gui/glyphcell.cxx
index f573f7a..c9edf11 100644
--- a/gui/glyphcell.cxx
+++ b/gui/glyphcell.cxx
@@ -26,6 +26,7 @@
 #include "glyph.h"
 #include <QIcon>
 #include "glyphsmodel.h"
+#include "fontdocument.h"
 
 GlyphCell::GlyphCell(GlyphsModel *model, const QModelIndex &index) : QGraphicsView(), m_model(model)
 {
diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index b742922..904e3bb 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -17,6 +17,7 @@
 #include "glyph.h"
 #include "contour.h"
 #include "glyphref.h"
+#include "fontdocument.h"
 
 /** Construct an empty glyph with given name.
  * @param name a name for the new glyph.
diff --git a/nongui/glyph.h b/nongui/glyph.h
index e7487c6..566d72b 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -19,7 +19,6 @@
 #include <QString>
 #include <QList>
 #include <QVariant>
-#include "fontdocument.h"
 
 class FontDocument;
 

commit e4dc0fb96ea0abefa6405cd1abfc8a367550180c
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Wed Nov 28 21:39:57 2007 +0100

    remove Lookup and Script classes (NIY)

diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index c4359d4..1bcfa88 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -19,7 +19,6 @@
 #include <QString>
 #include "cvtentry.h"
 #include "glyph.h"
-#include "lookup.h"
 #include <QHash>
 #include <QVector>
 
@@ -97,8 +96,6 @@ public:
 	void setChanged(bool changed = true);
 	bool changed() const;
 
-	QList<Lookup> lookups;
-
 	bool changeCvtEntry(int index, const CVTEntry &newEntry);
 	void removeCvtEntries(int first, int count);
 	void insertCvtEntries(int first, int count);
diff --git a/nongui/fontdocumentreader.cxx b/nongui/fontdocumentreader.cxx
index 258f4f5..acb4a27 100644
--- a/nongui/fontdocumentreader.cxx
+++ b/nongui/fontdocumentreader.cxx
@@ -20,7 +20,6 @@
 #include "glyphref.h"
 #include "contour.h"
 #include "fontdocument.h"
-#include "lookup.h"
 
 bool FontDocumentReader::read(QIODevice *device)
 {
@@ -117,8 +116,6 @@ void FontDocumentReader::readFont()
 			}
 			else if (name() == "copyright")
 				doc->setCopyright(readElementText());
-			else if (name() == "lookups")
-				readLookups();
 			else if (name() == "fpgm")
 				readFpgm();
 			else if (name() == "prep")
@@ -326,122 +323,6 @@ void FontDocumentReader::readContour(Glyph *glyph)
 	glyph->content << qVariantFromValue(contour);
 }
 
-void FontDocumentReader::readLookups()
-{
-	Q_ASSERT(isStartElement() && name() == "lookups");
-
-	while (!atEnd()) {
-		readNext();
-
-		if (isEndElement())
-			break;
-
-		if (isStartElement()) {
-			if (name() == "lookup")
-				readLookup();
-			else
-				readUnknownElement();
-		}
-	}
-}
-
-void FontDocumentReader::readLookup()
-{
-	Q_ASSERT(isStartElement() && name() == "lookup");
-
-	QStringRef lookupName = attributes().value("name");
-	if (lookupName.isEmpty()) {
-		raiseError("lookup: attribute name is null or empty");
-		return;
-	}
-	Lookup lookup(lookupName.toString());
-
-	while (!atEnd()) {
-		readNext();
-
-		if (isEndElement())
-			break;
-
-		if (isStartElement()) {
-			if (name() == "subtable") {
-				QStringRef subtableName = attributes().value("name");
-				if (subtableName.isEmpty()) {
-					raiseError("subtable: attribute name is null or empty");
-					return;
-				}
-				lookup.addSubtable(subtableName.toString()); 
-				readUnknownElement();
-			}
-			else if (name() == "feature")
-				readFeature(lookup);
-			else
-				readUnknownElement();
-		}
-	}
-	doc->lookups << lookup;
-}
-
-void FontDocumentReader::readFeature(Lookup &lookup)
-{
-	Q_ASSERT(isStartElement() && name() == "feature");
-
-	QStringRef featureType = attributes().value("type");
-	if (featureType.isEmpty()) {
-		raiseError("feature: attribute type is null or empty");
-		return;
-	}
-	lookup.setFeature(featureType.toString());
-
-	while (!atEnd()) {
-		readNext();
-
-		if (isEndElement())
-			break;
-
-		if (isStartElement()) {
-			if (name() == "script")
-				readScript(lookup);
-			else
-				readUnknownElement();
-		}
-	}
-}
-
-void FontDocumentReader::readScript(Lookup &lookup)
-{
-	Q_ASSERT(isStartElement() && name() == "script");
-
-	QStringRef scriptName = attributes().value("name");
-	if (scriptName.isEmpty()) {
-		raiseError("script: attribute name is null or empty");
-		return;
-	}
-
-	Script script(scriptName.toString());
-
-	while (!atEnd()) {
-		readNext();
-
-		if (isEndElement())
-			break;
-
-		if (isStartElement()) {
-			if (name() == "language") {
-				QStringRef languageName = attributes().value("name");
-				if (languageName.isEmpty()) {
-					raiseError("language: attribute name is null or empty");
-					return;
-				}
-				script.addLanguage(languageName.toString());
-				readUnknownElement();
-			}
-			else
-				readUnknownElement();
-		}
-	}
-	lookup.addScript(script);
-}
-
 void FontDocumentReader::readCvt()
 {
 	Q_ASSERT(isStartElement() && name() == "cvt");
diff --git a/nongui/fontdocumentreader.h b/nongui/fontdocumentreader.h
index 138b715..4a7dbe7 100644
--- a/nongui/fontdocumentreader.h
+++ b/nongui/fontdocumentreader.h
@@ -21,7 +21,6 @@
 
 class FontDocument;
 class Glyph;
-class Lookup;
 
 /** A class for reading a font document.
  * @sa FontDocument
@@ -49,10 +48,6 @@ private:
 	void readGlyph();
 	void readContent(Glyph *glyph);
 	void readContour(Glyph *glyph);
-	void readLookups();
-	void readLookup();
-	void readFeature(Lookup &lookup);
-	void readScript(Lookup &lookup);
 	void readCvt();
 	void readMaxp();
 
diff --git a/nongui/fontdocumentwriter.cxx b/nongui/fontdocumentwriter.cxx
index 7d4716f..5a3fd1b 100644
--- a/nongui/fontdocumentwriter.cxx
+++ b/nongui/fontdocumentwriter.cxx
@@ -19,7 +19,6 @@
 #include "glyph.h"
 #include "contour.h"
 #include "glyphref.h"
-#include "lookup.h"
 
 FontDocumentWriter::FontDocumentWriter(const FontDocument *doc)
 {
@@ -36,7 +35,6 @@ bool FontDocumentWriter::write(QIODevice *device)
 	writeDefaultNamespace("http://people.debian.org/~eugen/fondue/2007");
 
 	writeHeaderData();
-	writeLookups();
 	writeInstructionTables();
 	writeGlyphs();
 
@@ -171,36 +169,3 @@ bool FontDocumentWriter::writeGlyphContent(const QList<QVariant> &content)
 
 	return true;
 }
-
-bool FontDocumentWriter::writeLookups()
-{
-	if (!doc->lookups.isEmpty()) {
-		writeStartElement("lookups");
-		foreach (const Lookup &lookup, doc->lookups) {
-			writeStartElement("lookup");
-			writeAttribute("name", lookup.name());
-			foreach (const QString &subtable, lookup.subtables()) {
-				writeEmptyElement("subtable");
-				writeAttribute("name", subtable);
-			}
-			if (!lookup.feature().isEmpty()) {
-				writeStartElement("feature");
-				writeAttribute("type", lookup.feature());
-				foreach (const Script &script, lookup.scripts()) {
-					writeStartElement("script");
-					writeAttribute("name", script.name());
-					foreach (const QString &language, script.languages()) {
-						writeEmptyElement("language");
-						writeAttribute("name", language);
-					}
-					writeEndElement(); // script
-				}
-				writeEndElement(); // feature
-			}
-			writeEndElement(); // lookup
-		}
-		writeEndElement(); // lookups
-	}
-
-	return true;
-}
diff --git a/nongui/fontdocumentwriter.h b/nongui/fontdocumentwriter.h
index 52860ed..94330db 100644
--- a/nongui/fontdocumentwriter.h
+++ b/nongui/fontdocumentwriter.h
@@ -44,7 +44,6 @@ private:
 	bool writeInstructionTables();
 	bool writeGlyphs();
 	bool writeGlyphContent(const QList<QVariant> &content);
-	bool writeLookups();
 };
 
 #endif
diff --git a/nongui/lookup.h b/nongui/lookup.h
deleted file mode 100644
index c2e92f2..0000000
--- a/nongui/lookup.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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 LOOKUP_H
-#define LOOKUP_H
-
-#include <QString>
-#include <QStringList>
-#include <QList>
-#include "script.h"
-
-class Lookup {
-public:
-	Lookup(const QString &name) {m_name = name;}
-	void setName(const QString &name) {m_name = name;}
-	QString name() const {return m_name;}
-	void addSubtable(const QString &name) {m_subtables << name;}
-	const QStringList &subtables() const {return m_subtables;}
-	void setFeature(const QString &feature) {m_feature = feature;}
-	QString feature() const {return m_feature;}
-	void addScript(const Script &script) {m_scripts << script;}
-	const QList<Script> &scripts() const {return m_scripts;}
-private:
-	QString m_name;
-	QStringList m_subtables;
-	QString m_feature; // FIXME is it correct to split scriptlist from feature?
-	QList<Script> m_scripts;
-};
-
-#endif
diff --git a/nongui/nongui.rules b/nongui/nongui.rules
index 4cd09d6..0da5196 100644
--- a/nongui/nongui.rules
+++ b/nongui/nongui.rules
@@ -45,8 +45,6 @@ noinst_HEADERS +=			\
 	nongui/fontdocumentreader.h	\
 	nongui/fontdocumentwriter.h	\
 	nongui/cvtentry.h		\
-	nongui/lookup.h			\
-	nongui/script.h			\
 	nongui/ttfencode.h		\
 	nongui/cvtmodel.h		\
 	nongui/ttfwriter.h		\
diff --git a/nongui/script.h b/nongui/script.h
deleted file mode 100644
index 3841095..0000000
--- a/nongui/script.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* 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 SCRIPT_H
-#define SCRIPT_H
-#include <QString>
-#include <QStringList>
-
-class Script {
-public:
-	Script(const QString &name) : m_name(name) {}
-	void setName(const QString &name) {m_name = name;}
-	QString name() const {return m_name;}
-	void addLanguage(const QString &language) {m_languages << language;}
-	const QStringList &languages() const {return m_languages;}
-private:
-	QString m_name;
-	QStringList m_languages;
-};
-
-#endif
diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 3ff230d..a1f3775 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -23,6 +23,7 @@
 #include <QBuffer>
 #include "ttfencode.h"
 #include "contour.h"
+#include <QStringList>
 
 static inline quint32 makeTag(unsigned char a, unsigned char b,
 		unsigned char c, unsigned char d)

commit 2b9c14155045729dc4cc8d6fe0db0d1cbcd411bf
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Wed Nov 28 21:32:44 2007 +0100

    make some more functions const

diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index cb26a3c..5c7a3c5 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -175,7 +175,7 @@ bool FontDocument::addGlyph(Glyph *glyph)
 /** Check whether glyph with given name present in the document.
  * @return true if document contains glyph with the given name, false otherwise.
  */
-bool FontDocument::hasGlyph(const QString &name)
+bool FontDocument::hasGlyph(const QString &name) const
 {
 	return nameHash.contains(name);
 }
@@ -184,7 +184,7 @@ bool FontDocument::hasGlyph(const QString &name)
  * @return pointer to the named glyph or 0 if document contains no glyph with such name.
  * @see hasGlyph()
  */
-Glyph *FontDocument::getGlyph(const QString &name)
+Glyph *FontDocument::getGlyph(const QString &name) const
 {
 	// XXX is this hash needed?
 	if (hasGlyph(name))
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 8a182f2..c4359d4 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -123,8 +123,8 @@ public:
 	bool setMaxStackDepth(unsigned depth);
 public slots:
 	bool addGlyph(Glyph *glyph);
-	bool hasGlyph(const QString &name);
-	Glyph *getGlyph(const QString &name);
+	bool hasGlyph(const QString &name) const;
+	Glyph *getGlyph(const QString &name) const;
 
 	void removeGlyphs(int first, int count);
 

commit 04e13ea1919ad4aca8d79c075e6fa1e1b61526fd
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 21:50:53 2007 +0100

    rm FontDocument::changeUnicodeValue()

diff --git a/gui/glyphsmodel.cxx b/gui/glyphsmodel.cxx
index 23661c9..88e266c 100644
--- a/gui/glyphsmodel.cxx
+++ b/gui/glyphsmodel.cxx
@@ -143,7 +143,7 @@ bool GlyphsModel::setData(const QModelIndex &index, const QVariant &value, int r
 			break;
 		case UnicodeColumn:
 			qDebug() << value;
-			ret = doc->changeUnicodeValue(glyph, value.toInt());
+			ret = glyph->setUnicode(value.toInt());
 			qDebug() << ret;
 			if (ret)
 				emitChangeSignals(index);
diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 2ffb716..cb26a3c 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -166,6 +166,8 @@ bool FontDocument::addGlyph(Glyph *glyph)
 	connect(glyph, SIGNAL(outlineChanged()), this, SLOT(glyphOutlineChanged()));
 	connect(glyph, SIGNAL(glyphNameChanged(const QString&, const QString&)),
 			this, SLOT(glyphRenamed(const QString&, const QString&)));
+	connect(glyph, SIGNAL(unicodeChanged(int, int)),
+			this, SLOT(unicodeValueChanged(int, int)));
 
 	return true;
 }
@@ -323,24 +325,21 @@ bool FontDocument::hasUnicodeGlyph(int unicode) const
 	return unicodeHash.contains(unicode);
 }
 
-bool FontDocument::changeUnicodeValue(Glyph *glyph, int unicode)
+void FontDocument::unicodeValueChanged(int oldUnicode, int newUnicode)
 {
-	Q_ASSERT(glyph);
+	Q_ASSERT(hasUnicodeGlyph(oldUnicode));
+	Q_ASSERT(!hasUnicodeGlyph(newUnicode));
+	Q_ASSERT(qobject_cast<Glyph *>(sender()));
 
-	unicode = (unicode < 0) ? -1 : unicode;
-	int oldValue = glyph->unicode();
+	newUnicode = (newUnicode < 0) ? -1 : newUnicode;
 
-	if (oldValue == unicode)
-		return true;
-	if (hasUnicodeGlyph(unicode))
-		return false;
-	if (oldValue != -1)
-		unicodeHash.remove(oldValue);
-	glyph->setUnicode(unicode);
-	if (unicode != -1)
-		unicodeHash[unicode] = glyph;
+	if (oldUnicode == newUnicode)
+		return;
+	if (oldUnicode != -1)
+		unicodeHash.remove(oldUnicode);
+	if (newUnicode != -1)
+		unicodeHash[newUnicode] = qobject_cast<Glyph *>(sender());
 	setChanged();
-	return true;
 }
 
 void FontDocument::removeGlyphs(int first, int count)
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 0f1c74e..8a182f2 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -99,8 +99,6 @@ public:
 
 	QList<Lookup> lookups;
 
-	bool changeUnicodeValue(Glyph *glyph, int unicode);
-
 	bool changeCvtEntry(int index, const CVTEntry &newEntry);
 	void removeCvtEntries(int first, int count);
 	void insertCvtEntries(int first, int count);
@@ -134,6 +132,7 @@ public slots:
 protected slots:
 	void glyphOutlineChanged();
 	void glyphRenamed(const QString &oldName, const QString &newName);
+	void unicodeValueChanged(int oldUnicode, int newUnicode);
 signals:
 	void copyrightChanged();
 	void prepChanged();
diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index fb01482..b742922 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -210,10 +210,19 @@ QString Glyph::comment() const
 	return m_comment;
 }
 
-void Glyph::setUnicode(int u)
+bool Glyph::setUnicode(int u)
 {
-	if (setIfChanged(m_unicode, u))
-		setChanged();
+	if (m_unicode != u) {
+		if (!parent() || !document()->hasUnicodeGlyph(u)) {
+			int old_value = m_unicode;
+			if (setIfChanged(m_unicode, u)) {
+				emit unicodeChanged(old_value, u);
+				setChanged();
+				return true;
+			}
+		}
+	}
+	return false;
 }
 
 int Glyph::unicode() const
diff --git a/nongui/glyph.h b/nongui/glyph.h
index c525c76..e7487c6 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -67,7 +67,7 @@ public:
 	void setComment(const QString &s);
 	QString comment() const;
 
-	void setUnicode(int u);
+	bool setUnicode(int u);
 	int unicode() const;
 
 	void setChanged(bool c = true);
@@ -80,6 +80,7 @@ public:
 signals:
 	void glyphChanged();
 	void glyphNameChanged(const QString &oldName, const QString &newName);
+	void unicodeChanged(int oldUnicode, int newUnicode);
 
 	void pointMoved(int component, int pointNo, const QPointF &newPos);
 	void outlineChanged();

commit ee35c4b102772a9492d2f37493a5fd57b983932f
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 21:36:42 2007 +0100

    FontDocument::hasUnicodeGlyph() -> public slot

diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index c9c2d20..0f1c74e 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -99,7 +99,6 @@ public:
 
 	QList<Lookup> lookups;
 
-	bool hasUnicodeGlyph(int unicode) const;
 	bool changeUnicodeValue(Glyph *glyph, int unicode);
 
 	bool changeCvtEntry(int index, const CVTEntry &newEntry);
@@ -130,6 +129,8 @@ public slots:
 	Glyph *getGlyph(const QString &name);
 
 	void removeGlyphs(int first, int count);
+
+	bool hasUnicodeGlyph(int unicode) const;
 protected slots:
 	void glyphOutlineChanged();
 	void glyphRenamed(const QString &oldName, const QString &newName);

commit f9e16d957e35071e9fd0e43717a5a12710a73b15
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 21:33:53 2007 +0100

    remove FontDocument::changeInstructions()

diff --git a/gui/glyphsmodel.cxx b/gui/glyphsmodel.cxx
index 186ada9..23661c9 100644
--- a/gui/glyphsmodel.cxx
+++ b/gui/glyphsmodel.cxx
@@ -165,9 +165,8 @@ bool GlyphsModel::setData(const QModelIndex &index, const QVariant &value, int r
 			ret = true;
 			break;
 		case InstructionsColumn:
-			ret = doc->changeInstructions(glyph, value.toString());
-			if (ret)
-				emit dataChanged(index, index);
+			glyph->setInstructions(value.toString());
+			emit dataChanged(index, index);
 			break;
 		default:
 			break;
diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 45ae416..2ffb716 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -359,20 +359,6 @@ void FontDocument::removeGlyphs(int first, int count)
 		setChanged();
 }
 
-bool FontDocument::changeInstructions(Glyph *glyph, const QString &newInstructions)
-{
-	Q_ASSERT(glyph);
-
-	QString oldInstructions = glyph->instructions();
-	if (oldInstructions == newInstructions)
-		return true;
-	if (oldInstructions.isEmpty() && newInstructions.isEmpty())
-		return true;
-	glyph->setInstructions(newInstructions); // TODO validity
-	setChanged();
-	return true;
-}
-
 bool FontDocument::changeCvtEntry(int index, const CVTEntry &newEntry)
 {
 	if (newEntry == m_cvt.at(index))
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index db22248..c9c2d20 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -102,7 +102,6 @@ public:
 	bool hasUnicodeGlyph(int unicode) const;
 	bool changeUnicodeValue(Glyph *glyph, int unicode);
 
-	bool changeInstructions(Glyph *glyph, const QString &newInstructions);
 	bool changeCvtEntry(int index, const CVTEntry &newEntry);
 	void removeCvtEntries(int first, int count);
 	void insertCvtEntries(int first, int count);

commit 410feaaeae372aaf309feda371de523f36283200
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 21:30:02 2007 +0100

    allow invalid values FontDocument::addGlyph()'s argument (for QtScript)

diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index d8ff368..45ae416 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -137,8 +137,15 @@ QList<Glyph *> FontDocument::glyphs() const
  */
 bool FontDocument::addGlyph(Glyph *glyph)
 {
-	Q_ASSERT(glyph);
-	Q_ASSERT(!glyph->parent());
+	if (!glyph) {
+		qWarning("null value passed to FontDocument::addGlyph");
+		return false;
+	}
+
+	if (glyph->parent()) {
+		qWarning("glyph allready has a parent");
+		return false;
+	}
 
 	QString name = glyph->glyphName();
 	int unicode = glyph->unicode();

commit a1cdf069b7f1da80154a298d1806db301355dfae
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 20:52:45 2007 +0100

    FontDocument::removeGlyphs() -> public slot

diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index cd62a84..db22248 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -102,8 +102,6 @@ public:
 	bool hasUnicodeGlyph(int unicode) const;
 	bool changeUnicodeValue(Glyph *glyph, int unicode);
 
-	void removeGlyphs(int first, int count);
-
 	bool changeInstructions(Glyph *glyph, const QString &newInstructions);
 	bool changeCvtEntry(int index, const CVTEntry &newEntry);
 	void removeCvtEntries(int first, int count);
@@ -131,6 +129,8 @@ public slots:
 	bool addGlyph(Glyph *glyph);
 	bool hasGlyph(const QString &name);
 	Glyph *getGlyph(const QString &name);
+
+	void removeGlyphs(int first, int count);
 protected slots:
 	void glyphOutlineChanged();
 	void glyphRenamed(const QString &oldName, const QString &newName);

commit 94475a450663ee37f568f8d7fdf332b1c2276443
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 20:48:31 2007 +0100

    make slots from FontDocument::getGlyph(), FontDocument::hasGlyph(), FontDocument::addGlyph()

diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 323b330..cd62a84 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -70,10 +70,6 @@ public:
 
 	QList<Glyph *> glyphs() const;
 
-	bool addGlyph(Glyph *glyph);
-	bool hasGlyph(const QString &name);
-	Glyph *getGlyph(const QString &name);
-
 	void setFontName(const QString &name);
 	QString fontName() const;
 
@@ -131,6 +127,10 @@ public:
 
 	unsigned maxStackDepth() const;
 	bool setMaxStackDepth(unsigned depth);
+public slots:
+	bool addGlyph(Glyph *glyph);
+	bool hasGlyph(const QString &name);
+	Glyph *getGlyph(const QString &name);
 protected slots:
 	void glyphOutlineChanged();
 	void glyphRenamed(const QString &oldName, const QString &newName);

commit cf810c03b9435e55738547bca4722fbc5b3d38e4
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 20:41:08 2007 +0100

    use Glyph::setGlyphName() for renaming glyphs

diff --git a/gui/glyphsmodel.cxx b/gui/glyphsmodel.cxx
index 6a733e0..186ada9 100644
--- a/gui/glyphsmodel.cxx
+++ b/gui/glyphsmodel.cxx
@@ -132,7 +132,7 @@ bool GlyphsModel::setData(const QModelIndex &index, const QVariant &value, int r
 	if (role == Qt::EditRole) {
 		switch (index.column()) {
 		case NameColumn:
-			ret = doc->renameGlyph(glyph, value.toString());
+			ret = glyph->setGlyphName(value.toString());
 			if (ret)
 				emitChangeSignals(index);
 			break;
diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 1a7ec5c..d8ff368 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -157,6 +157,8 @@ bool FontDocument::addGlyph(Glyph *glyph)
 	glyph->setParent(this);
 
 	connect(glyph, SIGNAL(outlineChanged()), this, SLOT(glyphOutlineChanged()));
+	connect(glyph, SIGNAL(glyphNameChanged(const QString&, const QString&)),
+			this, SLOT(glyphRenamed(const QString&, const QString&)));
 
 	return true;
 }
@@ -296,21 +298,17 @@ bool FontDocument::changed() const
 	return m_documentChanged;
 }
 
-bool FontDocument::renameGlyph(Glyph *glyph, const QString &newName)
+void FontDocument::glyphRenamed(const QString &oldName, const QString &newName)
 {
-	Q_ASSERT(glyph);
+	Q_ASSERT(!oldName.isEmpty());
+	Q_ASSERT(!newName.isEmpty());
+	Q_ASSERT(hasGlyph(oldName));
+	Q_ASSERT(!hasGlyph(newName));
 
-	if (newName.isEmpty())
-		return false;
-	if (newName == glyph->glyphName())
-		return true;
-	if (hasGlyph(newName))
-		return false;
-	nameHash.remove(glyph->glyphName());
-	glyph->setGlyphName(newName);
+	Glyph *glyph = getGlyph(oldName);
+	nameHash.remove(oldName);
 	nameHash[newName] = glyph;
 	setChanged();
-	return true;
 }
 
 bool FontDocument::hasUnicodeGlyph(int unicode) const
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 2af650f..323b330 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -103,8 +103,6 @@ public:
 
 	QList<Lookup> lookups;
 
-	bool renameGlyph(Glyph *glyph, const QString &newName);
-
 	bool hasUnicodeGlyph(int unicode) const;
 	bool changeUnicodeValue(Glyph *glyph, int unicode);
 
@@ -135,6 +133,7 @@ public:
 	bool setMaxStackDepth(unsigned depth);
 protected slots:
 	void glyphOutlineChanged();
+	void glyphRenamed(const QString &oldName, const QString &newName);
 signals:
 	void copyrightChanged();
 	void prepChanged();
diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index 61addc0..fb01482 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -58,13 +58,17 @@ inline bool setIfChanged(QString &what, const QString &to)
 
 bool Glyph::setGlyphName(const QString &name)
 {
-	// FIXME
 	if (name.isEmpty())
 		return false;
 
-	if (setIfChanged(m_glyphName, name)) {
-		setObjectName(name);
-		setChanged();
+	if (m_glyphName != name) {
+		if (!parent() || !document()->hasGlyph(name)) {
+			QString oldName = m_glyphName;
+			m_glyphName = name;
+			setObjectName(name);
+			emit glyphNameChanged(oldName, name);
+			setChanged();
+		}
 	}
 	return true;
 }
diff --git a/nongui/glyph.h b/nongui/glyph.h
index b3344aa..c525c76 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -79,6 +79,7 @@ public:
 	void movePoint(int component, int pointNo, const QPointF &newPos);
 signals:
 	void glyphChanged();
+	void glyphNameChanged(const QString &oldName, const QString &newName);
 
 	void pointMoved(int component, int pointNo, const QPointF &newPos);
 	void outlineChanged();

commit 1b5e33135dc626aa7780ae7eb228fb72aa3ba552
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Tue Nov 27 20:25:37 2007 +0100

    add properties 'glyphs' and 'cvt'
    do not return references from functions

diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 1f9d000..1a7ec5c 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -114,7 +114,7 @@ void FontDocument::addCvtEntry(qint16 value, QString variableName, QString comme
 /** returns control value table.
  * @sa addCvtEntry()
  */
-const QVector<CVTEntry> &FontDocument::cvt() const
+QVector<CVTEntry> FontDocument::cvt() const
 {
 	return m_cvt;
 }
@@ -122,7 +122,7 @@ const QVector<CVTEntry> &FontDocument::cvt() const
 /** returns list of glyphs in this document.
  * @sa addGlyph()
  */
-const QList<Glyph *> &FontDocument::glyphs() const
+QList<Glyph *> FontDocument::glyphs() const
 {
 	return m_glyphs;
 }
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 07583a0..2af650f 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -25,6 +25,11 @@
 
 class Glyph;
 
+Q_DECLARE_METATYPE(Glyph *)
+Q_DECLARE_METATYPE(QList<Glyph *>)
+Q_DECLARE_METATYPE(CVTEntry)
+Q_DECLARE_METATYPE(QVector<CVTEntry>)
+
 /** Class that represents a font document.
  */
 class FontDocument : public QObject {
@@ -47,6 +52,8 @@ class FontDocument : public QObject {
 	Q_PROPERTY(unsigned maxFDEFs READ maxFDEFs WRITE setMaxFDEFs)
 	Q_PROPERTY(unsigned maxIDEFs READ maxIDEFs WRITE setMaxIDEFs)
 	Q_PROPERTY(unsigned maxStackDepth READ maxStackDepth WRITE setMaxStackDepth)
+	Q_PROPERTY(QList<Glyph *> glyphs READ glyphs)
+	Q_PROPERTY(QVector<CVTEntry> cvt READ cvt)
 public:
 	FontDocument(QObject *parent = 0);
 	
@@ -59,9 +66,9 @@ public:
 	QString fpgm() const;
 
 	void addCvtEntry(qint16 value, QString variableName = QString(), QString comment = QString());
-	const QVector<CVTEntry> &cvt() const;
+	QVector<CVTEntry> cvt() const;
 
-	const QList<Glyph *> &glyphs() const;
+	QList<Glyph *> glyphs() const;
 
 	bool addGlyph(Glyph *glyph);
 	bool hasGlyph(const QString &name);

commit 35d0002dc35f32b12905562a9fb44e1fa15d945d
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 26 21:38:30 2007 +0100

    fix typo in property name s/setHorizAdvX/horizAdvX/

diff --git a/nongui/glyph.h b/nongui/glyph.h
index 1cca5d5..b3344aa 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -29,7 +29,7 @@ class FontDocument;
 class Glyph : public QObject {
 	Q_OBJECT
 	Q_PROPERTY(QString glyphName READ glyphName WRITE setGlyphName)
-	Q_PROPERTY(qreal setHorizAdvX READ horizAdvX WRITE setHorizAdvX RESET unsetHorizAdvX)
+	Q_PROPERTY(qreal horizAdvX READ horizAdvX WRITE setHorizAdvX RESET unsetHorizAdvX)
 	Q_PROPERTY(QString instructions READ instructions WRITE setInstructions)
 	Q_PROPERTY(bool instructionsAreValid READ instructionsAreValid WRITE setInstructionsValidity)
 	Q_PROPERTY(QString colorString READ colorString WRITE setColorString)

commit 708913064cffe2b6f900d84123a1403a613d2e64
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 26 21:37:50 2007 +0100

    initialize horiz_adv_x

diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index fb50fc0..61addc0 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -22,7 +22,7 @@
  * @param name a name for the new glyph.
  */
 Glyph::Glyph(const QString &name) :
-	QObject(), m_glyphName(name), horiz_adv_x_set(false), m_unicode(-1), m_changed(false)
+	QObject(), m_glyphName(name), horiz_adv_x(0), horiz_adv_x_set(false), m_unicode(-1), m_changed(false)
 {
 	setObjectName(name);
 }

commit 2c105c4aec27b8bff9382c96926876acdab37111
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 5 22:00:53 2007 +0100

    fix prototype for Glyph::outlineChanged() signal

diff --git a/gui/glyphgraphics.cxx b/gui/glyphgraphics.cxx
index cf23e52..dd13901 100644
--- a/gui/glyphgraphics.cxx
+++ b/gui/glyphgraphics.cxx
@@ -91,7 +91,7 @@ GlyphGraphics::GlyphGraphics(GlyphGraphics *parent, Glyph *glyph, const QPointF
 	}
 
 	item->setPos(pos.x(), -pos.y());
-	connect(m_glyph, SIGNAL(outlineChanged(Glyph *)), this, SLOT(glyphOutlineChanged()));
+	connect(m_glyph, SIGNAL(outlineChanged()), this, SLOT(glyphOutlineChanged()));
 }
 
 QPainterPath GlyphGraphics::contourToPath(const Contour &contour)

commit babfdeee7aa83e506dcf864c2ce473546265918f
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 5 21:36:37 2007 +0100

    reset changed attribute on glyphs after loading from file

diff --git a/nongui/fontdocumentreader.cxx b/nongui/fontdocumentreader.cxx
index 6b8e584..258f4f5 100644
--- a/nongui/fontdocumentreader.cxx
+++ b/nongui/fontdocumentreader.cxx
@@ -241,6 +241,9 @@ void FontDocumentReader::readGlyph()
 				readUnknownElement();
 		}
 	}
+
+	glyph->setChanged(false);
+
 	if (!doc->addGlyph(glyph)) {
 		qWarning() << "Duplicate glyph ignored: " << glyph->glyphName();
 		delete glyph;

commit a1fe7b2266daf4ffa91992f59a22176b8fc444af
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 5 21:32:32 2007 +0100

    set changed flag for class Glyph when needed

diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index f8a9606..fb50fc0 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -32,13 +32,37 @@ FontDocument *Glyph::document() const
 	return qobject_cast<FontDocument *>(parent());
 }
 
+template <typename T>
+static inline bool setIfChanged(T &what, const T& to)
+{
+	if (what != to) {
+		what = to;
+		return true;
+	}
+	return false;
+}
+
+template <>
+inline bool setIfChanged(QString &what, const QString &to)
+{
+	QString newString;
+
+	if (!to.isEmpty())
+		newString = to;
+	if (what != to) {
+		what = to;
+		return true;
+	}
+	return false;
+}
+
 bool Glyph::setGlyphName(const QString &name)
 {
 	// FIXME
 	if (name.isEmpty())
 		return false;
-	if (m_glyphName != name) {
-		m_glyphName = name;
+
+	if (setIfChanged(m_glyphName, name)) {
 		setObjectName(name);
 		setChanged();
 	}
@@ -57,8 +81,16 @@ QString Glyph::glyphName() const
  */
 void Glyph::setHorizAdvX(qreal adv)
 {
-	horiz_adv_x = adv;
-	horiz_adv_x_set = true;
+	bool changed = false;
+
+	if (setIfChanged(horiz_adv_x, adv))
+		changed = true;	
+
+	if (setIfChanged(horiz_adv_x_set, true))
+		changed = true;
+
+	if (changed)
+		setChanged();
 }
 
 /** Unset flag that indicates that horizontal advance was set for this glyph
@@ -94,8 +126,14 @@ qreal Glyph::horizAdvX() const
  */
 void Glyph::setInstructions(const QString &instructions, bool valid)
 {
-	m_instructions = instructions;
-	instructions_valid = valid;
+	bool changed = false;
+
+	if (setIfChanged(m_instructions, instructions))
+		changed = true;
+	if (setIfChanged(instructions_valid, valid))
+		changed = true;
+	if (changed)
+		setChanged();
 }
 
 /** return TrueType instructions for the glyph.
@@ -121,7 +159,8 @@ bool Glyph::hasInstructions() const
  */
 void Glyph::setInstructionsValidity(bool valid)
 {
-	instructions_valid = valid;
+	if (setIfChanged(instructions_valid, valid))
+		setChanged();
 }
 
 /** Returns validity flag for TrueType instructions.
@@ -138,7 +177,8 @@ bool Glyph::instructionsAreValid() const
  */
 void Glyph::setColorString(const QString &s)
 {
-	m_colorString = s;
+	if (setIfChanged(m_colorString, s))
+		setChanged();
 }
 
 /** returns color string.
@@ -154,7 +194,8 @@ QString Glyph::colorString() const
  */
 void Glyph::setComment(const QString &s) 
 {
-	m_comment = s;
+	if (setIfChanged(m_comment, s))
+		setChanged();
 }
 
 /** returns comment string
@@ -167,7 +208,8 @@ QString Glyph::comment() const
 
 void Glyph::setUnicode(int u)
 {
-	m_unicode = u;
+	if (setIfChanged(m_unicode, u))
+		setChanged();
 }
 
 int Glyph::unicode() const

commit 8b85da97b016ee0865eec9d34e5488855f41a666
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Mon Nov 5 01:37:14 2007 +0100

    remove Glyph* argument from class Glyph signals
    QObject::sender() can be used instead

diff --git a/gui/glyphgraphics.cxx b/gui/glyphgraphics.cxx
index 4d3803d..cf23e52 100644
--- a/gui/glyphgraphics.cxx
+++ b/gui/glyphgraphics.cxx
@@ -60,9 +60,9 @@ GlyphGraphics::GlyphGraphics(GlyphCell *parent, Glyph *glyph) :
 		}
 	}
 	p->scene()->addItem(item);
-	connect(m_glyph, SIGNAL(outlineChanged(Glyph *)), this, SLOT(glyphOutlineChanged()));
-	connect(m_glyph, SIGNAL(pointMoved(Glyph *, int, int, QPointF)),
-			this, SLOT(glyphPointMoved(Glyph *, int, int, QPointF)));
+	connect(m_glyph, SIGNAL(outlineChanged()), this, SLOT(glyphOutlineChanged()));
+	connect(m_glyph, SIGNAL(pointMoved(int, int, QPointF)),
+			this, SLOT(glyphPointMoved(int, int, QPointF)));
 }
 
 GlyphGraphics::GlyphGraphics(GlyphGraphics *parent, Glyph *glyph, const QPointF &pos) :
@@ -141,9 +141,8 @@ void GlyphGraphics::glyphOutlineChanged()
 	item->update();
 }
 
-void GlyphGraphics::glyphPointMoved(Glyph *glyph, int component, int pointNo, const QPointF &newPos)
+void GlyphGraphics::glyphPointMoved(int component, int pointNo, const QPointF &newPos)
 {
-	Q_UNUSED(glyph);
 	ControlPoint *pt = 0;
 
 	for (int i = 0; i < points.size(); i++) {
diff --git a/gui/glyphgraphics.h b/gui/glyphgraphics.h
index de8477f..073bafe 100644
--- a/gui/glyphgraphics.h
+++ b/gui/glyphgraphics.h
@@ -45,7 +45,7 @@ public:
 	void changePoint(const GlyphGraphics::PointIndex &idx, const QPointF &newPoint);
 public slots:
 	void glyphOutlineChanged();
-	void glyphPointMoved(Glyph *glyph, int component, int pointNo, const QPointF &newPos);
+	void glyphPointMoved(int component, int pointNo, const QPointF &newPos);
 private:
 	GlyphGraphics(GlyphGraphics *parent, Glyph *glyph, const QPointF &pos);
 	GlyphCell *p;
diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 1ab9719..1f9d000 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -156,7 +156,7 @@ bool FontDocument::addGlyph(Glyph *glyph)
 		unicodeHash[unicode] = glyph;
 	glyph->setParent(this);
 
-	connect(glyph, SIGNAL(outlineChanged(Glyph *)), this, SLOT(glyphOutlineChanged(Glyph *)));
+	connect(glyph, SIGNAL(outlineChanged()), this, SLOT(glyphOutlineChanged()));
 
 	return true;
 }
@@ -488,8 +488,13 @@ bool FontDocument::setMaxStackDepth(unsigned depth)
 	return true;
 }
 
-void FontDocument::glyphOutlineChanged(Glyph *g)
+void FontDocument::glyphOutlineChanged()
 {
+	Glyph *g = qobject_cast<Glyph *>(sender());
+	
+	if (!g)
+		return;
+
 	int idx = m_glyphs.indexOf(g);
 	Q_ASSERT(idx != -1);
 
diff --git a/nongui/fontdocument.h b/nongui/fontdocument.h
index 7251930..07583a0 100644
--- a/nongui/fontdocument.h
+++ b/nongui/fontdocument.h
@@ -127,7 +127,7 @@ public:
 	unsigned maxStackDepth() const;
 	bool setMaxStackDepth(unsigned depth);
 protected slots:
-	void glyphOutlineChanged(Glyph *g);
+	void glyphOutlineChanged();
 signals:
 	void copyrightChanged();
 	void prepChanged();
diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index 4eec513..f8a9606 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -179,7 +179,7 @@ void Glyph::setChanged(bool c)
 {
 	if (m_changed != c) {
 		m_changed = c;
-		emit glyphChanged(this);
+		emit glyphChanged();
 	}
 }
 
@@ -258,7 +258,7 @@ void Glyph::movePoint(int component, int pointNo, const QPointF &newPos)
 		contour[pointNo] = pt;
 		content[component] = qVariantFromValue(contour);
 
-		emit pointMoved(this, component, pointNo, newPos);
-		emit outlineChanged(this);
+		emit pointMoved(component, pointNo, newPos);
+		emit outlineChanged();
 	}
 }
diff --git a/nongui/glyph.h b/nongui/glyph.h
index a1c2c9c..1cca5d5 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -78,10 +78,10 @@ public:
 
 	void movePoint(int component, int pointNo, const QPointF &newPos);
 signals:
-	void glyphChanged(Glyph *g);
+	void glyphChanged();
 
-	void pointMoved(Glyph *g, int component, int pointNo, const QPointF &newPos);
-	void outlineChanged(Glyph *g);
+	void pointMoved(int component, int pointNo, const QPointF &newPos);
+	void outlineChanged();
 private:
 	QString m_glyphName;
 	qreal horiz_adv_x;

commit 563eb52825b745787e2acaee2e68827d5635255b
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sun Nov 4 22:59:49 2007 +0100

    unset attribute Qt::WA_QuitOnClose on GlyphEditWidget

diff --git a/gui/glypheditwidget.cxx b/gui/glypheditwidget.cxx
index 67cb486..2a47ee9 100644
--- a/gui/glypheditwidget.cxx
+++ b/gui/glypheditwidget.cxx
@@ -33,7 +33,9 @@
 GlyphEditWidget::GlyphEditWidget(QWidget *parent, GlyphsModel *model, const QModelIndex &index) : QMainWindow(parent)
 {
 	setAttribute(Qt::WA_DeleteOnClose);
-	
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
+
 	valid = false;
 
 	if (!index.isValid()) // FIXME maybe assert?

commit e3a03a68dd2d9b29ef41b57fd6695aabbe10333a
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sun Nov 4 22:57:34 2007 +0100

    unset attribute Qt::WA_QuitOnClose on all dialogs, otherwise application will not exit (probably bug in Qt)

diff --git a/gui/cvteditor.cxx b/gui/cvteditor.cxx
index 4276adc..d994348 100644
--- a/gui/cvteditor.cxx
+++ b/gui/cvteditor.cxx
@@ -29,6 +29,9 @@ CVTEditor::CVTEditor(class QAbstractItemModel *model, QWidget *parent) : QDialog
 	Qt::WindowFlags flags = windowFlags();
 	setWindowFlags(flags & ~Qt::Dialog | Qt::Window);
 
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
+
 	// TODO make some better layout
 	QVBoxLayout *vbox = new QVBoxLayout;
 
diff --git a/gui/documentinfoeditor.cxx b/gui/documentinfoeditor.cxx
index 90c5da7..745e347 100644
--- a/gui/documentinfoeditor.cxx
+++ b/gui/documentinfoeditor.cxx
@@ -30,6 +30,9 @@ DocumentInfoEditor::DocumentInfoEditor(QAbstractItemModel *model, QWidget *paren
 
 	Qt::WindowFlags flags = windowFlags();
 	setWindowFlags(flags & ~Qt::Dialog | Qt::Window);
+	
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
 
 	QTextEdit *copyrightEditor = new QTextEdit;
 	QLineEdit *fontNameEditor = new QLineEdit;
diff --git a/gui/glyphpropertieseditor.cxx b/gui/glyphpropertieseditor.cxx
index 0126dcc..ba79982 100644
--- a/gui/glyphpropertieseditor.cxx
+++ b/gui/glyphpropertieseditor.cxx
@@ -37,6 +37,9 @@ GlyphPropertiesEditor::GlyphPropertiesEditor(QAbstractItemModel *model, const QM
 
 	Qt::WindowFlags flags = windowFlags();
 	setWindowFlags(flags & ~Qt::Dialog | Qt::Window);
+	
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
 
 	QLabel *nameLabel = new QLabel("Glyph name:");
 	QLineEdit *nameEdit = new QLineEdit;
diff --git a/gui/maxpeditor.cxx b/gui/maxpeditor.cxx
index a79c669..d1859ec 100644
--- a/gui/maxpeditor.cxx
+++ b/gui/maxpeditor.cxx
@@ -28,6 +28,9 @@ MAXPEditor::MAXPEditor(QAbstractItemModel *model, QWidget *parent) : QDialog(par
 
 	setAttribute(Qt::WA_DeleteOnClose);
 
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
+
 	QLabel *zonesLabel = new QLabel("Zones:");
 	QSpinBox *zonesEdit = new QSpinBox; // TODO use something else
 	zonesEdit->setMinimum(1);
diff --git a/gui/ttieditor.cxx b/gui/ttieditor.cxx
index f3f1dbf..4b56880 100644
--- a/gui/ttieditor.cxx
+++ b/gui/ttieditor.cxx
@@ -34,6 +34,9 @@ TTIEditor::TTIEditor(QAbstractItemModel *model, const QModelIndex &item, QWidget
 	setWindowFlags(flags & ~Qt::Dialog | Qt::Window);
 
 	setAttribute(Qt::WA_DeleteOnClose);
+	
+	// Qt does not like this on non-top-level windows
+	setAttribute(Qt::WA_QuitOnClose, false);
 
 	textEditor = new QTextEdit;
 	QFont font;

commit f73a45e6612bfc9762bf2bc8575f7ba4ee958879
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sun Nov 4 22:52:54 2007 +0100

    remove documentClosed() signal

diff --git a/gui/mainwindow.cxx b/gui/mainwindow.cxx
index c6ff03d..ea466f1 100644
--- a/gui/mainwindow.cxx
+++ b/gui/mainwindow.cxx
@@ -339,7 +339,6 @@ void MainWindow::editPrep()
 	QModelIndex prepIdx = documentInfoModel->index(DocumentInfoModel::PrepRow, 0);
 
 	TTIEditor *editor = new TTIEditor(documentInfoModel, prepIdx, this);
-	connect(this, SIGNAL(documentClosed()), editor, SLOT(close()));
 
 	if (!m_doc->fontName().isEmpty())
 		editor->setWindowTitle(QString("prep table in %1").arg(m_doc->fontName()));
@@ -356,7 +355,6 @@ void MainWindow::editFpgm()
 	QModelIndex fpgmIdx = documentInfoModel->index(DocumentInfoModel::FpgmRow, 0);
 
 	TTIEditor *editor = new TTIEditor(documentInfoModel, fpgmIdx, this);
-	connect(this, SIGNAL(documentClosed()), editor, SLOT(close()));
 
 	if (!m_doc->fontName().isEmpty())
 		editor->setWindowTitle(QString("fpgm table in %1").arg(m_doc->fontName()));
@@ -394,11 +392,8 @@ void MainWindow::editGlyph(const QModelIndex &index)
 	QAbstractProxyModel *proxy = qobject_cast<QAbstractProxyModel *>(glyphsView->model());
 	if (proxy) {
 		GlyphEditWidget *editor = new GlyphEditWidget(this, qobject_cast<GlyphsModel *>(proxy->sourceModel()), proxy->mapToSource(index));
-		if (editor->isValid()) {
-			// Is it realy needed?
-			connect(this, SIGNAL(documentClosed()), editor, SLOT(close()));
+		if (editor->isValid())
 			editor->show();
-		}
 		else
 			delete editor;
 	}
@@ -412,7 +407,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
 			return;
 		}
 	}
-	emit documentClosed();
 	writeSettings();
 	event->accept();
 }
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index dd0ebb3..6f7bf45 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -60,7 +60,6 @@ public slots:
 	void documentChanged();
 signals:
 	void documentAvailable(bool available);
-	void documentClosed();
 private:
 	FontDocument *m_doc;
 	QString m_currentFile;

commit 6139dfb9f9b9f877df6794243add5a0f7b8beb0a
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sun Nov 4 21:41:14 2007 +0100

    add properties "changed" and "glyphName" to class Glyph

diff --git a/gui/glyphsmodel.cxx b/gui/glyphsmodel.cxx
index e75f074..6a733e0 100644
--- a/gui/glyphsmodel.cxx
+++ b/gui/glyphsmodel.cxx
@@ -43,10 +43,10 @@ QVariant GlyphsModel::data(const QModelIndex &index, int role) const
 	switch (index.column()) {
 	case GlyphColumn:
 		if (role == Qt::DisplayRole)
-			return glyph->objectName();
+			return glyph->glyphName();
 		if (role == Qt::ToolTipRole) {
 			int unicode = glyph->unicode();
-			return UnicodeNamesList::makeDescription(unicode, glyph->objectName());
+			return UnicodeNamesList::makeDescription(unicode, glyph->glyphName());
 		}
 		else if (role == Qt::DecorationRole) {
 			QVariant var;
@@ -65,7 +65,7 @@ QVariant GlyphsModel::data(const QModelIndex &index, int role) const
 		break;
 	case NameColumn:
 		if (role == Qt::DisplayRole || role == Qt::EditRole)
-			return glyph->objectName();
+			return glyph->glyphName();
 		break;
 	case ColorColumn:
 		if (role == Qt::DisplayRole || role == Qt::EditRole)
diff --git a/nongui/fontdocument.cxx b/nongui/fontdocument.cxx
index 0d706fd..1ab9719 100644
--- a/nongui/fontdocument.cxx
+++ b/nongui/fontdocument.cxx
@@ -140,7 +140,7 @@ bool FontDocument::addGlyph(Glyph *glyph)
 	Q_ASSERT(glyph);
 	Q_ASSERT(!glyph->parent());
 
-	QString name = glyph->objectName();
+	QString name = glyph->glyphName();
 	int unicode = glyph->unicode();
 
 	if (name.isEmpty())
@@ -302,12 +302,12 @@ bool FontDocument::renameGlyph(Glyph *glyph, const QString &newName)
 
 	if (newName.isEmpty())
 		return false;
-	if (newName == glyph->objectName())
+	if (newName == glyph->glyphName())
 		return true;
 	if (hasGlyph(newName))
 		return false;
-	nameHash.remove(glyph->objectName());
-	glyph->setObjectName(newName);
+	nameHash.remove(glyph->glyphName());
+	glyph->setGlyphName(newName);
 	nameHash[newName] = glyph;
 	setChanged();
 	return true;
@@ -345,7 +345,7 @@ void FontDocument::removeGlyphs(int first, int count)
 	for (int i = 0; i < count; i++) {
 		const Glyph *g = m_glyphs.at(first);
 		unicodeHash.remove(g->unicode());
-		nameHash.remove(g->objectName());
+		nameHash.remove(g->glyphName());
 		m_glyphs.removeAt(first);
 		delete g;
 		changed = true;
diff --git a/nongui/fontdocumentreader.cxx b/nongui/fontdocumentreader.cxx
index ef64ea5..6b8e584 100644
--- a/nongui/fontdocumentreader.cxx
+++ b/nongui/fontdocumentreader.cxx
@@ -242,7 +242,7 @@ void FontDocumentReader::readGlyph()
 		}
 	}
 	if (!doc->addGlyph(glyph)) {
-		qWarning() << "Duplicate glyph ignored: " << glyph->objectName();
+		qWarning() << "Duplicate glyph ignored: " << glyph->glyphName();
 		delete glyph;
 	}
 }
diff --git a/nongui/fontdocumentwriter.cxx b/nongui/fontdocumentwriter.cxx
index e072ced..7d4716f 100644
--- a/nongui/fontdocumentwriter.cxx
+++ b/nongui/fontdocumentwriter.cxx
@@ -120,7 +120,7 @@ bool FontDocumentWriter::writeGlyphs()
 	writeStartElement("glyphs");
 	foreach (const Glyph *g, doc->glyphs()) {
 		writeStartElement("glyph");
-		writeAttribute("glyph-name", g->objectName());
+		writeAttribute("glyph-name", g->glyphName());
 		if (g->hasHorizAdvX())
 			writeAttribute("horiz-adv-x", QString::number(g->horizAdvX()));
 		writeStringAttribute("color", g->colorString());
diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index 0ecdb8a..4eec513 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -22,7 +22,7 @@
  * @param name a name for the new glyph.
  */
 Glyph::Glyph(const QString &name) :
-	QObject(), horiz_adv_x_set(false), m_unicode(-1)
+	QObject(), m_glyphName(name), horiz_adv_x_set(false), m_unicode(-1), m_changed(false)
 {
 	setObjectName(name);
 }
@@ -32,6 +32,24 @@ FontDocument *Glyph::document() const
 	return qobject_cast<FontDocument *>(parent());
 }
 
+bool Glyph::setGlyphName(const QString &name)
+{
+	// FIXME
+	if (name.isEmpty())
+		return false;
+	if (m_glyphName != name) {
+		m_glyphName = name;
+		setObjectName(name);
+		setChanged();
+	}
+	return true;
+}
+
+QString Glyph::glyphName() const
+{
+	return m_glyphName;
+}
+
 /** Set horizontal advance.
  * This function sets horizontal advance for the glyph.
  * @param adv a new value for horizontal advance
@@ -157,6 +175,19 @@ int Glyph::unicode() const
 	return m_unicode;
 }
 
+void Glyph::setChanged(bool c)
+{
+	if (m_changed != c) {
+		m_changed = c;
+		emit glyphChanged(this);
+	}
+}
+
+bool Glyph::changed() const
+{
+	return m_changed;
+}
+
 bool Glyph::computeMetrics(qreal &xMin, qreal &xMax, qreal &yMin, qreal &yMax) const
 {
 	// TODO do something with open contours
diff --git a/nongui/glyph.h b/nongui/glyph.h
index b689e07..a1c2c9c 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -25,16 +25,17 @@ class FontDocument;
 
 /** %Glyph description.
  * This class contains information about a glyph.
- * Glyph name is stored in objectName() property.
  */
 class Glyph : public QObject {
 	Q_OBJECT
+	Q_PROPERTY(QString glyphName READ glyphName WRITE setGlyphName)
 	Q_PROPERTY(qreal setHorizAdvX READ horizAdvX WRITE setHorizAdvX RESET unsetHorizAdvX)
 	Q_PROPERTY(QString instructions READ instructions WRITE setInstructions)
 	Q_PROPERTY(bool instructionsAreValid READ instructionsAreValid WRITE setInstructionsValidity)
 	Q_PROPERTY(QString colorString READ colorString WRITE setColorString)
 	Q_PROPERTY(QString comment READ comment WRITE setComment)
 	Q_PROPERTY(int unicode READ unicode WRITE setUnicode)
+	Q_PROPERTY(bool changed READ changed WRITE setChanged)
 public:
 	Glyph(const QString &name = QString());
 
@@ -45,7 +46,10 @@ public:
 	 * @sa Contour and GlyphRef
 	 */
 	QList<QVariant> content; // TODO hide it
-	
+
+	bool setGlyphName(const QString &name);
+	QString glyphName() const;
+
 	void setHorizAdvX(qreal adv);
 	void unsetHorizAdvX();
 	bool hasHorizAdvX() const;
@@ -66,14 +70,20 @@ public:
 	void setUnicode(int u);
 	int unicode() const;
 
+	void setChanged(bool c = true);
+	bool changed() const;
+
 	bool computeMetrics(qreal &xMin, qreal &xMax, qreal &yMin, qreal &yMax) const;
 	void countParts(unsigned &nContours, unsigned &nRefs) const;
 
 	void movePoint(int component, int pointNo, const QPointF &newPos);
 signals:
+	void glyphChanged(Glyph *g);
+
 	void pointMoved(Glyph *g, int component, int pointNo, const QPointF &newPos);
 	void outlineChanged(Glyph *g);
 private:
+	QString m_glyphName;
 	qreal horiz_adv_x;
 	bool horiz_adv_x_set;
 	QString m_instructions;
@@ -81,6 +91,7 @@ private:
 	QString m_colorString;
 	QString m_comment;
 	int m_unicode;
+	bool m_changed;
 };
 
 #endif
diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index d7f9eb4..3ff230d 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -322,7 +322,7 @@ bool TTFWriter::writeSimpleGlyph(QIODevice *dev, const Glyph *g)
 	qint16 nContours = g->content.size();
 	qreal xMin, xMax, yMin, yMax;
 	if (!g->computeMetrics(xMin, xMax, yMin, yMax)) {
-		qDebug() << "computeMinMax failed:" << g->objectName();
+		qDebug() << "computeMinMax failed:" << g->glyphName();
 		return false;
 	}
 	bool ret = writeBigEndian(dev, nContours);
@@ -348,7 +348,7 @@ bool TTFWriter::writeSimpleGlyph(QIODevice *dev, const Glyph *g)
 		instsBuf.open(QBuffer::WriteOnly);
 		TTInstructionsEncoder encoder(g->instructions());
 		if (!encoder.encode(&instsBuf)) {
-			qDebug() << "Bad instructions for glyph" << g->objectName();
+			qDebug() << "Bad instructions for glyph" << g->glyphName();
 			return false;
 		}
 		instsBuf.close();
@@ -646,7 +646,7 @@ bool TTFWriter::writePost()
 		// TODO check if names are standard
 		if (!writeBigEndian(&buffer, (quint16)(257 + i))) // TODO check bounds
 			return false;
-		glyphNames << sortedGlyphs.at(i)->objectName();
+		glyphNames << sortedGlyphs.at(i)->glyphName();
 	}
 	// write names, if any
 	foreach (const QString &s, glyphNames) {
@@ -682,7 +682,7 @@ void TTFWriter::createGlyphList()
 		// FIXME do not allow .notdef to be encoded
 		if (g->unicode() != -1)
 			encoded << g;
-		else if (g->objectName() == ".notdef")
+		else if (g->glyphName() == ".notdef")
 			notdefGlyph = g;
 		else
 			unencoded << g;

commit 3f80bc320cf53aa01f908d7d2ae35f2ee1df260c
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Sun Nov 4 21:22:47 2007 +0100

    declare properties of class Glyph

diff --git a/nongui/glyph.h b/nongui/glyph.h
index fa19ef1..b689e07 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -29,6 +29,12 @@ class FontDocument;
  */
 class Glyph : public QObject {
 	Q_OBJECT
+	Q_PROPERTY(qreal setHorizAdvX READ horizAdvX WRITE setHorizAdvX RESET unsetHorizAdvX)
+	Q_PROPERTY(QString instructions READ instructions WRITE setInstructions)
+	Q_PROPERTY(bool instructionsAreValid READ instructionsAreValid WRITE setInstructionsValidity)
+	Q_PROPERTY(QString colorString READ colorString WRITE setColorString)
+	Q_PROPERTY(QString comment READ comment WRITE setComment)
+	Q_PROPERTY(int unicode READ unicode WRITE setUnicode)
 public:
 	Glyph(const QString &name = QString());
 

-- 
Fondue Font Editor



More information about the fondue-commits mailing list