Пример #1
0
	GLfloat QueryXOffsets(
		const CodePoint* cps,
		GLsizei size,
		std::vector<GLfloat>& x_offsets
	) const
	{
		if(size <= 0) return 0.0f;
		x_offsets.resize(size);

		float scale = _tt_font.ScaleForPixelHeight(_font_resolution);
		scale /= _font_resolution;
		aux::STBTTFontGlyph g = _tt_font.GetGlyph(cps[0]);

		GLfloat sum = g.LeftBearing()*scale;
		x_offsets[0] = sum;


		GLsizei i = 0;
		while(++i != size)
		{
			sum += g.Width()*scale;

			aux::STBTTFontGlyph pg = g;
			g = _tt_font.GetGlyph(cps[i]);

			sum += KernAdvance(pg, g)*scale;

			x_offsets[i] = sum;
		}
		return sum + g.Width()*scale;
	}
Пример #2
0
OGLPLUS_LIB_FUNC
float STBTTFont2D::Width(
	std::size_t size_in_pixels,
	const Layout& layout
) const
{
	float scale = ScaleForPixelHeight(float(size_in_pixels));
	float width = 0.0f;
	for(auto i=layout.begin(), p=i, e=layout.end(); i!=e; p = i, ++i)
	{
		if(p != i) width += KernAdvance(*p, *i);
		width += i->Width();
	}
	return width*scale;
}
Пример #3
0
OGLPLUS_LIB_FUNC
void STBTTFont2D::Render(
	std::size_t size_in_pixels,
	const STBTTFont2D::Layout& layout,
	unsigned char* buffer_start,
	const std::size_t buffer_width,
	const std::size_t buffer_height,
	const int xposition,
	const int yposition
) const
{
	if(int(buffer_height)  <   yposition) return;
	if(int(size_in_pixels) <= -yposition) return;

	std::vector<unsigned char> tmp_buffer;
	int tmp_height = int(size_in_pixels);
	int tmp_width = 0;

	float scale = ScaleForPixelHeight(float(size_in_pixels));

	float xoffset = 0.0f;
	for(auto i=layout.begin(), p=i, e=layout.end(); i!=e; ++i)
	{
		const int xo = int(std::floor(xoffset))+xposition;
		const float advance = i->Width()*scale;

		int width_in_pixels = int(std::ceil(advance));

		if(xo >= int(buffer_width))
		{
			break;
		}
		if(xo+width_in_pixels < 0)
		{
			xoffset += advance;
			continue;
		}

		if(tmp_width < width_in_pixels)
		{
			tmp_width = width_in_pixels;
			tmp_buffer.resize(tmp_width*tmp_height);
		}
		std::fill(tmp_buffer.begin(), tmp_buffer.end(), 0x00);

		if(p != i) xoffset += KernAdvance(*p, *i)*scale;
		const float xshift = xoffset - std::floor(xoffset);
		int x0, y0, x1, y1;
		i->GetBitmapBoxSubpixel(
			scale, scale,
			xshift, 0,
			x0, y0,
			x1, y1
		);
		const float yshift = std::floor((i->Ascent()*scale+y0));

		::stbtt_MakeGlyphBitmapSubpixel(
			&_font,
			tmp_buffer.data(),
			tmp_width,
			tmp_height,
			tmp_width,
			scale,
			scale,
			xshift,
			yshift,
			i->_index
		);

		const int yo = yposition;

		int gb = xo<0?-xo:0;
		int gw = int(gb+1+(x1-x0));
		if(gw > tmp_width) gw = tmp_width;
		if(gw > int(buffer_width-xo)) gw = int(buffer_width-xo);
		int gy = (std::floor(yshift));
		if(gy < -yo) gy = -yo;
		int gh = tmp_height;
		if(gh > int(buffer_height-yo)) gh = int(buffer_height-yo);

		while(gy < gh)
		{
			int gx = gb;
			while(gx < gw)
			{
				int si = gy*tmp_width+gx;
				unsigned src = tmp_buffer[si];
				if(src != 0)
				{
					int di = (gy+yo)*buffer_width+gx+xo+x0;
					unsigned dst = buffer_start[di]+src;

					if(dst > 0xFF) dst = 0xFF;
					buffer_start[di] = dst & 0xFF;
				}
				++gx;
			}
			++gy;
		}

		p = i;
		xoffset += advance;
	}
}