Пример #1
0
CRasterFont::CRasterFont(urde::CInputStream& in, urde::IObjectStore& store)
{
    u32 magic;
    in.readBytesToBuf(&magic, 4);
    if (magic != SBIG('FONT'))
        return;

    u32 version = in.readUint32Big();
    x4_monoWidth = in.readUint32Big();
    x8_monoHeight = in.readUint32Big();

    if (version >= 1)
        x8c_baseline = in.readUint32Big();
    else
        x8c_baseline = x8_monoHeight;

    if (version >= 2)
        x90_lineMargin = in.readUint32Big();

    bool tmp1 = in.readBool();
    bool tmp2 = in.readBool();

    u32 tmp3 = in.readUint32Big();
    u32 tmp4 = in.readUint32Big();
    std::string name= in.readString();
    u32 txtrId = in.readUint32Big();
    x30_fontInfo = CFontInfo(tmp1, tmp2, tmp3, tmp4, name.c_str());
    x80_texture = store.GetObj({'TXTR', txtrId});
    EColorType mode = EColorType(in.readUint32Big());
    /* TODO: Make an enum */
    if (mode == EColorType::One)
        x2c_mode = EColorType::One;
    else if (mode == EColorType::Zero)
        x2c_mode = EColorType::Zero;

    u32 glyphCount = in.readUint32Big();
    xc_glyphs.reserve(glyphCount);

    for (u32 i = 0 ; i < glyphCount ; ++i)
    {
        wchar_t chr = in.readUint16Big();
        float startU = in.readFloatBig();
        float startV = in.readFloatBig();
        float endU = in.readFloatBig();
        float endV = in.readFloatBig();
        s32 a = in.readInt32Big();
        s32 b = in.readInt32Big();
        s32 c = in.readInt32Big();
        s32 cellWidth = in.readInt32Big();
        s32 cellHeight = in.readInt32Big();
        s32 baseline = in.readInt32Big();
        s32 kernStart = in.readInt32Big();
        xc_glyphs[i] = std::make_pair(chr, CGlyph(a, b, c, startU, startV, endU, endV,
                                                  cellWidth, cellHeight, baseline, kernStart));
    }

    std::sort(xc_glyphs.begin(), xc_glyphs.end(), [=](auto& a, auto& b) -> bool{
        return a.first < b.first;
    });

    u32 kernCount = in.readUint32Big();
    x1c_kerning.reserve(kernCount);

    for (u32 i = 0 ; i < kernCount ; ++i)
    {
        wchar_t first = in.readUint16Big();
        wchar_t second = in.readUint16Big();
        s32 howMuch = in.readUint32Big();
        x1c_kerning[i] = CKernPair(first, second, howMuch);
    }
}
Пример #2
0
CTextRenderer::CGlyph* CTextRenderer::CGlyphCache::NewGlyph(CGlyphId GlyphId, int Width, int Height)
{	
	ivec2 Granularity;
	Granularity.x = (Width%m_PPG == 0 ? (Width / m_PPG) : (Width / m_PPG) + 1);
	Granularity.y = (Height%m_PPG == 0 ? (Height / m_PPG) : (Height / m_PPG) + 1);
	if(Granularity.x < 1)
		Granularity.x = 1;
	if(Granularity.y < 1)
		Granularity.y = 1;
	
	//First pass: find a free slot in blocks
		//We use backward iteration because non-full blockes are at the end
	for(int i=m_Blocks.size()-1; i>=0; i--)
	{
		if(m_Blocks[i].m_Granularity == Granularity)
		{
			if(!m_Blocks[i].IsFull())
			{
				CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))];
				
				pGlyph->m_Width = Width;
				pGlyph->m_Height = Height;
				pGlyph->m_Granularity = Granularity;
				pGlyph->m_Block = i;
				pGlyph->m_BlockPos = m_Blocks[i].m_Size;
				UpdateGlyph(pGlyph);
		
				m_Blocks[pGlyph->m_Block].m_Size++;
				
				return pGlyph;
			}
			else
				break; //Only the last block of this granularity can be non-full
		}
	}
	
	//Second pass: find the oldest glyph with the same granularity
	int OldestTick = m_RenderTick;
	int OldestGlyph = -1;
	for(int i=0; i<m_Glyphs.size(); i++)
	{
		if(m_Glyphs[i].m_Granularity == Granularity && m_Glyphs[i].m_RenderTick < OldestTick)
		{
			OldestTick = m_Glyphs[i].m_RenderTick;
			OldestGlyph = i;
		}
	}
	
	if(OldestGlyph >= 0) //Replace the glyph
	{
		CGlyph Glyph = CGlyph(GlyphId);
		Glyph.m_Block = m_Glyphs[OldestGlyph].m_Block;
		Glyph.m_BlockPos = m_Glyphs[OldestGlyph].m_BlockPos;
		
		m_Glyphs.remove_index(OldestGlyph);
		
		int GlyphId = m_Glyphs.add(Glyph);
		CGlyph* pGlyph = &m_Glyphs[GlyphId];
		
		pGlyph->m_Width = Width;
		pGlyph->m_Height = Height;
		pGlyph->m_Granularity = Granularity;
		UpdateGlyph(pGlyph);
		UpdateVersion();
		
		return pGlyph;
	}
	else //Add a new block
	{
		int BlockId = NewBlock(Granularity);

		CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))];
		
		pGlyph->m_Width = Width;
		pGlyph->m_Height = Height;
		pGlyph->m_Granularity = Granularity;
		pGlyph->m_Block = BlockId;
		pGlyph->m_BlockPos = 0;
		
		UpdateGlyph(pGlyph);
		
		m_Blocks[pGlyph->m_Block].m_Size++;
		
		return pGlyph;
	}
}