Skip to content

Commit

Permalink
[ttf] parse loca table
Browse files Browse the repository at this point in the history
  • Loading branch information
harrand committed Sep 23, 2023
1 parent d42337d commit 71dfbfa
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/tz/io/ttf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace tz::io
tz::assert(this->head.canary, "TTF Head Table canary value was never set to true, this means that a head table was not located. Most likely the TTF is malformed or corrupted.");
tz::assert(this->maxp.canary, "TTF maxp Table canary value was never set to true, this means that a head table was not located. Most likely the TTF is malformed or corrupted.");
tz::assert(this->hhea.canary, "TTF hhea Table canary value was never set to true, this means that a head table was not located. Most likely the TTF is malformed or corrupted.");
tz::assert(this->hmtx.canary, "TTF hmtx Table canary value was never set to true, this means that a head table was not located. Most likely the TTF is malformed or corrupted.");
tz::assert(this->loca.canary, "TTF loca Table canary value was never set to true, this means that a head table was not located. Most likely the TTF is malformed or corrupted.");
}

std::string_view ttf::parse_header(std::string_view str)
Expand Down Expand Up @@ -102,6 +104,7 @@ namespace tz::io
this->parse_maxp_table(data, this->find_table_by_tag("maxp"));
this->parse_hhea_table(data, this->find_table_by_tag("hhea"));
this->parse_hmtx_table(data, this->find_table_by_tag("hmtx"));
this->parse_loca_table(data, this->find_table_by_tag("loca"));
}

std::uint32_t ttf::calculate_table_checksum(std::string_view data, std::uint32_t offset, std::uint32_t length) const
Expand Down Expand Up @@ -242,4 +245,35 @@ namespace tz::io
}
this->hmtx.canary = true;
}

void ttf::parse_loca_table(std::string_view data, ttf_table table_descriptor)
{
tz::assert(data.size() > table_descriptor.offset + table_descriptor.length);
data.remove_prefix(table_descriptor.offset);
data.remove_suffix(data.size() - table_descriptor.length);
tz::assert(data.size() == (table_descriptor.length));

tz::assert(this->head.canary, "Cannot parse loca table until head table is parsed.");
tz::assert(this->maxp.canary, "Cannot parse loca table until maxp table is parsed.");
tz::assert(!this->loca.canary, "When parsing loca table, noticed canary already switched to true. Double hhea table discovery? Most likely malformed TTF.");
const char* ptr = data.data();

if(this->head.index_to_loc_format == 0)
{
// 16 bit
for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs); i++)
{
this->loca.locations16.push_back(ttf_read_value<std::uint16_t>(ptr));
}
}
else
{
// 32 bit
for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs); i++)
{
this->loca.locations32.push_back(ttf_read_value<std::uint32_t>(ptr));
}
}
this->loca.canary = true;
}
}
9 changes: 9 additions & 0 deletions src/tz/io/ttf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ namespace tz::io
bool canary = false;
};

struct ttf_loca_table
{
std::vector<std::uint16_t> locations16 = {};
std::vector<std::uint32_t> locations32 = {};
bool canary = false;
};

class ttf
{
public:
Expand All @@ -115,13 +122,15 @@ namespace tz::io
void parse_maxp_table(std::string_view data, ttf_table table_descriptor);
void parse_hhea_table(std::string_view data, ttf_table table_descriptor);
void parse_hmtx_table(std::string_view data, ttf_table table_descriptor);
void parse_loca_table(std::string_view data, ttf_table table_descriptor);
ttf_header header = {};

std::vector<ttf_table> tables = {};
ttf_head_table head = {};
ttf_maxp_table maxp = {};
ttf_hhea_table hhea = {};
ttf_hmtx_table hmtx = {};
ttf_loca_table loca = {};
};
}

Expand Down

0 comments on commit 71dfbfa

Please sign in to comment.