// Generates the character and texture data for the layer.
bool FontFaceLayer::Initialise(const FontFaceHandle* _handle, FontEffect* _effect, const FontFaceLayer* clone, bool deep_clone)
{
	handle = _handle;
	effect = _effect;
	if (effect != NULL)
	{
		effect->AddReference();
		colour = effect->GetColour();
	}

	const FontGlyphMap& glyphs = handle->GetGlyphs();

	// Clone the geometry and textures from the clone layer.
	if (clone != NULL)
	{
		// Copy the cloned layer's characters.
		characters = clone->characters;

		// Copy (and reference) the cloned layer's textures.
		for (size_t i = 0; i < clone->textures.size(); ++i)
			textures.push_back(clone->textures[i]);

		// Request the effect (if we have one) adjust the origins as appropriate.
		if (!deep_clone &&
			effect != NULL)
		{
			for (FontGlyphMap::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
			{
				const FontGlyph& glyph = i->second;

				CharacterMap::iterator character_iterator = characters.find(i->first);
				if (character_iterator == characters.end())
					continue;

				Character& character = character_iterator->second;

				Vector2i glyph_origin(Math::RealToInteger(character.origin.x), Math::RealToInteger(character.origin.y));
				Vector2i glyph_dimensions(Math::RealToInteger(character.dimensions.x), Math::RealToInteger(character.dimensions.y));

				if (effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, glyph))
				{
					character.origin.x = (float) glyph_origin.x;
					character.origin.y = (float) glyph_origin.y;
				}
				else
					characters.erase(character_iterator);
			}
		}
	}
	else
	{
		return AddNewGlyphs();
	}


	return true;
}
Exemple #2
0
// Generates the character and rectangle for a glyph.
void FontFaceLayer::GenerateCharacter( const FontGlyph& glyph )
{
	ROCKET_ASSERT(glyph.character < characters.size());
	if (characters[glyph.character])
		return;

	Vector2i glyph_origin(0, 0);
	Vector2i glyph_dimensions = glyph.bitmap_dimensions;

	// Adjust glyph origin / dimensions for the font outline effect.
	if (effect != NULL && effect->HasUniqueTexture())
	{
		if (!effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, glyph))
			return;
	}

	Character* character = new Character();
	character->origin = Vector2f((float) (glyph_origin.x + glyph.bearing.x), (float) (glyph_origin.y - glyph.bearing.y));
	character->dimensions = Vector2f((float) glyph_dimensions.x - glyph_origin.x, (float) glyph_dimensions.y - glyph_origin.y);
	characters[glyph.character] = character;

	//  Only adjust glyph origin for the font shadow effect.
	if (effect != NULL && !effect->HasUniqueTexture())
	{
		Vector2i glyph_origin(Math::RealToInteger(character->origin.x), Math::RealToInteger(character->origin.y));
		Vector2i glyph_dimensions(Math::RealToInteger(character->dimensions.x), Math::RealToInteger(character->dimensions.y));

		if (effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, glyph))
		{
			character->origin.x = (float) glyph_origin.x;
			character->origin.y = (float) glyph_origin.y;
		}
		else
			character->texture_index = -1;
	}
	else
		// Add the character's dimensions into the texture layout engine.
		texture_layout.AddRectangle(glyph.character, glyph_dimensions - glyph_origin);
}
Exemple #3
0
// Generates the character and texture data for the layer.
bool FontFaceLayer::Initialise(const FontFaceHandle* _handle, FontEffect* _effect, const FontFaceLayer* clone, bool deep_clone)
{
	handle = _handle;
	effect = _effect;
	if (effect != NULL)
	{
		effect->AddReference();
		colour = effect->GetColour();
	}

	const FontGlyphList& glyphs = handle->GetGlyphs();

	// Clone the geometry and textures from the clone layer.
	if (clone != NULL)
	{
		// Copy the cloned layer's characters.
		size_t character_count = clone->characters.size();
		characters.resize(character_count, NULL);
		for (size_t i = 0; i < character_count; ++i)
		{
			const Character* clone_character = clone->characters[i];
			if (clone_character)
				characters[i] = new Character(*clone_character);
		}

		// Copy (and reference) the cloned layer's textures.
		for (size_t i = 0; i < clone->textures.size(); ++i)
			textures.push_back(new Texture(*clone->textures[i]));

		// Request the effect (if we have one) adjust the origins as appropriate.
		if (!deep_clone &&
			effect != NULL)
		{
			for (FontGlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
			{
				const FontGlyph* glyph = *i;
				if (!glyph)
					continue;

				if (glyph->character >= character_count)
					continue;

				Character* character = characters[glyph->character];
				ROCKET_ASSERT(character);

				Vector2i glyph_origin(Math::RealToInteger(character->origin.x), Math::RealToInteger(character->origin.y));
				Vector2i glyph_dimensions(Math::RealToInteger(character->dimensions.x), Math::RealToInteger(character->dimensions.y));

				if (effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, *glyph))
				{
					character->origin.x = (float) glyph_origin.x;
					character->origin.y = (float) glyph_origin.y;
				}
				else
					character->texture_index = -1;
			}
		}
	}
	else
	{
		// Initialise the texture layout for the glyphs.
		characters.resize(glyphs.size(), NULL);
		for (FontGlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
		{
			const FontGlyph* glyph = *i;
			if (!glyph)
				continue;

			GenerateCharacter(*glyph);
		}

		if (!GenerateLayout())
			return false;
	}

	return true;
}
// Generates the character and texture data for the layer.
bool FontFaceLayer::Initialise(const FontFaceHandle* _handle, FontEffect* _effect, const FontFaceLayer* clone, bool deep_clone)
{
	handle = _handle;
	effect = _effect;
	if (effect != NULL)
	{
		effect->AddReference();
		colour = effect->GetColour();
	}

	const FontGlyphList& glyphs = handle->GetGlyphs();

	// Clone the geometry and textures from the clone layer.
	if (clone != NULL)
	{
		// Copy the cloned layer's characters.
		characters = clone->characters;

		// Copy (and reference) the cloned layer's textures.
		for (size_t i = 0; i < clone->textures.size(); ++i)
			textures.push_back(clone->textures[i]);

		// Request the effect (if we have one) adjust the origins as appropriate.
		if (!deep_clone &&
			effect != NULL)
		{
			for (FontGlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
			{
				const FontGlyph& glyph = *i;

				if (glyph.character >= characters.size())
					continue;

				Character& character = characters[glyph.character];

				Vector2i glyph_origin(Math::RealToInteger(character.origin.x), Math::RealToInteger(character.origin.y));
				Vector2i glyph_dimensions(Math::RealToInteger(character.dimensions.x), Math::RealToInteger(character.dimensions.y));

				if (effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, glyph))
				{
					character.origin.x = (float) glyph_origin.x;
					character.origin.y = (float) glyph_origin.y;
				}
				else
					character.texture_index = -1;
			}
		}
	}
	else
	{
		// Initialise the texture layout for the glyphs.
		characters.resize(glyphs.size(), Character());
		for (FontGlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
		{
			const FontGlyph& glyph = *i;

			Vector2i glyph_origin(0, 0);
			Vector2i glyph_dimensions = glyph.bitmap_dimensions;

			// Adjust glyph origin / dimensions for the font effect.
			if (effect != NULL)
			{
				if (!effect->GetGlyphMetrics(glyph_origin, glyph_dimensions, glyph))
					continue;
			}

			Character character;
			character.origin = Vector2f((float) (glyph_origin.x + glyph.bearing.x), (float) (glyph_origin.y - glyph.bearing.y));
			character.dimensions = Vector2f((float) glyph_dimensions.x - glyph_origin.x, (float) glyph_dimensions.y - glyph_origin.y);
			characters[glyph.character] = character;

			// Add the character's dimensions into the texture layout engine.
			texture_layout.AddRectangle(glyph.character, glyph_dimensions - glyph_origin);
		}

		// Generate the texture layout; this will position the glyph rectangles efficiently and
		// allocate the texture data ready for writing.
		if (!texture_layout.GenerateLayout(512))
			return false;


		// Iterate over each rectangle in the layout, copying the glyph data into the rectangle as
		// appropriate and generating geometry.
		for (int i = 0; i < texture_layout.GetNumRectangles(); ++i)
		{
			TextureLayoutRectangle& rectangle = texture_layout.GetRectangle(i);
			const TextureLayoutTexture& texture = texture_layout.GetTexture(rectangle.GetTextureIndex());
			Character& character = characters[(word) rectangle.GetId()];

			// Set the character's texture index.
			character.texture_index = rectangle.GetTextureIndex();

			// Generate the character's texture coordinates.
			character.texcoords[0].x = float(rectangle.GetPosition().x) / float(texture.GetDimensions().x);
			character.texcoords[0].y = float(rectangle.GetPosition().y) / float(texture.GetDimensions().y);
			character.texcoords[1].x = float(rectangle.GetPosition().x + rectangle.GetDimensions().x) / float(texture.GetDimensions().x);
			character.texcoords[1].y = float(rectangle.GetPosition().y + rectangle.GetDimensions().y) / float(texture.GetDimensions().y);
		}


		// Generate the textures.
		for (int i = 0; i < texture_layout.GetNumTextures(); ++i)
		{
			Texture texture;
			if (!texture.Load(String(64, "?font::%p/%p/%d", handle, effect, i)))
				return false;

			textures.push_back(texture);
		}
	}


	return true;
}