Skip to content

Commit

Permalink
Basic draft of variable BASE table (passes non-variable tests)
Browse files Browse the repository at this point in the history
  • Loading branch information
skef committed Jun 19, 2024
1 parent ede5f71 commit 8170306
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 46 deletions.
41 changes: 27 additions & 14 deletions c/addfeatures/hotconv/BASE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ int BASE::Fill() {
HorizAxis.prep(g);
VertAxis.prep(g);

version = VERSION(1, 0);

offset.curr = hdr_size();

Expand All @@ -105,6 +104,20 @@ int BASE::Fill() {
offset.shared = offset.curr; // Indicates start of shared area
offset.curr += fillSharedData();

bool seenVariable = false;
for (auto &bc : baseCoords) {
if (bc.vvr.isVariable()) {
seenVariable = true;
bc.pair = ivs.addValue(*(g->ctx.locMap), bc.vvr, g->logger);
}
}
if (seenVariable) {
version = VERSION(1, 1);
ivsOffset = offset.curr;
} else {
version = VERSION(1, 0);
}

return 1;
}

Expand Down Expand Up @@ -142,10 +155,8 @@ void BASE::writeSharedData() {
OUT2((uint16_t)c);
}

for (auto &b : baseCoords) {
OUT2(b.Format);
OUT2(b.Coordinate);
}
for (auto &b : baseCoords)
b.write(this);
}

void BASEWrite(hotCtx g) {
Expand All @@ -163,6 +174,8 @@ void BASE::Write() {
if (VertAxis.baseTagList.size() > 0)
VertAxis.write(offset.shared, this);
writeSharedData();
if (ivsOffset != 0)
ivs.write(g->vw);
}

void BASEReuse(hotCtx g) {
Expand Down Expand Up @@ -202,30 +215,30 @@ void BASE::setBaselineTags(bool doVert, std::vector<Tag> &baselineTag) {
HorizAxis.baseTagList.swap(baselineTag);
}

int32_t BASE::addCoord(int16_t c) {
int32_t BASE::addCoord(VarValueRecord &vvr) {
/* See if coord can be shared */
Offset o = 0;
for (int32_t i = 0; i < (int32_t) baseCoords.size(); i++) {
if (baseCoords[i].Coordinate == c)
if (baseCoords[i] == vvr)
return i;
}
if (!baseCoords.empty()) {
auto &back = baseCoords.back();
o = back.o + back.size();
}

baseCoords.emplace_back(c, o);
baseCoords.emplace_back(std::move(vvr), o);
return baseCoords.size() - 1;
}

int BASE::addBaseScript(int dfltInx, size_t nBaseTags, std::vector<int16_t> &coords) {
int BASE::addBaseScript(int dfltInx, size_t nBaseTags, std::vector<VarValueRecord> &coords) {
/* See if a baseScript can be shared */
for (size_t i = 0; i < baseScript.size(); i++) {
auto &bsi = baseScript[i];
if (bsi.dfltBaselineInx == dfltInx && nBaseTags == bsi.coordInx.size()) {
bool match = true;
for (size_t j = 0; j < nBaseTags; j++) {
if (baseCoords[bsi.coordInx[j]].Coordinate != coords[j]) {
if (!(baseCoords[bsi.coordInx[j]] == coords[j])) {
match = false;
break;
}
Expand All @@ -240,23 +253,23 @@ int BASE::addBaseScript(int dfltInx, size_t nBaseTags, std::vector<int16_t> &coo
BaseScriptInfo bsi {(int16_t)dfltInx};
bsi.coordInx.reserve(nBaseTags);

for (auto &c : coords)
bsi.coordInx.push_back(addCoord(c));
for (auto &vvr : coords)
bsi.coordInx.push_back(addCoord(vvr));

baseScript.emplace_back(std::move(bsi));

return baseScript.size() - 1;
}

void BASE::addScript(bool doVert, Tag script, Tag dfltBaseline,
std::vector<int16_t> &coords) {
std::vector<VarValueRecord> &coords) {
if (doVert)
VertAxis.addScript(*this, script, dfltBaseline, coords);
else
HorizAxis.addScript(*this, script, dfltBaseline, coords);
}

void BASE::Axis::addScript(BASE &h, Tag script, Tag dfltBaseline, std::vector<int16_t> &coords) {
void BASE::Axis::addScript(BASE &h, Tag script, Tag dfltBaseline, std::vector<VarValueRecord> &coords) {
size_t nBaseTags = baseTagList.size();

if (nBaseTags == 0)
Expand Down
42 changes: 33 additions & 9 deletions c/addfeatures/hotconv/BASE.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class BASE {
Offset tag_list_size() { return sizeof(uint16_t) + sizeof(uint32_t) * baseTagList.size(); }
Offset script_list_size() {
return sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint16_t)) * baseScriptList.size(); }
void addScript(BASE &h, Tag script, Tag dfltBaseline, std::vector<int16_t> &coords);
void addScript(BASE &h, Tag script, Tag dfltBaseline,
std::vector<VarValueRecord> &coords);
void prep(hotCtx g);
Offset fill(Offset curr);
void write(Offset shared, BASE *h);
Expand Down Expand Up @@ -73,28 +74,49 @@ class BASE {

struct BaseCoord {
BaseCoord() = delete;
BaseCoord(int16_t c, Offset o) : Coordinate(c), o(o) {}
uint16_t Format {1};
int16_t Coordinate {0};
Offset o {0};
Offset size() { return sizeof(uint16_t) * 2; }
BaseCoord(VarValueRecord &&vvr, Offset o) : vvr(std::move(vvr)), o(o) {}
bool operator==(const BaseCoord &rhs) const { return vvr == rhs.vvr; }
bool operator==(const VarValueRecord &ovvr) { return vvr == ovvr; }
uint16_t format() { return vvr.isVariable() ? 3 : 1; }
LOffset size() {
if (vvr.isVariable()) {
return sizeof(uint16_t) * 5 + sizeof(int16_t);
} else {
return sizeof(uint16_t) + sizeof(int16_t);
}
}
void write(BASE *h) {
OUT2(format());
OUT2(vvr.getDefault());
if (vvr.isVariable()) {
assert(pair.outerIndex != 0xFFFF);
OUT2(6);
OUT2(pair.outerIndex);
OUT2(pair.innerIndex);
OUT2(0x8000);
}
}
VarValueRecord vvr;
Offset o;
var_indexPair pair {0xFFFF, 0xFFFF};
};

public:
BASE() = delete;
explicit BASE(hotCtx g) : g(g) {}
void setBaselineTags(bool doVert, std::vector<Tag> &baselineTag);
void addScript(bool doVert, Tag script, Tag dfltBaseline,
std::vector<int16_t> &coords);
std::vector<VarValueRecord> &coords);
int Fill();
void Write();
void setAxisCount(uint16_t axisCount) { ivs.setAxisCount(axisCount); }
private:
int addBaseScript(int dfltInx, size_t nBaseTags, std::vector<int16_t> &coords);
int addBaseScript(int dfltInx, size_t nBaseTags, std::vector<VarValueRecord> &coords);
static Offset hdr_size() { return sizeof(int32_t) + sizeof(uint16_t) * 2; }
Offset fillAxis(bool doVert);
Offset fillSharedData();
void writeSharedData();
int32_t addCoord(int16_t c);
int32_t addCoord(VarValueRecord &c);

std::vector<BaseScriptInfo> baseScript;

Expand All @@ -112,6 +134,8 @@ class BASE {
std::vector<BaseValues> baseValues;
std::vector<BaseCoord> baseCoords;

itemVariationStore ivs;
LOffset ivsOffset {0};
hotCtx g; /* Package context */
};

Expand Down
16 changes: 9 additions & 7 deletions c/addfeatures/hotconv/FeatParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ void featparserParserInitialize() {
95,1,0,0,0,724,725,7,5,0,0,725,730,3,98,49,0,726,727,5,140,0,0,727,729,
3,98,49,0,728,726,1,0,0,0,729,732,1,0,0,0,730,728,1,0,0,0,730,731,1,0,
0,0,731,97,1,0,0,0,732,730,1,0,0,0,733,734,3,202,101,0,734,736,3,202,
101,0,735,737,5,153,0,0,736,735,1,0,0,0,737,738,1,0,0,0,738,736,1,0,0,
101,0,735,737,3,62,31,0,736,735,1,0,0,0,737,738,1,0,0,0,738,736,1,0,0,
0,738,739,1,0,0,0,739,99,1,0,0,0,740,741,5,68,0,0,741,743,5,129,0,0,742,
744,3,102,51,0,743,742,1,0,0,0,744,745,1,0,0,0,745,743,1,0,0,0,745,746,
1,0,0,0,746,747,1,0,0,0,747,748,5,130,0,0,748,749,5,68,0,0,749,750,5,
Expand Down Expand Up @@ -5376,12 +5376,12 @@ FeatParser::TagContext* FeatParser::BaseScriptContext::tag(size_t i) {
return getRuleContext<FeatParser::TagContext>(i);
}

std::vector<tree::TerminalNode *> FeatParser::BaseScriptContext::NUM() {
return getTokens(FeatParser::NUM);
std::vector<FeatParser::SingleValueLiteralContext *> FeatParser::BaseScriptContext::singleValueLiteral() {
return getRuleContexts<FeatParser::SingleValueLiteralContext>();
}

tree::TerminalNode* FeatParser::BaseScriptContext::NUM(size_t i) {
return getToken(FeatParser::NUM, i);
FeatParser::SingleValueLiteralContext* FeatParser::BaseScriptContext::singleValueLiteral(size_t i) {
return getRuleContext<FeatParser::SingleValueLiteralContext>(i);
}


Expand Down Expand Up @@ -5420,11 +5420,13 @@ FeatParser::BaseScriptContext* FeatParser::baseScript() {
_la = _input->LA(1);
do {
setState(735);
match(FeatParser::NUM);
singleValueLiteral();
setState(738);
_errHandler->sync(this);
_la = _input->LA(1);
} while (_la == FeatParser::NUM);
} while (_la == FeatParser::LPAREN

|| _la == FeatParser::NUM);

}
catch (RecognitionException &e) {
Expand Down
2 changes: 1 addition & 1 deletion c/addfeatures/hotconv/FeatParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ axisScripts:
;

baseScript:
script=tag db=tag NUM+
script=tag db=tag singleValueLiteral+
;

table_GDEF:
Expand Down
4 changes: 2 additions & 2 deletions c/addfeatures/hotconv/FeatParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,8 @@ class FeatParser : public antlr4::Parser {
virtual size_t getRuleIndex() const override;
std::vector<TagContext *> tag();
TagContext* tag(size_t i);
std::vector<antlr4::tree::TerminalNode *> NUM();
antlr4::tree::TerminalNode* NUM(size_t i);
std::vector<SingleValueLiteralContext *> singleValueLiteral();
SingleValueLiteralContext* singleValueLiteral(size_t i);


virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
Expand Down
2 changes: 1 addition & 1 deletion c/addfeatures/hotconv/FeatParser.interp

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions c/addfeatures/hotconv/FeatVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,19 +1414,18 @@ void FeatVisitor::translateBaseScript(FeatParser::BaseScriptContext *ctx,
Tag script = getTag(ctx->script);
Tag db = getTag(ctx->db);

std::vector<int16_t> sv;
std::vector<VarValueRecord> sv;
sv.reserve(cnt);

if ( ctx->NUM().size() != cnt ) {
if ( ctx->NUM().size() > cnt )
sv.reserve(ctx->NUM().size());
TOK(ctx);
if ( TOK(ctx)->singleValueLiteral().size() != cnt )
fc->featMsg(sERROR, "The number of coordinates is not equal to "
"the number of baseline tags");
}
"the number of baseline tags");

for (auto n : ctx->NUM())
sv.push_back(getNum<int16_t>(TOK(n)->getText(), 10));
for (auto svl : ctx->singleValueLiteral()) {
VarValueRecord vvr;
getSingleValueLiteral(svl, vvr);
sv.emplace_back(std::move(vvr));
}

fc->g->ctx.BASEp->addScript(vert, script, db, sv);
}
Expand Down
9 changes: 6 additions & 3 deletions c/addfeatures/hotconv/hot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "hotmap.h"
#include "FeatCtx.h"
#include "name.h"
#include "BASE.h"
#include "GPOS.h"
#include "GDEF.h"
#include "OS_2.h"
Expand Down Expand Up @@ -351,11 +352,13 @@ const char *hotReadFont(hotCtx g, int flags, bool &isROS) {

hotReadTables(g);

g->ctx.locMap = new VarLocationMap(g->ctx.feat->getAxisCount());
g->ctx.GDEFp->setAxisCount(g->ctx.feat->getAxisCount());
auto axisCount = g->ctx.feat->getAxisCount();
g->ctx.locMap = new VarLocationMap(axisCount);
g->ctx.GDEFp->setAxisCount(axisCount);
g->ctx.BASEp->setAxisCount(axisCount);
if (g->ctx.MVAR == nullptr)
g->ctx.MVAR = new var_MVAR {};
g->ctx.MVAR->setAxisCount(g->ctx.feat->getAxisCount());
g->ctx.MVAR->setAxisCount(axisCount);
if (g->ctx.axes != nullptr && g->ds != nullptr)
g->ds->checkAxes(*g->ctx.axes);

Expand Down

0 comments on commit 8170306

Please sign in to comment.