/archive/olddraw/PdfDraw/TTFReader.cpp
C++ | 311 lines | 271 code | 38 blank | 2 comment | 54 complexity | a056d2c5e158ac36422a71c4a4baf1b5 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, BSD-2-Clause, BSD-3-Clause, LGPL-3.0, GPL-3.0
- #include "PdfDraw.h"
- NAMESPACE_UPP
- #define LLOG(x) // LOG(x)
- #define LDUMP(x) // LLOG(#x << " = " << x);
- int TTFReader::Peek8(const char *s)
- {
- if(s + 1 > font.End())
- Error();
- return (byte)*s;
- }
- int TTFReader::Peek16(const char *s)
- {
- if(s + 2 > font.End())
- Error();
- return ((byte)s[0] << 8) | (byte)s[1];
- }
- int TTFReader::Peek32(const char *s)
- {
- if(s + 4 > font.End())
- Error();
- return ((byte)s[0] << 24) | ((byte)s[1] << 16) | ((byte)s[2] << 8) | (byte)s[3];
- }
- int TTFReader::Peek8(const char *s, int i)
- {
- return Peek16(s + i);
- }
- int TTFReader::Peek16(const char *s, int i)
- {
- return Peek16(s + 2 * i);
- }
- int TTFReader::Peek32(const char *s, int i)
- {
- return Peek32(s + 4 * i);
- }
- int TTFReader::Read8(const char *&s)
- {
- int q = byte(*s); s++; return q;
- }
- int TTFReader::Read16(const char *&s)
- {
- int q = Peek16(s); s += 2; return q;
- }
- int TTFReader::Read32(const char *&s)
- {
- int q = Peek32(s); s += 4; return q;
- }
- String TTFReader::Read(const char *&s, int n)
- {
- if(s + n > font.End())
- Error();
- String q(s, n);
- s += n;
- return q;
- }
- void TTFReader::Reset()
- {
- memset(zero, 0, sizeof(zero));
- for(int i = 0; i < 256; i++)
- cmap[i] = zero;
- }
- void TTFReader::Free()
- {
- for(int i = 0; i < 256; i++)
- if(cmap[i] != zero)
- delete[] cmap[i];
- }
- void TTFReader::SetGlyph(wchar chr, word glyph)
- {
- int h = HIBYTE(chr);
- if(cmap[h] == zero)
- memset(cmap[h] = new word[256], 0, 256 * sizeof(word));
- cmap[h][LOBYTE(chr)] = glyph;
- }
- const char *TTFReader::Seek(const char *tab, int& len)
- {
- ASSERT(strlen(tab) == 4);
- int q = table.Find(tab);
- if(q < 0)
- Error();
- len = table[q].length;
- return ~font + table[q].offset;
- }
- const char *TTFReader::Seek(const char *tab)
- {
- int dummy;
- return Seek(tab, dummy);
- }
- void TTFReader::Seek(const char *tab, TTFStreamIn& s)
- {
- int len;
- s.beg = s.s = Seek(tab, len);
- s.lim = s.s + len;
- }
- String TTFReader::GetTable(const char *tab)
- {
- ASSERT(strlen(tab) == 4);
- int q = table.Find(tab);
- if(q < 0)
- return Null;
- return String(~font + table[q].offset, table[q].length);
- }
- bool TTFReader::Open(const String& fnt, bool symbol, bool justcheck)
- {
- try {
- int i;
- Free();
- Reset();
- table.Clear();
- glyphinfo.Clear();
- font = fnt;
- const char *s = fnt;
- int q = Read32(s);
- if(q != 0x74727565 && q != 0x00010000)
- Error();
- int n = Read16(s);
- s += 6;
- while(n--) {
- Table& t = table.Add(Read(s, 4));
- s += 4;
- t.offset = Read32(s);
- t.length = Read32(s);
- }
- for(i = 0; i < table.GetCount(); i++)
- LLOG("table: " << table.GetKey(i) << " offset: " << table[i].offset << " length: " << table[i].length);
- TTFStreamIn is;
- Seek("head", is);
- head.Serialize(is);
- if(head.magicNumber != 0x5F0F3CF5)
- Error();
- LDUMP(head.unitsPerEm);
- LDUMP(head.xMin);
- LDUMP(head.yMin);
- LDUMP(head.xMax);
- LDUMP(head.yMax);
- LDUMP(head.indexToLocFormat);
- Seek("maxp", is);
- maxp.Serialize(is);
- LDUMP(maxp.numGlyphs);
- Seek("post", is);
- post.Serialize(is);
- // LLOGHEXLDUMP(is.s, is.lim - is.s);
- LDUMP((post.format >> 16));
- LDUMP(post.italicAngle);
- LDUMP(post.italicAngle);
- LDUMP(post.underlinePosition);
- LDUMP(post.underlineThickness);
- LDUMP(post.italicAngle);
- if(justcheck)
- return true;
- Seek("hhea", is);
- hhea.Serialize(is);
- LDUMP(hhea.ascent);
- LDUMP(hhea.descent);
- LDUMP(hhea.lineGap);
- LDUMP(hhea.advanceWidthMax);
- LDUMP(hhea.numOfLongHorMetrics);
- if(hhea.numOfLongHorMetrics > maxp.numGlyphs)
- Error();
- glyphinfo.SetCount(maxp.numGlyphs);
- s = Seek("hmtx");
- int aw = 0;
- for(i = 0; i < hhea.numOfLongHorMetrics; i++) {
- aw = glyphinfo[i].advanceWidth = (uint16)Read16(s);
- glyphinfo[i].leftSideBearing = (int16)Read16(s);
- }
- for(; i < maxp.numGlyphs; i++) {
- glyphinfo[i].advanceWidth = aw;
- glyphinfo[i].leftSideBearing = (int16)Read16(s);
- }
- s = Seek("loca");
- for(i = 0; i < maxp.numGlyphs; i++)
- if(head.indexToLocFormat) {
- glyphinfo[i].offset = Peek32(s, i);
- glyphinfo[i].size = Peek32(s, i + 1) - glyphinfo[i].offset;
- }
- else {
- glyphinfo[i].offset = 2 * (word)Peek16(s, i);
- glyphinfo[i].size = 2 * (word)Peek16(s, i + 1) - glyphinfo[i].offset;
- }
- for(i = 0; i < maxp.numGlyphs; i++)
- LLOG(i << " advance: " << glyphinfo[i].advanceWidth << ", left: " << glyphinfo[i].leftSideBearing
- << ", offset: " << glyphinfo[i].offset << ", size: " << glyphinfo[i].size);
- s = Seek("cmap");
- const char *p = s;
- p += 2;
- n = Read16(p);
- while(n--) {
- int pid = Read16(p);
- int psid = Read16(p);
- int offset = Read32(p);
- LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << Peek16(s + offset));
- //Test with Symbol font !!!; improve - Unicode first, 256 bytes later..., symbol...
- if(symbol) {
- if(pid == 1 && psid == 0 && Peek16(s + offset) == 0) {
- LLOG("Reading symbol table");
- p = s + offset + 6;
- for(int i = 0; i < 256; i++)
- SetGlyph(i, (byte)p[i]);
- break;
- }
- }
- else
- if(pid == 3 && psid == 1) {
- p = s + offset;
- n = Peek16(p + 6) >> 1;
- LLOG("Found UNICODE encoding, offset " << offset << ", segments " << n);
- const char *seg_end = p + 14;
- const char *seg_start = seg_end + 2 * n + 2;
- const char *idDelta = seg_start + 2 * n;
- const char *idRangeOffset = idDelta + 2 * n;
- for(int i = 0; i < n; i++) {
- int start = Peek16(seg_start, i);
- int end = Peek16(seg_end, i);
- int delta = Peek16(idDelta, i);
- int ro = Peek16(idRangeOffset, i);
- if (ro && delta == 0) {
- LLOG("RangeOffset start: " << start << ", end: " << end << ", delta: " << (int16)delta);
- LLOG("ro " << ro);
- const char *q = idRangeOffset + 2 * i + ro;
- for(int c = start; c <= end; c++) {
- SetGlyph(c, (word)Read16(q));
- }
- }
- else {
- LLOG("start: " << start << ", end: " << end << ", delta: " << (int16)delta);
- for(int c = start; c <= end; c++)
- SetGlyph(c, c + delta);
- }
- }
- break;
- }
- }
- const char *strings = Seek("name");
- s = strings + 2;
- int count = Read16(s);
- strings += (word)Read16(s);
- for(int i = 0; i < count; i++) {
- int platform = Read16(s);
- s += 4;
- if(Read16(s) == 6) {
- int len = Read16(s);
- int offset = Read16(s);
- if(platform == 1)
- ps_name = String(strings + offset, len);
- else {
- s = strings + offset;
- len >>= 1;
- while(len--)
- ps_name.Cat(Read16(s));
- }
- break;
- }
- s += 4;
- }
- LDUMP(ps_name);
- }
- catch(Fail) {
- return false;
- }
- catch(TTFStream::Fail) {
- return false;
- }
- return true;
- }
- TTFReader::TTFReader()
- {
- Reset();
- }
- TTFReader::~TTFReader()
- {
- Free();
- }
- END_UPP_NAMESPACE