#include "name.h" #include #include #include #include #include const std::map Name::nameIds({ { "copyright", 0 }, { "fontFamily", 1 }, { "fontSubfamily", 2 }, { "uniqueSubfamilyId", 3 }, { "fullFontName", 4 }, { "nameTableVersion", 5 }, { "postScriptName", 6 }, { "trademarkNotice", 7 }, { "manufacturerName", 8 }, { "designerName", 9 }, { "description", 10 }, { "vendorURL", 11 }, { "designerURL", 12 }, { "licenseDescription", 13 }, { "licenseURL", 14 }, { "preferredFamily", 16 }, { "preferredSubfamily", 17 }, { "compatibleFull", 18 }, { "sampleText", 19 }, { "postScriptCID", 20 } }); Name::Name(const std::string& p_tag, uint32_t p_checkSum, uint32_t p_offset, uint32_t p_length): Table(p_tag, p_checkSum, p_offset, p_length), names() { } Name::~Name() { } void Name::read(const std::string& path) { std::ifstream file(path, std::ios::in | std::ios::binary); file.seekg(offset); char * buffer; buffer = new char[2]; file.read(buffer, 2); //format. it is always 0 or 1 for stupid microsoft langTags, but I don't cate, gonna use offset; file.read(buffer, 2); uint16_t count = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint32_t storageOffset = offset + ntohs(*((uint16_t*) buffer)); std::list list; std::set ids; for (int i = 0; i < count; ++i) { file.read(buffer, 2); uint16_t pid = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint16_t eid = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint16_t lid = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint16_t nid = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint16_t length = ntohs(*((uint16_t*) buffer)); file.read(buffer, 2); uint16_t nameOffset = ntohs(*((uint16_t*) buffer)); //std::cout << "Found pid " << pid << ", eid " << eid << ", nid " << nid << std::endl; if (ids.find(nid) == ids.end()) { if ((pid == 0 && (eid == 3 || eid == 4)) || (pid == 3 && eid == 1)) { //screw microsoft, screw apple; list.emplace_back(pid, eid, lid, nid, length, nameOffset); ids.insert(nid); } } } std::list::const_iterator itr; for (itr = list.begin(); itr != list.end(); ++itr) { const NameRecord& nr = *itr; file.seekg(storageOffset + nr.offset); if ((nr.platformId == 0 && (nr.encodingId == 3 || nr.encodingId == 4)) || (nr.platformId == 3 && nr.encodingId == 1)) { char16_t buf[nr.length / 2]; for (int i = 0; i < nr.length / 2; ++i) { file.read(buffer, 2); buf[i] = ntohs(*((char16_t*) buffer)); } std::u16string string(buf, nr.length / 2); std::wstring_convert, char16_t> convert; names.insert(std::make_pair(nr.nameId, convert.to_bytes(string))); } } delete[] buffer; file.close(); } std::string Name::getRecord(uint16_t id) const { std::string res(""); std::map::const_iterator itr = names.find(id); if (itr != names.end()) { res = itr->second; } return res; } std::string Name::getRecord(const std::string& name) const { std::map::const_iterator itr = nameIds.find(name); if (itr == nameIds.end()) { return ""; } else { return getRecord(itr->second); } } NameRecord::NameRecord(uint16_t pid, uint16_t eid, uint16_t lid, uint16_t nid, uint16_t p_l, uint16_t p_o): platformId(pid), encodingId(eid), languageId(lid), nameId(nid), length(p_l), offset(p_o) { }