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()]; } }
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); } } }