Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // copyright 2014 "aciddose"
- // made available under "DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004"
- // see: http://www.wtfpl.net/about/
- // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- // Version 2, December 2004
- //
- // Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
- //
- // Everyone is permitted to copy and distribute verbatim or modified
- // copies of this license document, and changing it is allowed as long
- // as the name is changed.
- //
- // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- //
- // 0. You just DO WHAT THE FUCK YOU WANT TO.
- // I modified the license text by inserting it in a comment. Arch-Rebel.
- #include <stdio.h>
- #include <stdint.h>
- #include <vector>
- #include <fstream>
- #include <assert.h>
- // yes, this code is "terrific".
- // no, not the modern slang. the literal definition of "terrific".
- // "terrific": 2. archaic: causing terror.
- // fix it if you don't like it, smart guy.
- struct file : public std::vector<char>
- {
- file(const char *filename)
- {
- std::ifstream f(filename, std::ifstream::binary);
- if (f.is_open()) {
- f.seekg(0, std::ios::end);
- resize(size_t(f.tellg()));
- f.seekg(0, std::ios::beg);
- f.read(data(), size());
- name = filename;
- } else {
- printf("failure loading file: %s\n", filename);
- assert(false);
- }
- }
- void write(const char *filename)
- {
- std::ofstream f(filename, std::ofstream::binary);
- if (f.is_open()) {
- f.write(data(), size());
- } else {
- printf("failure writing file: %s\n", filename);
- assert(false);
- }
- }
- const char *get_name() const
- {
- return name.c_str();
- }
- private:
- std::string name;
- };
- namespace ttf
- {
- typedef uint32_t u32;
- typedef uint16_t u16;
- typedef uint8_t u08;
- u32 swap(const u32 x)
- {
- return ((x >> 24) | ((x & 0x00FF0000) >> 8) | ((x & 0x0000FF00) << 8) | (x << 24));
- }
- u16 swap(const u16 x)
- {
- return ((x >> 8) | (x << 8));
- }
- struct header_t
- {
- void print(const char *indent) const;
- u32 version;
- u16 tables;
- u16 search;
- u16 select;
- u16 shift;
- };
- struct index_t
- {
- u08 id[4];
- u32 checksum;
- u32 offset;
- u32 length;
- };
- typedef std::vector<index_t *> directory_index;
- struct gasp_t
- {
- static void print(const char *indent, const char *p, int offset, int length)
- {
- const gasp_t *t = (gasp_t *)(p + offset);
- t->print(indent);
- }
- struct range_t
- {
- const char *get_behavior_string() const
- {
- static const char *str[] =
- {
- "none", "grid fit", "smoothing", "grid fit + smoothing",
- "symmetric grid fit", 0, 0, 0,
- "symmetric smoothing", 0, 0, 0,
- "symmetric grid fit + smoothing", 0, 0, 0,
- };
- const int i = swap(behavior);
- return (i >= 0 && i < 16 ? str[i] : "out of range behavior flag");
- }
- u16 max_ppem;
- u16 behavior;
- };
- const range_t &get_range(int i) const
- {
- assert(i >= 0);
- assert(i < swap(ranges));
- range_t *range = (range_t *)(this + 1);
- return range[i];
- }
- void print(const char *indent) const;
- u16 version;
- u16 ranges;
- };
- struct table_dat_t
- {
- typedef void(*print_table_func)(const char *indent, const char *p, int offset, int length);
- table_dat_t(const char *_id, const char *_desc, print_table_func _ptfunc = 0) :
- id(_id),
- description(_desc),
- print_table(_ptfunc)
- {
- }
- const char *id;
- const char *description;
- print_table_func print_table;
- };
- // do these strings cause any issue with copyright?
- // if so i suppose we can change these to various flavors
- // of cheese. although as descriptions of fact, i suspect not.
- table_dat_t tables[] =
- {
- // "required tables"
- table_dat_t("cmap", "character to glyph mapping"),
- table_dat_t("glyf", "glyph data"),
- table_dat_t("head", "font header"),
- table_dat_t("hhea", "horizontal header"),
- table_dat_t("hmtx", "horizontal metrics"),
- table_dat_t("loca", "index to location"),
- table_dat_t("maxp", "maximum profile"),
- table_dat_t("name", "naming"),
- table_dat_t("post", "postscript information"),
- table_dat_t("OS/2", "os/2 & windows specific metrics"),
- // "optional tables"
- table_dat_t("cvt ", "control values"),
- table_dat_t("EBDT", "bitmap data"),
- table_dat_t("EBLC", "bitmap location"),
- table_dat_t("EBSC", "bitmap scaling"),
- table_dat_t("fpgm", "font program"),
- table_dat_t("gasp", "grid-fitting and scan conversion procedure", &gasp_t::print),
- table_dat_t("hdmx", "horizontal device metrics"),
- table_dat_t("kern", "kerning"),
- table_dat_t("LTSH", "linear thresholds"),
- table_dat_t("prep", "CVT program"),
- table_dat_t("PCLT", "PCL5"),
- table_dat_t("VDMX", "vertical device metrics"),
- table_dat_t("vhea", "vertical metrics header"),
- table_dat_t("vmtx", "vertical metrics"),
- table_dat_t(0, 0),
- };
- table_dat_t *find_table_dat(std::string id)
- {
- for (int i = 0; tables[i].id; i++) {
- if (id.compare(tables[i].id) == 0) {
- return &tables[i];
- }
- }
- return 0;
- }
- #if 1
- // this is hopefully a proper replacement
- // which operates entirely within length
- u32 checksum(const char *p, int length)
- {
- const u08 *table = (u08 *)p;
- u32 sum = 0;
- u32 data = 0;
- int i = 0;
- for (; i < length; i++) {
- data = (data << 8) | table[i];
- if ((i & 3) == 3) {
- sum += data;
- data = 0;
- }
- }
- // zero pad the remaining bytes
- //ad::u32 good_data = swap(*(ad::u32 *)&table[i&~3]);
- sum += data << (8 * (4 - (length & 3)));
- return sum;
- }
- #else
- // this method is "dumb" in that it may access data outside the specified 'length'.
- // to work at all, relies upon chunks being aligned and padded to dwords.
- u32 checksum(const char *p, int length)
- {
- const u32 *table = (u32 *)p;
- const u32 *end = table + ((length + 3) & ~3) / sizeof(u32);
- u32 sum = 0;
- while (table < end) {
- sum += swap(*table++);
- }
- return sum;
- }
- #endif
- };
- void ttf::header_t::print(const char *indent) const
- {
- printf("%sversion %i.%i\n", indent, version>>8, version&0xFF);
- printf("%stables %i\n", indent, swap(tables));
- printf("%ssearch %i\n", indent, swap(search));
- printf("%sselect %i\n", indent, swap(select));
- printf("%sshift %i\n", indent, swap(shift));
- }
- void ttf::gasp_t::print(const char *indent) const
- {
- printf("%sversion %i\n", indent, swap(version));
- printf("%sranges %i\n", indent, swap(ranges));
- const int _ranges = swap(ranges);
- for (int i = 0; i < _ranges; i++) {
- const gasp_t::range_t &range = get_range(i);
- // force to anti-aliasing
- //range.behavior = 3;
- const int max_ppem = swap(range.max_ppem);
- printf("%s\t%i: %-5i %s\n", indent, i + 1, max_ppem, range.get_behavior_string());
- }
- }
- void print_directory(ttf::directory_index &directory, const char *data_start)
- {
- for (unsigned int i = 0; i < directory.size(); i++) {
- ttf::index_t *dir = directory[i];
- char *id = (char *)&dir->id;
- char id_string[8];
- for (int j = 0; j < 4; j++) {
- id_string[j] = id[j];
- }
- id_string[4] = 0;
- const int offset = ttf::swap(dir->offset);
- const int length = ttf::swap(dir->length);
- printf("\t%-2i '%s' %-8i %-8i", i + 1, id_string, offset, length);
- ttf::table_dat_t *table_dat = ttf::find_table_dat(id_string);
- if (table_dat) {
- printf(" %s", table_dat->description);
- }
- printf("\n");
- ttf::u32 checksum = ttf::swap(dir->checksum);
- ttf::u32 calculated_checksum = ttf::checksum(data_start + offset, length);
- if (checksum != calculated_checksum) {
- printf("\tBAD CHECKSUM\n\n");
- dir->checksum = ttf::swap(calculated_checksum);
- }
- }
- }
- void print_table(const char *id, ttf::directory_index &directory, const char *data_start)
- {
- ttf::index_t *dir = 0;
- for (unsigned int i = 0; i < directory.size(); i++) {
- if (!memcmp(&directory[i]->id, id, 4)) {
- dir = directory[i];
- break;
- }
- }
- if (dir) {
- printf("'%s' table:\n", id);
- ttf::table_dat_t *table_dat = ttf::find_table_dat(id);
- if (table_dat && table_dat->print_table) {
- table_dat->print_table("\t", data_start, ttf::swap(dir->offset), ttf::swap(dir->length));
- } else {
- printf("\tno function specified to print this table type\n");
- }
- } else {
- printf("couldn't locate '%s' table in directory\n", id);
- }
- }
- void read_ttf(const char *ttf_filename)
- {
- using namespace ttf;
- file ttf(ttf_filename);
- printf("%s (%i bytes)\n\n", ttf.get_name(), ttf.size());
- if (ttf.size()) {
- char *data = ttf.data();
- ttf::header_t *head = (header_t *)data;
- const int version = swap(head->version);
- const int tables = swap(head->tables);
- printf("header:\n");
- head->print("\t");
- printf("\n");
- // populate table directory
- ttf::index_t *pdir = (index_t *)(head + 1);
- ttf::directory_index directory(tables);
- for (int i = 0; i < tables; i++) {
- directory[i] = &pdir[i];
- }
- printf("directory:\n");
- print_directory(directory, data);
- printf("\n");
- print_table("gasp", directory, data);
- printf("\n");
- print_table("name", directory, data);
- printf("\n");
- #if write_to_modified
- char filename[1024];
- strcpy(filename, ttf.get_name());
- char *path = strrchr(filename, '/');
- path = path ? path+1 : filename;
- const char *file = strrchr(ttf.get_name(), '/');
- file = file ? file+1 : ttf.get_name();
- if (path && file) {
- strcpy(path, "modified");
- //_mkdir(filename);
- strcat(path, "/");
- strcat(path, file);
- ttf.write(filename);
- }
- #endif
- }
- printf("\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement