GlyphData *BMFontRasterizer::getGlyphData(uint32 glyph) const
{
	auto it = characters.find(glyph);

	// Return an empty GlyphData if we don't have the glyph character.
	if (it == characters.end())
		return new GlyphData(glyph, GlyphMetrics(), GlyphData::FORMAT_RGBA);

	const BMFontCharacter &c = it->second;
	GlyphData *g = new GlyphData(glyph, c.metrics, GlyphData::FORMAT_RGBA);

	const auto &imagepair = images.find(c.page);

	if (imagepair == images.end())
	{
		g->release();
		return new GlyphData(glyph, GlyphMetrics(), GlyphData::FORMAT_RGBA);
	}

	image::ImageData *imagedata = imagepair->second.get();
	image::pixel *pixels = (image::pixel *) g->getData();
	const image::pixel *ipixels = (const image::pixel *) imagedata->getData();

	love::thread::Lock lock(imagedata->getMutex());

	// Copy the subsection of the texture from the ImageData to the GlyphData.
	for (int y = 0; y < c.metrics.height; y++)
	{
		size_t idindex = (c.y + y) * imagedata->getWidth() + c.x;
		memcpy(&pixels[y * c.metrics.width], &ipixels[idindex], sizeof(image::pixel) * c.metrics.width);
	}

	return g;
}
Example #2
0
int w_GlyphData_getGlyph(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);
	uint32 glyph = t->getGlyph();
	lua_pushnumber(L, (lua_Number) glyph);
	return 1;
}
Example #3
0
int w_GlyphData_getBearing(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);
	lua_pushinteger(L, t->getBearingX());
	lua_pushinteger(L, t->getBearingY());
	return 2;
}
Example #4
0
int w_GlyphData_getGlyphString(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);

	luax_catchexcept(L, [&](){ luax_pushstring(L, t->getGlyphString()); });
	return 1;
}
Example #5
0
int w_GlyphData_getDimensions(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);
	lua_pushinteger(L, t->getWidth());
	lua_pushinteger(L, t->getHeight());
	return 2;
}
Example #6
0
GlyphData Font::getGlyphDataFromChar(unsigned long c)
{
	FT_Load_Char(*m_face, c, FT_LOAD_DEFAULT | FT_LOAD_RENDER);
	GlyphData g;
	g.initFromFace(m_face, c);
	return g;
}
 void FontTexture::upload(const GlyphData &glyphData)
 {
     if (!glId && glyphData.isValid())
     {
         auto glyphWidth = glyphData.width;
         auto glyphHeight = glyphData.height;
         auto glyphPadding = glyphData.padding;
         auto buffer = glyphData.getBuffer();
         
         useMipmap = glyphData.useMipmap;
         width = utils::math::nextPowerOfTwo(glyphWidth + glyphPadding * 2);
         height = utils::math::nextPowerOfTwo(glyphHeight + glyphPadding * 2);
         
         auto data = new unsigned char[width * height](); // ZERO-FILLED
         
         for (int y = 0; y < glyphHeight; y++)
         {
             for (int x = 0; x < glyphWidth; x++)
             {
                 data[(y + glyphPadding) * width + (x + glyphPadding)] = buffer[y * glyphWidth + x];
             }
         }
         
         // ---
         
         glGenTextures(1, &glId);
         glBindTexture(GL_TEXTURE_2D, glId);
         
         if (useMipmap)
         {
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
         }
         else
         {
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
         }
         
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         
         if (useMipmap)
         {
             glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
             glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
         }
         
         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
         
         if (useMipmap)
         {
             glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
         }
         
         glBindTexture(GL_TEXTURE_2D, 0);
         delete[] data;
     }
 }
Example #8
0
int w_GlyphData_getFormat(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);

	const char *str;
	if (!GlyphData::getConstant(t->getFormat(), str))
		return luaL_error(L, "unknown GlyphData format.");

	lua_pushstring(L, str);
	return 1;
}
Example #9
0
int w_GlyphData_getBoundingBox(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);

	int minX = t->getMinX();
	int minY = t->getMinY();
	int maxX = t->getMaxX();
	int maxY = t->getMaxY();

	int width = maxX - minX;
	int height = maxY - minY;

	lua_pushinteger(L, minX);
	lua_pushinteger(L, minY);
	lua_pushinteger(L, width);
	lua_pushinteger(L, height);

	return 4;
}
Example #10
0
int w_newGlyphData(lua_State *L)
{
	Rasterizer *r = luax_checkrasterizer(L, 1);
	GlyphData *t = nullptr;

	// newGlyphData accepts a unicode character or a codepoint number.
	if (lua_type(L, 2) == LUA_TSTRING)
	{
		std::string glyph = luax_checkstring(L, 2);
		luax_catchexcept(L, [&](){ t = instance()->newGlyphData(r, glyph); });
	}
	else
	{
		uint32 g = (uint32) luaL_checknumber(L, 2);
		t = instance()->newGlyphData(r, g);
	}

	luax_pushtype(L, FONT_GLYPH_DATA_ID, t);
	t->release();
	return 1;
}
Example #11
0
	GlyphData * ImageRasterizer::getGlyphData(unsigned short glyph) const
	{
		GlyphMetrics gm;
		gm.height = metrics.height;
		gm.width = widths[glyph];
		gm.advance = spacing[glyph] + widths[glyph];
		gm.bearingX = 0;
		gm.bearingY = 0;
		GlyphData * g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA);
		if (gm.width == 0) return g;
		unsigned char * gd = (unsigned char*)g->getData();
		love::image::pixel * pixels = (love::image::pixel *)(imageData->getData());
		for (unsigned int i = 0; i < widths[glyph]*getHeight(); i++) {
			love::image::pixel p = pixels[ positions[glyph] + (i % widths[glyph]) + (imageData->getWidth() * (i / widths[glyph])) ];
			gd[i*4] = p.r;
			gd[i*4+1] = p.g;
			gd[i*4+2] = p.b;
			gd[i*4+3] = p.a;
		}
		return g;
	}
Example #12
0
GlyphData *ImageRasterizer::getGlyphData(uint32 glyph) const
{
	GlyphMetrics gm = {};

	// Set relevant glyph metrics if the glyph is in this ImageFont
	std::map<uint32, ImageGlyphData>::const_iterator it = imageGlyphs.find(glyph);
	if (it != imageGlyphs.end())
	{
		gm.width = it->second.width;
		gm.advance = it->second.width + extraSpacing;
	}

	gm.height = metrics.height;

	GlyphData *g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA);

	if (gm.width == 0)
		return g;

	// We don't want another thread modifying our ImageData mid-copy.
	love::thread::Lock lock(imageData->getMutex());

	love::image::pixel *gdpixels = (love::image::pixel *) g->getData();
	love::image::pixel *imagepixels = (love::image::pixel *) imageData->getData();

	// copy glyph pixels from imagedata to glyphdata
	for (int i = 0; i < g->getWidth() * g->getHeight(); i++)
	{
		love::image::pixel p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))];

		// Use transparency instead of the spacer color
		if (equal(p, spacer))
			gdpixels[i].r = gdpixels[i].g = gdpixels[i].b = gdpixels[i].a = 0;
		else
			gdpixels[i] = p;
	}

	return g;
}
Example #13
0
int w_GlyphData_getAdvance(lua_State *L)
{
	GlyphData *t = luax_checkglyphdata(L, 1);
	lua_pushinteger(L, t->getAdvance());
	return 1;
}