Skip to content

Commit

Permalink
Slight reorg, allow mixing of variable and fixed metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
skef committed Mar 15, 2024
1 parent 8399c2b commit d6da970
Show file tree
Hide file tree
Showing 11 changed files with 817 additions and 805 deletions.
1,487 changes: 736 additions & 751 deletions c/addfeatures/hotconv/FeatParser.cpp

Large diffs are not rendered by default.

15 changes: 6 additions & 9 deletions c/addfeatures/hotconv/FeatParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -198,29 +198,26 @@ valueRecord:
;

valueLiteral:
NUM
| parenLocationValue
| ( BEGINVALUE NUM NUM NUM NUM ENDVALUE )
singleValueLiteral
| ( BEGINVALUE singleValueLiteral singleValueLiteral
singleValueLiteral singleValueLiteral ENDVALUE )
| ( LPAREN locationMultiValueLiteral+ RPAREN )
| ( BEGINVALUE parenLocationValue parenLocationValue
parenLocationValue parenLocationValue ENDVALUE )
;

singleValueLiteral:
NUM
| parenLocationValue
NUM | parenLocationValue
;

parenLocationValue:
LPAREN locationValueLiteral+ RPAREN
;

locationValueLiteral:
locationSpecifier COLON NUM
(locationSpecifier COLON)? NUM
;

locationMultiValueLiteral:
locationSpecifier COLON BEGINVALUE NUM NUM NUM NUM ENDVALUE
(locationSpecifier COLON)? BEGINVALUE NUM NUM NUM NUM ENDVALUE
;

locationSpecifier:
Expand Down
12 changes: 5 additions & 7 deletions c/addfeatures/hotconv/FeatParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,10 +801,8 @@ class FeatParser : public antlr4::Parser {
public:
ValueLiteralContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<antlr4::tree::TerminalNode *> NUM();
antlr4::tree::TerminalNode* NUM(size_t i);
std::vector<ParenLocationValueContext *> parenLocationValue();
ParenLocationValueContext* parenLocationValue(size_t i);
std::vector<SingleValueLiteralContext *> singleValueLiteral();
SingleValueLiteralContext* singleValueLiteral(size_t i);
antlr4::tree::TerminalNode *BEGINVALUE();
antlr4::tree::TerminalNode *ENDVALUE();
antlr4::tree::TerminalNode *LPAREN();
Expand Down Expand Up @@ -853,9 +851,9 @@ class FeatParser : public antlr4::Parser {
public:
LocationValueLiteralContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *NUM();
LocationSpecifierContext *locationSpecifier();
antlr4::tree::TerminalNode *COLON();
antlr4::tree::TerminalNode *NUM();


virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
Expand All @@ -868,12 +866,12 @@ class FeatParser : public antlr4::Parser {
public:
LocationMultiValueLiteralContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LocationSpecifierContext *locationSpecifier();
antlr4::tree::TerminalNode *COLON();
antlr4::tree::TerminalNode *BEGINVALUE();
std::vector<antlr4::tree::TerminalNode *> NUM();
antlr4::tree::TerminalNode* NUM(size_t i);
antlr4::tree::TerminalNode *ENDVALUE();
LocationSpecifierContext *locationSpecifier();
antlr4::tree::TerminalNode *COLON();


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.

37 changes: 32 additions & 5 deletions c/addfeatures/hotconv/FeatVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,10 +1433,19 @@ void FeatVisitor::getValueRecord(FeatParser::ValueRecordContext *ctx,

void FeatVisitor::getValueLiteral(FeatParser::ValueLiteralContext *ctx,
MetricsInfo &mi) {
int cnt = ctx->NUM().size();
assert(cnt == 1 || cnt == 4);
for (int16_t i = 0; i < cnt; ++i)
mi.metrics.emplace_back(getNum<int16_t>(TOK(ctx->NUM(i))->getText(), 10));
if (ctx->singleValueLiteral().size() != 0) {
assert(ctx->singleValueLiteral().size() == 1 ||
ctx->singleValueLiteral().size() == 4);
for (auto svl : ctx->singleValueLiteral()) {
VarValueRecord vvr;
getSingleValueLiteral(svl, vvr);
mi.metrics.emplace_back(std::move(vvr));
}
} else {
assert(ctx->locationMultiValueLiteral().size() != 0);
for (auto lmvl : ctx->locationMultiValueLiteral())
addLocationMultiValue(lmvl, mi);
}
}

void FeatVisitor::getSingleValueLiteral(FeatParser::SingleValueLiteralContext *ctx,
Expand All @@ -1463,7 +1472,25 @@ void FeatVisitor::addLocationValueLiteral(FeatParser::LocationValueLiteralContex
vvr.addLocationValue(locIndex, num, fc->g->logger);
}

uint32_t FeatVisitor::getLocationSpecifier(FeatParser::LocationSpecifierContext *ctx) {
void FeatVisitor::addLocationMultiValue(FeatParser::LocationMultiValueLiteralContext *ctx,
MetricsInfo &mi) {
if (mi.metrics.size() == 0)
mi.metrics.resize(4);
assert(mi.metrics.size() == 4);
assert(ctx->NUM().size() == 4);
uint32_t locIndex = getLocationSpecifier(ctx->locationSpecifier());
for (size_t i = 0; i < 4; i++) {
int16_t num = getNum<int16_t>(TOK(ctx->NUM(i))->getText(), 10);
mi.metrics[i].addLocationValue(locIndex, num, fc->g->logger);
}
}

uint32_t FeatVisitor::getLocationSpecifier(FeatParser::LocationSpecifierContext *ctx, bool errorOnNull) {
if (ctx == nullptr) {
if (errorOnNull)
fc->featMsg(sERROR, "Missing location specifier");
return 0; // default location
}
if (ctx->LNAME() != nullptr)
return fc->getLocationDef(TOK(ctx->LNAME())->getText());
else
Expand Down
9 changes: 8 additions & 1 deletion c/addfeatures/hotconv/FeatVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ class FeatVisitor : public FeatParserBaseVisitor {
VarValueRecord &vvr);
void addLocationValueLiteral(FeatParser::LocationValueLiteralContext *ctx,
VarValueRecord &vvr);
uint32_t getLocationSpecifier(FeatParser::LocationSpecifierContext *ctx);
void addLocationMultiValue(FeatParser::LocationMultiValueLiteralContext *ctx,
MetricsInfo &mi);
uint32_t getLocationSpecifier(FeatParser::LocationSpecifierContext *ctx, bool errorOnNull = false);
uint32_t getLocationLiteral(FeatParser::LocationLiteralContext *ctx);
bool addAxisLocationLiteral(FeatParser::AxisLocationLiteralContext *ctx,
std::vector<var_F2dot14> &l);
Expand Down Expand Up @@ -207,6 +209,11 @@ class FeatVisitor : public FeatParserBaseVisitor {
antlrcpp::Any visitValueRecord(FeatParser::ValueRecordContext *) override { DEBSTOP }
antlrcpp::Any visitValueLiteral(FeatParser::ValueLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitLocationLiteral(FeatParser::LocationLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitParenLocationValue(FeatParser::ParenLocationValueContext *) override { DEBSTOP }
antlrcpp::Any visitSingleValueLiteral(FeatParser::SingleValueLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitLocationValueLiteral(FeatParser::LocationValueLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitLocationMultiValueLiteral(FeatParser::LocationMultiValueLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitLocationSpecifier(FeatParser::LocationSpecifierContext *) override { DEBSTOP }
antlrcpp::Any visitAxisLocationLiteral(FeatParser::AxisLocationLiteralContext *) override { DEBSTOP }
antlrcpp::Any visitAnchor(FeatParser::AnchorContext *) override { DEBSTOP }
antlrcpp::Any visitLookupPattern(FeatParser::LookupPatternContext *) override { DEBSTOP }
Expand Down
51 changes: 23 additions & 28 deletions c/addfeatures/hotconv/GPOS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ LOffset GPOS::recordValues(uint32_t valFmt, MetricsInfo &mi, LOffset o) {
if (valFmt & (b << 4)) {
if (vvr.isVariable()) {
setDevOffset(t, o);
o += sizeof(uint16) * 3;
o += sizeof(uint16_t) * 3;
} else {
setDevOffset(t, 0);
}
Expand Down Expand Up @@ -288,7 +288,7 @@ void GPOS::writeVarSubtables(uint32_t valFmt, ValueIndex vi) {
// XXX refactor
OUT2(v.getOuterIndex());
OUT2(v.getInnerIndex());
OUT2(0x8000);
OUT2((uint16_t)0x8000);
}
}
}
Expand Down Expand Up @@ -1026,40 +1026,38 @@ GPOS::PairPos::Format1::Format1(GPOS &h, GPOS::SubtableInfo &si) : PairPos(h, si
ValueFormat1 = si.pairValFmt1;
ValueFormat2 = si.pairValFmt2;

auto nvals = MetricsInfo::numValues(ValueFormat1) + MetricsInfo::numValues(ValueFormat2);
auto nvars = MetricsInfo::numVariables(ValueFormat1) + MetricsInfo::numVariables(ValueFormat2);

// Map pair sets and build coverage table
LOffset offst = 0;
auto previ = si.pairs.begin();
std::vector<std::pair<decltype(previ), LOffset>> pairSetInfo;
std::vector<decltype(previ)> pairSetEnds;
cac->coverageBegin();
for (auto i = previ + 1; i <= si.pairs.end(); i++) {
if (i == si.pairs.end() || i->first != previ->first) {
cac->coverageAddGlyph(previ->first);
pairSetInfo.emplace_back(i, offst);
offst += pairSetSize(i - previ, nvals, nvars);
pairSetEnds.emplace_back(i);
previ = i;
}
}

LOffset pairSetOffset = pair1Size(pairSetInfo.size());
offst += pairSetOffset;
PairSets.reserve(pairSetInfo.size());
auto nvals = MetricsInfo::numValues(ValueFormat1) + MetricsInfo::numValues(ValueFormat2);
auto nvars = MetricsInfo::numVariables(ValueFormat1) + MetricsInfo::numVariables(ValueFormat2);

LOffset offst = pair1Size(pairSetEnds.size());
valueIndex = h.nextValueIndex();
PairSets.reserve(pairSetEnds.size());

/* Fill pair sets */
auto i = si.pairs.begin();
for (auto [e, o] : pairSetInfo) {
PairSet curr;
curr.offset = o + pairSetOffset;
for (auto e : pairSetEnds) {
PairSet curr {offst};
curr.secondGlyphs.reserve(e - i);
for (auto k = i; k < e; k++) {
LOffset doff = pairSetSize(e - i, nvals, nvars);
for (auto k = i; k != e; k++) {
curr.secondGlyphs.push_back(k->second);
offst = h.recordValues(ValueFormat1, k->metricsInfo1, offst);
offst = h.recordValues(ValueFormat2, k->metricsInfo2, offst);
doff = h.recordValues(ValueFormat1, k->metricsInfo1, doff);
doff = h.recordValues(ValueFormat2, k->metricsInfo2, doff);
}
PairSets.emplace_back(std::move(curr));
offst += doff;
i = e;
}

Expand Down Expand Up @@ -1187,22 +1185,20 @@ void GPOS::PairPos::Format1::write(OTL *h) {

for (auto &ps : PairSets) {
OUT2((uint16_t)ps.secondGlyphs.size());
auto vcopy = v;
for (auto g : ps.secondGlyphs) {
OUT2(g);
auto vcopy = v;
h->writeValueRecord(ValueFormat1, v);
v += nvals1;
h->writeValueRecord(ValueFormat2, v);
v += nvals2;
}
}

v = valueIndex;
for (auto &ps : PairSets) {
for (auto g : ps.secondGlyphs) {
h->writeVarSubtables(ValueFormat1, v);
v += nvals1;
h->writeVarSubtables(ValueFormat2, v);
v += nvals2;
h->writeVarSubtables(ValueFormat1, vcopy);
vcopy += nvals1;
h->writeVarSubtables(ValueFormat2, vcopy);
vcopy += nvals2;
}
}

Expand All @@ -1214,8 +1210,7 @@ void GPOS::PairPos::Format1::write(OTL *h) {
void GPOS::PairPos::Format2::write(OTL *h) {
if (!isExt()) {
/* Adjust coverage and class offsets */
LOffset classAdjust = h->subOffset() - offset +
cac->coverageSize();
LOffset classAdjust = h->subOffset() - offset + cac->coverageSize();
Coverage += h->subOffset() - offset;
ClassDef1 += classAdjust;
ClassDef2 += classAdjust;
Expand Down
1 change: 1 addition & 0 deletions c/addfeatures/hotconv/GPOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ class GPOS : public OTL {
};

struct PairSet {
explicit PairSet(LOffset o) : offset(o) {}
LOffset offset {0};
std::vector<GID> secondGlyphs;
};
Expand Down
4 changes: 2 additions & 2 deletions c/spot/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ int main__spot(int argc, int8_t *argv[]) {
filename = argv[argi];

if (files > 1) {
spotInform("Proofing %s.", filename);
spotInform(SPOT_MSG_PROOFING, filename);
}

if (outputfilebase == NULL)
Expand Down Expand Up @@ -594,7 +594,7 @@ int main__spot(int argc, int8_t *argv[]) {
fileOpen(filename);
if (outputfilebase == NULL)
outputfilebase = filename;
spotInform("Proofing %s.", filename);
spotInform(SPOT_MSG_PROOFING, filename);
goodFileCount++;

if (readFile(filename)) {
Expand Down
1 change: 1 addition & 0 deletions c/spot/spotmsgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const int8_t *SpotEnglishMessages[] =
"proof and feature file format dumps do not support recursive calls to contextual lookups. context format %d.\n", /* SPOT_MSG_CNTX_RECURSION */
"Duplicate glyph in coverage Type1. gid: '%d'.\n", /* SPOT_MSG_DUP_IN_COV */
"Cannot proof multiple inputs with more than one group greater than 1. Not all substitutions may be displayed.\n", /* SPOT_MSG_GSUBMULTIPLEINPUTS */
"Proofing %s.", /* SPOT_MSG_PROOFING */
};

const int8_t *spotMsg(int msgId) {
Expand Down
3 changes: 2 additions & 1 deletion c/spot/spotmsgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ extern const int8_t *spotMsg(int msgId);
#define SPOT_MSG_CNTX_RECURSION 102
#define SPOT_MSG_DUP_IN_COV 103
#define SPOT_MSG_GSUBMULTIPLEINPUTS 104
#define SPOT_MSG_PROOFING 105

#define SPOT_MSG_ENDSENTINEL SPOT_MSG_GSUBMULTIPLEINPUTS
#define SPOT_MSG_ENDSENTINEL SPOT_MSG_PROOFING
#endif

0 comments on commit d6da970

Please sign in to comment.