--- nono/util/ttfext/ttfext.cpp 2026/04/29 17:05:16 1.1.1.1 +++ nono/util/ttfext/ttfext.cpp 2026/04/29 17:05:27 1.1.1.2 @@ -21,6 +21,7 @@ #include #include #include +#include #include #define HOWMANY(x, y) (((x) + (y - 1)) / (y)) @@ -90,19 +91,19 @@ class File } // TTF はビッグエンディアンなので、専用読み込みルーチンを用意 - uint8 Read8() { + uint8 Read1() { uint8 buf[1]; Read(&buf, sizeof(buf)); return buf[0]; } - uint16 Read16() { + uint16 Read2() { uint8 buf[2]; Read(&buf, sizeof(buf)); return (buf[0] << 8) | buf[1]; } - uint32 Read32() { + uint32 Read4() { uint8 buf[4]; Read(&buf, sizeof(buf)); return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; @@ -501,11 +502,11 @@ TTFFile::Open(const File& file_) file = file_; // 先頭のファイルヘッダ(オフセットテーブルというらしい)は 12バイト - uint32 version = file.Read32(); - uint32 numTables = file.Read16(); - uint32 searchRange __unused = file.Read16(); - uint32 entrySelector __unused = file.Read16(); - uint32 rangeShift __unused = file.Read16(); + uint32 version = file.Read4(); + uint32 numTables = file.Read2(); + uint32 searchRange __unused = file.Read2(); + uint32 entrySelector __unused = file.Read2(); + uint32 rangeShift __unused = file.Read2(); if (debug) { printf("version = %08x\n", version); printf("numTables = %d\n", numTables); @@ -513,10 +514,10 @@ TTFFile::Open(const File& file_) // テーブルを調べて、必要なセクションの開始位置を取得 for (int i = 0; i < numTables; i++) { - uint32_t namecc = file.Read32(); - uint32_t csum = file.Read32(); - uint32_t offset = file.Read32(); - uint32_t len = file.Read32(); + uint32_t namecc = file.Read4(); + uint32_t csum = file.Read4(); + uint32_t offset = file.Read4(); + uint32_t len = file.Read4(); (void)csum; @@ -683,7 +684,7 @@ TTFFile::LoadGlyphFormat1_7(const IndexS int nbit = 0; for (int j = 0; j < bytelen; j++) { // 入力キューに下から詰めていく - input = (input << 8) | file.Read8(); + input = (input << 8) | file.Read1(); nbit += 8; // 1ライン分を超えてる間切り出す while (nbit >= width) { @@ -760,7 +761,7 @@ TTFFile::LoadGlyphFormat2_5(const IndexS int nbit = 0; // input 内の有効ビット for (int j = 0; j < bytes; j++) { // 入力キューに下から詰めていく - input = (input << 8) | file.Read8(); + input = (input << 8) | file.Read1(); nbit += 8; // 1ライン分を超えたら切り出す if (nbit >= width) { @@ -1033,19 +1034,19 @@ TTFFile::MakeChar(uint code, int w, int TTF_name::TTF_name(File& file, off_t offset_name) { file.Seek(offset_name); - uint32 version = file.Read16(); - uint32 count = file.Read16(); - uint32 storageOffset = file.Read16(); + uint32 version = file.Read2(); + uint32 count = file.Read2(); + uint32 storageOffset = file.Read2(); nameRecord.resize(count); for (int i = 0; i < count; i++) { auto& rec = nameRecord[i]; - rec.platformID = file.Read16(); - rec.encodingID = file.Read16(); - rec.languageID = file.Read16(); - rec.nameID = file.Read16(); - rec.length = file.Read16(); - rec.stringOffset = file.Read16(); + rec.platformID = file.Read2(); + rec.encodingID = file.Read2(); + rec.languageID = file.Read2(); + rec.nameID = file.Read2(); + rec.length = file.Read2(); + rec.stringOffset = file.Read2(); } for (auto& rec : nameRecord) { file.Seek(offset_name + storageOffset + rec.stringOffset); @@ -1053,13 +1054,13 @@ TTF_name::TTF_name(File& file, off_t off // UTF-16BE エンコーディングと規定されている std::vector src(rec.length); for (int j = 0; j < rec.length; j++) { - src[j] = file.Read8(); + src[j] = file.Read1(); } rec.name = FromUTF16("utf-16be", src); } else { // とりあえず ASCII だと思ってそのまま使う for (int j = 0; j < rec.length; j++) { - rec.name += (char)file.Read8(); + rec.name += (char)file.Read1(); } } } @@ -1131,12 +1132,12 @@ TTF_EBLC::TTF_EBLC(const File& file_, of // numSizes フィールドの次から、BitmapSize が numSizes 個並んでるっぽい。 file.Seek(offset_EBLC); - auto majorVersion = file.Read16(); - auto minorVersion = file.Read16(); + auto majorVersion = file.Read2(); + auto minorVersion = file.Read2(); if (majorVersion != 2 || minorVersion != 0) { errx(1, "Unknown EBLC version %d.%d", majorVersion, minorVersion); } - uint32 numSizes = file.Read32(); + uint32 numSizes = file.Read4(); if (debug) { printf("EBLC.numSizes=%d\n", numSizes); } @@ -1145,18 +1146,18 @@ TTF_EBLC::TTF_EBLC(const File& file_, of bitmapSizes.resize(numSizes); for (int i = 0; i < numSizes; i++) { auto& bs = bitmapSizes[i]; - bs.indexSubTableArrayOffset = file.Read32(); - bs.indexTablesSize = file.Read32(); - bs.numberOfIndexSubTables = file.Read32(); - bs.colorRef = file.Read32(); + bs.indexSubTableArrayOffset = file.Read4(); + bs.indexTablesSize = file.Read4(); + bs.numberOfIndexSubTables = file.Read4(); + bs.colorRef = file.Read4(); bs.hori.Load(file); bs.vert.Load(file); - bs.startGlyphIndex = file.Read16(); - bs.endGlyphIndex = file.Read16(); - bs.ppemX = file.Read8(); - bs.ppemY = file.Read8(); - bs.bitDepth = file.Read8(); - bs.flags = file.Read8(); + bs.startGlyphIndex = file.Read2(); + bs.endGlyphIndex = file.Read2(); + bs.ppemX = file.Read1(); + bs.ppemY = file.Read1(); + bs.bitDepth = file.Read1(); + bs.flags = file.Read1(); if (debug) { printf("bitmapSizes[%d]\n", i); #define A(fmt, name) printf(" %-24s = " #fmt "\n", #name, bs.name) @@ -1236,9 +1237,9 @@ TTF_EBLC::TTF_EBLC(const File& file_, of file.Seek(offset_EBLC + bs.indexSubTableArrayOffset); for (int j = 0; j < bs.numberOfIndexSubTables; j++) { auto& sub = bs.indexSubTable[j]; - sub.firstGlyphIndex = file.Read16(); - sub.lastGlyphIndex = file.Read16(); - sub.additionalOffsetToIndexSubTable = file.Read32(); + sub.firstGlyphIndex = file.Read2(); + sub.lastGlyphIndex = file.Read2(); + sub.additionalOffsetToIndexSubTable = file.Read4(); if (debug) { printf("indexSubTable[%d] GlyphIndex=%4d-%4d " "additionalOffsetToIndexSubTable=$%08x\n", j, @@ -1254,9 +1255,9 @@ TTF_EBLC::TTF_EBLC(const File& file_, of + bs.indexSubTableArrayOffset + sub.additionalOffsetToIndexSubTable); // ここが indexSubType header - sub.indexFormat = file.Read16(); - sub.imageFormat = file.Read16(); - sub.imageDataOffset = file.Read32(); + sub.indexFormat = file.Read2(); + sub.imageFormat = file.Read2(); + sub.imageDataOffset = file.Read4(); if (debug) { printf("[%d] indexFormat=%d imageFormat=%d " "imageDataOffset=$%08x\n", @@ -1276,7 +1277,7 @@ TTF_EBLC::TTF_EBLC(const File& file_, of int nglyph = sub.lastGlyphIndex - sub.firstGlyphIndex + 1; sub.sbitOffset.resize(nglyph); for (int i = 0; i < nglyph; i++) { - uint32 offset = file.Read32(); + uint32 offset = file.Read4(); sub.sbitOffset[i] = offset; if (debug) { printf(" %08x", offset); @@ -1296,7 +1297,7 @@ TTF_EBLC::TTF_EBLC(const File& file_, of // IndexSubType header; // uint32 imageSize; // BigGlyphMetrics bigMetrics; - sub.imageSize = file.Read32(); + sub.imageSize = file.Read4(); auto& big = sub.bigMetrics; big.Load(file); if (debug) { @@ -1329,8 +1330,8 @@ TTF_cmap::TTF_cmap(const File& file_, of // EncodingRecord encodingRecords[numTables]; file.Seek(offset); - uint16 version = file.Read16(); - uint16 numTables = file.Read16(); + uint16 version = file.Read2(); + uint16 numTables = file.Read2(); if (version != 0) { errx(1, "Unsupported cmap version %d\n", version); @@ -1340,9 +1341,9 @@ TTF_cmap::TTF_cmap(const File& file_, of encodingRecords.resize(numTables); for (int i = 0; i < encodingRecords.size(); i++) { auto& enc = encodingRecords[i]; - enc.platformID = file.Read16(); - enc.encodingID = file.Read16(); - enc.subtableOffset = file.Read32(); + enc.platformID = file.Read2(); + enc.encodingID = file.Read2(); + enc.subtableOffset = file.Read4(); if (debug) { printf("[%d] %s subtableOffset=%08x\n", i, @@ -1365,13 +1366,13 @@ TTF_cmap::TTF_cmap(const File& file_, of // Unicode2.0 BMP の場合 offset の先は Format4 らしい。 // subtableOffset は cmap 先頭からのオフセット。 off_t tablestart = file.Seek(offset + uenc->subtableOffset); - sub.format = file.Read16(); - sub.length = file.Read16(); - sub.language = file.Read16(); - sub.segCountX2 = file.Read16(); - sub.searchRange = file.Read16(); - sub.entrySelector = file.Read16(); - sub.rangeShift = file.Read16(); + sub.format = file.Read2(); + sub.length = file.Read2(); + sub.language = file.Read2(); + sub.segCountX2 = file.Read2(); + sub.searchRange = file.Read2(); + sub.entrySelector = file.Read2(); + sub.rangeShift = file.Read2(); int segCount = sub.segCountX2 / 2; sub.endCode.resize(segCount); @@ -1380,24 +1381,24 @@ TTF_cmap::TTF_cmap(const File& file_, of sub.idRangeOffsets.resize(segCount); for (int i = 0; i < segCount; i++) { - sub.endCode[i] = file.Read16(); + sub.endCode[i] = file.Read2(); } - file.Read16(); // reservedPad + file.Read2(); // reservedPad for (int i = 0; i < segCount; i++) { - sub.startCode[i] = file.Read16(); + sub.startCode[i] = file.Read2(); } for (int i = 0; i < segCount; i++) { - sub.idDelta[i] = file.Read16(); + sub.idDelta[i] = file.Read2(); } for (int i = 0; i < segCount; i++) { - sub.idRangeOffsets[i] = file.Read16(); + sub.idRangeOffsets[i] = file.Read2(); } // glyphIdArray[] の長さは直接は書いてないが、sub.length が // (たぶん subtable 先頭からの) subtable のバイト長らしいので、そこまで。 int remain = sub.length - (file.Tell() - tablestart); sub.glyphIdArray.resize(remain / 2); for (int i = 0; i < remain / 2; i++) { - sub.glyphIdArray[i] = file.Read16(); + sub.glyphIdArray[i] = file.Read2(); } if (debug) { @@ -1529,32 +1530,32 @@ TTF_cmap::Code2GID(int code) const void BigGlyphMetrics::Load(File& file) { - height = file.Read8(); - width = file.Read8(); - horiBearingX = file.Read8(); - horiBearingY = file.Read8(); - horiAdvance = file.Read8(); - vertBearingX = file.Read8(); - vertBearingY = file.Read8(); - vertAdvance = file.Read8(); + height = file.Read1(); + width = file.Read1(); + horiBearingX = file.Read1(); + horiBearingY = file.Read1(); + horiAdvance = file.Read1(); + vertBearingX = file.Read1(); + vertBearingY = file.Read1(); + vertAdvance = file.Read1(); } // SbitLineMetrics を読み込む。file は更新される。 void SbitLineMetrics::Load(File& file) { - ascender = file.Read8(); - descender = file.Read8(); - widthMax = file.Read8(); - caretSlopeNumerator = file.Read8(); - caretSlopeDenominator = file.Read8(); - caretOffset = file.Read8(); - minOriginSB = file.Read8(); - minAdvanceSB = file.Read8(); - maxBeforeBL = file.Read8(); - minAfterBL = file.Read8(); - pad1 = file.Read8(); - pad2 = file.Read8(); + ascender = file.Read1(); + descender = file.Read1(); + widthMax = file.Read1(); + caretSlopeNumerator = file.Read1(); + caretSlopeDenominator = file.Read1(); + caretOffset = file.Read1(); + minOriginSB = file.Read1(); + minAdvanceSB = file.Read1(); + maxBeforeBL = file.Read1(); + minAfterBL = file.Read1(); + pad1 = file.Read1(); + pad2 = file.Read1(); } // NameRecord.NameID の名前を文字列で返す