mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-08 17:39:19 +00:00
Update Graphite to v1.3.9
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
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
|
||||
. Fix ARM misalignment problem
|
||||
. Track latest cmake
|
||||
|
||||
1.3.4
|
||||
. Transition from Mercurial to Git
|
||||
. Bug fixes
|
||||
. Fix Collision Kerning ignoring some diacritics
|
||||
. Handle pass bits 16-31 to speed up fonts with > 16 passes
|
||||
. Various minor fuzz bug fixes
|
||||
. Make Coverity happy
|
||||
. Add GR_FALLTHROUGH macro for clang c++11
|
||||
|
||||
1.3.3
|
||||
. Slight speed up in Collision Avoidance
|
||||
. Remove dead bidi code
|
||||
. Bug fixes
|
||||
. Between pass bidi reorderings and at the end
|
||||
. Decompressor fuzz bugs
|
||||
. Other fuzz bugs
|
||||
|
||||
1.3.2
|
||||
. Remove full bidi. All segments are assumed to be single directioned.
|
||||
. Bug fixes:
|
||||
. Decompressor corner cases
|
||||
. Various fuzz bugs
|
||||
|
||||
1.3.1
|
||||
. Deprecation warning: Full bidi support is about to be deprecated. Make contact
|
||||
if this impacts you.
|
||||
. Change compression block format slightly to conform to LZ4
|
||||
. Bug fixes:
|
||||
. Handle mono direction text with diacritics consistently. Fonts
|
||||
now see the direction they expect consistently and bidi now
|
||||
gives expected results.
|
||||
. Fixed lots of fuzz bugs
|
||||
. Coverity cleanups
|
||||
. Build now works for clang and/or asan and/or afl etc.
|
||||
|
||||
1.3.0
|
||||
. Add collision avoidance
|
||||
. Shift Collider
|
||||
. Kern Collider
|
||||
. Octabox outlines and subboxes
|
||||
. Add compressed Silf and Glat table support
|
||||
. Bug fixes:
|
||||
. Stop loops forming in the child, sibling tree
|
||||
. Handle bidi mirroring correctly if no bidi occurring
|
||||
|
||||
1.2.4
|
||||
. Face failure now has error code reporting via debug logging
|
||||
. can now call gr_start_logging(NULL, fname)
|
||||
. gr2fonttest --alltrace added
|
||||
. Format 14 table support
|
||||
. Not done. To be handled entirely in the compiler
|
||||
. Bidi support for Unicode 6.3 Isolating direction controls
|
||||
. Fonts no longer require a glyf/loca table. In such cases the bounding box is always 0.
|
||||
. Clang ASAN build support added for testing.
|
||||
. Handle out of memory sanely.
|
||||
. Documentation improvements
|
||||
. Bug fixes:
|
||||
. Enforce fonts having to store glyph attributes by monotonically increasing attribute number
|
||||
. zeropadding was not getting called on feature tags
|
||||
. automatic associations for unassociated characters
|
||||
. use direct engine on Mac
|
||||
. various extreme case reading 1 past the end errors fixed
|
||||
. remove tabs from sources so that it becomes readable again
|
||||
|
||||
1.2.3
|
||||
. Bug fixes only:
|
||||
. fix byte swapping when testing cmap subtable lengths
|
||||
. work around armel compilation problems with conditional operators
|
||||
. fix pseudoglyph support for advance and bbox
|
||||
|
||||
1.2.2
|
||||
. Add support for passKeySlot (makes Charis 2x faster) up to 32 passes
|
||||
. Add telemetry output to json if enabled in build GRAPHITE2_TELEMETRY
|
||||
. Shrink font memory footprint particularly in the fsm
|
||||
. Add -S to comparerenderer
|
||||
. Bug fixes:
|
||||
. Fix shift.x being reversed for rtl text
|
||||
. Fix faulty fallback justification
|
||||
. Fix bad cmap handling
|
||||
. Support compiling on old Solaris where bidi attributes clash with register names
|
||||
. Follow the crowd in using Windows.h
|
||||
|
||||
1.2.1
|
||||
. Bug fixes:
|
||||
. Allow glyph reattachment
|
||||
. Allow signed glyph attributes
|
||||
. Various build problems with MacOS, old gcc versions, etc.
|
||||
. Various overrun read errors fixed
|
||||
|
||||
1.2.0
|
||||
. API Changes:
|
||||
. Added Windows friendly gr_start_logging and gr_stop_logging, now per face
|
||||
. Added gr_make_face_with_ops, gr_make_face_with_seg_cache_and_ops
|
||||
. Added gr_make_font_with_ops
|
||||
. Added gr_face_is_char_supported
|
||||
. Added gr_face_info to give info to apps about face capabilities
|
||||
. Deprecated gr_make_face, gr_make_face_with_seg_cache, gr_make_font_with_advance_fn
|
||||
. Deprecated graphite_start_logging and graphite_stop_logging
|
||||
. These functions are stubbed now and do nothing, but do compile and link.
|
||||
. Bump API version to 3
|
||||
. Add C# wrapper to contrib
|
||||
. Handle justification information in a font and do something useful with it
|
||||
. Builds clang clean (has done for a while)
|
||||
. Bug fixes
|
||||
. Windows build and bug fixes
|
||||
. Add extra information to json debug output
|
||||
. Added windows build documentation
|
||||
. Added freetype sample code and test
|
||||
|
||||
1.1.3
|
||||
. Default build has GRAPHITE2_COMPARE_RENDERER to OFF to reduce dependencies
|
||||
. Builds on Mac with clang
|
||||
. Debug output improvements
|
||||
. Tidy up perl wrappers
|
||||
. Fuzz tester improvements
|
||||
. Various bug fixes for bad font handling
|
||||
|
||||
1.1.2
|
||||
. Support feature ids < 4 chars when space padded for inclusion in FF 14.
|
||||
. More fuzztesting and removal of causes of valgrind bad reads and sigabrts
|
||||
. Remove contrib/android into its own repo (http://hg.palaso.org/grandroid)
|
||||
. Update comparerenderer to latest harfbuzzng api
|
||||
|
||||
1.1.1
|
||||
. Missing Log.h included
|
||||
. perl wrappers updated
|
||||
|
||||
1.1.0
|
||||
. Refactored debug output to use json
|
||||
. Renamed VM_MACHINE_TYPE to GRAPHITE2_VM_TYPE
|
||||
. Renamed DISABLE_SEGCACHE to GRAPHITE2_NSEGCACE
|
||||
. Renamed DISBALE_FILE_FACE to GRAPHITE2_NFILEFACE
|
||||
. Renamed ENABLE_COMPARE_RENDERER to GRAPHTIE2_COMPARE_RENDERER
|
||||
. Renamed DOXYGEN_CONFIG to GRAPHITE2_DOXYGEN_CONFIG
|
||||
. Renamed GR2_CUSTOM_HEADER to GRAPHITE2_CUSTOM_HEADER
|
||||
. Renamed GR2_EXPORTING to GRAPHITE2_EXPORTING
|
||||
. Added GRAPHITE2_STATIC for static only builds
|
||||
. Added GRAPHITE2_NTRACING to compile out tracing code
|
||||
. Documented GRAPHITE2_{EXPORTING,STATIC,NTRACING} in hacking.txt
|
||||
. Bump libtool version to 2.1.0
|
||||
. dumb font rendering works
|
||||
. slot user attributes are now signed rather than unsigned
|
||||
. add support for long class maps
|
||||
. Rename perl library to avoid nameclash on Windows
|
||||
. Various robustness fixes
|
||||
. Moved internal .h files into src/inc
|
||||
. Parallelise fuzztest
|
||||
. General build improvements, particularly on Windows
|
||||
|
||||
1.0.3
|
||||
. Fix UTF16 surrogate support
|
||||
. script and lang tags may be space padded or null padded
|
||||
. Remove need for WORDS_BIGENDIAN, do it all automatically
|
||||
. Remove all #include <new>. Use CLASS_NEW_DELETE instead.
|
||||
. Fix comparerenderer to work with current hbng
|
||||
. Add valgrind to fuzztest to ensure good memory use at all times
|
||||
. Fix new fuzztest exposed bugs.
|
||||
. Fix bugs exposed by Mozilla security review
|
||||
. Add continuous integration build on Windows support
|
||||
|
||||
1.0.2
|
||||
. Fix Windows build
|
||||
. Comparerenderer uses hbng enforcing ot rendering
|
||||
. Add Bidi .hasChar support and refactor mirroring code
|
||||
. Make cmake default Release rather than debug
|
||||
. Don't compile in a boat load of TtfUtil that isn't used, saving 15% of binary
|
||||
. Chase the FSF around its latest office moves
|
||||
. WORDS_BIGENDIAN is set at the top so tests now pass on ppc, etc.
|
||||
. More words in the manual
|
||||
|
||||
1.0.1
|
||||
. Release is the default build in cmake now.
|
||||
. Refactor cmake build to not rebuild things so much.
|
||||
. Include a missing file
|
||||
. Remove -nostdlibs, making gcc happy everywhere
|
||||
. Update comparerenderer to latest hbng interface
|
||||
. Add changelog
|
||||
|
||||
1.0.0
|
||||
. First major release of perfect code!
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+17
-14
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user