Segment::~Segment()
{ for (SlotRope::iterator i = m_slots.begin(); i != m_slots.end(); ++i)
free(*i); for (AttributeRope::iterator i = m_userAttrs.begin(); i != m_userAttrs.end(); ++i)
free(*i); for (JustifyRope::iterator i = m_justifies.begin(); i != m_justifies.end(); ++i)
free(*i); delete[] m_charinfo;
free(m_collisions);
}
void Segment::appendSlot(int id, int cid, int gid, int iFeats, size_t coffset)
{
Slot *aSlot = newSlot();
// reverse the slots but keep diacritics in their same position after their bases void Segment::reverseSlots()
{
m_dir = m_dir ^ 64; // invert the reverse flag if (m_first == m_last) return; // skip 0 or 1 glyph runs
while (curr && getSlotBidiClass(curr) == 16)
curr = curr->next(); if (!curr) return;
tfirst = curr->prev();
tlast = curr;
while (curr)
{ if (getSlotBidiClass(curr) == 16)
{
Slot *d = curr->next(); while (d && getSlotBidiClass(d) == 16)
d = d->next();
d = d ? d->prev() : m_last;
Slot *p = out->next(); // one after the diacritics. out can't be null if (p)
p->prev(d); else
tlast = d;
t = d->next();
d->next(p);
curr->prev(out);
out->next(curr);
} else// will always fire first time round the loop
{ if (out)
out->prev(curr);
t = curr->next();
curr->next(out);
out = curr;
}
curr = t;
}
out->prev(tfirst); if (tfirst)
tfirst->next(out); else
m_first = out;
m_last = tlast;
}
void Segment::linkClusters(Slot *s, Slot * end)
{
end = end->next();
for (; s != end && !s->isBase(); s = s->next());
Slot * ls = s;
if (m_dir & 1)
{ for (; s != end; s = s->next())
{ if (!s->isBase()) continue;
s->sibling(ls);
ls = s;
}
} else
{ for (; s != end; s = s->next())
{ if (!s->isBase()) continue;
ls->sibling(s);
ls = s;
}
}
}
Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bool isRtl, bool isFinal)
{
Position currpos(0., 0.); float clusterMin = 0.;
Rect bbox; bool reorder = (currdir() != isRtl);
if (reorder)
{
Slot *temp;
reverseSlots();
temp = iStart;
iStart = iEnd;
iEnd = temp;
} if (!iStart) iStart = m_first; if (!iEnd) iEnd = m_last;
if (!iStart || !iEnd) // only true for empty segments return currpos;
if (isRtl)
{ for (Slot * s = iEnd, * const end = iStart->prev(); s && s != end; s = s->prev())
{ if (s->isBase())
currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
}
} else
{ for (Slot * s = iStart, * const end = iEnd->next(); s && s != end; s = s->next())
{ if (s->isBase())
currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
}
} if (reorder)
reverseSlots(); return currpos;
}
void Segment::associateChars(int offset, size_t numChars)
{ int i = 0, j = 0;
CharInfo *c, *cend; for (c = m_charinfo + offset, cend = m_charinfo + offset + numChars; c != cend; ++c)
{
c->before(-1);
c->after(-1);
} for (Slot * s = m_first; s; s->index(i++), s = s->next())
{
j = s->before(); if (j < 0) continue;
for (constint after = s->after(); j <= after; ++j)
{
c = charinfo(j); if (c->before() == -1 || i < c->before()) c->before(i); if (c->after() < i) c->after(i);
}
} for (Slot *s = m_first; s; s = s->next())
{ int a; for (a = s->after() + 1; a < offset + int(numChars) && charinfo(a)->after() < 0; ++a)
{ charinfo(a)->after(s->index()); }
--a;
s->after(a);
for (a = s->before() - 1; a >= offset && charinfo(a)->before() < 0; --a)
{ charinfo(a)->before(s->index()); }
++a;
s->before(a);
}
}
const typename utf_iter::codeunit_type * const base = c; for (; n_chars; --n_chars, ++c, ++slotid)
{ const uint32 usv = *c;
uint16 gid = cmap[usv]; if (!gid) gid = face.findPseudo(usv);
seg.appendSlot(slotid, usv, gid, fid, c - base);
}
}
bool Segment::read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void* pStart, size_t nChars)
{
assert(face);
assert(pFeats); if (!m_charinfo) returnfalse;
// utf iterator is self recovering so we don't care about the error state of the iterator. switch (enc)
{ case gr_utf8: process_utf_data(*this, *face, addFeatures(*pFeats), utf8::const_iterator(pStart), nChars); break; case gr_utf16: process_utf_data(*this, *face, addFeatures(*pFeats), utf16::const_iterator(pStart), nChars); break; case gr_utf32: process_utf_data(*this, *face, addFeatures(*pFeats), utf32::const_iterator(pStart), nChars); break;
} return true;
}
void Segment::doMirror(uint16 aMirror)
{
Slot * s; for (s = m_first; s; s = s->next())
{ unsignedshort g = glyphAttr(s->gid(), aMirror); if (g && (!(dir() & 4) || !glyphAttr(s->gid(), aMirror + 1)))
s->setGlyph(this, g);
}
}
bool Segment::initCollisions()
{
m_collisions = grzeroalloc<SlotCollision>(slotCount()); if (!m_collisions) returnfalse;
for (Slot *p = m_first; p; p = p->next()) if (p->index() < slotCount())
::new (collisionInfo(p)) SlotCollision(this, p); else returnfalse; return true;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.