// Generates the geometry required to render a single line of text.
int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index, word default_character) const
{
	int geometry_index = 0;
	int line_width = 0;

	ROCKET_ASSERT(layer_configuration_index >= 0);
	ROCKET_ASSERT(layer_configuration_index < (int) layer_configurations.size());

	// Fetch the requested configuration and generate the geometry for each one.
	const LayerConfiguration& layer_configuration = layer_configurations[layer_configuration_index];
	for (size_t i = 0; i < layer_configuration.size(); ++i)
	{
		FontFaceLayer* layer = layer_configuration[i];

		Colourb layer_colour;
		if (layer == base_layer)
			layer_colour = colour;
		else
			layer_colour = layer->GetColour();

		// Resize the geometry list if required.
		if ((int) geometry.size() < geometry_index + layer->GetNumTextures())
			geometry.resize(geometry_index + layer->GetNumTextures());

		// Bind the textures to the geometries.
		for (int i = 0; i < layer->GetNumTextures(); ++i)
			geometry[geometry_index + i].SetTexture(layer->GetTexture(i));

		line_width = 0;
		word prior_character = 0;

		const word* string_iterator = string.CString();
		const word* string_end = string.CString() + string.Length();
		word final_character;

		for (; string_iterator != string_end; string_iterator++)
		{
			final_character = *string_iterator;
			FontGlyphMap::const_iterator iterator = glyphs.find(*string_iterator);

			if (iterator == glyphs.end())
			{
				if (default_character >= 32)
				{
					iterator = glyphs.find(default_character);
					if (iterator == glyphs.end())
					{
						continue;
					}
					else
					{
						final_character = default_character;
					}
				}
				else
				{
					continue;
				}
			}

			// Adjust the cursor for the kerning between this character and the previous one.
			if (prior_character != 0)
				line_width += GetKerning(prior_character, final_character);

			layer->GenerateGeometry(&geometry[geometry_index], final_character, Vector2f(position.x + line_width, position.y), layer_colour);

			line_width += iterator->second.advance;
			prior_character = final_character;
		}

		geometry_index += layer->GetNumTextures();
	}

	// Cull any excess geometry from a previous generation.
	geometry.resize(geometry_index);

	return line_width;
}