summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/graphite2/ChangeLog18
-rw-r--r--gfx/graphite2/README.mcp6
-rw-r--r--gfx/graphite2/include/graphite2/Font.h2
-rw-r--r--gfx/graphite2/src/Code.cpp22
-rw-r--r--gfx/graphite2/src/Collider.cpp41
-rw-r--r--gfx/graphite2/src/Face.cpp3
-rw-r--r--gfx/graphite2/src/GlyphCache.cpp6
-rw-r--r--gfx/graphite2/src/Justifier.cpp9
-rw-r--r--gfx/graphite2/src/Pass.cpp31
-rw-r--r--gfx/graphite2/src/Segment.cpp5
-rw-r--r--gfx/graphite2/src/Silf.cpp10
-rw-r--r--gfx/graphite2/src/inc/Collider.h4
-rw-r--r--gfx/graphite2/src/inc/Machine.h2
-rw-r--r--gfx/graphite2/src/inc/Pass.h4
-rw-r--r--gfx/graphite2/src/inc/opcodes.h13
15 files changed, 118 insertions, 58 deletions
diff --git a/gfx/graphite2/ChangeLog b/gfx/graphite2/ChangeLog
index 40f8fd4a7..2554692aa 100644
--- a/gfx/graphite2/ChangeLog
+++ b/gfx/graphite2/ChangeLog
@@ -1,3 +1,21 @@
+1.3.9
+ . Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance
+ . Add segment and pass direction information to tracing output
+ . Bug fix rule length testing in 32-bit
+
+1.3.8
+ . Various bug fixes arising from fuzzing
+ . Fix regression that stopped piglatin from working
+ . Make collision avoidance kerning give more regular results
+ . Minor modification to clustering algorithm to handle variable width chars
+
+1.3.7
+ . Bug fixes
+ . Start to deprecate SegCache. This will be going away in a later release.
+
+1.3.6
+ . Bug fixes
+
1.3.5
. Bug fixes
. Security bug fix
diff --git a/gfx/graphite2/README.mcp b/gfx/graphite2/README.mcp
index dfbff3965..5c8632eb3 100644
--- a/gfx/graphite2/README.mcp
+++ b/gfx/graphite2/README.mcp
@@ -1,7 +1,7 @@
This directory contains the Graphite2 library from https://github.com/silnrsi/graphite/
-Current version derived from upstream release version 1.3.7 + additional fix.
-Commit used: 7dc29f3e4665b17f6e825957b707db6da36ae7d8
+Current version derived from upstream release version 1.3.9.
+Commit used: c14e40e0a48e0c58956bacc7e832e4b0c4325312
Edits were made to make it suitable for the Pale Moon source tree (as outlined below)
but the library is otherwise direct from upstream and unaltered.
@@ -18,4 +18,4 @@ Most notably:
* MozGrMalloc.h, Makefile.in and moz.build need to be preserved in src/
* Update source files and exports in moz.build with added/removed files in files.mk
(_SOURCES => CPP_SOURCES and _PUBLIC_HEADERS => EXPORTS.graphite2)
- \ No newline at end of file
+
diff --git a/gfx/graphite2/include/graphite2/Font.h b/gfx/graphite2/include/graphite2/Font.h
index 866294da9..b0de8e82b 100644
--- a/gfx/graphite2/include/graphite2/Font.h
+++ b/gfx/graphite2/include/graphite2/Font.h
@@ -30,7 +30,7 @@
#define GR2_VERSION_MAJOR 1
#define GR2_VERSION_MINOR 3
-#define GR2_VERSION_BUGFIX 7
+#define GR2_VERSION_BUGFIX 9
#ifdef __cplusplus
extern "C"
diff --git a/gfx/graphite2/src/Code.cpp b/gfx/graphite2/src/Code.cpp
index 851d73e7c..9428d76db 100644
--- a/gfx/graphite2/src/Code.cpp
+++ b/gfx/graphite2/src/Code.cpp
@@ -97,7 +97,7 @@ private:
opcode fetch_opcode(const byte * bc);
void analyse_opcode(const opcode, const int8 * const dp) throw();
bool emit_opcode(opcode opc, const byte * & bc);
- bool validate_opcode(const opcode opc, const byte * const bc);
+ bool validate_opcode(const byte opc, const byte * const bc);
bool valid_upto(const uint16 limit, const uint16 x) const throw();
bool test_context() const throw();
bool test_ref(int8 index) const throw();
@@ -266,13 +266,13 @@ bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
{
- const opcode opc = opcode(*bc++);
+ const byte opc = *bc++;
// Do some basic sanity checks based on what we know about the opcode
if (!validate_opcode(opc, bc)) return MAX_OPCODE;
// And check it's arguments as far as possible
- switch (opc)
+ switch (opcode(opc))
{
case NOP :
break;
@@ -470,7 +470,7 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
break;
}
- return bool(_code) ? opc : MAX_OPCODE;
+ return bool(_code) ? opcode(opc) : MAX_OPCODE;
}
@@ -629,7 +629,7 @@ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end
inline
-bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc)
+bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc)
{
if (opc >= MAX_OPCODE)
{
@@ -667,7 +667,17 @@ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) cons
inline
bool Machine::Code::decoder::test_ref(int8 index) const throw()
{
- return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
+ if (_code._constraint && !_in_ctxt_item)
+ {
+ if (index > 0 || -index > _max.pre_context)
+ {
+ failure(out_of_range_data);
+ return false;
+ }
+ }
+ else
+ return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
+ return true;
}
bool Machine::Code::decoder::test_context() const throw()
diff --git a/gfx/graphite2/src/Collider.cpp b/gfx/graphite2/src/Collider.cpp
index 87f067d3f..f6d6f6ecb 100644
--- a/gfx/graphite2/src/Collider.cpp
+++ b/gfx/graphite2/src/Collider.cpp
@@ -829,9 +829,9 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
// Calculate the height of the glyph and how many horizontal slices to use.
if (_maxy >= 1e37f)
{
- _maxy = ymax;
- _miny = ymin;
_sliceWidth = margin / 1.5f;
+ _maxy = ymax + margin;
+ _miny = ymin - margin;
numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f); // +2 helps with rounding errors
_edges.clear();
_edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
@@ -841,7 +841,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
{
if (_miny != ymin)
{
- numSlices = int((ymin - _miny) / _sliceWidth - 1);
+ numSlices = int((ymin - margin - _miny) / _sliceWidth - 1);
_miny += numSlices * _sliceWidth;
if (numSlices < 0)
_edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
@@ -855,7 +855,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
}
if (_maxy != ymax)
{
- numSlices = int((ymax - _miny) / _sliceWidth + 1);
+ numSlices = int((ymax + margin - _miny) / _sliceWidth + 1);
_maxy = numSlices * _sliceWidth + _miny;
if (numSlices > (int)_edges.size())
_edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
@@ -935,28 +935,33 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
return false;
const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
const float sx = slot->origin().x + currShift.x;
- float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
+ float x = (sx + (rtl > 0 ? bb.tr.x : bb.bl.x)) * rtl;
// this isn't going to reduce _mingap so skip
- if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
+ if (x < rtl * (_xbound - _mingap - currSpace))
return false;
const float sy = slot->origin().y + currShift.y;
- int smin = max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
- int smax = min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
+ int smin = max(1, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1)) - 1;
+ int smax = min((int)_edges.size() - 2, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1)) + 1;
+ if (smin > smax)
+ return false;
bool collides = false;
+ float below = smin > 0 ? _edges[smin-1] * rtl : 1e38f;
+ float here = _edges[smin] * rtl;
+ float above = smin < (int)_edges.size() - 1 ? _edges[smin+1] * rtl : 1e38f;
for (int i = smin; i <= smax; ++i)
{
float t;
float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
- if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
+ if ( (x > here - _mingap - currSpace)
+ || (x > below - _mingap - currSpace)
+ || (x > above - _mingap - currSpace))
{
// 2 * currSpace to account for the space that is already separating them and the space we want to add
- float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
- t = rtl * (_edges[i] - m);
+ float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) * rtl + 2 * currSpace;
// Check slices above and below (if any).
- if (i < (int)_edges.size() - 1) t = min(t, rtl * (_edges[i+1] - m));
- if (i > 0) t = min(t, rtl * (_edges[i-1] - m));
+ t = min(min(here, below), above) - m;
// _mingap is positive to shrink
if (t < _mingap)
{
@@ -965,13 +970,15 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
}
#if !defined GRAPHITE2_NTRACING
// Debugging - remember the closest neighboring edge for this slice.
- if (rtl * m > rtl * _nearEdges[i])
+ if (m > rtl * _nearEdges[i])
{
_slotNear[i] = slot;
- _nearEdges[i] = m;
+ _nearEdges[i] = m * rtl;
}
#endif
}
+ below = here; here = above;
+ above = i < (int)_edges.size() - 2 ? _edges[i+2] * rtl : 1e38f;
}
return collides; // note that true is not a necessarily reliable value
@@ -1086,3 +1093,7 @@ float SlotCollision::getKern(int dir) const
return 0;
}
+bool SlotCollision::ignore() const
+{
+ return ((flags() & SlotCollision::COLL_IGNORE) || (flags() & SlotCollision::COLL_ISSPACE));
+} \ No newline at end of file
diff --git a/gfx/graphite2/src/Face.cpp b/gfx/graphite2/src/Face.cpp
index 1ab7a60f4..545c8f6da 100644
--- a/gfx/graphite2/src/Face.cpp
+++ b/gfx/graphite2/src/Face.cpp
@@ -190,9 +190,10 @@ bool Face::runGraphite(Segment *seg, const Silf *aSilf) const
#if !defined GRAPHITE2_NTRACING
if (dbgout)
{
- seg->positionSlots(0, 0, 0, aSilf->dir());
+ seg->positionSlots(0, 0, 0, seg->currdir());
*dbgout << json::item
<< json::close // Close up the passes array
+ << "outputdir" << (seg->currdir() ? "rtl" : "ltr")
<< "output" << json::array;
for(Slot * s = seg->first(); s; s = s->next())
*dbgout << dslot(seg, s);
diff --git a/gfx/graphite2/src/GlyphCache.cpp b/gfx/graphite2/src/GlyphCache.cpp
index ae9035d1d..b521d5e5a 100644
--- a/gfx/graphite2/src/GlyphCache.cpp
+++ b/gfx/graphite2/src/GlyphCache.cpp
@@ -211,6 +211,8 @@ GlyphCache::~GlyphCache()
const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
{
+ if (glyphid >= numGlyphs())
+ return _glyphs[0];
const GlyphFace * & p = _glyphs[glyphid];
if (p == 0 && _glyph_loader)
{
@@ -389,12 +391,14 @@ const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFa
gloce = be::peek<uint16>(gloc);
}
- if (glocs + 1 >= m_pGlat.size() || gloce > m_pGlat.size())
+ if (glocs >= m_pGlat.size() - 1 || gloce > m_pGlat.size())
return 0;
const uint32 glat_version = be::peek<uint32>(m_pGlat);
if (glat_version >= 0x00030000)
{
+ if (glocs >= gloce)
+ return 0;
const byte * p = m_pGlat + glocs;
uint16 bmap = be::read<uint16>(p);
int num = bit_set_count((uint32)bmap);
diff --git a/gfx/graphite2/src/Justifier.cpp b/gfx/graphite2/src/Justifier.cpp
index e40e02902..f8a6f3bbe 100644
--- a/gfx/graphite2/src/Justifier.cpp
+++ b/gfx/graphite2/src/Justifier.cpp
@@ -100,7 +100,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
int numLevels = silf()->numJustLevels();
if (!numLevels)
{
- for (s = pSlot; s != end; s = s->next())
+ for (s = pSlot; s && s != end; s = s->nextSibling())
{
CharInfo *c = charinfo(s->before());
if (isWhitespace(c->unicodeChar()))
@@ -113,7 +113,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
}
if (!icount)
{
- for (s = pSlot; s != end; s = s->nextSibling())
+ for (s = pSlot; s && s != end; s = s->nextSibling())
{
s->setJustify(this, 0, 3, 1);
s->setJustify(this, 0, 2, 1);
@@ -124,7 +124,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
}
Vector<JustifyTotal> stats(numLevels);
- for (s = pFirst; s != end; s = s->nextSibling())
+ for (s = pFirst; s && s != end; s = s->nextSibling())
{
float w = s->origin().x / scale + s->advance() - base;
if (w > currWidth) currWidth = w;
@@ -139,13 +139,14 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
float error = 0.;
float diffpw;
int tWeight = stats[i].weight();
+ if (tWeight == 0) continue;
do {
error = 0.;
diff = width - currWidth;
diffpw = diff / tWeight;
tWeight = 0;
- for (s = pFirst; s != end; s = s->nextSibling()) // don't include final glyph
+ for (s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
{
int w = s->getJustify(this, i, 3);
float pref = diffpw * w + error;
diff --git a/gfx/graphite2/src/Pass.cpp b/gfx/graphite2/src/Pass.cpp
index 6f6b91331..b6d789423 100644
--- a/gfx/graphite2/src/Pass.cpp
+++ b/gfx/graphite2/src/Pass.cpp
@@ -339,7 +339,7 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
*t = be::read<uint16>(states);
if (e.test(*t >= m_numStates, E_BADSTATE))
{
- face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 24));
+ face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 8));
return face.error(e);
}
}
@@ -523,7 +523,7 @@ void Pass::findNDoRule(Slot * & slot, Machine &m, FiniteStateMachine & fsm) cons
if (r != re)
{
const int adv = doAction(r->rule->action, slot, m);
- dumpRuleEventOutput(fsm, m, *r->rule, slot);
+ dumpRuleEventOutput(fsm, *r->rule, slot);
if (r->rule->action->deletes()) fsm.slots.collectGarbage(slot);
adjustSlot(adv, slot, fsm.slots);
*fsm.dbgout << "cursor" << objectid(dslot(&fsm.slots.segment, slot))
@@ -579,7 +579,7 @@ void Pass::dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEnt
}
-void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, const Rule & r, Slot * const last_slot) const
+void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * const last_slot) const
{
*fsm.dbgout << json::item << json::flat << json::object
<< "id" << &r - m_rules
@@ -597,7 +597,7 @@ void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, cons
<< json::close // close "input"
<< "slots" << json::array;
const Position rsb_prepos = last_slot ? last_slot->origin() : fsm.slots.segment.advance();
- fsm.slots.segment.positionSlots(0, 0, 0, m.slotMap().dir());
+ fsm.slots.segment.positionSlots(0, 0, 0, fsm.slots.segment.currdir());
for(Slot * slot = output_slot(fsm.slots, 0); slot != last_slot; slot = slot->next())
*fsm.dbgout << dslot(&fsm.slots.segment, slot);
@@ -635,7 +635,7 @@ bool Pass::testPassConstraint(Machine & m) const
bool Pass::testConstraint(const Rule & r, Machine & m) const
{
const uint16 curr_context = m.slotMap().context();
- if (unsigned(r.sort - r.preContext) > m.slotMap().size() - curr_context
+ if (unsigned(r.sort + curr_context - r.preContext) > m.slotMap().size()
|| curr_context - r.preContext < 0) return false;
vm::slotref * map = m.slotMap().begin() + curr_context - r.preContext;
@@ -861,7 +861,6 @@ bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
{
- KernCollider kerncoll(dbgout);
Slot *start = seg->first();
float ymin = 1e38f;
float ymax = -1e38f;
@@ -880,11 +879,14 @@ bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
const SlotCollision * c = seg->collisionInfo(s);
const Rect &bbox = seg->theGlyphBBoxTemporary(s->gid());
float y = s->origin().y + c->shift().y;
- ymax = max(y + bbox.tr.y, ymax);
- ymin = min(y + bbox.bl.y, ymin);
+ if (!(c->flags() & SlotCollision::COLL_ISSPACE))
+ {
+ ymax = max(y + bbox.tr.y, ymax);
+ ymin = min(y + bbox.bl.y, ymin);
+ }
if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
== (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
- resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
+ resolveKern(seg, s, start, dir, ymin, ymax, dbgout);
if (c->flags() & SlotCollision::COLL_END)
start = NULL;
if (c->flags() & SlotCollision::COLL_START)
@@ -963,8 +965,8 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
{
SlotCollision *cNbor = seg->collisionInfo(nbor);
bool sameCluster = nbor->isChildOf(base);
- if (nbor != slotFix // don't process if this is the slot of interest
- && !(cNbor->flags() & SlotCollision::COLL_IGNORE) // don't process if ignoring
+ if (nbor != slotFix // don't process if this is the slot of interest
+ && !(cNbor->ignore()) // don't process if ignoring
&& (nbor == base || sameCluster // process if in the same cluster as slotFix
|| !inKernCluster(seg, nbor) // or this cluster is not to be kerned
|| (rtl ^ ignoreForKern)) // or it comes before(ltr) or after(rtl)
@@ -1023,7 +1025,7 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
return true;
}
-float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
+float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, int dir,
float &ymin, float &ymax, json *const dbgout) const
{
Slot *nbor; // neighboring slot
@@ -1043,6 +1045,7 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
}
bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
bool isInit = false;
+ KernCollider coll(dbgout);
for (nbor = slotFix->next(); nbor; nbor = nbor->next())
{
@@ -1052,7 +1055,7 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
return 0.;
const Rect &bb = seg->theGlyphBBoxTemporary(nbor->gid());
SlotCollision *cNbor = seg->collisionInfo(nbor);
- if (bb.bl.y == 0.f && bb.tr.y == 0.f)
+ if ((bb.bl.y == 0.f && bb.tr.y == 0.f) || (cNbor->flags() & SlotCollision::COLL_ISSPACE))
{
if (m_kernColls == InWord)
break;
@@ -1066,7 +1069,7 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
float y = nbor->origin().y + cNbor->shift().y;
ymax = max(y + bb.tr.y, ymax);
ymin = min(y + bb.bl.y, ymin);
- if (nbor != slotFix && !(cNbor->flags() & SlotCollision::COLL_IGNORE))
+ if (nbor != slotFix && !cNbor->ignore())
{
seenEnd = true;
if (!isInit)
diff --git a/gfx/graphite2/src/Segment.cpp b/gfx/graphite2/src/Segment.cpp
index 966f75784..3020bfd36 100644
--- a/gfx/graphite2/src/Segment.cpp
+++ b/gfx/graphite2/src/Segment.cpp
@@ -412,8 +412,9 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bo
Position currpos(0., 0.);
float clusterMin = 0.;
Rect bbox;
+ bool reorder = (currdir() != isRtl);
- if (currdir() != isRtl)
+ if (reorder)
{
Slot *temp;
reverseSlots();
@@ -443,6 +444,8 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bo
currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
}
}
+ if (reorder)
+ reverseSlots();
return currpos;
}
diff --git a/gfx/graphite2/src/Silf.cpp b/gfx/graphite2/src/Silf.cpp
index 02876881e..72a22cd46 100644
--- a/gfx/graphite2/src/Silf.cpp
+++ b/gfx/graphite2/src/Silf.cpp
@@ -384,9 +384,12 @@ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi
if (dbgout)
{
*dbgout << json::item << json::object
+// << "pindex" << i // for debugging
<< "id" << -1
+ << "slotsdir" << (seg->currdir() ? "rtl" : "ltr")
+ << "passdir" << (m_dir & 1 ? "rtl" : "ltr")
<< "slots" << json::array;
- seg->positionSlots(0, 0, 0, m_dir);
+ seg->positionSlots(0, 0, 0, seg->currdir());
for(Slot * s = seg->first(); s; s = s->next())
*dbgout << dslot(seg, s);
*dbgout << json::close
@@ -408,9 +411,12 @@ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi
if (dbgout)
{
*dbgout << json::item << json::object
+// << "pindex" << i // for debugging
<< "id" << i+1
+ << "slotsdir" << (seg->currdir() ? "rtl" : "ltr")
+ << "passdir" << ((m_dir & 1) ^ m_passes[i].reverseDir() ? "rtl" : "ltr")
<< "slots" << json::array;
- seg->positionSlots(0, 0, 0, m_dir);
+ seg->positionSlots(0, 0, 0, seg->currdir());
for(Slot * s = seg->first(); s; s = s->next())
*dbgout << dslot(seg, s);
*dbgout << json::close;
diff --git a/gfx/graphite2/src/inc/Collider.h b/gfx/graphite2/src/inc/Collider.h
index bcbf3a224..378c0cf48 100644
--- a/gfx/graphite2/src/inc/Collider.h
+++ b/gfx/graphite2/src/inc/Collider.h
@@ -54,7 +54,8 @@ public:
COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it
COLL_ISCOL = 32, // this glyph has a collision
COLL_KNOWN = 64, // we've figured out what's happening with this glyph
- COLL_TEMPLOCK = 128, // Lock glyphs that have been given priority positioning
+ COLL_ISSPACE = 128, // treat this glyph as a space with regard to kerning
+ COLL_TEMPLOCK = 256, // Lock glyphs that have been given priority positioning
////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
};
@@ -93,6 +94,7 @@ public:
SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
float getKern(int dir) const;
+ bool ignore() const;
private:
Rect _limit;
diff --git a/gfx/graphite2/src/inc/Machine.h b/gfx/graphite2/src/inc/Machine.h
index d7bb4f389..1a01b7a43 100644
--- a/gfx/graphite2/src/inc/Machine.h
+++ b/gfx/graphite2/src/inc/Machine.h
@@ -184,7 +184,7 @@ inline Machine::status_t Machine::status() const throw()
return _status;
}
-inline void Machine::check_final_stack(const int32 * const sp)
+inline void Machine::check_final_stack(const stack_t * const sp)
{
stack_t const * const base = _stack + STACK_GUARD,
* const limit = base + STACK_MAX;
diff --git a/gfx/graphite2/src/inc/Pass.h b/gfx/graphite2/src/inc/Pass.h
index c8f1aa20b..074d501d9 100644
--- a/gfx/graphite2/src/inc/Pass.h
+++ b/gfx/graphite2/src/inc/Pass.h
@@ -74,14 +74,14 @@ private:
uint16 glyphToCol(const uint16 gid) const;
bool runFSM(FiniteStateMachine & fsm, Slot * slot) const;
void dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
- void dumpRuleEventOutput(const FiniteStateMachine & fsm, vm::Machine & m, const Rule & r, Slot * os) const;
+ void dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * os) const;
void adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
bool collisionShift(Segment *seg, int dir, json * const dbgout) const;
bool collisionKern(Segment *seg, int dir, json * const dbgout) const;
bool collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
bool resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
int dir, bool &moved, bool &hasCol, json * const dbgout) const;
- float resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
+ float resolveKern(Segment *seg, Slot *slot, Slot *start, int dir,
float &ymin, float &ymax, json *const dbgout) const;
const Silf * m_silf;
diff --git a/gfx/graphite2/src/inc/opcodes.h b/gfx/graphite2/src/inc/opcodes.h
index 23f595fde..3b6dd3fc3 100644
--- a/gfx/graphite2/src/inc/opcodes.h
+++ b/gfx/graphite2/src/inc/opcodes.h
@@ -67,7 +67,8 @@ of the License or (at your option) any later version.
// #define NOT_IMPLEMENTED assert(false)
#define NOT_IMPLEMENTED
-#define binop(op) const int32 a = pop(); *sp = int32(*sp) op a
+#define binop(op) const uint32 a = pop(); *sp = uint32(*sp) op a
+#define sbinop(op) const int32 a = pop(); *sp = int32(*sp) op a
#define use_params(n) dp += n
#define declare_params(n) const byte * param = dp; \
@@ -130,7 +131,7 @@ ENDOP
STARTOP(div_)
if (*sp == 0) DIE;
- binop(/);
+ sbinop(/);
ENDOP
STARTOP(min_)
@@ -181,19 +182,19 @@ STARTOP(not_eq_)
ENDOP
STARTOP(less)
- binop(<);
+ sbinop(<);
ENDOP
STARTOP(gtr)
- binop(>);
+ sbinop(>);
ENDOP
STARTOP(less_eq)
- binop(<=);
+ sbinop(<=);
ENDOP
STARTOP(gtr_eq)
- binop(>=);
+ sbinop(>=);
ENDOP
STARTOP(next)