void TextureFont::MeasureCharacterPos(const std::string &str, int charIndex, float &charX, float &charY)
{
    assert(charIndex >= 0);

    float x = 0.0f, y = GetHeight();
    int i = 0;
    Uint32 chr;
    int len = utf8_decode_char(&chr, &str[i]);
    while (str[i] && (i < charIndex)) {
        Uint32 nextChar;
        i += len;
        len = utf8_decode_char(&nextChar, &str[i]);
        assert(!str[i] || len); // assert valid encoding

        if (chr == '\n') {
            x = 0.0f;
            y += GetHeight();
        } else {
            const Glyph &glyph = GetGlyph(chr);
            float advance = glyph.advX;

            if (nextChar != '\n' && nextChar != '\0')
                advance += GetKern(glyph, GetGlyph(nextChar));

            x += advance;
        }

        chr = nextChar;
    }

    charX = x;
    charY = y;
}
Beispiel #2
0
int TextureFont::PickCharacter(const char *str, float mouseX, float mouseY) const
{
	assert(str && mouseX >= 0.0f && mouseY >= 0.0f);

	// at the point of the mouse in-box test, the vars have the following values:
	// i1: the index of the character being tested
	// i2: the index of the next character
	// charBytes: the number of bytes used to encode the next character
	// right: the right edge of the box being tested
	// bottom:  the bottom of the box being tested
	// x: the x-coordinate of the next character
	// chr1: the Unicode value of the character being tested
	// chr2: the Unicode value of the next character

	Uint32 chr2 = '\n'; // pretend we've just had a new line
	float bottom = 0.0f, x = 0.0f;
	int i2 = 0, charBytes = 0;
	do {
		int i1 = i2;
		Uint32 chr1 = chr2;

		// read the next character
		i2 += charBytes;
		charBytes = utf8_decode_char(&chr2, &str[i2]);
		assert(!str[i2] || charBytes); // assert valid encoding

		float right;
		if (chr1 == '\n') {
			right = std::numeric_limits<float>::max();
			x = 0.0f;
		} else {
			const glfglyph_t &glyph = GetGlyph(chr1);
			float advance = glyph.advx;

			if (chr2 != '\n' && chr2 != '\0') {
				FT_Vector kern;
				FT_Get_Kerning(m_face, glyph.ftIndex, GetGlyph(chr2).ftIndex, FT_KERNING_UNFITTED, &kern);
				advance += float(kern.x) / 64.0f;
			}

			right = x + (advance / 2.0f);
			x += advance;
		}

		if ((mouseY < bottom) && (mouseX < right))
			return i1;

		if (chr1 == '\n')
			bottom += GetHeight();
	} while (charBytes);

	return i2;
}
Beispiel #3
0
void FontInstance::DrawFinal( QuadTexture* Surface,const int Px, const int Py,Utf32String& Str,const unsigned long Color,bool Gen)
{
	ScopedLock Sl(Lock);
	FT_Error Error;
	ScanLineUserInfo Info;
	FT_Glyph	AGlyphs[512];   /* glyph image    */
	FT_Vector   APos   [512];   /* glyph position */

	//get all glyph and compute rendering pos
	int PosX=0;
	int PosY=0; //Py+(Face->height>>6)/3;
	unsigned int GlyphArrIdx=0;
	for (unsigned int i=0;i<Str.size();i++)
	{
		//retrieve the glyph with the UTF-32 code
		AGlyphs[GlyphArrIdx]=GetGlyph(Str[i]);

		if (AGlyphs[GlyphArrIdx]!=0)
		{
			/* store current pen position */
			APos[GlyphArrIdx].x = PosX;
			APos[GlyphArrIdx].y = PosY;

			//advance is in 16.16 fixed format
			PosX+=AGlyphs[GlyphArrIdx]->advance.x>>16;
			PosY+=AGlyphs[GlyphArrIdx]->advance.y>>16;

			GlyphArrIdx++;
		}
	}
Beispiel #4
0
int Font::GetLineWidthInSourcePixels( const wstring &szLine ) const
{
	int iLineWidth = 0;
	
	for( unsigned i=0; i<szLine.size(); i++ )
		iLineWidth += GetGlyph(szLine[i]).m_iHadvance;

	if( szLine.size() > 0 )
	{
		/* Add overdraw. */
		iLineWidth += GetGlyph(szLine[0]).m_pPage->m_iDrawExtraPixelsLeft;
		iLineWidth += GetGlyph(szLine[szLine.size()-1]).m_pPage->m_iDrawExtraPixelsRight;
	}

	return iLineWidth;
}
Beispiel #5
0
void OpenGLText::DrawString(const std::string &text, int x, int y) {
	for (char curChar : text) {
		OpenGLTextGlyph const& glyph = GetGlyph(curChar);
		glyph.Draw(x, y);
		x += glyph.w;
	}
}
Beispiel #6
0
void OpenGLText::GetExtent(wxString const& text, int &w, int &h) {
	lineHeight = 0;
	int dx=0, dy=0;
	w = 0;
	h = 0;

	// Simulate drawing of string
	for (int curChar : text) {
		// Handle carriage returns
		if (curChar == '\n') {
			if (dx > w) w = dx;
			dx = 0;
			dy += lineHeight;
			lineHeight = 0;
		}

		// Handle normal glyphs
		else {
			OpenGLTextGlyph const& glyph = GetGlyph(curChar);
			dx += glyph.w;
			if (glyph.h > lineHeight) lineHeight = glyph.h;
		}
	}

	// Return results
	if (dx > w) w = dx;
	h = dy+lineHeight;
}
Beispiel #7
0
void OpenGLText::GetExtent(std::string const& text, int &w, int &h) {
	w = h = 0;

	for (char curChar : text) {
		OpenGLTextGlyph const& glyph = GetGlyph(curChar);
		w += glyph.w;
		h = std::max(h, glyph.h);
	}
}
Beispiel #8
0
TBFontGlyph *TBFontGlyphCache::CreateAndCacheGlyph(const TBID &hash_id, UCS4 cp)
{
	assert(!GetGlyph(hash_id, cp));
	TBFontGlyph *glyph = new TBFontGlyph(hash_id, cp);
	if (glyph && m_glyphs.Add(glyph->hash_id, glyph))
		return glyph;
	delete glyph;
	return nullptr;
}
Beispiel #9
0
int Font::GetLineWidthInSourcePixels( const wstring &szLine ) const
{
	int iLineWidth = 0;
	
	for( unsigned i=0; i<szLine.size(); i++ )
		iLineWidth += GetGlyph(szLine[i]).m_iHadvance;

	return iLineWidth;
}
Beispiel #10
0
int Font::GetLineHeightInSourcePixels( const wstring &szLine ) const
{
	int iLineHeight = 0;

	/* The height of a line is the height of its tallest used font page. */
	for( unsigned i=0; i<szLine.size(); i++ )
		iLineHeight = max( iLineHeight, GetGlyph(szLine[i]).m_pPage->m_iHeight );

	return iLineHeight;
}
Beispiel #11
0
float CglFont::GetTextWidth_(const std::u8string& text)
{
	if (text.empty()) return 0.0f;

	float w = 0.0f;
	float maxw = 0.0f;

	const GlyphInfo* prv_g=NULL;
	const GlyphInfo* cur_g;

	int pos = 0;
	while (pos < text.length()) {
		const char32_t u = Utf8GetNextChar(text, pos);

		switch (u) {
			// inlined colorcode
			case ColorCodeIndicator:
				pos = SkipColorCodes(text, pos - 1);
				if (pos<0) {
					pos = text.length();
				}
				break;

			// reset color
			case ColorResetIndicator:
				break;

			// newline
			case 0x0d: // CR+LF
				if (pos < text.length() && text[pos] == 0x0a)
					pos++;
			case 0x0a: // LF
				if (prv_g)
					w += prv_g->advance;
				if (w > maxw)
					maxw = w;
				w = 0.0f;
				prv_g = NULL;
				break;

			// printable char
			default:
				cur_g = &GetGlyph(u);
				if (prv_g) w += GetKerning(*prv_g, *cur_g);
				prv_g = cur_g;
		}
	}

	if (prv_g)
		w += prv_g->advance;
	if (w > maxw)
		maxw = w;

	return maxw;
}
Beispiel #12
0
void TextureFont::RenderString(const char *str, float x, float y, const Color &color)
{
	PROFILE_SCOPED()
	m_vertices.Clear();

	float alpha_f = color.a / 255.0f;
	const Color premult_color = Color(color.r * alpha_f, color.g * alpha_f, color.b * alpha_f, color.a);

	float px = x;
	float py = y;

	int i = 0;
	while (str[i]) {
		if (str[i] == '\n') {
			px = x;
			py += GetHeight();
			i++;
		}

		else {
			Uint32 chr;
			int n = utf8_decode_char(&chr, &str[i]);
			assert(n);
			i += n;

			const Glyph &glyph = GetGlyph(chr);
			AddGlyphGeometry(&m_vertices, glyph, roundf(px), py, premult_color);

			if (str[i]) {
				Uint32 chr2;
				n = utf8_decode_char(&chr2, &str[i]);
				assert(n);

				px += GetKern(glyph, GetGlyph(chr2));
			}

			px += glyph.advX;
		}
	}

	m_renderer->DrawTriangles(&m_vertices, m_renderState, m_mat.get());
}
Beispiel #13
0
void TextureFont::RenderString(const char *str, float x, float y, const Color &color)
{
	m_renderer->SetBlendMode(Graphics::BLEND_ALPHA);
	m_vertices.Clear();

	float px = x;
	float py = y;

	int i = 0;
	while (str[i]) {
		if (str[i] == '\n') {
			px = x;
			py += GetHeight();
			i++;
		}

		else {
			Uint32 chr;
			int n = utf8_decode_char(&chr, &str[i]);
			assert(n);
			i += n;

			const glfglyph_t &glyph = GetGlyph(chr);
			AddGlyphGeometry(&m_vertices, glyph, roundf(px), py, color);

			if (str[i]) {
				Uint32 chr2;
				n = utf8_decode_char(&chr2, &str[i]);
				assert(n);

				FT_Vector kern;
				FT_Get_Kerning(m_face, glyph.ftIndex, GetGlyph(chr2).ftIndex, FT_KERNING_UNFITTED, &kern);
				px += float(kern.x) / 64.0;
			}

			px += glyph.advx;
		}
	}

	m_renderer->DrawTriangles(&m_vertices, m_mat.Get());
}
PRUint32
gfxFT2FontBase::GetGlyph(PRUint32 unicode, PRUint32 variation_selector)
{
    if (variation_selector) {
        PRUint32 id =
            gfxFT2LockedFace(this).GetUVSGlyph(unicode, variation_selector);
        if (id)
            return id;
    }

    return GetGlyph(unicode);
}
Beispiel #15
0
int FontInstance::GetLen(std::wstring& Text)
{
	ScopedLock Sl(Lock);
	float Length=0.0f;
	for (unsigned int i=0;i<Text.size();i++)
	{
		//retrieve the glyph with the UTF-32 code
		FT_Glyph Glyph=GetGlyph(Text[i]);
		Length+=(float)(Glyph->advance.x>>16);
		FT_Done_Glyph(Glyph);
	}
	return (int)Length;
};
Beispiel #16
0
bool FontRenderer::CreateGlyphTextures() {
  FT_Set_Pixel_Sizes(_face, _fontWidth, _fontHeight);

  for (auto& glyph : _glyphs) {
    glDeleteTextures(1, &glyph.texture);
    glGenTextures(1, &glyph.texture);
  }
  CHECK_GL_ERROR;
  
  for (int character = -std::numeric_limits<char>::max(); 
       character <= std::numeric_limits<char>::max(); ++character) {
    Glyph* glyph = GetGlyph(character);
    glBindTexture(GL_TEXTURE_2D, glyph->texture);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    
    // Uploading glyph bitmaps requires 1 byte alignment.
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
    // Try to load the character.
    if (FT_Load_Char(_face, character, FT_LOAD_RENDER) != FT_Err_Ok) {
      return false;
    }
    const FT_GlyphSlot glyphSlot = _face->glyph;

    // Upload the bitmap, which contains an 8bit grayscale image.
    glTexImage2D(GL_TEXTURE_2D, 
                  0, 
                  GL_RED, 
                  glyphSlot->bitmap.width, 
                  glyphSlot->bitmap.rows, 
                  0, 
                  GL_RED, 
                  GL_UNSIGNED_BYTE, 
                  glyphSlot->bitmap.buffer);

    glyph->left = glyphSlot->bitmap_left;
    glyph->top = glyphSlot->bitmap_top;
    glyph->width = glyphSlot->bitmap.width;
    glyph->rows = glyphSlot->bitmap.rows;
    glyph->advance_x = glyphSlot->advance.x;
    glyph->advance_y = glyphSlot->advance.y;
  }
  
  _glyphTexturesDirty = (GetGLErrorVerbose() != GL_NO_ERROR);

  return !_glyphTexturesDirty;
}
Beispiel #17
0
float CglFont::GetTextHeight_(const std::u8string& text, float* descender, int* numLines)
{
	if (text.empty()) {
		if (descender) *descender = 0.0f;
		if (numLines) *numLines = 0;
		return 0.0f;
	}

	float h = 0.0f, d = GetLineHeight() + GetDescender();
	unsigned int multiLine = 1;

	int pos = 0;
	while (pos < text.length()) {
		const char32_t u = Utf8GetNextChar(text, pos);
		switch(u) {
			// inlined colorcode
			case ColorCodeIndicator:
				pos = SkipColorCodes(text, pos - 1);
				if (pos<0) {
					pos = text.length();
				}
				break;

			// reset color
			case ColorResetIndicator:
				break;

			// newline
			case 0x0d: // CR+LF
				if (pos < text.length() && text[pos] == 0x0a)
					++pos;
			case 0x0a: // LF
				multiLine++;
				d = GetLineHeight() + GetDescender();
				break;

			// printable char
			default:
				const GlyphInfo& g = GetGlyph(u);
				if (g.descender < d) d = g.descender;
				if (multiLine < 2 && g.height > h) h = g.height; // only calc height for the first line
		}
	}

	if (multiLine>1) d -= (multiLine-1) * GetLineHeight();
	if (descender) *descender = d;
	if (numLines) *numLines = multiLine;

	return h;
}
Beispiel #18
0
void TextureFont::MeasureCharacterPos(const char *str, int charIndex, float &charX, float &charY) const
{
	assert(str && (charIndex >= 0));

	float x = 0.0f, y = GetHeight();
	int i = 0;
	Uint32 chr;
	int len = utf8_decode_char(&chr, &str[i]);
	while (str[i] && (i < charIndex)) {
		Uint32 nextChar;
		i += len;
		len = utf8_decode_char(&nextChar, &str[i]);
		assert(!str[i] || len); // assert valid encoding

		if (chr == '\n') {
			x = 0.0f;
			y += GetHeight();
		} else {
			const glfglyph_t &glyph = GetGlyph(chr);
			float advance = glyph.advx;

			if (nextChar != '\n' && nextChar != '\0') {
				FT_Vector kern;
				FT_Get_Kerning(m_face, glyph.ftIndex, GetGlyph(nextChar).ftIndex, FT_KERNING_UNFITTED, &kern);
				advance += float(kern.x) / 64.0f;
			}

			x += advance;
		}

		chr = nextChar;
	}

	charX = x;
	charY = y;
}
Beispiel #19
0
bool Font::FontCompleteForString( const wstring &str ) const
{
	map<wchar_t,glyph*>::const_iterator m_pDefault = m_iCharToGlyph.find( FONT_DEFAULT_GLYPH );
	if( m_pDefault == m_iCharToGlyph.end() )
		RageException::Throw( "The default glyph is missing from the font \"%s\".", path.c_str() );

	for( unsigned i = 0; i < str.size(); ++i )
	{
		/* If the glyph for this character is the default glyph, we're incomplete. */
		const glyph &g = GetGlyph( str[i] );
		if( &g == m_pDefault->second )
			return false;
	}
	return true;
}
Beispiel #20
0
int TBFontFace::GetStringWidth(const char *str, int len)
{
	int width = 0;
	int i = 0;
	while (str[i] && i < len)
	{
		UCS4 cp = utf8::decode_next(str, &i, len);
		if (cp == 0xFFFF)
			continue;
		if (!m_font_renderer) // This is the test font. Use same glyph width as height.
			width += m_metrics.height / 3 + 1;
		else if (TBFontGlyph *glyph = GetGlyph(cp, false))
			width += glyph->metrics.advance;
	}
	return width;
}
Beispiel #21
0
TBBitmapFragment *TBFontGlyphCache::CreateFragment(TBFontGlyph *glyph, int w, int h, int stride, uint32 *data)
{
	assert(GetGlyph(glyph->hash_id, glyph->cp));
	// Don't bother if the requested glyph is too large.
	if (w > TB_GLYPH_CACHE_WIDTH || h > TB_GLYPH_CACHE_HEIGHT)
		return nullptr;

	bool try_drop_largest = true;
	bool dropped_large_enough_glyph = false;
	do
	{
		// Attempt creating a fragment for the rendered glyph data
		if (TBBitmapFragment *frag = m_frag_manager.CreateNewFragment(glyph->hash_id, false, w, h, stride, data))
		{
			glyph->frag = frag;
			m_all_rendered_glyphs.AddLast(glyph);
			return frag;
		}
		// Drop the oldest glyph that's large enough to free up the space we need.
		if (try_drop_largest)
		{
			const int check_limit = 20;
			int check_count = 0;
			for (TBFontGlyph *oldest = m_all_rendered_glyphs.GetFirst(); oldest && check_count < check_limit; oldest = oldest->GetNext())
			{
				if (oldest->frag->Width() >= w && oldest->frag->GetAllocatedHeight() >= h)
				{
					DropGlyphFragment(oldest);
					dropped_large_enough_glyph = true;
					break;
				}
				check_count++;
			}
			try_drop_largest = false;
		}
		// We had no large enough glyph so just drop the oldest one. We will likely
		// spin around the loop, fail and drop again a few times before we succeed.
		if (!dropped_large_enough_glyph)
		{
			if (TBFontGlyph *oldest = m_all_rendered_glyphs.GetFirst())
				DropGlyphFragment(oldest);
			else
				break;
		}
	} while (true);
	return nullptr;
}
Beispiel #22
0
bool TBFontFace::RenderGlyphs(const char *glyph_str, int glyph_str_len)
{
	if (!m_font_renderer)
		return true; // This is the test font

	if (glyph_str_len == TB_ALL_TO_TERMINATION)
		glyph_str_len = strlen(glyph_str);

	bool has_all_glyphs = true;
	int i = 0;
	while (glyph_str[i] && i < glyph_str_len)
	{
		UCS4 cp = utf8::decode_next(glyph_str, &i, glyph_str_len);
		if (!GetGlyph(cp, true))
			has_all_glyphs = false;
	}
	return has_all_glyphs;
}
Beispiel #23
0
void CRasterFont::SinglePassDrawString(const CDrawStringOptions& opts, int x, int y, int& xout, int& yout,
                                       CTextRenderBuffer* renderBuf,
                                       const wchar_t* str, s32 length) const
{
    if (!x0_)
        return;

    const wchar_t* chr = str;
    const CGlyph* prevGlyph = nullptr;
    while (*chr == '\0')
    {
        const CGlyph* glyph = GetGlyph(*chr);
        if (glyph)
        {
            if (opts.x0_ == 0)
            {
                x += glyph->GetA();

                if (prevGlyph != 0)
                    x += KernLookup(x1c_kerning, prevGlyph->GetKernStart(), *chr);
                int left = 0;
                int top = 0;

                if (renderBuf)
                {
                    left += x;
                    top += glyph->GetBaseline() - y;
                    renderBuf->AddCharacter(zeus::CVector2i(left, top), *chr, opts.x4_vec[0]);
                }
                x += glyph->GetC() + glyph->GetB();
            }
        }
        prevGlyph = glyph;
        chr++;
        if (length == -1)
            continue;

        if ((str - chr) >= length)
            break;
    }

    xout = x;
    yout = y;
}
uint GetGlyphWidth(FontSize size, WChar key)
{
	FT_Face face = GetFontFace(size);
	GlyphEntry *glyph;

	if (face == NULL || (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END)) {
		SpriteID sprite = GetUnicodeGlyph(size, key);
		if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
		return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + (size != FS_NORMAL && size != FS_MONO) : 0;
	}

	glyph = GetGlyphPtr(size, key);
	if (glyph == NULL || glyph->sprite == NULL) {
		GetGlyph(size, key);
		glyph = GetGlyphPtr(size, key);
	}

	return glyph->width;
}
Beispiel #25
0
void OpenGLText::DrawString(const wxString &text, int x, int y) {
	lineHeight = 0;
	int dx=x, dy=y;

	for (int curChar : text) {
		// Handle carriage returns
		if (curChar == '\n') {
			dx = x;
			dy += lineHeight;
		}

		// Handle normal glyphs
		else {
			OpenGLTextGlyph const& glyph = GetGlyph(curChar);
			glyph.Draw(dx, dy);
			dx += glyph.w;
			if (glyph.h > lineHeight) lineHeight = glyph.h;
		}
	}
}
Beispiel #26
0
void CRasterFont::GetSize(const CDrawStringOptions& opts, int& width, int& height, const wchar_t* str, int len) const
{
    width = 0;
    height = 0;

    const wchar_t* chr = str;
    const CGlyph* prevGlyph = nullptr;
    int prevWidth = 0;
    while (*chr != L'\0')
    {
        const CGlyph* glyph = GetGlyph(*chr);

        if (glyph)
        {
            if (opts.x0_ == 0)
            {
                int advance = 0;
                if (prevGlyph)
                    advance = KernLookup(x1c_kerning, prevGlyph->GetKernStart(), *chr);

                s16 curWidth = prevWidth - (glyph->GetA() + glyph->GetB() + glyph->GetC() + advance);
                s16 curHeight = glyph->GetBaseline() - (x8_monoHeight + glyph->GetCellHeight());

                width = curWidth;
                prevWidth = curWidth;

                if (curHeight > height)
                    height = curHeight;
            }
        }

        prevGlyph = glyph;
        chr++;
        if (len == -1)
            continue;

        if ((str - chr) >= len)
            break;
    }
}
Beispiel #27
0
void TBFontFace::DrawString(int x, int y, const TBColor &color, const char *str, int len)
{
	if (m_bgFont)
		m_bgFont->DrawString(x+m_bgX, y+m_bgY, m_bgColor, str, len);

	if (m_font_renderer)
		g_renderer->BeginBatchHint(TBRenderer::BATCH_HINT_DRAW_BITMAP_FRAGMENT);

	int i = 0;
	while (str[i] && i < len)
	{
		UCS4 cp = utf8::decode_next(str, &i, len);
		if (cp == 0xFFFF)
			continue;
		if (TBFontGlyph *glyph = GetGlyph(cp, true))
		{
			if (glyph->frag)
			{
				TBRect dst_rect(x + glyph->metrics.x, y + glyph->metrics.y + GetAscent(), glyph->frag->Width(), glyph->frag->Height());
				TBRect src_rect(0, 0, glyph->frag->Width(), glyph->frag->Height());
				if (glyph->has_rgb)
					g_renderer->DrawBitmap(dst_rect, src_rect, glyph->frag);
				else
					g_renderer->DrawBitmapColored(dst_rect, src_rect, color, glyph->frag);
			}
			x += glyph->metrics.advance;
		}
		else if (!m_font_renderer) // This is the test font. Use same glyph width as height and draw square.
		{
			g_renderer->DrawRect(TBRect(x, y, m_metrics.height / 3, m_metrics.height), color);
			x += m_metrics.height / 3 + 1;
		}
	}

	if (m_font_renderer)
		g_renderer->EndBatchHint();
}
Beispiel #28
0
void ezioFont::SetGlyph(Uint8 glyph, const Uint8 *data)
{
	if (!data || !length || !bg || !pixel_on || !pixel_off)
		throw ezioException(EZIOEX_EMUL_FONT_SET_GLYPH);
	SDL_Surface *surface = GetGlyph(glyph);
	if (surface != NULL) {
		SDL_FreeSurface(surface);
		keymap[glyph] = NULL;
	}

	surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
		bg->w, bg->h, 32, rmask, gmask, bmask, amask);
	SDL_SetAlpha(surface, 0, 0);
	SDL_BlitSurface(bg, NULL, surface, NULL);

	SDL_Rect rect;
	rect.x = rect.y = 0;
	rect.w = pixel_on->w;
	rect.h = pixel_on->h;

	for (Sint32 y = 0; y < height; y++) {
		rect.x = 0;
		rect.w = pixel_on->w;
		rect.h = pixel_on->h;
		Uint8 bits = (Uint32)data[y];
		for (Sint32 x = 0; x < width; x++) {
			if ((bits & 0x80 ) != 0)
				SDL_BlitSurface(pixel_on, NULL, surface, &rect);
			bits = bits << 1;
			rect.x += pixel_on->w + 1;
		}
		rect.y += pixel_on->h + 1;
	}

	keymap[glyph] = surface;
}
Beispiel #29
0
void CglFont::RenderStringOutlined(float x, float y, const float& scaleX, const float& scaleY, const std::string& str)
{
	const float shiftX = (scaleX/fontSize) * GetOutlineWidth(), shiftY = (scaleY/fontSize) * GetOutlineWidth();

	const float startx = x;
	const float lineHeight_ = scaleY * GetLineHeight();
	const std::u8string& ustr = toustring(str);
	const size_t length = str.length();

	va.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);
	va2.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);

	int skippedLines;
	bool colorChanged;
	const GlyphInfo* g = NULL;
	float4 newColor = textColor;
	char32_t c;
	int i = 0;

	do {
		const bool endOfString = SkipColorCodesAndNewLines(ustr, &i, &newColor, &colorChanged, &skippedLines, &baseTextColor);

		if (endOfString)
			return;

		c = Utf8GetNextChar(str,i);

		if (colorChanged) {
			if (autoOutlineColor) {
				SetColors(&newColor,NULL);
			} else {
				SetTextColor(&newColor);
			}
		}

		const GlyphInfo* c_g = &GetGlyph(c);
		if (skippedLines>0) {
			x  = startx;
			y -= skippedLines * lineHeight_;
		} else if (g) {
			x += scaleX * GetKerning(*g, *c_g);
		}

		g = c_g;

		const auto&  tc = g->texCord;
		const auto& stc = g->shadowTexCord;
		const float dx0 = (scaleX * g->size.x0()) + x, dy0 = (scaleY * g->size.y0()) + y;
		const float dx1 = (scaleX * g->size.x1()) + x, dy1 = (scaleY * g->size.y1()) + y;

		// draw outline
		va2.AddVertexQ2dT(dx0-shiftX, dy1-shiftY, stc.x0(), stc.y1());
		va2.AddVertexQ2dT(dx0-shiftX, dy0+shiftY, stc.x0(), stc.y0());
		va2.AddVertexQ2dT(dx1+shiftX, dy0+shiftY, stc.x1(), stc.y0());
		va2.AddVertexQ2dT(dx1+shiftX, dy1-shiftY, stc.x1(), stc.y1());

		// draw the actual character
		va.AddVertexQ2dT(dx0, dy1, tc.x0(), tc.y1());
		va.AddVertexQ2dT(dx0, dy0, tc.x0(), tc.y0());
		va.AddVertexQ2dT(dx1, dy0, tc.x1(), tc.y0());
		va.AddVertexQ2dT(dx1, dy1, tc.x1(), tc.y1());
	} while(true);
}
Beispiel #30
0
void CglFont::RenderString(float x, float y, const float& scaleX, const float& scaleY, const std::string& str)
{
	/**
	 * NOTE:
	 * Font rendering does not use display lists, but VAs. It's actually faster
	 * (450% faster with a 7600GT!) for these reasons:
	 *
	 * 1. When using DLs, we can not group multiple glyphs into one glBegin/End pair
	 *    because glTranslatef can not go between such a pair.
	 * 2. We can now eliminate all glPushMatrix/PopMatrix pairs related to font rendering
	 *    because the transformations are calculated on the fly. These are just a couple of
	 *    floating point multiplications and shouldn't be too expensive.
	 */

	const float startx = x;
	const float lineHeight_ = scaleY * GetLineHeight();
	unsigned int length = (unsigned int)str.length();
	const std::u8string& ustr = toustring(str);

	va.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);

	int skippedLines;
	bool colorChanged;
	const GlyphInfo* g = NULL;
	float4 newColor = textColor;
	char32_t c;
	int i = 0;

	do {
		const bool endOfString = SkipColorCodesAndNewLines(ustr, &i, &newColor, &colorChanged, &skippedLines, &baseTextColor);

		if (endOfString)
			return;

		c = Utf8GetNextChar(str,i);

		if (colorChanged) {
			if (autoOutlineColor) {
				SetColors(&newColor,NULL);
			} else {
				SetTextColor(&newColor);
			}
		}
		const GlyphInfo* c_g = &GetGlyph(c);
		if (skippedLines>0) {
			x  = startx;
			y -= skippedLines * lineHeight_;
		} else if (g) {
			x += scaleX * GetKerning(*g, *c_g);
		}

		g = c_g;

		const auto&  tc = g->texCord;
		const float dx0 = (scaleX * g->size.x0()) + x, dy0 = (scaleY * g->size.y0()) + y;
		const float dx1 = (scaleX * g->size.x1()) + x, dy1 = (scaleY * g->size.y1()) + y;

		va.AddVertexQ2dT(dx0, dy1, tc.x0(), tc.y1());
		va.AddVertexQ2dT(dx0, dy0, tc.x0(), tc.y0());
		va.AddVertexQ2dT(dx1, dy0, tc.x1(), tc.y0());
		va.AddVertexQ2dT(dx1, dy1, tc.x1(), tc.y1());
	} while(true);
}