initial commit
This commit is contained in:
commit
4b60ece582
327 changed files with 28286 additions and 0 deletions
223
lib/fontParser/font.cpp
Normal file
223
lib/fontParser/font.cpp
Normal file
|
@ -0,0 +1,223 @@
|
|||
#include "font.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
Font::Font(const std::string& p_path):
|
||||
path(p_path),
|
||||
tables(),
|
||||
cmap(0),
|
||||
hhea(0),
|
||||
hmtx(0),
|
||||
head(0),
|
||||
name(0)
|
||||
{
|
||||
std::ifstream file(path, std::ios::in | std::ios::binary);
|
||||
|
||||
char * buffer;
|
||||
|
||||
buffer = new char[4];
|
||||
file.read(buffer, 4);
|
||||
uint32_t sfntVersion = ntohl(*((uint32_t*) buffer));
|
||||
if (sfntVersion == 0x00010000) {
|
||||
version = TrueTypeOutlines;
|
||||
} else if (sfntVersion == 0x4f54544f) {
|
||||
version = WithCFFData;
|
||||
} else {
|
||||
std::cout << "unsupported sfntVersion" << std::endl;
|
||||
throw 1;
|
||||
}
|
||||
delete[] buffer;
|
||||
|
||||
buffer = new char[2];
|
||||
file.read(buffer, 2);
|
||||
numberTables = ntohs(*((uint16_t*) buffer));
|
||||
|
||||
file.read(buffer, 2);
|
||||
searchRange = ntohs(*((uint16_t*) buffer));
|
||||
|
||||
file.read(buffer, 2);
|
||||
entrySelector = ntohs(*((uint16_t*) buffer));
|
||||
|
||||
file.read(buffer, 2);
|
||||
rangeShift = ntohs(*((uint16_t*) buffer));
|
||||
|
||||
for (int i = 0; i < numberTables; ++i) {
|
||||
Table* t = Table::fromIfStream(file);
|
||||
tables.insert(std::make_pair(t->tag, t));
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
{
|
||||
std::map<std::string, Table*>::const_iterator beg = tables.begin();
|
||||
std::map<std::string, Table*>::const_iterator end = tables.end();
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
delete beg->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Font::hasTable(const std::string& tag) const
|
||||
{
|
||||
std::map<std::string, Table*>::const_iterator itr = tables.find(tag);
|
||||
return itr != tables.end();
|
||||
}
|
||||
|
||||
std::list<std::string> Font::availableTables() const
|
||||
{
|
||||
std::list<std::string> res;
|
||||
std::map<std::string, Table*>::const_iterator beg = tables.begin();
|
||||
std::map<std::string, Table*>::const_iterator end = tables.end();
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
res.push_back(beg->first);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::map<uint32_t, uint32_t> Font::getCharCodeToCIDTable(uint32_t start, uint32_t end)
|
||||
{
|
||||
if (cmap == NULL) {
|
||||
cmap = static_cast<Cmap*>(tables.at("cmap"));
|
||||
cmap->read(path);
|
||||
}
|
||||
std::map<uint32_t, uint32_t> res;
|
||||
for (uint32_t i = start; i <= end; ++i) {
|
||||
res.insert(std::make_pair(i, cmap->getCID(i)));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::map<uint32_t, Hmtx::HMetric> Font::getCharCodeMetrics(uint32_t start, uint32_t end)
|
||||
{
|
||||
std::map<uint32_t, uint32_t> CCtoCID = getCharCodeToCIDTable(start, end);
|
||||
std::map<uint32_t, Hmtx::HMetric> res;
|
||||
|
||||
if (hmtx == NULL) {
|
||||
hmtx = static_cast<Hmtx*>(tables.at("hmtx"));
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
hmtx->numOfLongHorMetrics = hhea->numOfLongHorMetrics;
|
||||
hmtx->read(path);
|
||||
}
|
||||
|
||||
std::map<uint32_t, uint32_t>::const_iterator itr = CCtoCID.begin();
|
||||
std::map<uint32_t, uint32_t>::const_iterator mend = CCtoCID.end();
|
||||
|
||||
for (; itr != mend; ++itr) {
|
||||
res.insert(std::make_pair(itr->first, hmtx->getMetric(itr->second)));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Table * Font::getTable(const std::string& tag)
|
||||
{
|
||||
std::map<std::string, Table*>::iterator itr = tables.find(tag);
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
uint16_t Font::getUnitsPerEm()
|
||||
{
|
||||
if (head == NULL) {
|
||||
head = static_cast<Head*>(tables.at("head"));
|
||||
head->read(path);
|
||||
}
|
||||
return head->unitsPerEm;
|
||||
}
|
||||
|
||||
int16_t Font::getAscent()
|
||||
{
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
return hhea->ascent;
|
||||
}
|
||||
|
||||
int16_t Font::getDescent()
|
||||
{
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
return hhea->descent;
|
||||
}
|
||||
|
||||
int16_t Font::getLineGap()
|
||||
{
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
return hhea->lineGap;
|
||||
}
|
||||
|
||||
std::string Font::getNameField(std::string key)
|
||||
{
|
||||
if (name == NULL) {
|
||||
name = static_cast<Name*>(tables.at("name"));
|
||||
name->read(path);
|
||||
}
|
||||
return name->getRecord(key);
|
||||
}
|
||||
|
||||
int16_t Font::getCaretSlopeRise()
|
||||
{
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
return hhea->caretSlopeRise;
|
||||
}
|
||||
|
||||
int16_t Font::getCaretSlopeRun()
|
||||
{
|
||||
if (hhea == NULL) {
|
||||
hhea = static_cast<Hhea*>(tables.at("hhea"));
|
||||
hhea->read(path);
|
||||
}
|
||||
return hhea->caretSlopeRun;
|
||||
}
|
||||
|
||||
int16_t Font::getXMax()
|
||||
{
|
||||
if (head == NULL) {
|
||||
head = static_cast<Head*>(tables.at("head"));
|
||||
head->read(path);
|
||||
}
|
||||
return head->xMax;
|
||||
}
|
||||
|
||||
int16_t Font::getXMin()
|
||||
{
|
||||
if (head == NULL) {
|
||||
head = static_cast<Head*>(tables.at("head"));
|
||||
head->read(path);
|
||||
}
|
||||
return head->xMin;
|
||||
}
|
||||
|
||||
int16_t Font::getYMax()
|
||||
{
|
||||
if (head == NULL) {
|
||||
head = static_cast<Head*>(tables.at("head"));
|
||||
head->read(path);
|
||||
}
|
||||
return head->yMax;
|
||||
}
|
||||
|
||||
int16_t Font::getYMin()
|
||||
{
|
||||
if (head == NULL) {
|
||||
head = static_cast<Head*>(tables.at("head"));
|
||||
head->read(path);
|
||||
}
|
||||
return head->yMin;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue