Esempio n. 1
0
void TextureFont::MeasureString(const char *str, float &w, float &h)
{
	w = h = 0.0f;

	float line_width = 0.0f;

	int i = 0;
	while (str[i]) {
		if (str[i] == '\n') {
			if (line_width > w) w = line_width;
			line_width = 0.0f;
			h += GetHeight();
			i++;
		}
		
		else {
			Uint32 chr;
			int n = utf8_decode_char(&chr, &str[i]);
			assert(n);
			i += n;

			const glfglyph_t &glyph = m_glyphs[chr];

			line_width += glyph.advx;

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

				FT_UInt a = FT_Get_Char_Index(m_face, chr);
				FT_UInt b = FT_Get_Char_Index(m_face, chr2);

				FT_Vector kern;
				FT_Get_Kerning(m_face, a, b, FT_KERNING_UNFITTED, &kern);
				line_width += float(kern.x) / 64.0;
			}
		}
	}

	if (line_width > w) w = line_width;
	h += GetHeight() + GetDescender();
}
Esempio n. 2
0
void CglFont::glPrintTable(float x, float y, float s, const int options, const std::string& text)
{
	std::vector<std::string> coltext;
	coltext.push_back("");

	std::vector<SColor> colColor;
	SColor defaultcolor(0,0,0);
	defaultcolor[0] = ColorCodeIndicator;
	for (int i = 0; i < 3; ++i)
		defaultcolor[i+1] = (unsigned char)(textColor[i] * 255.0f);
	colColor.push_back(defaultcolor);
	SColor curcolor(defaultcolor);

	int col = 0;
	int row = 0;
	for (int pos = 0; pos < text.length(); pos++) {
		const unsigned char& c = text[pos];
		switch(c) {
			// inline colorcodes
			case ColorCodeIndicator:
				for (int i = 0; i < 4 && pos < text.length(); ++i, ++pos) {
					coltext[col] += text[pos];
					curcolor[i] = text[pos];
				}
				colColor[col] = curcolor;
				--pos;
				break;

			// column separator is `\t`==`horizontal tab`
			case '\t':
				++col;
				if (col >= coltext.size()) {
					coltext.push_back("");
					for(int i = 0; i < row; ++i)
						coltext[col] += 0x0a;
					colColor.push_back(defaultcolor);
				}
				if (colColor[col] != curcolor) {
					for(int i = 0; i < 4; ++i)
						coltext[col] += curcolor[i];
					colColor[col] = curcolor;
				}
				break;

			// newline
			case 0x0d: // CR+LF
				if (pos+1 < text.length() && text[pos + 1] == 0x0a)
					pos++;
			case 0x0a: // LF
				for (int i = 0; i < coltext.size(); ++i)
					coltext[i] += 0x0a;
				if (colColor[0] != curcolor) {
					for(int i = 0; i < 4; ++i)
						coltext[0] += curcolor[i];
					colColor[0] = curcolor;
				}
				col = 0;
				++row;
				break;

			// printable char
			default:
				coltext[col] += c;
		}
	}

	float totalWidth = 0.0f;
	float maxHeight = 0.0f;
	float minDescender = 0.0f;
	std::vector<float> colWidths(coltext.size(), 0.0f);
	for (int i = 0; i < coltext.size(); ++i) {
		float colwidth = GetTextWidth(coltext[i]);
		colWidths[i] = colwidth;
		totalWidth += colwidth;
		float textDescender;
		float textHeight = GetTextHeight(coltext[i], &textDescender);
		if (textHeight > maxHeight)
			maxHeight = textHeight;
		if (textDescender < minDescender)
			minDescender = textDescender;
	}

	// s := scale or absolute size?
	float ss = s;
	if (options & FONT_SCALE) {
		ss *= fontSize;
	}

	float sizeX = ss, sizeY = ss;

	// render in normalized coords (0..1) instead of screencoords (0..~1024)
	if (options & FONT_NORM) {
		sizeX *= globalRendering->pixelX;
		sizeY *= globalRendering->pixelY;
	}

	// horizontal alignment (FONT_LEFT is default)
	if (options & FONT_CENTER) {
		x -= sizeX * 0.5f * totalWidth;
	} else if (options & FONT_RIGHT) {
		x -= sizeX * totalWidth;
	}

	// vertical alignment
	if (options & FONT_BASELINE) {
		// nothing
	} else if (options & FONT_DESCENDER) {
		y -= sizeY * GetDescender();
	} else if (options & FONT_VCENTER) {
		y -= sizeY * 0.5f * maxHeight;
		y -= sizeY * 0.5f * minDescender;
	} else if (options & FONT_TOP) {
		y -= sizeY * maxHeight;
	} else if (options & FONT_ASCENDER) {
		y -= sizeY * GetDescender();
		y -= sizeY;
	} else if (options & FONT_BOTTOM) {
		y -= sizeY * minDescender;
	}

	for (int i = 0; i < coltext.size(); ++i) {
		glPrint(x, y, s, (options | FONT_BASELINE) & ~(FONT_RIGHT | FONT_CENTER), coltext[i]);
		x += sizeX * colWidths[i];
	}
}
Esempio n. 3
0
void CglFont::glPrint(float x, float y, float s, const int options, const std::string& text)
{
	// s := scale or absolute size?
	if (options & FONT_SCALE) {
		s *= fontSize;
	}

	float sizeX = s, sizeY = s;

	// render in normalized coords (0..1) instead of screencoords (0..~1024)
	if (options & FONT_NORM) {
		sizeX *= globalRendering->pixelX;
		sizeY *= globalRendering->pixelY;
	}

	// horizontal alignment (FONT_LEFT is default)
	if (options & FONT_CENTER) {
		x -= sizeX * 0.5f * GetTextWidth(text);
	} else if (options & FONT_RIGHT) {
		x -= sizeX * GetTextWidth(text);
	}


	// vertical alignment
	y += sizeY * GetDescender(); // move to baseline (note: descender is negative)
	if (options & FONT_BASELINE) {
		// nothing
	} else if (options & FONT_DESCENDER) {
		y -= sizeY * GetDescender();
	} else if (options & FONT_VCENTER) {
		float textDescender;
		y -= sizeY * 0.5f * GetTextHeight(text,&textDescender);
		y -= sizeY * 0.5f * textDescender;
	} else if (options & FONT_TOP) {
		y -= sizeY * GetTextHeight(text);
	} else if (options & FONT_ASCENDER) {
		y -= sizeY * GetDescender();
		y -= sizeY;
	} else if (options & FONT_BOTTOM) {
		float textDescender;
		GetTextHeight(text,&textDescender);
		y -= sizeY * textDescender;
	}

	if (options & FONT_NEAREST) {
		x = (int)x;
		y = (int)y;
	}

	// backup text & outline colors (also ::ColorResetIndicator will reset to those)
	baseTextColor = textColor;
	baseOutlineColor = outlineColor;

	// immediate mode?
	const bool immediate = !inBeginEnd;
	if (immediate) {
		Begin(!(options & (FONT_OUTLINE | FONT_SHADOW)));
	}


	// select correct decoration RenderString function
	if (options & FONT_OUTLINE) {
		RenderStringOutlined(x, y, sizeX, sizeY, text);
	} else if (options & FONT_SHADOW) {
		RenderStringShadow(x, y, sizeX, sizeY, text);
	} else {
		RenderString(x, y, sizeX, sizeY, text);
	}


	// immediate mode?
	if (immediate) {
		End();
	}

	// reset text & outline colors (if changed via in text colorcodes)
	SetColors(&baseTextColor,&baseOutlineColor);
}