[fondue-commits] [SCM] Fondue Font Editor branch, master, updated. 27cf9e647f964aa8405f8f640064c8a4bf67a88f
Eugeniy Meshcheryakov
eugen at debian.org
Fri Aug 31 20:12:47 UTC 2007
The branch, master has been updated
via 27cf9e647f964aa8405f8f640064c8a4bf67a88f (commit)
from 4d21308791bbc7e5a917cda8941a114d9c4e9c68 (commit)
- Shortlog ------------------------------------------------------------
27cf9e6 generate type 4 and (if needed) type 12 cmaps
Summary of changes:
nongui/ttfwriter.cxx | 103 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 92 insertions(+), 11 deletions(-)
-----------------------------------------------------------------------
Details of changes:
commit 27cf9e647f964aa8405f8f640064c8a4bf67a88f
Author: Eugeniy Meshcheryakov <eugen at debian.org>
Date: Fri Aug 31 22:12:36 2007 +0200
generate type 4 and (if needed) type 12 cmaps
diff --git a/nongui/ttfwriter.cxx b/nongui/ttfwriter.cxx
index 266142f..5ed9752 100644
--- a/nongui/ttfwriter.cxx
+++ b/nongui/ttfwriter.cxx
@@ -472,35 +472,116 @@ bool TTFWriter::writeHead()
return ret;
}
+struct TTUnicodeRange {
+ unsigned first;
+ unsigned last;
+ quint16 glyph;
+};
+
bool TTFWriter::writeCmap()
{
// XXX TODO writes minimal cmap
+ QList<TTUnicodeRange> ranges;
+ unsigned nBMP = 0; // number of ranges in BMP, at least partly
+ bool hasNonBMP = false; // if true, font needs additional type 12 cmap
+ bool has0xFFFF = false;
+ if (encodedGlyphsCount) {
+ TTUnicodeRange range;
+ range.first = range.last = sortedGlyphs.at(1)->unicode();
+ range.glyph = 1;
+ if (range.first < 0x10000)
+ nBMP++;
+
+ for (int i = 2; i <= encodedGlyphsCount; i++) {
+ unsigned u = sortedGlyphs.at(i)->unicode();
+ if (u == 0xFFFF)
+ has0xFFFF = true;
+ if (u == range.last + 1)
+ range.last += 1;
+ else {
+ ranges << range;
+ range.first = range.last = u;
+ range.glyph = i;
+ if (range.first < 0x10000)
+ nBMP++;
+ }
+ }
+ ranges << range;
+ if (range.last > 0xFFFF)
+ hasNonBMP = true;
+ }
+
QByteArray tbl;
QBuffer buffer(&tbl);
buffer.open(QBuffer::WriteOnly);
+ quint16 nSubtables = hasNonBMP? 2 : 1;
+ quint16 type4SegCount = has0xFFFF ? nBMP : nBMP + 1;
+ quint32 type4CmapOffset = 4 /* header */ + 8 * nSubtables /* subtables */;
+ quint16 type4Length = 16 /* fixed part of type4 cmap */ + 8 * type4SegCount;
+ quint32 type12CmapOffset = type4CmapOffset + type4Length;
+
+ quint16 type4SearchRange = 2 * maxPowerOfTwo(type4SegCount);
+ quint16 type4EntrySelector = integerLog2(type4SearchRange / 2);
+ quint16 type4RangeShift = 2 * type4SegCount - type4SearchRange;
+
bool ret = true;
// Table header
ret = ret && writeBigEndian(&buffer, (quint16)0); // Version
- ret = ret && writeBigEndian(&buffer, (quint16)1); // FIXME Number of subtables
+ ret = ret && writeBigEndian(&buffer, (quint16)nSubtables); // FIXME Number of subtables
// Subtables
ret = ret && writeBigEndian(&buffer, (quint16)3); // Platform ID, 3 - MS
ret = ret && writeBigEndian(&buffer, (quint16)1); // Encoding ID, 1 - Unicode
- ret = ret && writeBigEndian(&buffer, (quint32)12); // FIXME offset of cmap
+ ret = ret && writeBigEndian(&buffer, (quint32)type4CmapOffset); // Offset of cmap
+ if (hasNonBMP) {
+ ret = ret && writeBigEndian(&buffer, (quint16)3); // Platform ID, 3 - MS
+ ret = ret && writeBigEndian(&buffer, (quint16)10); // Encoding ID, 10 - UCS-4
+ ret = ret && writeBigEndian(&buffer, (quint32)type12CmapOffset); // Offset of cmap
+ }
// Type 4 cmap
ret = ret && writeBigEndian(&buffer, (quint16)4); // cmap format
- ret = ret && writeBigEndian(&buffer, (quint16)24); // FIXME Length
+ ret = ret && writeBigEndian(&buffer, (quint16)type4Length); // Length
ret = ret && writeBigEndian(&buffer, (quint16)0); // Language
- ret = ret && writeBigEndian(&buffer, (quint16)2); // FIXME 2 * SegCount
- ret = ret && writeBigEndian(&buffer, (quint16)4); // FIXME Search range
- ret = ret && writeBigEndian(&buffer, (quint16)1); // FIXME Entry selector
- ret = ret && writeBigEndian(&buffer, (quint16)0); // FIXME Range shift
- ret = ret && writeBigEndian(&buffer, (quint16)0xFFFF); // End code
+ ret = ret && writeBigEndian(&buffer, (quint16)(2 * type4SegCount)); // 2 * SegCount
+ ret = ret && writeBigEndian(&buffer, (quint16)type4SearchRange); // Search range
+ ret = ret && writeBigEndian(&buffer, (quint16)type4EntrySelector); // Entry selector
+ ret = ret && writeBigEndian(&buffer, (quint16)type4RangeShift); // Range shift
+ // End codes
+ for (unsigned i = 0; i < nBMP; i++)
+ ret = ret && writeBigEndian(&buffer,
+ (quint16)(ranges.at(i).last > 0xFFFF ? 0xFFFF : ranges.at(i).last));
+ if (!has0xFFFF)
+ ret = ret && writeBigEndian(&buffer, (quint16)0xFFFF);
ret = ret && writeBigEndian(&buffer, (quint16)0); // Reserved
- ret = ret && writeBigEndian(&buffer, (quint16)0xFFFF); // Start code
- ret = ret && writeBigEndian(&buffer, (quint16)1); // FIXME ID delta
- ret = ret && writeBigEndian(&buffer, (quint16)0); // FIXME ID range offset
+ // Start Codes
+ for (unsigned i = 0; i < nBMP; i++)
+ ret = ret && writeBigEndian(&buffer, (quint16)ranges.at(i).first);
+ if (!has0xFFFF)
+ ret = ret && writeBigEndian(&buffer, (quint16)0xFFFF);
+ // ID Delta
+ for (unsigned i = 0; i < nBMP; i++)
+ ret = ret && writeBigEndian(&buffer, (quint16)(ranges.at(i).glyph - ranges.at(i).first));
+ if (!has0xFFFF)
+ ret = ret && writeBigEndian(&buffer, (quint16)1);
+ for (unsigned i = 0; i < type4SegCount; i++)
+ ret = ret && writeBigEndian(&buffer, (quint16)0); // ID range offset
+ if (ret)
+ Q_ASSERT(buffer.pos() == type4CmapOffset + type4Length); // FIXME remove or check for overflows
+
+ if (hasNonBMP) {
+ // type 12 cmap
+ ret = ret && writeBigEndian(&buffer, (quint32)0x000C0000); // Format, 12.0
+ ret = ret && writeBigEndian(&buffer, (quint32)(ranges.size() * 12 + 16)); // Length
+ ret = ret && writeBigEndian(&buffer, (quint32)0); // Language, 0 - don't care
+ ret = ret && writeBigEndian(&buffer, (quint32)ranges.size()); // Number of groups
+ foreach (const TTUnicodeRange &r, ranges) {
+ ret = ret && writeBigEndian(&buffer, (quint32)r.first);
+ ret = ret && writeBigEndian(&buffer, (quint32)r.last);
+ ret = ret && writeBigEndian(&buffer, (quint32)r.glyph);
+ }
+ }
+
buffer.close();
if (ret)
appendTable(makeTag('c', 'm', 'a', 'p'), tbl);
--
Fondue Font Editor
More information about the fondue-commits
mailing list