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

Eugeniy Meshcheryakov eugen at debian.org
Fri Aug 31 16:15:05 UTC 2007


The branch, master has been updated
       via  4d21308791bbc7e5a917cda8941a114d9c4e9c68 (commit)
       via  000080403dd785c197bdb1364c1553ff513b3222 (commit)
       via  0ad53f62cf9786b1e3c9e2aa558413d70c71f2ad (commit)
       via  f4c531fb479c4d79041b58eabfc754f5bdd33114 (commit)
       via  54f01cf8f248839e0b30be90cc5809eeb4fa6444 (commit)
       via  734bf7bfb24368f1ca7f679c39c0e787f7597b1c (commit)
      from  860cb5636013aeb33a1a33f6fb834577dd944e9f (commit)


- Shortlog ------------------------------------------------------------
4d21308 fix lsb and advance calculations for hmtx table
0000804 FWord is 16 bit, not 32 bit
0ad53f6 make only coordinates of first point in a glyph relative to 0, not first point of each contour
f4c531f write hmtx and hhea tables
54f01cf fix calculations for TTF header
734bf7b remove comment

Summary of changes:
 nongui/ttfwriter.cxx |  138 ++++++++++++++++++++++++++++++++++++++++++++++----
 nongui/ttfwriter.h   |   10 ++++
 2 files changed, 137 insertions(+), 11 deletions(-)
-----------------------------------------------------------------------
Details of changes:

commit 4d21308791bbc7e5a917cda8941a114d9c4e9c68
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 18:12:49 2007 +0200

    fix lsb and advance calculations for hmtx table

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 9bd8869..266142f 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -630,8 +630,8 @@ bool TTFWriter::writeHmtx()
 		if (g) {
 			qreal xMin, xMax, yMin, yMax;
 			g->computeMetrics(xMin, xMax, yMin, yMax);
-			advance = (quint16)xMin;
-			lsb = (qint16)g->horizAdvX();
+			lsb = (quint16)xMin;
+			advance = (qint16)g->horizAdvX();
 			qint16 ascent = (qint16)yMax;
 			qint16 descent = (qint16)yMin;
 			qint16 rsb = (qint16)xMax;

commit 000080403dd785c197bdb1364c1553ff513b3222
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 18:09:09 2007 +0200

    FWord is 16 bit, not 32 bit

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 9a466e2..9bd8869 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -256,12 +256,12 @@ bool TTFWriter::writeGlyphs()
 	if (firstGlyph) {
 		qreal xMin, xMax, yMin, yMax;
 		firstGlyph->computeMetrics(xMin, xMax, yMin, yMax);
-		qint32 ascent = (qint32)yMax;
-		qint32 descent = (qint32)yMin;
-		quint32 advanceWidth = (quint32)firstGlyph->horizAdvX();
-		qint32 lsb = (qint32)xMin;
-		qint32 rsb = (qint32)xMax;
-		qint32 extent = rsb; // FIXME is this correct?
+		qint16 ascent = (qint16)yMax;
+		qint16 descent = (qint16)yMin;
+		quint16 advanceWidth = (quint16)firstGlyph->horizAdvX();
+		qint16 lsb = (qint16)xMin;
+		qint16 rsb = (qint16)xMax;
+		qint16 extent = rsb; // FIXME is this correct?
 
 		maxAscent = ascent;
 		maxDescent =  descent;
@@ -632,15 +632,14 @@ bool TTFWriter::writeHmtx()
 			g->computeMetrics(xMin, xMax, yMin, yMax);
 			advance = (quint16)xMin;
 			lsb = (qint16)g->horizAdvX();
-			qint32 ascent = (qint32)yMax;
-			qint32 descent = (qint32)yMin;
-			quint32 advanceWidth = (quint32)g->horizAdvX();
-			qint32 rsb = (qint32)xMax;
-			qint32 extent = rsb; // FIXME is this correct?
+			qint16 ascent = (qint16)yMax;
+			qint16 descent = (qint16)yMin;
+			qint16 rsb = (qint16)xMax;
+			qint16 extent = rsb; // FIXME is this correct?
 
 			if (maxAscent < ascent) maxAscent = ascent;
 			if (maxDescent > descent) maxDescent = descent;
-			if (maxAdvanceWidth < advanceWidth) maxAdvanceWidth = advanceWidth;
+			if (maxAdvanceWidth < advance) maxAdvanceWidth = advance;
 			if (minLSB > lsb) minLSB = lsb;
 			if (minRSB > rsb) minRSB = rsb;
 			if (maxExtent < extent) maxExtent = extent;
@@ -666,14 +665,15 @@ bool TTFWriter::writeHhea()
 	buffer.open(QBuffer::WriteOnly);
 	bool ret = true;
 	ret = ret && writeBigEndian(&buffer, (qint32)0x00010000); // Version, 1.0
-	ret = ret && writeBigEndian(&buffer, (qint32)maxAscent); // Ascent
-	ret = ret && writeBigEndian(&buffer, (qint32)maxDescent); // Descent
-	ret = ret && writeBigEndian(&buffer, (qint32)0); // FIXME Line gap
-	ret = ret && writeBigEndian(&buffer, (quint32)maxAdvanceWidth); // Max advance width
-	ret = ret && writeBigEndian(&buffer, (qint32)minLSB); // Min left side bearing
-	ret = ret && writeBigEndian(&buffer, (qint32)minRSB); // Min right side bearing
-	ret = ret && writeBigEndian(&buffer, (qint32)maxExtent); // Max extent
+	ret = ret && writeBigEndian(&buffer, (qint16)maxAscent); // Ascent
+	ret = ret && writeBigEndian(&buffer, (qint16)maxDescent); // Descent
+	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Line gap
+	ret = ret && writeBigEndian(&buffer, (quint16)maxAdvanceWidth); // Max advance width
+	ret = ret && writeBigEndian(&buffer, (qint16)minLSB); // Min left side bearing
+	ret = ret && writeBigEndian(&buffer, (qint16)minRSB); // Min right side bearing
+	ret = ret && writeBigEndian(&buffer, (qint16)maxExtent); // Max extent
 	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Caret slope rise
+	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Caret slope run
 	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Caret offset
 	ret = ret && writeBigEndian(&buffer, (qint64)0); // Reserved
 	ret = ret && writeBigEndian(&buffer, (qint16)0); // Metric data format
diff --git a/nongui/ttfwriter.h b/nongui/ttfwriter.h
index 08cec6b..81eb78e 100644
--- a/nongui/ttfwriter.h
+++ b/nongui/ttfwriter.h
@@ -57,12 +57,12 @@ private:
 	int encodedGlyphsCount;
 
 	// some global maximums
-	qint32 maxAscent;
-	qint32 maxDescent;
-	quint32 maxAdvanceWidth;
-	qint32 minLSB;
-	qint32 minRSB;
-	qint32 maxExtent;
+	qint16 maxAscent;
+	qint16 maxDescent;
+	quint16 maxAdvanceWidth;
+	qint16 minLSB;
+	qint16 minRSB;
+	qint16 maxExtent;
 };
 
 #endif

commit 0ad53f62cf9786b1e3c9e2aa558413d70c71f2ad
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 17:54:49 2007 +0200

    make only coordinates of first point in a glyph relative to 0, not first point of each contour

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 221f8d7..9a466e2 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -372,8 +372,8 @@ bool TTFWriter::writeSimpleGlyph(QIODevice *dev, const Glyph *g)
 	// write coordiantes
 	// all coordinates are 16-bit for now
 	// start with x-coordinates
+	qint16 prev = 0;
 	foreach (QVariant v, g->content) {
-		qint16 prev = 0;
 		Contour c = v.value<Contour>();
 		// XXX FIXME coordinates should be relative!
 		foreach (const GlyphPoint &pt, c) {
@@ -384,8 +384,8 @@ bool TTFWriter::writeSimpleGlyph(QIODevice *dev, const Glyph *g)
 		}
 	}
 	// and y-coordinates
+	prev = 0;
 	foreach (QVariant v, g->content) {
-		qint16 prev = 0;
 		Contour c = v.value<Contour>();
 		foreach (const GlyphPoint &pt, c) {
 			qint16 thisPoint =  (qint16)pt.y();

commit f4c531fb479c4d79041b58eabfc754f5bdd33114
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 17:49:56 2007 +0200

    write hmtx and hhea tables

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 8deb8a1..221f8d7 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -114,6 +114,14 @@ bool TTFWriter::write(QIODevice *dev)
 		qDebug() << "writePost failed";
 		goto fail;
 	}
+	if (!writeHmtx()) {
+		qDebug() << "writeHmtx failed";
+		goto fail;
+	}
+	if (!writeHhea()) {
+		qDebug() << "writeHhea failed";
+		goto fail;
+	}
 	{
 		// TODO other tables, check order
 		buf.open(QBuffer::WriteOnly);
@@ -241,6 +249,31 @@ bool TTFWriter::writeGlyphs()
 	glyfBuffer.open(QBuffer::WriteOnly);
 	locaBuffer.open(QBuffer::WriteOnly);
 
+	// calculate initial value for maximums
+	const Glyph *firstGlyph = sortedGlyphs.at(0);
+	if (!firstGlyph && sortedGlyphs.size() > 1)
+		firstGlyph = sortedGlyphs.at(1);
+	if (firstGlyph) {
+		qreal xMin, xMax, yMin, yMax;
+		firstGlyph->computeMetrics(xMin, xMax, yMin, yMax);
+		qint32 ascent = (qint32)yMax;
+		qint32 descent = (qint32)yMin;
+		quint32 advanceWidth = (quint32)firstGlyph->horizAdvX();
+		qint32 lsb = (qint32)xMin;
+		qint32 rsb = (qint32)xMax;
+		qint32 extent = rsb; // FIXME is this correct?
+
+		maxAscent = ascent;
+		maxDescent =  descent;
+		maxAdvanceWidth = advanceWidth;
+		minLSB = lsb;
+		minRSB = rsb;
+		maxExtent = extent;
+	}
+	else {
+		maxAscent = maxDescent = maxAdvanceWidth = minLSB = minRSB = maxExtent = 0;
+	}
+
 	foreach (const Glyph *g, sortedGlyphs) {
 		// write offset of the glyphs into loca table
 		if (!writeBigEndian(&locaBuffer, (quint32)glyfBuffer.pos()))
@@ -580,3 +613,75 @@ void TTFWriter::createGlyphList()
 	sortedGlyphs << unencoded;
 	encodedGlyphsCount = encoded.size();
 }
+
+bool TTFWriter::writeHmtx()
+{
+	// TODO maybe move this into writeGlyphs()?
+	QByteArray tbl;
+	QBuffer buffer(&tbl);
+
+	buffer.open(QBuffer::WriteOnly);
+
+	foreach (const Glyph *g, sortedGlyphs) {
+		bool ret = true;
+		quint16 advance = 0;
+		qint16 lsb = 0;
+
+		if (g) {
+			qreal xMin, xMax, yMin, yMax;
+			g->computeMetrics(xMin, xMax, yMin, yMax);
+			advance = (quint16)xMin;
+			lsb = (qint16)g->horizAdvX();
+			qint32 ascent = (qint32)yMax;
+			qint32 descent = (qint32)yMin;
+			quint32 advanceWidth = (quint32)g->horizAdvX();
+			qint32 rsb = (qint32)xMax;
+			qint32 extent = rsb; // FIXME is this correct?
+
+			if (maxAscent < ascent) maxAscent = ascent;
+			if (maxDescent > descent) maxDescent = descent;
+			if (maxAdvanceWidth < advanceWidth) maxAdvanceWidth = advanceWidth;
+			if (minLSB > lsb) minLSB = lsb;
+			if (minRSB > rsb) minRSB = rsb;
+			if (maxExtent < extent) maxExtent = extent;
+		}
+		
+		ret = ret && writeBigEndian(&buffer, advance); // Advance width
+		ret = ret && writeBigEndian(&buffer, lsb); // Left side bearing //FIXME is it correct?
+		if (!ret)
+			return false;
+	}
+
+	buffer.close();
+	appendTable(makeTag('h', 'm', 't', 'x'), tbl);
+
+	return true;
+}
+
+bool TTFWriter::writeHhea()
+{
+	QByteArray tbl;
+	QBuffer buffer(&tbl);
+
+	buffer.open(QBuffer::WriteOnly);
+	bool ret = true;
+	ret = ret && writeBigEndian(&buffer, (qint32)0x00010000); // Version, 1.0
+	ret = ret && writeBigEndian(&buffer, (qint32)maxAscent); // Ascent
+	ret = ret && writeBigEndian(&buffer, (qint32)maxDescent); // Descent
+	ret = ret && writeBigEndian(&buffer, (qint32)0); // FIXME Line gap
+	ret = ret && writeBigEndian(&buffer, (quint32)maxAdvanceWidth); // Max advance width
+	ret = ret && writeBigEndian(&buffer, (qint32)minLSB); // Min left side bearing
+	ret = ret && writeBigEndian(&buffer, (qint32)minRSB); // Min right side bearing
+	ret = ret && writeBigEndian(&buffer, (qint32)maxExtent); // Max extent
+	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Caret slope rise
+	ret = ret && writeBigEndian(&buffer, (qint16)0); // FIXME Caret offset
+	ret = ret && writeBigEndian(&buffer, (qint64)0); // Reserved
+	ret = ret && writeBigEndian(&buffer, (qint16)0); // Metric data format
+	ret = ret && writeBigEndian(&buffer, (quint16)sortedGlyphs.size()); // Number of advance widths in metrics table
+
+	buffer.close();
+	if (ret)
+		appendTable(makeTag('h', 'h', 'e', 'a'), tbl);
+
+	return ret;
+}
diff --git a/nongui/ttfwriter.h b/nongui/ttfwriter.h
index 653e212..08cec6b 100644
--- a/nongui/ttfwriter.h
+++ b/nongui/ttfwriter.h
@@ -40,6 +40,8 @@ private:
 	bool writeCmap();
 	bool writeName();
 	bool writePost();
+	bool writeHmtx();
+	bool writeHhea();
 
 	bool writeCompositeGlyph(QIODevice *dev, const Glyph *g);
 	bool writeSimpleGlyph(QIODevice *dev, const Glyph *g);
@@ -53,6 +55,14 @@ private:
 
 	QList<const Glyph *> sortedGlyphs;
 	int encodedGlyphsCount;
+
+	// some global maximums
+	qint32 maxAscent;
+	qint32 maxDescent;
+	quint32 maxAdvanceWidth;
+	qint32 minLSB;
+	qint32 minRSB;
+	qint32 maxExtent;
 };
 
 #endif

commit 54f01cf8f248839e0b30be90cc5809eeb4fa6444
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 16:38:24 2007 +0200

    fix calculations for TTF header

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 2b1aeb6..8deb8a1 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -30,6 +30,23 @@ static inline quint32 makeTag(unsigned char a, unsigned char b,
 	return (a << 24) + (b << 16) + (c << 8) + d;
 }
 
+// TODO it should be possible to optimize it with GCC extensions
+template <typename T>
+static inline T integerLog2(T v)
+{
+	T ret = 0;
+
+	for (T i = v / 2; i; i /= 2)
+		ret++;
+	return ret;
+}
+
+template <typename T>
+static inline T maxPowerOfTwo(T v)
+{
+	return 1 << integerLog2(v);
+}
+
 TTFWriter::TTFWriter(const FontDocument *doc) : m_doc(doc)
 {
 	Q_ASSERT(m_doc);
@@ -101,14 +118,9 @@ bool TTFWriter::write(QIODevice *dev)
 		// TODO other tables, check order
 		buf.open(QBuffer::WriteOnly);
 
-		quint16 searchRange = 0;
 		quint16 nTables = tables.size();
-		for (int i = nTables / 2; i; i /= 2)
-			searchRange++;
-		quint16 entrySelector = 0;
-		for (int i = searchRange / 2; i; i /= 2)
-			entrySelector++;
-		searchRange *= 16;
+		quint16 searchRange = maxPowerOfTwo(nTables) * 16;
+		quint16 entrySelector = integerLog2(nTables);
 		quint16 rangeShift = nTables * 16 - searchRange;
 
 		bool ret = true;
@@ -373,7 +385,7 @@ bool TTFWriter::writeMaxp()
 
 	bool ret = true;
 	ret = ret && writeBigEndian(&buffer, (qint32)0x00010000); // Table version
-	ret = ret && writeBigEndian(&buffer, (qint16)sortedGlyphs.size()); // number of glyphs // FIXME +1 is for .notdef
+	ret = ret && writeBigEndian(&buffer, (qint16)sortedGlyphs.size()); // number of glyphs
 	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

commit 734bf7bfb24368f1ca7f679c39c0e787f7597b1c
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date:   Fri Aug 31 16:17:31 2007 +0200

    remove comment

diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 271981d..2b1aeb6 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -499,7 +499,6 @@ bool TTFWriter::writePost()
 	QBuffer buffer(&tbl);
 
 	buffer.open(QBuffer::WriteOnly);
-	// TODO write real post table, or not?
 	bool ret = true;
 	ret = ret && writeBigEndian(&buffer, (quint32)0x00020000); // Table format
 	ret = ret && writeBigEndian(&buffer, (quint32)(m_doc->italicAngle() * 0x10000)); // Italic angle

-- 
Fondue Font Editor



More information about the fondue-commits mailing list