diff options
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-src/src/Slot.cpp')
-rw-r--r-- | Build/source/libs/graphite2/graphite2-src/src/Slot.cpp | 93 |
1 files changed, 50 insertions, 43 deletions
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp b/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp index 3330c8131fb..4227327c4b3 100644 --- a/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp +++ b/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp @@ -85,10 +85,10 @@ void Slot::update(int /*numGrSlots*/, int numCharInfo, Position &relpos) m_position = m_position + relpos; } -Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal) +Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth) { SlotCollision *coll = NULL; - if (attrLevel && m_attLevel > attrLevel) return Position(0, 0); + if (depth > 100 || (attrLevel && m_attLevel > attrLevel)) return Position(0, 0); float scale = font ? font->scale() : 1.0f; Position shift(m_shift.x * (rtl * -2 + 1) + m_just, m_shift.y); float tAdvance = m_advance.x + m_just; @@ -133,13 +133,13 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R if (m_child && m_child != this && m_child->attachedTo() == this) { - Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal); + Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1); if ((!m_parent || m_advance.x >= 0.5f) && tRes.x > res.x) res = tRes; } if (m_parent && m_sibling && m_sibling != this && m_sibling->attachedTo() == m_parent) { - Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal); + Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1); if (tRes.x > res.x) res = tRes; } @@ -165,25 +165,25 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, boo switch (metrics(metric)) { case kgmetLsb : - return static_cast<uint32>(bbox.bl.x); + return bbox.bl.x; case kgmetRsb : - return static_cast<uint32>(res.x - bbox.tr.x); + return res.x - bbox.tr.x; case kgmetBbTop : - return static_cast<uint32>(bbox.tr.y); + return bbox.tr.y; case kgmetBbBottom : - return static_cast<uint32>(bbox.bl.y); + return bbox.bl.y; case kgmetBbLeft : - return static_cast<uint32>(bbox.bl.x); + return bbox.bl.x; case kgmetBbRight : - return static_cast<uint32>(bbox.tr.x); + return bbox.tr.x; case kgmetBbWidth : - return static_cast<uint32>(bbox.tr.x - bbox.bl.x); + return bbox.tr.x - bbox.bl.x; case kgmetBbHeight : - return static_cast<uint32>(bbox.tr.y - bbox.bl.y); + return bbox.tr.y - bbox.bl.y; case kgmetAdvWidth : - return static_cast<uint32>(res.x); + return res.x; case kgmetAdvHeight : - return static_cast<uint32>(res.y); + return res.y; default : return 0; } @@ -295,9 +295,22 @@ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, cons if (idx < map.size() && map[idx]) { Slot *other = map[idx]; - if (other == this || other == m_parent) break; - if (m_parent) m_parent->removeChild(this); - if (!other->isChildOf(this) && other->child(this)) + if (other == this || other == m_parent || other->isCopied()) break; + if (m_parent) { m_parent->removeChild(this); attachTo(NULL); } + Slot *pOther = other; + int count = 0; + bool foundOther = false; + while (pOther) + { + ++count; + if (pOther == this) foundOther = true; + pOther = pOther->attachedTo(); + } + for (pOther = m_child; pOther; pOther = pOther->m_child) + ++count; + for (pOther = m_sibling; pOther; pOther = pOther->m_sibling) + ++count; + if (count < 100 && !foundOther && other->child(this)) { attachTo(other); if ((map.dir() != 0) ^ (idx > subindex)) @@ -421,31 +434,24 @@ bool Slot::sibling(Slot *ap) bool Slot::removeChild(Slot *ap) { - if (this == ap || !m_child) return false; + if (this == ap || !m_child || !ap) return false; else if (ap == m_child) { Slot *nSibling = m_child->nextSibling(); - m_child->removeSibling(nSibling); + m_child->nextSibling(NULL); m_child = nSibling; return true; } - else - return m_child->removeSibling(ap); - return true; -} - -bool Slot::removeSibling(Slot *ap) -{ - if (this == ap || !m_sibling) return false; - else if (ap == m_sibling) + for (Slot *p = m_child; p; p = p->m_sibling) { - m_sibling = m_sibling->nextSibling(); - if (m_sibling) ap->removeSibling(m_sibling); - return true; + if (p->m_sibling && p->m_sibling == ap) + { + p->m_sibling = p->m_sibling->m_sibling; + ap->nextSibling(NULL); + return true; + } } - else - return m_sibling->removeSibling(ap); - return true; + return false; } void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph) @@ -480,11 +486,13 @@ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph) } } -void Slot::floodShift(Position adj) +void Slot::floodShift(Position adj, int depth) { + if (depth > 100) + return; m_position += adj; - if (m_child) m_child->floodShift(adj); - if (m_sibling) m_sibling->floodShift(adj); + if (m_child) m_child->floodShift(adj, depth + 1); + if (m_sibling) m_sibling->floodShift(adj, depth + 1); } void SlotJustify::LoadSlot(const Slot *s, const Segment *seg) @@ -519,10 +527,9 @@ Slot * Slot::nextInCluster(const Slot *s) const bool Slot::isChildOf(const Slot *base) const { - if (m_parent == base) - return true; - else if (!m_parent) - return false; - else - return m_parent->isChildOf(base); + for (Slot *p = m_parent; p; p = p->m_parent) + if (p == base) + return true; + return false; } + |