summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-src/src/Slot.cpp')
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Slot.cpp93
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;
}
+