// Attempts to position unplaced rectangles from the layout into this row.
int TextureLayoutRow::Generate(TextureLayout& layout, int max_width, int y)
{
	int placed_rectangles = 0;

	while(!layout.unplaced_rectangles.empty())
	{
		TextureLayoutRectangle* rectangle = layout.unplaced_rectangles.front();
		if (placed_width + rectangle->GetDimensions().x + 1 > max_width)
			break;

		// Increment the row height if necessary.
		height = Math::Max(height, rectangle->GetDimensions().y);

		// Add this glyph onto our list and mark it as placed.
		rectangles.push_back(rectangle);
		if (layout.has_generated)
			rectangle->Place(layout.GetNumTextures()-1, Vector2i(placed_width, y));
		else
			rectangle->Place(layout.GetNumTextures(), Vector2i(placed_width, y));
		++placed_rectangles;

		// Increment our width. An extra pixel is added on so the rectangles aren't pushed up
		// against each other. This will avoid filtering artifacts.
		if (rectangle->GetDimensions().x > 0)
			placed_width += rectangle->GetDimensions().x + 1;

		layout.rectangles.push_back(rectangle);
		layout.unplaced_rectangles.pop();
	}

	return placed_rectangles;
}
Exemple #2
0
// Generates the texture data for a layer (for the texture database).
bool FontFaceLayer::GenerateTexture(int texture_id)
{
	if (texture_id < 0 ||
		texture_id > texture_layout.GetNumTextures())
		return false;

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

	// Generate the texture data.
	TextureLayoutTexture* texture = texture_layout.GetTexture(texture_id);
	if (texture && !texture->GetTextureData())
		texture->AllocateTexture();

	int rectangle_count = texture_layout.GetNumRectangles();
	for (int i = 0; i < rectangle_count; ++i)
	{
		TextureLayoutRectangle* rectangle = texture_layout.GetRectangle(i);
		if (rectangle->GetTextureIndex() != texture_id)
			continue;

		Character* character = characters[(word) rectangle->GetId()];	
		if (!character)
			continue;

		const FontGlyph* glyph = glyphs[rectangle->GetId()];
		if (!glyph)
			continue;

		if (effect == NULL)
		{
			// Copy the glyph's bitmap data into its allocated texture.
			if (glyph->bitmap_data != NULL)
			{
				byte* destination = rectangle->GetTextureData();
				byte* source = glyph->bitmap_data;

				for (int j = 0; j < glyph->bitmap_dimensions.y; ++j)
				{
					for (int k = 0; k < glyph->bitmap_dimensions.x; ++k)
						destination[k * 4 + 3] = source[k];

					destination += rectangle->GetTextureStride();
					source += glyph->bitmap_dimensions.x;
				}
			}
		}
		else
		{
			effect->GenerateGlyphTexture(rectangle->GetTextureData(), Vector2i(Math::RealToInteger(character->dimensions.x), Math::RealToInteger(character->dimensions.y)), rectangle->GetTextureStride(), *glyph);
		}
	}

	return true;
}
Exemple #3
0
TextureLayout& TextureLayout::operator+=(const TextureLayout &layout)
{
  const int texture_size = GetNumTextures();

  for (TextureList::const_iterator i = layout.textures.begin(); i != layout.textures.end(); ++i)
  {
    TextureLayoutTexture *texture = *i;

    texture->AddReference();
    textures.push_back(texture);
  }
  for (RectangleList::const_iterator i = layout.rectangles.begin(); i != layout.rectangles.end(); ++i)
  {
    TextureLayoutRectangle *rect = *i;

    rect->AddReference();
    rect->Place(texture_size + rect->GetTextureIndex(), rect->GetPosition());
    rectangles.push_back(rect);
  }

  return *this;
}
Exemple #4
0
// Generate texture layout for all unplaced characters
bool FontFaceLayer::GenerateLayout()
{
	int prior_num_rectangles = texture_layout.GetNumRectangles();
	int prior_num_textures = texture_layout.GetNumTextures();

	// 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.
	int rectangle_count = texture_layout.GetNumRectangles();
	for (int i = prior_num_rectangles; i < rectangle_count; ++i)
	{
		TextureLayoutRectangle* rectangle = texture_layout.GetRectangle(i);
		Character* character = characters[(word) rectangle->GetId()];
		if (!character)
			continue;
		const TextureLayoutTexture* texture = texture_layout.GetTexture(rectangle->GetTextureIndex());

		// 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);
	}

	if (prior_num_textures > 0 && prior_num_rectangles != rectangle_count)
		textures[prior_num_textures-1]->Update();

	// Generate the textures.
	int texture_count = texture_layout.GetNumTextures();
	for (int i = prior_num_textures; i < texture_count; ++i)
	{
		Texture* texture = new Texture();
		if (!texture->Load(String(64, "?font::%p/%p/%d/%p", handle, effect, i, texture_layout.GetTexture(i))))
		{
			delete texture;
			return false;
		}

		textures.push_back(texture);
	}

	return true;
}
Exemple #5
0
	bool operator()(const TextureLayoutRectangle& lhs, const TextureLayoutRectangle& rhs) const
	{
		return lhs.GetDimensions().y > rhs.GetDimensions().y;
	}