Пример #1
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()];
    }
}
Пример #2
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);
        }
    }
}