Example #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()];
    }
}
Example #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);
        }
    }
}
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);
                }
            }
        }
    }
}
Example #4
0
void CHM_Static::Update	()
{
	Fvector&	view	= Device.vCameraPosition;
	int			v_x		= iFloor(view.x/dhm_size);
	int			v_z		= iFloor(view.z/dhm_size);
	
	// *****	SCROLL
	if (v_x!=c_x)	{
		if (v_x>c_x)	{
			// scroll matrix to left
			++c_x;
			for (int z=0; z<dhm_matrix; ++z)
			{
				Slot*	S	= data[z][0];
				if (S->bReady)	{	S->bReady = FALSE; task.push_back(S); }
				for (int x=1; x<dhm_matrix; ++x)	data[z][x-1] = data[z][x];
				data[z][dhm_matrix-1] = S;
				S->set	(c_x-dhm_line+dhm_matrix-1, c_z-dhm_line+z);
			}
		} else {
			// scroll matrix to right
			--c_x;
			for (int z=0; z<dhm_matrix; ++z)
			{
				Slot*	S	= data[z][dhm_matrix-1];
				if (S->bReady)	{	S->bReady = FALSE; task.push_back(S); }
				for (int x=dhm_matrix-1; x>0; --x)	data[z][x] = data[z][x-1]; 
				data[z][0]	= S;
				S->set	(c_x-dhm_line+0,c_z-dhm_line+z);
			}
		}
	}
	if (v_z!=c_z)	{
		if (v_z>c_z)	{
			// scroll matrix down a bit
			++c_z;
			for (int x=0; x<dhm_matrix; ++x)
			{
				Slot*	S	= data[dhm_matrix-1][x];
				if (S->bReady)	{	S->bReady = FALSE; task.push_back(S); }
				for (int z=dhm_matrix-1; z>0; --z)	data[z][x] = data[z-1][x];
				data[0][x]	= S;
				S->set	(c_x-dhm_line+x,c_z-dhm_line+0);
			}
		} else {
			// scroll matrix up
			--c_z;
			for (int x=0; x<dhm_matrix; ++x)
			{
				Slot*	S = data[0][x];
				if (S->bReady)	{	S->bReady = FALSE; task.push_back(S); }
				for (int z=0; z<dhm_matrix; ++z)	data[z-1][x] = data[z][x];
				data[dhm_matrix-1][x]	= S;
				S->set	(c_x-dhm_line+x,c_z-dhm_line+dhm_matrix-1);
			}
		}
	}
	
	// *****	perform TASKs
	for (int taskid=0; (taskid<tasksPerFrame) && (!task.empty()); ++taskid)
	{
		Slot*	S	= task.back	();	task.pop_back();
		S->bReady	= TRUE;

		// Build BBox
		Fbox				bb;
		bb.min.set			(S->x*dhm_size,		view.y-limit_down,	S->z*dhm_size);
		bb.max.set			(bb.min.x+dhm_size,	view.y+limit_up,	bb.min.z+dhm_size);
		bb.grow				(EPS_L);
		
		// Select polygons
		XRC.BBoxMode		(0); // BBOX_TRITEST
		XRC.BBoxCollide		(precalc_identity,g_pGameLevel->ObjectSpace.GetStaticModel(),precalc_identity,bb);
		u32	triCount	= XRC.GetBBoxContactCount();
		if (0==triCount)	{
			S->clear	();
			continue;
		}
		
		// Cull polys
		RAPID::tri* tris	= g_pGameLevel->ObjectSpace.GetStaticTris();
		Fvector		vecUP;	vecUP.set(0,1,0);
		for (u32 tid=0; tid<triCount; ++tid)
		{
			RAPID::tri&	T		= tris[XRC.BBoxContact[tid].id];
			Poly		P;
			Fvector		N;
			P.v[0].set	(*T.verts[0]);	P.v[1].set	(*T.verts[1]);	P.v[2].set	(*T.verts[2]);
			N.mknormal	(P.v[0],P.v[1],P.v[2]);
			if (N.dotproduct(vecUP)<=0)	continue;
			polys.push_back		(P);
		}
		
		// Perform testing
		for (int z=0; z<dhm_precision; ++z)
		{
			for (int x=0; x<dhm_precision; ++x)
			{
				float	rx	= (float(x)/float(dhm_precision))*dhm_size + bb.min.x;
				float	rz	= (float(z)/float(dhm_precision))*dhm_size + bb.min.z;
				float	ry	= bb.min.y-5;
				Fvector pos; pos.set(rx,bb.max.y,rz);
				Fvector	dir; dir.set(0,-1,0);
				
				float	r_u,r_v,r_range;
				for (u32 tid=0; tid<polys.size(); ++tid)
				{
					if (RAPID::TestRayTri(pos,dir,polys[tid].v,r_u,r_v,r_range,TRUE))
					{
						if (r_range>=0)	{
							float y_test	= pos.y - r_range;
							if (y_test>ry)	ry = y_test;
						}
					}
				}
				S->data[z][x] = ry;
			}
		}
	}
}