Beispiel #1
0
inline
Slot * input_slot(const SlotMap &  slots, const int n)
{
	Slot * s = slots[slots.context() + n];
	if (!s->isCopied()) 	return s;

	return s->prev() ? s->prev()->next() : (s->next() ? s->next()->prev() : slots.segment.last());
}
Beispiel #2
0
void Segment::splice(size_t offset, size_t length, Slot * const startSlot,
                       Slot * endSlot, const Slot * srcSlot,
                       const size_t numGlyphs)
{
    size_t numChars = length;
    extendLength(numGlyphs - length);
    // remove any extra
    if (numGlyphs < length)
    {
        Slot * end = endSlot->next();
        do
        {
            endSlot = endSlot->prev();
            freeSlot(endSlot->next());
        } while (numGlyphs < --length);
        endSlot->next(end);
        if (end)
            end->prev(endSlot);
    }
    else
    {
        // insert extra slots if needed
        while (numGlyphs > length)
        {
            Slot * extra = newSlot();
            if (!extra) return;
            extra->prev(endSlot);
            extra->next(endSlot->next());
            endSlot->next(extra);
            if (extra->next())
                extra->next()->prev(extra);
            if (m_last == endSlot)
                m_last = extra;
            endSlot = extra;
            ++length;
        }
    }

    endSlot = endSlot->next();
    assert(numGlyphs == length);
    assert(offset + numChars <= m_numCharinfo);
    Slot * indexmap[eMaxSpliceSize*3];
    assert(numGlyphs < sizeof indexmap/sizeof *indexmap);
    Slot * slot = startSlot;
    for (uint16 i=0; i < numGlyphs; slot = slot->next(), ++i)
        indexmap[i] = slot;

    for (slot = startSlot; slot != endSlot; slot = slot->next(), srcSlot = srcSlot->next())
    {
        slot->set(*srcSlot, offset, m_silf->numUser(), m_silf->numJustLevels(), numChars);
        if (srcSlot->attachedTo())  slot->attachTo(indexmap[srcSlot->attachedTo()->index()]);
        if (srcSlot->nextSibling()) slot->m_sibling = indexmap[srcSlot->nextSibling()->index()];
        if (srcSlot->firstChild())  slot->m_child = indexmap[srcSlot->firstChild()->index()];
    }
}
Beispiel #3
0
SegCacheEntry::SegCacheEntry(const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset, long long cacheTime)
    : m_glyphLength(0), m_unicode(gralloc<uint16>(length)), m_glyph(NULL),
    m_attr(NULL), m_justs(NULL),
    m_accessCount(0), m_lastAccess(cacheTime)
{
    if (m_unicode)
        for (uint16 i = 0; i < length; i++)
            m_unicode[i] = cmapGlyphs[i];

    const size_t    glyphCount = seg->slotCount(),
                    sizeof_sjust = SlotJustify::size_of(seg->silf()->numJustLevels());
    if (!glyphCount) return;
    size_t num_justs = 0,
           justs_pos = 0;
    if (seg->hasJustification())
    {
        for (const Slot * s = seg->first(); s; s = s->next())
        {
            if (s->m_justs == 0)    continue;
            ++num_justs;
        }
        m_justs = gralloc<byte>(sizeof_sjust * num_justs);
    }
    const Slot * slot = seg->first();
    m_glyph = new Slot[glyphCount];
    m_attr = gralloc<int16>(glyphCount * seg->numAttrs());
    if (!m_glyph || (!m_attr && seg->numAttrs())) return;
    m_glyphLength = glyphCount;
    Slot * slotCopy = m_glyph;
    m_glyph->prev(NULL);

    uint16 pos = 0;
    while (slot)
    {
        slotCopy->userAttrs(m_attr + pos * seg->numAttrs());
        slotCopy->m_justs = m_justs ? reinterpret_cast<SlotJustify *>(m_justs + justs_pos++ * sizeof_sjust) : 0;
        slotCopy->set(*slot, -static_cast<int32>(charOffset), seg->numAttrs(), seg->silf()->numJustLevels(), length);
        slotCopy->index(pos);
        if (slot->firstChild())
            slotCopy->m_child = m_glyph + slot->firstChild()->index();
        if (slot->attachedTo())
            slotCopy->attachTo(m_glyph + slot->attachedTo()->index());
        if (slot->nextSibling())
            slotCopy->m_sibling = m_glyph + slot->nextSibling()->index();
        slot = slot->next();
        ++slotCopy;
        ++pos;
        if (slot)
        {
            slotCopy->prev(slotCopy-1);
            (slotCopy-1)->next(slotCopy);
        }
    }
}
Beispiel #4
0
// 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

    Slot *t = 0;
    Slot *curr = m_first;
    Slot *tlast;
    Slot *tfirst;
    Slot *out = 0;

    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;
}
Beispiel #5
0
void Segment::appendSlot(int id, int cid, int gid, int iFeats, size_t coffset)
{
    Slot *aSlot = newSlot();
    
    if (!aSlot) return;
    m_charinfo[id].init(cid);
    m_charinfo[id].feats(iFeats);
    m_charinfo[id].base(coffset);
    const GlyphFace * theGlyph = m_face->glyphs().glyphSafe(gid);
    m_charinfo[id].breakWeight(theGlyph ? theGlyph->attrs()[m_silf->aBreak()] : 0);
    
    aSlot->child(NULL);
    aSlot->setGlyph(this, gid, theGlyph);
    aSlot->originate(id);
    aSlot->before(id);
    aSlot->after(id);
    if (m_last) m_last->next(aSlot);
    aSlot->prev(m_last);
    m_last = aSlot;
    if (!m_first) m_first = aSlot;
    if (theGlyph && m_silf->aPassBits())
        m_passBits &= theGlyph->attrs()[m_silf->aPassBits()] 
                    | (m_silf->numPasses() > 16 ? (theGlyph->attrs()[m_silf->aPassBits() + 1] << 16) : 0);
}
SegCacheEntry::SegCacheEntry(const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset, long long cacheTime)
    : m_glyphLength(0), m_unicode(gralloc<uint16>(length)), m_glyph(NULL),
    m_attr(NULL),
    m_accessCount(0), m_lastAccess(cacheTime)
{
    for (uint16 i = 0; i < length; i++)
    {
        m_unicode[i] = cmapGlyphs[i];
    }
    size_t glyphCount = seg->slotCount();
    const Slot * slot = seg->first();
    m_glyph = new Slot[glyphCount];
    m_attr = gralloc<uint16>(glyphCount * seg->numAttrs());
    m_glyphLength = glyphCount;
    Slot * slotCopy = m_glyph;
    m_glyph->prev(NULL);
    struct Index2Slot {
        Index2Slot(uint16 i, const Slot * s) : m_i(i), m_slot(s) {};
        Index2Slot() : m_i(0), m_slot(NULL) {};
        uint16 m_i;
        const Slot * m_slot;
    };
    struct Index2Slot parentGlyphs[eMaxSpliceSize];
    struct Index2Slot childGlyphs[eMaxSpliceSize];
    uint16 numParents = 0;
    uint16 numChildren = 0;
    uint16 pos = 0;
    while (slot)
    {
        slotCopy->userAttrs(m_attr + pos * seg->numAttrs());
        slotCopy->set(*slot, -static_cast<int32>(charOffset), seg->numAttrs());
        if (slot->firstChild())
        {
            new(parentGlyphs + numParents) Index2Slot( pos, slot );
            ++numParents;
        }
        if (slot->attachedTo())
        {
            new(childGlyphs + numChildren) Index2Slot( pos, slot );
            ++numChildren;
        }
        slot = slot->next();
        ++slotCopy;
        ++pos;
        if (slot)
        {
            slotCopy->prev(slotCopy-1);
            (slotCopy-1)->next(slotCopy);
        }
    }
    // loop over the attached children finding their siblings and parents
    for (int16 i = 0; i < numChildren; i++)
    {
        if (childGlyphs[i].m_slot->nextSibling())
        {
            for (int16 j = i; j < numChildren; j++)
            {
                if (childGlyphs[i].m_slot->nextSibling() == childGlyphs[j].m_slot)
                {
                    m_glyph[childGlyphs[i].m_i].sibling(m_glyph + childGlyphs[j].m_i);
                    break;
                }
            }
            if (!m_glyph[childGlyphs[i].m_i].nextSibling())
            {
                // search backwards
                for (int16 j = i-1; j >= 0; j--)
                {
                    if (childGlyphs[i].m_slot->nextSibling() == childGlyphs[j].m_slot)
                    {
                        m_glyph[childGlyphs[i].m_i].sibling(m_glyph + childGlyphs[j].m_i);
                        break;
                    }
                }
            }
        }
        // now find the parent glyph
        for (int16 j = 0; j < numParents; j++)
        {
            if (childGlyphs[i].m_slot->attachedTo() == parentGlyphs[j].m_slot)
            {
                m_glyph[childGlyphs[i].m_i].attachTo(m_glyph + parentGlyphs[j].m_i);
                if (parentGlyphs[j].m_slot->firstChild() == childGlyphs[i].m_slot)
                {
                    m_glyph[parentGlyphs[j].m_i].child(m_glyph + childGlyphs[i].m_i);
                }
            }
        }
    }
}
Beispiel #7
0
void SetDeferredRunClass(Slot *s, Slot *sRun, int nval)
{
    if (!sRun || s == sRun) return;
    for (Slot *p = s->prev(); p != sRun; p = p->prev())
        p->setBidiClass(nval);
}