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

Eugeniy Meshcheryakov eugen at debian.org
Fri Aug 31 14:16:07 UTC 2007


The branch, master has been updated
       via  860cb5636013aeb33a1a33f6fb834577dd944e9f (commit)
       via  918b60247955a0a5252cce8d421daef6667d1a50 (commit)
       via  2c78bc338255e1385f8015dc63abe7101df3a335 (commit)
      from  36ffff05aaea3f454bc2ed11626d82599b9440dd (commit)


- Shortlog ------------------------------------------------------------
860cb56 write format 2 post table
918b602 Sort glyphs by encoding value for TTF export
2c78bc3 move reference and contour counting function to class Glyph

Summary of changes:
 nongui/glyph.cxx     |   16 +++++++
 nongui/glyph.h       |    1 +
 nongui/ttfwriter.cxx |  119 +++++++++++++++++++++++++++++++++++--------------
 nongui/ttfwriter.h   |    5 ++
 4 files changed, 107 insertions(+), 34 deletions(-)
-----------------------------------------------------------------------
Details of changes:

commit 860cb5636013aeb33a1a33f6fb834577dd944e9f
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 16:15:54 2007 +0200

    write format 2 post table

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 399eedc..271981d 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -482,6 +482,17 @@ bool TTFWriter::writeName()
 	return ret;
 }
 
+static bool writePascalString(QIODevice *dev, const QString &s)
+{
+	Q_ASSERT(dev);
+	QByteArray bytes = s.toUtf8();
+	if (bytes.size() > 255)
+		bytes.resize(255);
+	bool ret = dev->putChar(bytes.size());
+	ret = ret && (dev->write(bytes) == bytes.size());
+	return ret;
+}
+
 bool TTFWriter::writePost()
 {
 	QByteArray tbl;
@@ -490,7 +501,7 @@ bool TTFWriter::writePost()
 	buffer.open(QBuffer::WriteOnly);
 	// TODO write real post table, or not?
 	bool ret = true;
-	ret = ret && writeBigEndian(&buffer, (quint32)0x00030000); // FIXME Table format, 3 - no names
+	ret = ret && writeBigEndian(&buffer, (quint32)0x00020000); // Table format
 	ret = ret && writeBigEndian(&buffer, (quint32)(m_doc->italicAngle() * 0x10000)); // Italic angle
 	ret = ret && writeBigEndian(&buffer, (qint16)m_doc->underlinePosition()); // Underline position
 	ret = ret && writeBigEndian(&buffer, (qint16)m_doc->underlineThickness()); // Underline thickness
@@ -499,11 +510,30 @@ bool TTFWriter::writePost()
 	ret = ret && writeBigEndian(&buffer, (quint32)0); // Max mem type42 - unknown
 	ret = ret && writeBigEndian(&buffer, (quint32)0); // Min mem type1 - unknown
 	ret = ret && writeBigEndian(&buffer, (quint32)0); // Max mem type1 - unknown
+	// number of glyphs for format 2
+	ret = ret && writeBigEndian(&buffer, (quint16)sortedGlyphs.size());
+	// glyphs names
+	ret = ret && writeBigEndian(&buffer, (quint16)0); // for .notdef
+	if (!ret)
+		return false;
+	// other glyph names (string numbers)
+	QStringList glyphNames;
+	for (int i = 1; i < sortedGlyphs.size(); i++) {
+		// TODO check if names are standard
+		if (!writeBigEndian(&buffer, (quint16)(257 + i))) // TODO check bounds
+			return false;
+		glyphNames << sortedGlyphs.at(i)->objectName();
+	}
+	// write names, if any
+	foreach (const QString &s, glyphNames) {
+		if (!writePascalString(&buffer, s))
+			return false;
+	}
+
 	buffer.close();
 
-	if (ret)
-		appendTable(makeTag('p', 'o', 's', 't'), tbl);
-	return ret;
+	appendTable(makeTag('p', 'o', 's', 't'), tbl);
+	return true;
 }
 
 static bool glyphUnicodeLessThan(const Glyph *g1, const Glyph *g2)

commit 918b60247955a0a5252cce8d421daef6667d1a50
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 15:55:56 2007 +0200

    Sort glyphs by encoding value for TTF export
    Move .notdef to the begining of the font (if present)
    Ignore mixed-contend glyphs
    Do not export glyphs that only have color

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 8cb2e1a..399eedc 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -33,6 +33,7 @@ static inline quint32 makeTag(unsigned char a, unsigned char b,
 TTFWriter::TTFWriter(const FontDocument *doc) : m_doc(doc)
 {
 	Q_ASSERT(m_doc);
+	createGlyphList();
 }
 
 template <typename T>
@@ -228,34 +229,26 @@ bool TTFWriter::writeGlyphs()
 	glyfBuffer.open(QBuffer::WriteOnly);
 	locaBuffer.open(QBuffer::WriteOnly);
 
-	// FIXME using 32-bit version of loca table
-	// write offset of .notdef glyph
-	if (!writeBigEndian(&locaBuffer, (quint32)0))
-		return false;
-	// TODO move .notdef to the begining of the font
-
-	// TODO skip glyphs that only have color
-	foreach (const Glyph *g, m_doc->glyphs()) {
+	foreach (const Glyph *g, sortedGlyphs) {
 		// write offset of the glyphs into loca table
 		if (!writeBigEndian(&locaBuffer, (quint32)glyfBuffer.pos()))
 			return false;
 
-		// is glyph simple, composite, empty or invalid?
-		unsigned nContours, nRefs;
-		g->countParts(nContours, nRefs);
+		if (g) {
+			// is glyph simple, composite, empty or invalid?
+			unsigned nContours, nRefs;
+			g->countParts(nContours, nRefs);
 
-		if (nContours && nRefs) {
-			qDebug() << "Invalid glyph found:" << g->objectName();
-			return false; // glyph is invalid
-		}
+			Q_ASSERT(!(nContours && nRefs)); // FIXME handle them
 
-		bool ret = true;
-		if (nRefs)
-			ret = writeCompositeGlyph(&glyfBuffer, g);
-		else if (nContours)
-			ret = writeSimpleGlyph(&glyfBuffer, g);
-		if (!ret)
-			return false;
+			bool ret = true;
+			if (nRefs)
+				ret = writeCompositeGlyph(&glyfBuffer, g);
+			else if (nContours)
+				ret = writeSimpleGlyph(&glyfBuffer, g);
+			if (!ret)
+				return false;
+		}
 	}
 
 	if (!writeBigEndian(&locaBuffer, (quint32)glyfBuffer.pos()))
@@ -380,7 +373,7 @@ bool TTFWriter::writeMaxp()
 
 	bool ret = true;
 	ret = ret && writeBigEndian(&buffer, (qint32)0x00010000); // Table version
-	ret = ret && writeBigEndian(&buffer, (qint16)(m_doc->glyphs().size() + 1)); // number of glyphs // FIXME +1 is for .notdef
+	ret = ret && writeBigEndian(&buffer, (qint16)sortedGlyphs.size()); // number of glyphs // FIXME +1 is for .notdef
 	ret = ret && writeBigEndian(&buffer, (qint16)100); // FIXME Max number of points in non-composite glyph
 	ret = ret && writeBigEndian(&buffer, (qint16)100); // FIXME Max number of contours in non-composite glyph
 	ret = ret && writeBigEndian(&buffer, (qint16)100); // FIXME Max number of points in composite glyph
@@ -512,3 +505,37 @@ bool TTFWriter::writePost()
 		appendTable(makeTag('p', 'o', 's', 't'), tbl);
 	return ret;
 }
+
+static bool glyphUnicodeLessThan(const Glyph *g1, const Glyph *g2)
+{
+	return g1->unicode() < g2->unicode();
+}
+
+void TTFWriter::createGlyphList()
+{
+	QList<const Glyph *> encoded;
+	QList<const Glyph *> unencoded;
+	const Glyph *notdefGlyph = 0;
+
+	foreach (const Glyph *g, m_doc->glyphs()) {
+		unsigned nContours, nRefs;
+		g->countParts(nContours, nRefs);
+		if (nContours && nRefs)
+			continue; // no not allow mixed glyphs for now
+		if ((!nContours && !nRefs) && !g->hasHorizAdvX())
+			continue; // not a real glyph
+
+		// FIXME do not allow .notdef to be encoded
+		if (g->unicode() != -1)
+			encoded << g;
+		else if (g->objectName() == ".notdef")
+			notdefGlyph = g;
+		else
+			unencoded << g;
+	}
+	qSort(encoded.begin(), encoded.end(), glyphUnicodeLessThan);
+	sortedGlyphs << notdefGlyph;
+	sortedGlyphs << encoded;
+	sortedGlyphs << unencoded;
+	encodedGlyphsCount = encoded.size();
+}
diff --git a/nongui/ttfwriter.h b/nongui/ttfwriter.h
index 3c1d403..653e212 100644
--- a/nongui/ttfwriter.h
+++ b/nongui/ttfwriter.h
@@ -29,6 +29,8 @@ public:
 	TTFWriter(const FontDocument *doc);
 	bool write(QIODevice *dev);
 private:
+	void createGlyphList();
+
 	bool writeCvt();
 	bool writeFpgm();
 	bool writePrep();
@@ -48,6 +50,9 @@ private:
 
 	QMap<quint32, QByteArray> tables;
 	QHash<quint32, quint32> tableLengths;
+
+	QList<const Glyph *> sortedGlyphs;
+	int encodedGlyphsCount;
 };
 
 #endif

commit 2c78bc338255e1385f8015dc63abe7101df3a335
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 15:11:21 2007 +0200

    move reference and contour counting function to class Glyph

diff --git a/nongui/glyph.cxx b/nongui/glyph.cxx
index dfc4772..7a1c536 100644
--- a/nongui/glyph.cxx
+++ b/nongui/glyph.cxx
@@ -16,6 +16,7 @@
  */
 #include "glyph.h"
 #include "contour.h"
+#include "glyphref.h"
 
 bool Glyph::computeMetrics(qreal &xMin, qreal &xMax, qreal &yMin, qreal &yMax) const
 {
@@ -55,3 +56,18 @@ bool Glyph::computeMetrics(qreal &xMin, qreal &xMax, qreal &yMin, qreal &yMax) c
 	}
 	return true;
 }
+
+void Glyph::countParts(unsigned &nContours, unsigned &nRefs) const
+{
+	nContours = 0;
+	nRefs = 0;
+
+	foreach (const QVariant &v, content) {
+		if (v.canConvert<Contour>())
+			nContours++;
+		else {
+			Q_ASSERT(v.canConvert<GlyphRef>());
+			nRefs++;
+		}
+	}
+}
diff --git a/nongui/glyph.h b/nongui/glyph.h
index 5fd9109..2e1ae70 100644
--- a/nongui/glyph.h
+++ b/nongui/glyph.h
@@ -112,6 +112,7 @@ public:
 	int unicode() const {return m_unicode;}
 
 	bool computeMetrics(qreal &xMin, qreal &xMax, qreal &yMin, qreal &yMax) const;
+	void countParts(unsigned &nContours, unsigned &nRefs) const;
 private:
 	qreal horiz_adv_x;
 	bool horiz_adv_x_set;
diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index d0a645b..8cb2e1a 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -236,20 +236,14 @@ bool TTFWriter::writeGlyphs()
 
 	// TODO skip glyphs that only have color
 	foreach (const Glyph *g, m_doc->glyphs()) {
-		int nContours = 0;
-		int nRefs = 0;
-
 		// write offset of the glyphs into loca table
 		if (!writeBigEndian(&locaBuffer, (quint32)glyfBuffer.pos()))
 			return false;
 
 		// is glyph simple, composite, empty or invalid?
-		foreach (QVariant v, g->content) {
-			if (v.canConvert<Contour>())
-				nContours++;
-			else
-				nRefs++;
-		}
+		unsigned nContours, nRefs;
+		g->countParts(nContours, nRefs);
+
 		if (nContours && nRefs) {
 			qDebug() << "Invalid glyph found:" << g->objectName();
 			return false; // glyph is invalid

-- 
Fondue Font Editor



More information about the fondue-commits mailing list